Skip to main content

Ping Pong Bot

Ping Pong Bot คืออะไร?

หลักการของปิงปองบอทคือเมื่อ user พิมพ์ข้อความว่า "ping" ลงใน server ตัวบอทของเราก็จะส่งข้อความว่า "pong" กลับมานั่นเอง โดยในการสร้างปิงปองบอทนั้น เริ่มจาก

สร้าง Ping Pong Bot
1. สร้าง discord connection 

ขั้นแรกให้น้องๆสร้างไฟล์ที่ชื่อว่า main.py แล้วเขียนโค้ดตามด้านล่างนี้ไป

import discord
from discord.ext import commands

TOKEN = "MTE4NDgzNTY0NDk0NjY1NzI4MA.G2fFfc.lxYxgLY-EOgh39tFfCO_MSrH10p7Ig9byjJ1vE"
client = commands.Bot(command_prefix="!", intents=discord.Intents.all())

@client.event
async def on_ready():
    print(f'{client.user} has connected to Discord!')

client.run(TOKEN)

โดยน้องๆสามารถเอา token มาจากหน้า Bot ใน Developer Portal  ในส่วนของ Build-A-Bot แล้วกด copy token ของบอทมาใส่ 

7.png

client คือ object ที่แสดงถึง discord connection, โดย client จะทำหน้าที่จัดการ event, ติดตามสถานะ , และโต้ตอบกับกับ discord APIs

ซึ่งในโค้ดด้านบน น้องๆได้สร้าง client และใช้ on_ready event ซึ่งจะถูกเรียกเมื่อ client ได้สร้างการเชื่อมต่อกับ Discord เรียบร้อยแล้ว

เมื่อน้องๆรัน  python main.py ใน terminal น้องๆจะเห็นข้อความว่า "JPCBot#8035 has connected to Discord!" ขึ้นมา

2. responding to messages 
import discord
from discord.ext import commands

TOKEN = "MTE4NDgzNTY0NDk0NjY1NzI4MA.G2fFfc.lxYxgLY-EOgh39tFfCO_MSrH10p7Ig9byjJ1vE"
client = commands.Bot(command_prefix="!", intents=discord.Intents.all())

@client.event
async def on_ready():
    print(f'{client.user} has connected to Discord!')

@client.event
async def on_message(message):
    if message.author == client.user:
        return

    if message.content == 'ping':
        # Get the member who sent the message
        member = message.author

        # Send a DM to the member
        await member.create_dm()
        await member.dm_channel.send("pong")

        # Send message to channel
        await message.channel.send("pong")
client.run(TOKEN)

จากโค้ดด้านบน on_message() event จะถูกเรียกใช้เมื่อมี message ใหม่เข้ามาใน server โดยเมื่อ message ใหม่ที่เข้ามาตรงกับเงื่อนไขในโค้ดบรรทัดที่ 16 ซึ่งก็คือเมื่อ message.content == 'ping' ตัวบอทของเราจะส่งข้อความกลับมาใน channel server และใน dm ว่า pong 

ในส่วนของบรรทัด 13-14 เป็นการเช็คว่าข้อความนั้นไม่ใช้ข้อความที่ส่งมาโดยตัวบอทเอง เพื่อป้องกันการเกิน loop หรือการตอบกลับที่ไม่จำเป็นในบางเคส

3. using Bot command

ในส่วนนี้เราจะมาลองใช้ command แทนการใช้ event กัน โดยการใช้ command เป็นการเรียกใช้ฟังก์ชั่นต่างๆผ่าน command prefix + command name

import discord
from discord.ext import commands

TOKEN = "MTE4NDgzNTY0NDk0NjY1NzI4MA.G2fFfc.lxYxgLY-EOgh39tFfCO_MSrH10p7Ig9byjJ1vE"
client = commands.Bot(command_prefix="!", intents=discord.Intents.all())

@client.event
async def on_ready():
    print(f'{client.user} has connected to Discord!')

@client.command(name='ping')
async def pingpong(ctx):

    # Sending a message to the channel
    await ctx.send('pong!')

    # Sending a message to the user's DM
    user = ctx.message.author
    await user.create_dm()
    await user.dm_channel.send('pong!')

client.run(TOKEN)

น้องๆ สามารถลองพิมพ์ !ping ใน server ของน้องๆ แล้วตัวบอทก็จะตอบกลับข้อความว่า pong เหมือนโค้ดก่อนหน้า และน้องๆยังสามารถเปลี่ยน prefix ตามใจชอบ เช่น / ? แทน ! ได้เหมือนกัน

command แตกต่างจากใช้ event ยังไง?
  • ฟังก์ชันนี้จะถูกเรียกใช้เมื่อมีการใช้คำสั่ง !ping ในแชทเท่านั้น ซึ่งจะแตกต่างจาก event on_message() ที่ถูกเรียกทุกครั้งที่ user ส่งข้อความ ไม่ว่าเนื้อหาจะเป็นอะไรก็ตาม 
  • การใช้ command จะต้องขึ้นต้นด้วย prefix เท่านั้น ซึ่งในที่นี้ก็คือ ! 
4. Checking command predicates 

เราจะเติม @commands.has_role('ADMIN!!') ที่ด้านล่างของ command ซึ่งเป็นการอนุญาตแค่บาง role ( ADMIN!! )ในการเรียกใช้ command นั้นๆ 

import discord
from discord.ext import commands

TOKEN = "MTE4NDgzNTY0NDk0NjY1NzI4MA.G2fFfc.lxYxgLY-EOgh39tFfCO_MSrH10p7Ig9byjJ1vE"
client = commands.Bot(command_prefix="!", intents=discord.Intents.all())

@client.event
async def on_ready():
    print(f'{client.user} has connected to Discord!')

@client.command(name='ping')
@commands.has_role('ADMIN!!')
async def pingpong(ctx):

    # Sending a message to the channel
    await ctx.send('pong!')

    # Sending a message to the user's DM
    user = ctx.message.author
    await user.create_dm()
    await user.dm_channel.send('pong!')

@client.event
async def on_command_error(ctx, error):
    if isinstance(error, commands.errors.CheckFailure):
        await ctx.send('You do not have the correct role for this command.')
    
client.run(TOKEN)

และใช้ on_command_error เพื่อจัดการกับเคสที่ไม่เข้าเงื่อนไข role ของ command โดยเมื่อ user ที่ไม่ใช่ role ADMIN!! เมื่อใช้คำสั่ง !ping บอทจะส่งข้อความกลับมาว่า "You do not have the correct role for this command."