ทำ Discord bot แจ้งเตือนคนในทีมให้ไปประชุม
การประชุมเป็นส่วนหนึ่งในกิจวัตรประจำวัน ตามพิธีกรรมใน Agile ดังนั้น เราก็เลยลองทำดู ว่ามันทำยังไงได้บ้างนะ
ทำความเข้าใจเกี่ยวกับบอทสักนิดนึง
หลายๆคนคงเคยอ่าน 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
ในบล็อกนี้เราจะกล่าวถึง bot ที่ส่งข้อความหาเราฝ่ายเดียว ซึ่งมันจะ fix เฉพาะห้องเนอะ เพราะต้องใช้ webhook ของ channel นั้นๆใน Discord นั่นเอง
webhook คืออะไร? เอาแบบสั้นๆ เพราะเมื่อก่อนก็ตอบคำถามนี้กับตัวเองไม่ได้เหมือนกัน ก็คือที่อยู่ในการส่งข้อความ โดยไม่ต้องผ่านแอพ
วิธีการนำ webhook ของ channel ออกมา
ใน server นั้น เราจะต้องมี role เป็น Admin เท่านั้น ถึงจะทำได้นะ
อ่ะถ้าเป็น Admin แล้ว ให้ไปที่ channel ที่เราต้องการ แล้วคลิกที่เจ้าฟันเฟือง เพื่อทำการ Edit Channel เนอะ
ไปที่ Integrations กดที่ Create Webhook เพื่อสร้าง webhook นี้ขึ้นมาเนอะ
จากนั้นทำการใส่รูป ชื่อ และ channel ที่ต้องการ โดย 1 webhook จะใส่ได้แค่ 1 channel เท่านั้นนะ
เมื่อเรียบร้อยแล้วกด save
แล้วทำการ Copy Webhook URL มา โดยหน้าตาของตัว webhook จะเป็นดังนี้
https://discord/com/api/webhooks/{id}/{token}
ในสิ่งที่เราได้ทำการ copy ไปนั้น เราจะใช้ส่วน id
และ token
ต่อในโค้ดของเราจ้า
และตัว webhook ที่ได้นั้น เมื่อนำไปยิง GET ใน Postman แล้ว เราจะได้ตัว channel_id
และ guild_id
ไปใช้ต่อไปได้จ้า
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
- จากการเรียน Node.js Crash Course นั้น เราคิดว่าควรจะลงเจ้า nodemon ไว้ เพราะเวลาที่เรา save code แล้วรันใหม่ได้เลยไม่ต้องเรียกทุกครั้งหลังจาก save โดยเราจะลงผ่าน command
npm install nodemon --save-dev
ที่มี-dev
เพราะเราจะใช้ในตอนที่เรา develop นั่นเอง จากนั้นใส่เพิ่มในpackage.json
ในส่วนของ script
"scripts": {
"start": "nodemon index.js"
}
เริ่มทำการยิงข้อความไปหา channel ของเรากันเถอะ
ก่อนอื่นสร้างเจ้า webhook client มากันก่อนจ้า
การนำ webhook มาใช้สำหรับ single webhook มี 2 วิธี คือ
- วิธีนี้เราต้อง require admin permission ด้วยนะ ไม่งั้นทำให้ตายก็ไม่มา มุแง
const webhooks = await channel.fetchWebhooks();
const webhook = webhooks.first();
2. ถ้าทำวิธีที่แล้วไม่รอด เปลี่ยนมาใช้ webhook id และ webhook token จาก webhook ที่เราได้มานั่นแหละ
ตรงนี้เราก็จะนำ id และ token ที่ได้มาใช้ในการสร้างสิ่งนี้เนอะ
const webhookClient = new Discord.WebhookClient('id', 'token');
จากนั้นเราลองทำข้อความออกมาส่งตัวนึง เราจะส่งข้อความออกไปผ่าน webhook.send()
โดย parameter แรกคือตัวข้อความที่เราจะส่ง และ parameter ที่สองคือ ชื่อและ avatar ของบอท ซึ่งไม่จำเป็นต้องเป็นชื่อและรูปเดียวกันกับใน webhook นะ
webhook.send(
'Webhook test',
{
username: 'some-username',
avatarURL: 'https://i.imgur.com/wSTFkRM.png'
}
);
จริงๆก็ไม่ต้องใส่ก็ได้นี่นา ชื่อกับรูปก็จะตรงตามใน webhook นะ
และเราสามารถ enbed ข้อความอื่นๆเข้าไปได้ด้วยนะ โดยสร้างตัวแปร emded
ที่เป็น MessageEmbed
เข้าไป แล้วเอาไปใส่เพิ่มใน field ชื่อว่า embeds
โดยในนี้จะเป็น array ไม่แน่ใจว่าใส่ได้มากที่สุดเท่าไหร่แฮะ ในตัวอย่างจะเป็นดังนี้
const embed = new Discord.MessageEmbed()
.setTitle('Meow')
.setColor('#0099ff');
webhook.send(
'Webhook test',
{
username: 'some-username',
avatarURL: 'https://i.imgur.com/wSTFkRM.png',
embeds: [embed]
}
);
หน้าตาก็จะมีตัวที่แนบมาหล่ะหลังข้อความ โดยเรา set title ว่า Meow และใช้สีเป็นสีฟ้าๆ
จริงๆมัน embed อะไรได้บ้างอ่ะ?
ในตัวอย่างพอไป document พบว่า มันแนบไปได้เยอะมากกกก นอกจาก setTitle()
และ setColor()
ยังใส่รูป แนบลิ้ง ยัด json เข้าไป เพิ่ม field อีก รายละเอียดก็ค่อนข้างเยอะอยู่สามารถไปอ่านได้ใน document นะ
ข้างในใส่อะไรแล้วจะเป็นอะไร ตัว guide ก็ทำมาให้เราดูบ้างแล้วแหละ
สรุปโค้ดทั้งหมดจะเป็นประมาณนี้ก่อนนะ
ทำการตั้งเวลาโดยใช้ cronjob กันเถอะ
ใน JavaScript เราจะใช้ library ที่ชื่อว่า node-cron กันจ้า ดังนั้นเราจะมาเข้าใจ cron syntax กันแบบง่ายๆก่อน
ซึ่งจริงๆเคยเล่าไปแล้วในบล็อกที่ชื่อว่า การทำ cron job ของ CI สำหรับชาว Developer ทั้งหลาย แต่เราจะมา wrap-up สั้นๆอีกที
Cronjob ก็เป็นสคริปต์ไว้ตั้งเวลาการทำงานล่วงหน้า เมื่อถึงเวลาที่ตั้งไว้จะทำงานโดยอัตโนมัตินั่นเอง
ตัวที่เราตั้งเวลาการทำงานนั้นก็คือ Cron Table นั่นเอง เรียกสั้นๆว่า Crontab นั่นเอง โดยรูปแบบคำสั่งจะอยู่ในรูปนี้เลยจ้า
reference:
ถ้าใครยังงงๆ สามารถลองเล่นได้ที่นี่จ้า
วิธีการใช้งานง่ายๆ ก่อนอื่น import เข้ามาก่อน
const cron = require('node-cron');
เราจะใช้ในการตั้ง schedule ตามเวลาที่เราตั้งไว้ ไม่ได้รอ event อะไร ดังนั้นเราจะเอามาใส่ใน event ของ Discord ที่ชื่อว่า ready
โค้ดทั้งหมดจะเป็นดังน้ี
เราจะทำการ schedule ตัว cron job ตัวนี้ หลังจากที่เข้า event ready
และเมื่อถึงเวลา 10:30 ทุกวันจันทร์ถึงศุกร์ ที่มี standup meeting จะทำการแจ้งเตือนให้ทุกคนมาประชุมกัน
อันนี้เป็นตัวบอทจริง ที่ทีมเรา standup meeting ตอน 10:45 และตัว BB-9E ก็เป็นชื่อของเจ้าบอทที่พี่ในทีมท่านน้านนน สร้างขึ้นมา
และก็จะเห็นได้ว่า ภายใต้น้องเมทที่น่ารักนั้น ก็ยังเป็นบอทตัวเดียวกับใน webhook นั่นแหละ
Reference
บล็อกภาคต่อก็มาจ้า
download แอพอ่านบล็อกใหม่ของเราได้ที่นี่
ติดตามข่าวสารและบทความใหม่ๆได้ที่
และช่องทางใหม่ใน Twiter จ้า