สร้างบอท Discord ไว้คุยกับทีมแบบง่ายๆกันเถอะ
พอดีทีมใช้ Discord ในการคุยงานกัน และจะสร้างบอทวันลา เลยลองมาสร้างบอทใน Discord ดูกันเนอะ

ดังนั้นเราลองมาทำบอทแบบง่ายๆใน Discord กัน ก่อนอื่นต้องรู้ภาษา JavaScript มานิดหน่อย แล้วในที่นี้ไม่ต้องรันผ่าน server จริงเลยก็ใช้ทดสอบได้นะ
ทำความเข้าใจเกี่ยวกับบอทสักนิดนึง
หลายๆคนคงเคยอ่าน blog ที่เกี่ยวกับ chatbot ของเราบ้างแล้ว จากที่ไป research ของฝั่ง Discord มานั้น ทำได้ 2 แบบด้วยกัน ขอใช้คำอ้างอิงจากคอร์ส Building LINE Chatbot using DialogFlow นะ เพื่อให้เข้าใจได้ง่ายๆ
- Push Message : ก็คือบอทส่งข้อความหาเราอย่างเดียว เราจะส่งข้อความไปหาบอทไม่ได้ อันนี้ก็จะเป็นการยิง message ไปยัง webhook ของ channel ใน server เนอะ บอทประเภทนี้จะอยู่แค่ channel เดียวเพราะมันผูก webhook ไว้ ในบล็อกนี้ยังไม่พูดถึงและจะแยกไปอีกบล็อกนึงเลย เหมาะกับพวกประมาณว่า ให้บอทเตือนว่ามา standup meeting ได้แล้วจ้า อย่าลืมกินข้าวเที่ยงนะ เป็นต้น
อันนี้มีบล็อกแล้ว ไปอ่านได้ด้านล่างจ้า

- Reply Message : สร้างน้องบอทมา แล้ว invite เข้า server เหมือน user ปกติเลย เมื่อเราพิมพ์ข้อความหาบอท บอทจะตอบเรา ไม่ว่าเราจะพิมพ์อะไรลอยๆใน channel ไหนก็ตาม มันก็ตามเราไปตอบที่นั่น เปรียบดังเงาตามตัว 555
บล็อกนี้เราจะเขียนเฉพาะส่วนพื้นฐานการใช้งานเนอะ คือจริงๆมันสามารถเชื่อมกับ ervice 3rd-party ต่างๆ เช่น Google Calendar แล้วก็พวก gif น้องหลังบ้านใช้ tenor แล้วเพราะใช้ giphy สุ่มแล้วไม่ค่อยถูกใจเท่าไหร่ 555555 ก็คือจริงๆน้องหลังบ้าน implement ไปเยอะมากๆแล้ว เรายังตามน้องไม่ทันเลย5555555555555555
สร้างบอทใน Discord

- ไปที่ Discord Developer Portal เลือก New Application และใส่ข้อมูลต่างๆให้เรียบร้อย จากนั้นกด Create เลยจ้า

- ไปที่แท็บ Bot กด Add bot แล้วคลิก popup เพื่อ confirm ในการสร้าง



- token ของ bot ก็คือ password ของบอทนั่นเอง เก็บรักษาดีๆอย่าเอาไปให้ใครง่ายๆ โดยตัว token หน้าตาจะประมาณนี้
NzkyNzE1NDU0MTk2MDg4ODQy.X-hvzA.Ovy4MCQywSkoMRRclStW4xAYK7I
ถ้าดันได้สั้นๆมา ให้ใช้ client secret แทน

- สาเหตุที่ต้องรักษา token ไว้ให้ดีเพราะว่าถ้าบอทเราเปิด public ให้คนใช้เยอะๆ ตัวบอทอาจจะโดนคนที่ไม่หวังดี spam ได้ แนะนำให้เก็บไว้ที่ Environment variables
จากนั้น invite bot เข้า server โดยใช้ไปที่ OAuth2 แล้วไปที่ SCOPES จิ้มเลือก bot จากนั้นก็อปลิ้งออกมา ส่วน BOT PERMISSIONS เลือกที่ Administrator

นำลิ้งที่ copy มาไปเปิดที่ browser จากนั้นทำการเลือก server โดยคนที่ลากเข้า server ได้นั้น จะต้องเป็น admin ของ server เท่านั้นนะ

จากนั้นให้ permission น้องบอทไป เป็นอันเสร็จสิ้น

และน้องบอทเรานั้นยังไม่ได้กำเนิด ดังนั้นเราจะทำการ implement เพื่อให้น้องบอทนั้นมีชีวิตจิตใจต่อไป

ปลุกน้องบอทให้มีชีวิตด้วยโค้ด
ขั้นตอนการเขียนโค้ดเนอะ เราจะต้อง setup อะไรให้เรียบร้อย และทำการเรียนรู้การใช้ discord.js ไปพร้อมๆกัน
Setup
- ลง node.js ให้เรียบร้อย โดยตัว discord.js จะรองรับ version 12 หรือมากกว่านะ สามารถตรวจสอบ version ได้โดยพิมพ์ command
node -v
- สร้าง folder project
- ทำการ init มันก่อน
npm init
- ลง discord.js โดยใช้ command
npm install discord.js --save
เจอ warning ไม่ต้องตกใจ มันทำงานได้ตามปกติ - จากนั้นทำการสร้าง
package.json
เพื่อให้คนอื่นๆสามารถลง 3rd-party library ตรงกับ version ที่เราใช้ ด้วย commandnpm init
- ลง
npm install eslint
และ set rule อันนี้ optional - จากการเรียน Node.js Crash Course นั้น เราคิดว่าควรจะลงเจ้า nodemon ไว้ เพราะเวลาที่เรา save code แล้วรันใหม่ได้เลยไม่ต้องเรียกทุกครั้งหลังจาก save โดยเราจะลงผ่าน command
npm install nodemon --save-dev
ที่มี-dev
เพราะเราจะใช้ในตอนที่เรา develop นั่นเอง จากนั้นใส่เพิ่มในpackage.json
ในส่วนของ script
"scripts": {
"start": "nodemon index.js"
}
เริ่ม coding
ก่อนอื่นเราจะให้ทุกคนดูโค้ดเต็มในช่วงแรกก่อนเนอะ เพราะมีเรื่อง refactor code ไปเรื่อยๆด้วย เพื่อทำความเข้าใจกันก่อนเนอะ
ก่อนอื่นทำการ import discord.js เข้ามาในโปรเจกของเราก่อน
const Discord = require('discord.js');
จากนั้นสร้าง object ของ Discord client ขึ้นมา
const client = new Discord.Client();
ถ้าเราต่อเรียบร้อยแล้ว
client.once('ready', () => {
console.log('Ready!');
});
จากนั้นเราจะทำการ login ด้วย token ที่ได้จากการสร้างบอท
const config = require("./config.json");
client.login(config.token);
การเก็บ token ก็จะมี 2 แบบ คือ
- ในที่นี้จะใส่ไว้ใน
config.json
ข้างในเป็นไฟล์ json ธรรมดา ที่มีหน้าตาแบบนี้
{
"token": "YOUR_BOT_TOKEN"
}
- ไปใส่ไว้ในไฟล์
process.env
ไว้แบบนี้
TOKEN=YOUR_BOT_TOKEN
การนำ token ใน process.env
นี้ไปใช้งานนั้น จะต้องทำการ install ตัว dotenv
ก่อน
npm install dotenv —save
จากนั้นนำไปใช้งานในการ login เข้ามา
client.login(process.env.DISCORD_TOKEN);
ถ้าเอาไปใช้จริงบน server บางเจ้าเราก็สามารถเพิ่มตัวแปร environment แล้วใส่ token เข้าไปได้ เพื่อความปลอดกันเนอะ
แล้วบอทจะดัก message ที่เราๆพิมพ์มาใน Discord ตอนไหนนะ? เราจะต้อง implement ในส่วน listener ใน event ที่ชื่อว่า message
client.on('message', message => {
console.log(message.content);
// read message and reply with BB-8
if (message.content === '!ping') {
message.channel.send('beep! beep!');
}
});
จากนั้น condition ต่างๆก็จะอยู่ใน callback ของอันนี้เนอะ เราจะทำการ check ว่า ถ้าเราพิมพ์ว่า !ping
จะให้บอทส่งมาว่า beep! beep!
โดยเราจะดึงสิ่งที่เราพิมพ์ไปผ่าน message.content
นั่นเอง
อ่ะ มันต้องมีคนสงสัย ทำไมต้องเป็น ! นำหน้าหล่ะ อันนี้แล้วแต่เลย อาจจะเป็นประโยคธรรมดาๆ เช่น "หิวจัง วันนี้กินอะไรดี" ก็ได้นะ แล้วแต่เราเลย แต่เขานิยมใช้ prefix !
กัน ทางเราเข้าใจว่าที่เป็นน้องเครื่องหมายตกใจ เพราะมีมนุษย์คนไหนใส่เครื่องหมายตกใจหน้าประโยคไหม ก็ไม่ และจะได้แยกออกว่าคุยกับบอทด้วยมั้งนะ
จากนั้นทำการ deploy ใน develop ก่อนโดยพิมพ์คำสั่ง npm start
บอทเราก็จะใช้งานได้แล้วนะ

แต่เมื่อเราทำการปิด develop server บอทก็จะนอนหลับไป เพราะในที่นี้เราจะลองใน local ก่อนเนอะ
หลังจากเราทำตามตัวอย่าง พบว่าหลายๆคำสั่งที่จะให้บอทตอบนั้น ล้วนมี prefix เป็น ! ทั้งสิ้น ดังนั้นไปประกาศตัวแปร prefix กันก่อน
const prefix = '!';
และเริ่มทำการ refactor กันต่อ ภายใน client.on('message', message => {}
เราจะทำการดักว่าถ้าเราใส่ prefix เช่นคุยกับเพื่อน หรือบอทเป็นคนส่งข้อความมา ก็ไม่ต้องทำอะไร return ออกไป
if (!message.content.startsWith(prefix) || message.author.bot) return;
และถ้าเราอยากจะ refactor ให้สวยงาม และรองรับบาง command ที่เราใส่ argument ต่างๆ เช่น เราต้องการหา gif ที่เราต้องการ เราจะพิมพ์คำสั่งว่า !gf smile
เราก็จะได้ command ที่ชื่อว่า gf
และ parameter ในการเอาไปใช้หา gif ต่อก็คือ smile
นั่นเอง
const commandBody = message.content.slice(prefix.length)
const args = commandBody.split(' ');
const command = args.shift().toLowerCase();
และ function ที่เราทำทั้งหมดคร่าวๆก็จะประมาณนี้
if (command === 'ping') {
message.channel.send('beep! beep!');
} else if (command === 'beep') {
message.channel.send('boop! boop!.');
} else if (command === 'server') {
message.channel.send(`Server name: ${message.guild.name}\nTotal members: ${message.guild.memberCount}`);
} else if (command === 'help') {
message.channel.send('BB-8 Calendar');
}
แล้วใน message
มีอะไรบ้างหล่ะ?
หลักๆที่ลองเล่นดูจะมีแบบนี้
message.author
ชื่อคนที่คุยกับบอท บอทจะส่งกลับโดยการ mention กลับไปหาmessage.guild.name
ชื่อ servermessage.guild.memberCount
จำนวนคนใน server
เมื่อเรามีหลายๆ feature ที่เพิ่มมากขึ้น ทำไฟล์เดียวโค้ดมันจะรก ดังนั้นเราสามารถสร้างไฟล์เพื่อทำส่วน library และเอาไปใช้ในไฟล์หลักของเราได้เนอะ
ในบล็อกนี้ก็หวังว่าพอจะทำ Discord bot แบบเบื้องต้นได้เนอะ :D
Reference

ติดตามข่าวสารตามช่องทางต่าง ๆ และทุกช่องทางโดเนทกันไว้ที่นี่เลย
ติดตามข่าวสารแบบไว ๆ มาที่ Twitter เลย บางอย่างไม่มีในบล็อก และหน้าเพจนะ
สวัสดีจ้า ฝากเนื้อฝากตัวกับชาวทวิตเตอร์ด้วยน้าา
— Minseo | Stocker DAO (@mikkipastel) August 24, 2020