Discord เป็นแพลตฟอร์มการส่งข้อความแบบเรียลไทม์ที่เรียกเก็บเงินจากตัวเองว่าเป็น“ การแชทด้วยเสียงและข้อความแบบครบวงจรสำหรับเกมเมอร์” เนื่องจากอินเทอร์เฟซที่ลื่นไหลใช้งานง่ายและคุณสมบัติที่หลากหลาย Discord จึงเติบโตอย่างรวดเร็วและได้รับความนิยมมากขึ้นเรื่อย ๆ แม้ในกลุ่มผู้ที่มีความสนใจในวิดีโอเกมเพียงเล็กน้อย ระหว่างเดือนพฤษภาคม 2017 ถึงพฤษภาคม 2018 ฐานผู้ใช้เพิ่มขึ้นจาก 45 ล้านคนเป็นมากกว่า 130 ล้าน โดยมีผู้ใช้มากกว่าสองเท่าต่อวัน หย่อน .
หนึ่งในคุณสมบัติที่น่าสนใจที่สุดของ Discord จากไฟล์ นักพัฒนาแชทบอท เปอร์สเป็คทีฟคือการรองรับบอทที่ตั้งโปรแกรมได้อย่างแข็งแกร่งซึ่งช่วยในการผสานความขัดแย้งกับโลกภายนอกและมอบประสบการณ์ที่น่าสนใจให้กับผู้ใช้ บอทเป็นที่แพร่หลายใน Discord และให้บริการที่หลากหลายรวมถึงความช่วยเหลือในการกลั่นกรองเกมเพลงการค้นหาทางอินเทอร์เน็ตการประมวลผลการชำระเงินและอื่น ๆ
ในบทช่วยสอนเรื่องบอท Discord นี้เราจะเริ่มต้นด้วยการพูดคุยเกี่ยวกับอินเทอร์เฟซผู้ใช้ Discord และ REST และ WebSocket API สำหรับบอทก่อนที่จะไปยังบทช่วยสอนที่เราจะเขียนบอท Discord แบบง่ายๆใน JavaScript สุดท้ายนี้เราจะได้รับคำตอบจากนักพัฒนาเกี่ยวกับเมตริกบางอย่างบอทยอดนิยมของ Discord และประสบการณ์ของเขาในการพัฒนาและดูแลโครงสร้างพื้นฐานและโค้ดเบสที่สำคัญของเขา
ก่อนที่เราจะพูดถึงรายละเอียดทางเทคนิคสิ่งสำคัญคือต้องเข้าใจว่าผู้ใช้โต้ตอบกับ Discord อย่างไรและ Discord นำเสนอตัวเองต่อผู้ใช้อย่างไร วิธีการนำเสนอตัวเองต่อบอทนั้นคล้ายคลึงกันในเชิงแนวคิด (แต่แน่นอนว่าไม่ใช่ภาพ) ในความเป็นจริงแอปพลิเคชัน Discord อย่างเป็นทางการสร้างขึ้นจาก API เดียวกันกับที่บอทใช้ ในทางเทคนิคเป็นไปได้ที่จะเรียกใช้บ็อตภายในบัญชีผู้ใช้ทั่วไปโดยมีการปรับเปลี่ยนเพียงเล็กน้อย แต่ข้อกำหนดในการให้บริการของ Discord ไม่อนุญาต บอทต้องทำงานในบัญชีบอท
โปรดดูเวอร์ชันเบราว์เซอร์ หนึ่ง ของแอปพลิเคชัน Discord ที่ทำงานอยู่ภายใน Chrome
หนึ่ง Discord UI สำหรับแอปพลิเคชันเดสก์ท็อปนั้นแทบจะเหมือนกับเว็บแอปพลิเคชันที่มาพร้อมกับ Electron แอปพลิเคชัน iOS สร้างขึ้นด้วย React Native แอปพลิเคชัน Android เป็นรหัส Java ดั้งเดิมของ Android
มาทำลายมันกัน
ทางด้านซ้ายคือรายชื่อเซิร์ฟเวอร์ที่ฉันเป็นสมาชิก หากคุณคุ้นเคยกับ Slack เซิร์ฟเวอร์จะคล้ายกับพื้นที่ทำงานของ Slack และแสดงถึงกลุ่มผู้ใช้ที่สามารถโต้ตอบกันได้ภายในช่องทางอย่างน้อยหนึ่งช่องในเซิร์ฟเวอร์ เซิร์ฟเวอร์ได้รับการจัดการโดยผู้สร้างและ / หรือเจ้าหน้าที่คนใดก็ตามที่พวกเขาเลือกและเลือกที่จะมอบหมายความรับผิดชอบให้ ผู้สร้างและ / หรือเจ้าหน้าที่กำหนดกฎโครงสร้างของช่องในเซิร์ฟเวอร์และจัดการผู้ใช้
ในกรณีของฉันไฟล์ Discord API เซิร์ฟเวอร์อยู่ที่ด้านบนสุดของรายการเซิร์ฟเวอร์ของฉัน เป็นสถานที่ที่ดีเยี่ยมในการรับความช่วยเหลือและพูดคุยกับนักพัฒนาซอฟต์แวร์คนอื่น ๆ ด้านล่างเป็นเซิร์ฟเวอร์ที่ฉันสร้างขึ้นชื่อ ทดสอบ . เราจะทดสอบบ็อตที่เราสร้างขึ้นในภายหลัง ด้านล่างเป็นปุ่มสำหรับสร้างเซิร์ฟเวอร์ใหม่ ทุกคนสามารถสร้างเซิร์ฟเวอร์ได้ด้วยการคลิกเพียงไม่กี่ครั้ง
โปรดทราบว่าในขณะที่คำที่ใช้ในอินเทอร์เฟซผู้ใช้ของ Discord คือ เซิร์ฟเวอร์ คำที่ใช้ในเอกสารสำหรับนักพัฒนาซอฟต์แวร์และ API คือ กิลด์ . เมื่อเราพูดถึงหัวข้อทางเทคนิคแล้วเราจะเปลี่ยนไปพูดถึง กิลด์ . สองคำนี้ใช้แทนกันได้
ทางด้านขวาของรายการเซิร์ฟเวอร์คือรายการช่องสำหรับเซิร์ฟเวอร์ที่ฉันกำลังดูอยู่ (ในกรณีนี้คือเซิร์ฟเวอร์ Discord API) ช่องสามารถแบ่งออกเป็นหมวดหมู่ตามจำนวนที่กำหนดได้ ในเซิร์ฟเวอร์ Discord API หมวดหมู่ต่างๆ ได้แก่ INFORMATION, GENERAL และ LIBS ดังที่แสดง แต่ละช่องจะทำหน้าที่เป็นห้องสนทนาที่ผู้ใช้สามารถพูดคุยเกี่ยวกับหัวข้อใดก็ได้ที่ช่องนั้นทุ่มเทให้ ช่องที่เรากำลังดูอยู่ (ข้อมูล) มีพื้นหลังสีอ่อนกว่า ช่องที่มีข้อความใหม่ตั้งแต่ที่เราดูครั้งล่าสุดจะมีข้อความสีขาว
นี่คือมุมมองช่องที่เราสามารถดูสิ่งที่ผู้ใช้พูดถึงในช่องที่เรากำลังดูอยู่ เราสามารถเห็นหนึ่งข้อความที่นี่ปรากฏเพียงบางส่วน เป็นรายการลิงก์เพื่อสนับสนุนเซิร์ฟเวอร์สำหรับไลบรารีบอท Discord แต่ละรายการ ผู้ดูแลระบบเซิร์ฟเวอร์ได้กำหนดค่าช่องสัญญาณนี้เพื่อให้ผู้ใช้ทั่วไปอย่างฉันไม่สามารถส่งข้อความเข้าไปได้ ผู้ดูแลระบบใช้ช่องนี้เป็นกระดานข่าวเพื่อโพสต์ข้อมูลสำคัญบางอย่างที่สามารถมองเห็นได้ง่ายและแชทจะไม่จมน้ำตาย
ทางด้านขวาคือรายชื่อผู้ใช้ที่ออนไลน์อยู่ในเซิร์ฟเวอร์นี้ ผู้ใช้จะถูกจัดเป็นหมวดหมู่ต่างๆและชื่อของพวกเขาจะมีสีที่แตกต่างกัน นี่เป็นผลมาจากไฟล์ บทบาท ที่พวกเขามี บทบาทอธิบายถึงหมวดหมู่ (ถ้ามี) ที่ผู้ใช้ควรปรากฏภายใต้สีของชื่อควรเป็นอย่างไรและสิทธิ์ใดในเซิร์ฟเวอร์ ผู้ใช้สามารถมีบทบาทได้มากกว่าหนึ่งบทบาท (และบ่อยครั้งมาก) และมีการคำนวณลำดับความสำคัญบางอย่างที่กำหนดสิ่งที่เกิดขึ้นในกรณีนั้น อย่างน้อยที่สุดผู้ใช้ทุกคนมีบทบาท @ ทุกคน บทบาทอื่น ๆ ถูกสร้างและมอบหมายโดยเจ้าหน้าที่เซิร์ฟเวอร์
นี่คือการป้อนข้อความที่ฉันสามารถพิมพ์และส่งข้อความได้หากฉันได้รับอนุญาต เนื่องจากฉันไม่ได้รับอนุญาตให้ส่งข้อความในช่องนี้ฉันจึงพิมพ์ที่นี่ไม่ได้
นี่คือผู้ใช้ปัจจุบัน ฉันตั้งชื่อผู้ใช้เป็น“ ฉัน” เพื่อช่วยไม่ให้สับสนและเพราะฉันแย่มากในการเลือกชื่อ ด้านล่างชื่อผู้ใช้ของฉันคือตัวเลข (# 9484) ซึ่งเป็นตัวเลือกของฉัน อาจมีผู้ใช้คนอื่นหลายคนชื่อ“ ฉัน” แต่ฉันเป็นคนเดียว“ ฉัน # 9484” นอกจากนี้ยังเป็นไปได้ที่ฉันจะตั้งชื่อเล่นสำหรับตัวเองตามเซิร์ฟเวอร์ดังนั้นฉันจึงสามารถเป็นที่รู้จักด้วยชื่อที่แตกต่างกันในเซิร์ฟเวอร์ที่แตกต่างกัน
สิ่งเหล่านี้เป็นส่วนพื้นฐานของอินเทอร์เฟซผู้ใช้ Discord แต่ยังมีอีกมากมายเช่นกัน การเริ่มใช้ Discord เป็นเรื่องง่ายโดยไม่ต้องสร้างบัญชีดังนั้นอย่าลังเลที่จะใช้เวลาสักครู่เพื่อสำรวจ คุณสามารถเข้าสู่ Discord ได้โดยไปที่ หน้าแรกของ Discord คลิก 'เปิด Discord ในเบราว์เซอร์' เลือกชื่อผู้ใช้และอาจเล่น 'คลิกรูปรถบัส' รอบใหม่
Discord API ประกอบด้วยสองส่วนแยกกัน: WebSocket และ REST API กล่าวโดยทั่วไป WebSocket API ใช้เพื่อรับเหตุการณ์จาก Discord แบบเรียลไทม์ในขณะที่ REST API ใช้เพื่อดำเนินการภายใน Discord
WebSocket API ใช้เพื่อรับเหตุการณ์จาก Discord รวมถึงการสร้างข้อความการลบข้อความเหตุการณ์เตะ / แบนของผู้ใช้การอัปเดตสิทธิ์ผู้ใช้และอื่น ๆ อีกมากมาย การสื่อสารจากบอทไปยัง WebSocket API ในทางกลับกันมีข้อ จำกัด มากขึ้น บอทใช้ WebSocket API เพื่อขอการเชื่อมต่อระบุตัวตนการเต้นของหัวใจจัดการการเชื่อมต่อด้วยเสียงและทำสิ่งพื้นฐานอีกสองสามอย่าง สามารถอ่านรายละเอียดเพิ่มเติมได้ที่ Discord’s เอกสารเกตเวย์ (การเชื่อมต่อเดียวกับ WebSocket API เรียกว่าเกตเวย์) สำหรับการดำเนินการอื่น ๆ จะใช้ REST API
เหตุการณ์จาก WebSocket API มี payload รวมถึงข้อมูลที่ขึ้นอยู่กับประเภทของเหตุการณ์ ตัวอย่างเช่นทั้งหมด สร้างข้อความ เหตุการณ์จะมาพร้อมกับวัตถุของผู้ใช้ที่เป็นตัวแทนของผู้เขียนข้อความ อย่างไรก็ตามออบเจ็กต์ผู้ใช้เพียงอย่างเดียวไม่มีข้อมูลทั้งหมดที่ควรทราบเกี่ยวกับผู้ใช้ ตัวอย่างเช่นไม่มีข้อมูลเกี่ยวกับสิทธิ์ของผู้ใช้ หากคุณต้องการข้อมูลเพิ่มเติมคุณสามารถค้นหา REST API ได้ แต่ด้วยเหตุผลที่อธิบายเพิ่มเติมในส่วนถัดไปโดยทั่วไปคุณควรเข้าถึงแคชที่คุณควรสร้างขึ้นจากเพย์โหลดที่ได้รับจากเหตุการณ์ก่อนหน้าแทน มีหลายเหตุการณ์ที่ส่งมอบเพย์โหลดที่เกี่ยวข้องกับสิทธิ์ของผู้ใช้ซึ่งรวมถึง แต่ไม่ จำกัด เพียง สร้างกิลด์ , อัปเดตบทบาทกิลด์ และ อัปเดตช่อง .
บอทสามารถนำเสนอได้สูงสุด 2,500 กิลด์ต่อการเชื่อมต่อ WebSocket เพื่อให้บอทแสดงในกิลด์ได้มากขึ้นบอทจะต้องใช้การชาร์ดและเปิดการเชื่อมต่อ WebSocket แยกกันหลายรายการกับ Discord หากบอทของคุณทำงานภายในกระบวนการเดียวบนโหนดเดียวนี่เป็นเพียงความซับซ้อนที่เพิ่มเข้ามาให้คุณซึ่งอาจดูเหมือนไม่จำเป็น แต่ถ้าบอทของคุณได้รับความนิยมอย่างมากและจำเป็นต้องมีการกระจายแบ็คเอนด์ไปตามโหนดต่างๆการสนับสนุนการชาร์ดของ Discord จะทำให้สิ่งนี้ง่ายกว่าที่เป็นอยู่
บอท Discord REST API ใช้เพื่อดำเนินการส่วนใหญ่เช่นการส่งข้อความการเตะ / แบนผู้ใช้และการอัปเดตสิทธิ์ของผู้ใช้ (คล้ายคลึงกับเหตุการณ์ที่ได้รับจาก WebSocket API ในวงกว้าง) REST API ยังสามารถใช้เพื่อสอบถามข้อมูล อย่างไรก็ตามบอทส่วนใหญ่อาศัยเหตุการณ์จาก WebSocket API แทนและแคชข้อมูลที่ได้รับจากเหตุการณ์ WebSocket
มีหลายเหตุผลนี้. การสืบค้น REST API เพื่อรับข้อมูลผู้ใช้ทุกครั้งที่ก สร้างข้อความ ตัวอย่างเช่นได้รับเหตุการณ์ไม่ได้ปรับขนาดเนื่องจากขีด จำกัด อัตราของ REST API นอกจากนี้ยังซ้ำซ้อนในกรณีส่วนใหญ่เนื่องจาก WebSocket API ให้ข้อมูลที่จำเป็นและคุณควรมีไว้ในแคชของคุณ
อย่างไรก็ตามมีข้อยกเว้นบางประการและบางครั้งคุณอาจต้องการข้อมูลที่ไม่มีอยู่ในแคชของคุณ เมื่อบอทเชื่อมต่อกับเกตเวย์ WebSocket ในตอนแรก a พร้อม เหตุการณ์และหนึ่ง สร้างกิลด์ เหตุการณ์ต่อกิลด์ที่บอทมีอยู่ในชาร์ดนั้นจะถูกส่งไปยังบ็อตในตอนแรกเพื่อให้สามารถเติมข้อมูลแคชด้วยสถานะปัจจุบันได้ สร้างกิลด์ กิจกรรมสำหรับกิลด์ที่มีประชากรมากจะรวมเฉพาะข้อมูลเกี่ยวกับผู้ใช้ออนไลน์เท่านั้น หากบอทของคุณต้องการรับข้อมูลเกี่ยวกับผู้ใช้ออฟไลน์ข้อมูลที่เกี่ยวข้องอาจไม่มีอยู่ในแคชของคุณ ในกรณีนี้คุณควรส่งคำขอไปยัง REST API หรือหากคุณพบว่าตัวเองต้องการรับข้อมูลเกี่ยวกับผู้ใช้ออฟไลน์บ่อยครั้งคุณสามารถเลือกที่จะส่งไฟล์ ขอสมาชิกกิลด์ opcode ไปยัง WebSocket API เพื่อขอสมาชิกกิลด์ออฟไลน์
ข้อยกเว้นอีกประการหนึ่งคือหากแอปพลิเคชันของคุณไม่ได้เชื่อมต่อกับ WebSocket API เลย ตัวอย่างเช่นหากบอทของคุณมีหน้าแดชบอร์ดของเว็บที่ผู้ใช้สามารถเข้าสู่ระบบและเปลี่ยนการตั้งค่าของบอทในเซิร์ฟเวอร์ของตนได้ แดชบอร์ดของเว็บสามารถทำงานในกระบวนการแยกต่างหากโดยไม่ต้องเชื่อมต่อกับ WebSocket API และไม่มีแคชข้อมูลจาก Discord อาจจำเป็นต้องสร้างคำขอ REST API เพียงเล็กน้อยเป็นครั้งคราว ในสถานการณ์แบบนี้คุณควรพึ่งพา REST API เพื่อรับข้อมูลที่คุณต้องการ
แม้ว่าจะเป็นความคิดที่ดีที่จะมีความเข้าใจในทุกระดับของกลุ่มเทคโนโลยีของคุณ แต่การใช้ Discord WebSocket และ REST API โดยตรงนั้นใช้เวลานานเกิดข้อผิดพลาดโดยทั่วไปไม่จำเป็นและในความเป็นจริงแล้วเป็นอันตราย
Discord ให้ไฟล์ รายชื่อห้องสมุดที่ได้รับการตรวจสอบอย่างเป็นทางการ และเตือนว่า:
การใช้การใช้งานแบบกำหนดเองหรือไลบรารีที่ไม่เป็นไปตามข้อกำหนดซึ่งใช้ API ในทางที่ผิดหรือทำให้อัตรา จำกัด มากเกินไปอาจส่งผลให้มีการแบนถาวร
ไลบรารีที่ได้รับการตรวจสอบอย่างเป็นทางการโดย Discord นั้นโดยทั่วไปแล้วมีเอกสารครบถ้วนและมีคุณสมบัติครอบคลุม Discord API อย่างสมบูรณ์ นักพัฒนาบอทส่วนใหญ่จะไม่มีเหตุผลที่ดีในการพัฒนาการใช้งานที่กำหนดเองยกเว้นด้วยความอยากรู้อยากเห็นหรือความกล้าหาญ!
ในขณะนี้ไลบรารีที่ได้รับการตรวจสอบอย่างเป็นทางการรวมถึงการใช้งานสำหรับ Crystal, C #, D, Go, Java, JavaScript, Lua, Nim, PHP, Python, Ruby, Rust และ Swift อาจมีห้องสมุดสองแห่งหรือมากกว่าสำหรับภาษาที่คุณเลือก การเลือกใช้อาจเป็นการตัดสินใจที่ยากลำบาก นอกเหนือจากการตรวจสอบเอกสารที่เกี่ยวข้องแล้วคุณอาจต้องการเข้าร่วมไฟล์ เซิร์ฟเวอร์ Discord API อย่างไม่เป็นทางการ และสัมผัสได้ว่าห้องสมุดแต่ละแห่งเป็นชุมชนแบบไหน
มาลงมือทำธุรกิจกัน เรากำลังจะสร้างบอท Discord ที่แฮงเอาท์ในเซิร์ฟเวอร์ของเราและรับฟังเว็บฮุคจาก โค - ไฟ . Ko-fi เป็นบริการที่ช่วยให้คุณสามารถรับเงินบริจาคเข้าบัญชี PayPal ของคุณได้อย่างง่ายดาย การตั้งค่าเว็บฮุกที่นั่นง่ายมากเมื่อเทียบกับ PayPal ที่คุณต้องมีบัญชีธุรกิจดังนั้นจึงเหมาะอย่างยิ่งสำหรับวัตถุประสงค์ในการสาธิตหรือการดำเนินการบริจาคขนาดเล็ก
เมื่อผู้ใช้บริจาค $ 10 ขึ้นไปบอทจะกำหนด Premium Member
ให้กับพวกเขา บทบาทที่เปลี่ยนสีชื่อและย้ายไปที่ด้านบนสุดของรายชื่อผู้ใช้ออนไลน์ สำหรับโครงการนี้เราจะใช้ Node.js และไลบรารี Discord API ชื่อ Eris (ลิงก์เอกสาร: https://abal.moe/Eris/) Eris ไม่ใช่ไลบรารี JavaScript เพียงอย่างเดียว คุณสามารถเลือก discord.js แทน โค้ดที่เราจะเขียนจะคล้ายกันมากไม่ว่าจะด้วยวิธีใดก็ตาม
นอกจาก Patreon ซึ่งเป็นผู้ประมวลผลการบริจาคอีกรายหนึ่งยังจัดเตรียมไฟล์ บอท Discord อย่างเป็นทางการ และรองรับการกำหนดค่าบทบาท Discord เป็นสิทธิประโยชน์ของผู้มีส่วนร่วม เรากำลังจะนำสิ่งที่คล้ายกันมาใช้ แต่แน่นอนว่าพื้นฐานกว่า
รหัสสำหรับทุกขั้นตอนของการสอนมีอยู่ใน GitHub ( https://github.com/mistval/premium_bot ). ขั้นตอนบางอย่างที่แสดงในโพสต์นี้จะละเว้นโค้ดที่ไม่เปลี่ยนแปลงเพื่อความกะทัดรัดดังนั้นให้ทำตามลิงก์ที่ให้มาเพื่อไปยัง GitHub หากคุณคิดว่าคุณอาจขาดอะไรไป
ก่อนที่เราจะเริ่มเขียนโค้ดได้เราจำเป็นต้องมีบัญชีบอท ก่อนที่เราจะสร้างบัญชีบอทได้เราจำเป็นต้องมีบัญชีผู้ใช้ ในการสร้างบัญชีผู้ใช้ให้ทำตามคำแนะนำ ที่นี่ .
จากนั้นในการสร้างบัญชีบอทเรา:
1) สร้างแอปพลิเคชันในไฟล์ พอร์ทัลนักพัฒนา .
2) กรอกรายละเอียดพื้นฐานเกี่ยวกับแอปพลิเคชัน (โปรดสังเกตรหัสลูกค้าที่แสดงที่นี่เราจะต้องใช้ในภายหลัง)
3) เพิ่มผู้ใช้บอทที่เชื่อมต่อกับแอปพลิเคชัน
4) ปิดสวิตช์ BOT สาธารณะและสังเกตโทเค็นบอทที่แสดง (เราจะต้องใช้สิ่งนี้ในภายหลังเช่นกัน) หากคุณเคยใช้โทเค็นของบ็อตรั่วตัวอย่างเช่นโดยการเผยแพร่เป็นรูปภาพในบล็อกโพสต์ของ ApeeScape คุณจำเป็นต้องสร้างโทเค็นใหม่ทันที ใครก็ตามที่ครอบครองโทเค็นบ็อตของคุณจะสามารถควบคุมบัญชีบอทของคุณและอาจทำให้เกิดปัญหาร้ายแรงและถาวรสำหรับคุณและผู้ใช้ของคุณ
5) เพิ่มบอทในกิลด์ทดสอบของคุณ ในการเพิ่มบอทในกิลด์ให้เปลี่ยนรหัสไคลเอ็นต์ (ที่แสดงไว้ก่อนหน้า) ใน URI ต่อไปนี้และไปที่มันในเบราว์เซอร์
https://discordapp.com/api/oauth2/authorize?scope=bot&client_id=XXX
หลังจากคลิกอนุญาตบอทจะอยู่ในกิลด์ทดสอบของฉันและฉันสามารถดูได้ในรายชื่อผู้ใช้ ออฟไลน์อยู่ แต่เราจะแก้ไขในไม่ช้า
สมมติว่าคุณมี โหนด js ติดตั้งสร้างโปรเจ็กต์และติดตั้ง Eris (ไลบรารีบ็อตที่เราจะใช้), Express (เฟรมเวิร์กแอปพลิเคชันบนเว็บที่เราจะใช้ในการสร้างตัวฟังเว็บฮุก) และตัวแยกวิเคราะห์เนื้อหา (สำหรับการแยกวิเคราะห์เนื้อหาเว็บฮุก)
mkdir premium_bot cd premium_bot npm init npm install eris express body-parser
เริ่มต้นด้วยขั้นตอนทารก อันดับแรกเราจะได้รับบอทออนไลน์และตอบกลับเรา เราทำได้ในโค้ด 10-20 บรรทัด ภายในไฟล์ bot.js ใหม่เราจำเป็นต้องสร้างอินสแตนซ์ไคลเอนต์ Eris ส่งโทเค็นบอทของเรา (ได้มาเมื่อเราสร้างแอปพลิเคชันบอทด้านบน) สมัครรับกิจกรรมบางอย่างในอินสแตนซ์ไคลเอ็นต์และบอกให้เชื่อมต่อกับ Discord . เพื่อจุดประสงค์ในการสาธิตเราจะฮาร์ดโค้ดโทเค็นบอทของเราลงในไฟล์ bot.js แต่การสร้างไฟล์กำหนดค่าแยกต่างหากและการยกเว้นจากการควบคุมแหล่งที่มาถือเป็นแนวทางปฏิบัติที่ดี
(ลิงค์รหัส GitHub: https://github.com/mistval/premium_bot/blob/master/src/bot_step1.js )
const eris = require('eris'); // Create a Client instance with our bot token. const bot = new eris.Client('my_token'); // When the bot is connected and ready, log to console. bot.on('ready', () => { console.log('Connected and ready.'); }); // Every time a message is sent anywhere the bot is present, // this event will fire and we will check if the bot was mentioned. // If it was, the bot will attempt to respond with 'Present'. bot.on('messageCreate', async (msg) => { const botWasMentioned = msg.mentions.find( mentionedUser => mentionedUser.id === bot.user.id, ); if (botWasMentioned) { try { await msg.channel.createMessage('Present'); } catch (err) { // There are various reasons why sending a message may fail. // The API might time out or choke and return a 5xx status, // or the bot may not have permission to send the // message (403 status). console.warn('Failed to respond to mention.'); console.warn(err); } } }); bot.on('error', err => { console.warn(err); }); bot.connect();
หากทุกอย่างเป็นไปด้วยดีเมื่อคุณเรียกใช้รหัสนี้ด้วยโทเค็นบอทของคุณเอง Connected and ready.
จะถูกพิมพ์ไปยังคอนโซลและคุณจะเห็นบอทของคุณออนไลน์ในเซิร์ฟเวอร์ทดสอบของคุณ คุณสามารถพูดถึง2บอทของคุณโดยคลิกขวาและเลือก“ พูดถึง” หรือพิมพ์ชื่อที่นำหน้าด้วย @ บอทควรตอบกลับโดยพูดว่า 'นำเสนอ'
2 การพูดถึงเป็นวิธีดึงดูดความสนใจของผู้ใช้รายอื่นแม้ว่าพวกเขาจะไม่อยู่ก็ตาม เมื่อกล่าวถึงผู้ใช้ทั่วไปจะได้รับการแจ้งเตือนด้วยการแจ้งเตือนบนเดสก์ท็อปการแจ้งเตือนแบบพุชมือถือและ / หรือไอคอนสีแดงเล็ก ๆ ที่ปรากฏเหนือไอคอนของ Discord ในถาดระบบ ลักษณะการแจ้งเตือนผู้ใช้จะขึ้นอยู่กับการตั้งค่าและสถานะออนไลน์ของผู้ใช้ ในทางกลับกันบอทไม่ได้รับการแจ้งเตือนพิเศษใด ๆ เมื่อมีการกล่าวถึง พวกเขาได้รับกิจกรรมสร้างข้อความตามปกติเหมือนกับที่ทำกับข้อความอื่น ๆ และสามารถตรวจสอบการกล่าวถึงที่แนบมากับกิจกรรมเพื่อตรวจสอบว่ามีการกล่าวถึงหรือไม่
ตอนนี้เรารู้แล้วว่าเราสามารถหาบอทออนไลน์ได้แล้วเรามากำจัดกระแสของเรากันดีกว่า สร้างข้อความ ตัวจัดการเหตุการณ์และสร้างรายการใหม่ที่ช่วยให้เราแจ้งบอทว่าเราได้รับการชำระเงินจากผู้ใช้
เพื่อแจ้งการชำระเงินให้บอทเราจะออกคำสั่งที่มีลักษณะดังนี้:
pb!addpayment @user_mention payment_amount
ตัวอย่างเช่น pb!addpayment @Me 10.00
เพื่อบันทึกการชำระเงินจำนวน $ 10.00 โดยฉัน
pb! ส่วนหนึ่งเรียกว่าคำนำหน้าคำสั่ง เป็นวิธีที่ดีในการเลือกคำนำหน้าว่าคำสั่งทั้งหมดในบอทของคุณต้องขึ้นต้นด้วย สิ่งนี้จะสร้างการวัดเนมสเปซสำหรับบ็อตและช่วยหลีกเลี่ยงการปะทะกับบอทอื่น ๆ บอทส่วนใหญ่มีคำสั่งช่วยเหลือ แต่ลองนึกดูว่าถ้าคุณมีบอทสิบตัวในกิลด์ของคุณและพวกมันก็ตอบสนอง ช่วยด้วย ! ใช้ pb! เนื่องจากคำนำหน้าไม่ใช่วิธีแก้ปัญหาที่เข้าใจผิดเนื่องจากอาจมีบอทอื่น ๆ ที่ใช้คำนำหน้าเหมือนกัน บอทยอดนิยมส่วนใหญ่อนุญาตให้กำหนดค่าคำนำหน้าตามแต่ละกิลด์เพื่อช่วยป้องกันการปะทะกัน อีกทางเลือกหนึ่งคือใช้การกล่าวถึงของบอทเป็นคำนำหน้าแม้ว่าจะทำให้การออกคำสั่งมีรายละเอียดมากขึ้น
(ลิงค์รหัส GitHub: https://github.com/mistval/premium_bot/blob/master/src/bot_step2.js )
const eris = require('eris'); const PREFIX = 'pb!'; const bot = new eris.Client('my_token'); const commandHandlerForCommandName = {}; commandHandlerForCommandName['addpayment'] = (msg, args) => { const mention = args[0]; const amount = parseFloat(args[1]); // TODO: Handle invalid command arguments, such as: // 1. No mention or invalid mention. // 2. No amount or invalid amount. return msg.channel.createMessage(`${mention} paid $${amount.toFixed(2)}`); }; bot.on('messageCreate', async (msg) => { const content = msg.content; // Ignore any messages sent as direct messages. // The bot will only accept commands issued in // a guild. if (!msg.channel.guild) { return; } // Ignore any message that doesn't start with the correct prefix. if (!content.startsWith(PREFIX)) { return; } // Extract the parts of the command and the command name const parts = content.split(' ').map(s => s.trim()).filter(s => s); const commandName = parts[0].substr(PREFIX.length); // Get the appropriate handler for the command, if there is one. const commandHandler = commandHandlerForCommandName[commandName]; if (!commandHandler) { return; } // Separate the command arguments from the command prefix and command name. const args = parts.slice(1); try { // Execute the command. await commandHandler(msg, args); } catch (err) { console.warn('Error handling command'); console.warn(err); } }); bot.on('error', err => { console.warn(err); }); bot.connect();
ลองดู.
เราไม่เพียง แต่ทำให้บอทตอบสนองต่อ pb!addpayment
คำสั่ง แต่เราสร้างรูปแบบทั่วไปสำหรับจัดการคำสั่ง เราสามารถเพิ่มคำสั่งเพิ่มเติมได้เพียงแค่เพิ่มตัวจัดการเพิ่มเติมใน commandHandlerForCommandName
พจนานุกรม. เรามีการสร้างกรอบคำสั่งง่ายๆที่นี่ การจัดการคำสั่งเป็นส่วนพื้นฐานของการสร้างบอทที่หลาย ๆ คนเขียนและกรอบคำสั่งโอเพนซอร์สที่คุณสามารถใช้แทนการเขียนของคุณเอง กรอบคำสั่งมักจะอนุญาตให้คุณระบุคูลดาวน์สิทธิ์ผู้ใช้ที่ต้องการนามแฝงคำสั่งคำอธิบายคำสั่งและตัวอย่างการใช้งาน (สำหรับคำสั่งวิธีใช้ที่สร้างขึ้นโดยอัตโนมัติ) และอื่น ๆ Eris มาพร้อมกับในตัว กรอบคำสั่ง .
เมื่อพูดถึงสิทธิ์บอทของเรามีปัญหาด้านความปลอดภัยเล็กน้อย ทุกคนสามารถเรียกใช้ addpayment
คำสั่ง มา จำกัด เพื่อให้มีเพียงเจ้าของบ็อตเท่านั้นที่ใช้งานได้ เราจะรีแฟคเตอร์ commandHandlerForCommandName
พจนานุกรมและมีวัตถุ JavaScript เป็นค่า วัตถุเหล่านั้นจะมี execute
คุณสมบัติที่มีตัวจัดการคำสั่งและ botOwnerOnly
คุณสมบัติที่มีค่าบูลีน นอกจากนี้เราจะฮาร์ดโค้ดรหัสผู้ใช้ของเราลงในส่วนค่าคงที่ของบอทเพื่อให้บอทรู้ว่าใครเป็นเจ้าของ คุณสามารถค้นหา ID ผู้ใช้ของคุณได้โดยเปิดใช้งานโหมดนักพัฒนาซอฟต์แวร์ในการตั้งค่า Discord ของคุณจากนั้นคลิกขวาที่ชื่อผู้ใช้ของคุณแล้วเลือก Copy ID
(ลิงค์รหัส GitHub: https://github.com/mistval/premium_bot/blob/master/src/bot_step3.js )
const eris = require('eris'); const PREFIX = 'pb!'; const BOT_OWNER_ID = '123456789'; const bot = new eris.Client('my_token'); const commandForName = {}; commandForName['addpayment'] = { botOwnerOnly: true, execute: (msg, args) => { const mention = args[0]; const amount = parseFloat(args[1]); // TODO: Handle invalid command arguments, such as: // 1. No mention or invalid mention. // 2. No amount or invalid amount. return msg.channel.createMessage(`${mention} paid $${amount.toFixed(2)}`); }, }; bot.on('messageCreate', async (msg) => { try { const content = msg.content; // Ignore any messages sent as direct messages. // The bot will only accept commands issued in // a guild. if (!msg.channel.guild) { return; } // Ignore any message that doesn't start with the correct prefix. if (!content.startsWith(PREFIX)) { return; } // Extract the parts and name of the command const parts = content.split(' ').map(s => s.trim()).filter(s => s); const commandName = parts[0].substr(PREFIX.length); // Get the requested command, if there is one. const command = commandForName[commandName]; if (!command) { return; } // If this command is only for the bot owner, refuse // to execute it for any other user. const authorIsBotOwner = msg.author.id === BOT_OWNER_ID; if (command.botOwnerOnly && !authorIsBotOwner) { return await msg.channel.createMessage('Hey, only my owner can issue that command!'); } // Separate the command arguments from the command prefix and name. const args = parts.slice(1); // Execute the command. await command.execute(msg, args); } catch (err) { console.warn('Error handling message create event'); console.warn(err); } }); bot.on('error', err => { console.warn(err); }); bot.connect();
ตอนนี้บอทจะปฏิเสธที่จะดำเนินการ addpayment
อย่างโกรธเกรี้ยว คำสั่งหากบุคคลอื่นที่ไม่ใช่เจ้าของบอทพยายามที่จะดำเนินการ
ต่อไปมาให้บอทกำหนด Premium Member
บทบาทของทุกคนที่บริจาคสิบดอลลาร์ขึ้นไป ในส่วนบนสุดของไฟล์ bot.js:
(ลิงค์รหัส GitHub: https://github.com/mistval/premium_bot/blob/master/src/bot_step4.js )
const eris = require('eris'); const PREFIX = 'pb!'; const BOT_OWNER_ID = '523407722880827415'; const PREMIUM_CUTOFF = 10; const bot = new eris.Client('my_token'); const premiumRole = { name: 'Premium Member', color: 0x6aa84f, hoist: true, // Show users with this role in their own section of the member list. }; async function updateMemberRoleForDonation(guild, member, donationAmount) { // If the user donated more than , give them the premium role. if (guild && member && donationAmount >= PREMIUM_CUTOFF) { // Get the role, or if it doesn't exist, create it. let role = Array.from(guild.roles.values()) .find(role => role.name === premiumRole.name); if (!role) { role = await guild.createRole(premiumRole); } // Add the role to the user, along with an explanation // for the guild log (the 'audit log'). return member.addRole(role.id, 'Donated or more.'); } } const commandForName = {}; commandForName['addpayment'] = { botOwnerOnly: true, execute: (msg, args) => { const mention = args[0]; const amount = parseFloat(args[1]); const guild = msg.channel.guild; const userId = mention.replace(//, (match, group1) => group1); const member = guild.members.get(userId); // TODO: Handle invalid command arguments, such as: // 1. No mention or invalid mention. // 2. No amount or invalid amount. return Promise.all([ msg.channel.createMessage(`${mention} paid $${amount.toFixed(2)}`), updateMemberRoleForDonation(guild, member, amount), ]); }, };
ตอนนี้ฉันสามารถลองพูด pb!addpayment @Me 10.00
และบอทควรกำหนด Premium Member
บทบาท.
อ๊ะเกิดข้อผิดพลาดเกี่ยวกับการอนุญาตที่ขาดหายไปปรากฏในคอนโซล
DiscordRESTError: DiscordRESTError [50013]: Missing Permissions index.js:85 code:50013
บอทไม่มีสิทธิ์จัดการบทบาทในกิลด์ทดสอบดังนั้นจึงไม่สามารถสร้างหรือกำหนดบทบาทได้ เราสามารถให้สิทธิ์ผู้ดูแลระบบแก่บอทได้และเราจะไม่เกิดปัญหาแบบนี้อีก แต่เช่นเดียวกับระบบใด ๆ ที่ดีที่สุดคือให้สิทธิ์ขั้นต่ำแก่ผู้ใช้ (หรือในกรณีนี้คือบอท) เท่านั้น
เราสามารถให้สิทธิ์จัดการบทบาทแก่บอทได้โดยสร้างบทบาทในการตั้งค่าเซิร์ฟเวอร์เปิดใช้งานสิทธิ์จัดการบทบาทสำหรับบทบาทนั้นและกำหนดบทบาทให้กับบอท
ตอนนี้เมื่อฉันพยายามเรียกใช้คำสั่งอีกครั้งบทบาทจะถูกสร้างและกำหนดให้กับฉันและฉันมีสีชื่อแฟนซีและตำแหน่งพิเศษในรายชื่อสมาชิก
ในตัวจัดการคำสั่งเรามีข้อคิดเห็นสิ่งที่ต้องทำซึ่งแนะนำว่าเราต้องตรวจสอบข้อโต้แย้งที่ไม่ถูกต้อง มาดูแลตอนนี้กันดีกว่า
(ลิงค์รหัส GitHub: https://github.com/mistval/premium_bot/blob/master/src/bot_step5.js )
const commandForName = {}; commandForName['addpayment'] = { botOwnerOnly: true, execute: (msg, args) => { const mention = args[0]; const amount = parseFloat(args[1]); const guild = msg.channel.guild; const userId = mention.replace(//, (match, group1) => group1); const member = guild.members.get(userId); const userIsInGuild = !!member; if (!userIsInGuild) { return msg.channel.createMessage('User not found in this guild.'); } const amountIsValid = amount && !Number.isNaN(amount); if (!amountIsValid) { return msg.channel.createMessage('Invalid donation amount'); } return Promise.all([ msg.channel.createMessage(`${mention} paid $${amount.toFixed(2)}`), updateMemberRoleForDonation(guild, member, amount), ]); }, };
นี่คือรหัสทั้งหมดจนถึงตอนนี้:
(ลิงค์รหัส GitHub: https://github.com/mistval/premium_bot/blob/master/src/bot_step5.js )
const eris = require('eris'); const PREFIX = 'pb!'; const BOT_OWNER_ID = '123456789'; const PREMIUM_CUTOFF = 10; const bot = new eris.Client('my_token'); const premiumRole = { name: 'Premium Member', color: 0x6aa84f, hoist: true, // Show users with this role in their own section of the member list. }; async function updateMemberRoleForDonation(guild, member, donationAmount) { // If the user donated more than , give them the premium role. if (guild && member && donationAmount >= PREMIUM_CUTOFF) { // Get the role, or if it doesn't exist, create it. let role = Array.from(guild.roles.values()) .find(role => role.name === premiumRole.name); if (!role) { role = await guild.createRole(premiumRole); } // Add the role to the user, along with an explanation // for the guild log (the 'audit log'). return member.addRole(role.id, 'Donated or more.'); } } const commandForName = {}; commandForName['addpayment'] = { botOwnerOnly: true, execute: (msg, args) => { const mention = args[0]; const amount = parseFloat(args[1]); const guild = msg.channel.guild; const userId = mention.replace(//, (match, group1) => group1); const member = guild.members.get(userId); const userIsInGuild = !!member; if (!userIsInGuild) { return msg.channel.createMessage('User not found in this guild.'); } const amountIsValid = amount && !Number.isNaN(amount); if (!amountIsValid) { return msg.channel.createMessage('Invalid donation amount'); } return Promise.all([ msg.channel.createMessage(`${mention} paid $${amount.toFixed(2)}`), updateMemberRoleForDonation(guild, member, amount), ]); }, }; bot.on('messageCreate', async (msg) => { try { const content = msg.content; // Ignore any messages sent as direct messages. // The bot will only accept commands issued in // a guild. if (!msg.channel.guild) { return; } // Ignore any message that doesn't start with the correct prefix. if (!content.startsWith(PREFIX)) { return; } // Extract the parts and name of the command const parts = content.split(' ').map(s => s.trim()).filter(s => s); const commandName = parts[0].substr(PREFIX.length); // Get the requested command, if there is one. const command = commandForName[commandName]; if (!command) { return; } // If this command is only for the bot owner, refuse // to execute it for any other user. const authorIsBotOwner = msg.author.id === BOT_OWNER_ID; if (command.botOwnerOnly && !authorIsBotOwner) { return await msg.channel.createMessage('Hey, only my owner can issue that command!'); } // Separate the command arguments from the command prefix and name. const args = parts.slice(1); // Execute the command. await command.execute(msg, args); } catch (err) { console.warn('Error handling message create event'); console.warn(err); } }); bot.on('error', err => { console.warn(err); }); bot.connect();
สิ่งนี้จะช่วยให้คุณมีแนวคิดพื้นฐานที่ดีในการสร้างบอท Discord ตอนนี้เราจะมาดูวิธีการรวมบอทกับ Ko-fi หากต้องการคุณสามารถสร้างเว็บฮุคในไฟล์ แผงควบคุม ที่ Ko-fi ตรวจสอบให้แน่ใจว่าเราเตอร์ของคุณได้รับการกำหนดค่าให้ส่งต่อพอร์ต 80 และส่งเว็บฮุคทดสอบจริงให้ตัวคุณเอง แต่ฉันจะใช้ บุรุษไปรษณีย์ เพื่อจำลองคำขอ
Webhooks จาก Ko-fi ส่งมอบน้ำหนักบรรทุกที่มีลักษณะดังนี้:
data: { 'message_id':'3a1fac0c-f960-4506-a60e-824979a74e74', 'timestamp':'2017-08-21T13:04:30.7296166Z', 'type':'Donation','from_name':'John Smith', 'message':'Good luck with the integration!', 'amount':'3.00', 'url':'https://ko-fi.com' }
มาสร้างซอร์สไฟล์ใหม่ชื่อ webhook_listener.js และใช้ Express เพื่อฟังเว็บฮุก เราจะมีเส้นทาง Express เพียงเส้นทางเดียวและมีจุดประสงค์เพื่อการสาธิตดังนั้นเราจึงไม่ต้องกังวลมากเกินไปกับการใช้โครงสร้างไดเรกทอรีสำนวน เราจะใส่ตรรกะของเว็บเซิร์ฟเวอร์ทั้งหมดไว้ในไฟล์เดียว
(ลิงค์รหัส GitHub: https://github.com/mistval/premium_bot/blob/master/src/webhook_listener_step6.js )
const express = require('express'); const app = express(); const PORT = process.env.PORT || 80; class WebhookListener { listen() { app.get('/kofi', (req, res) => { res.send('Hello'); }); app.listen(PORT); } } const listener = new WebhookListener(); listener.listen(); module.exports = listener;
จากนั้นเรามาต้องการไฟล์ใหม่ที่ด้านบนของ bot.js เพื่อให้ผู้ฟังเริ่มต้นเมื่อเราเรียกใช้ bot.js
(ลิงค์รหัส GitHub: https://github.com/mistval/premium_bot/blob/master/src/bot_step6.js )
const eris = require('eris'); const webhookListener = require('./webhook_listener.js');
หลังจากเริ่มบอทคุณจะเห็น“ สวัสดี” เมื่อคุณไปที่ http: // localhost / kofi ในเบราว์เซอร์ของคุณ
ตอนนี้มามี WebhookListener
ประมวลผลข้อมูลจากเว็บฮุคและปล่อยเหตุการณ์ และตอนนี้เราได้ทดสอบแล้วว่าเบราว์เซอร์ของเราสามารถเข้าถึงเส้นทางได้แล้วเรามาเปลี่ยนเส้นทางเป็นเส้นทาง POST เนื่องจาก Webhook จาก Ko-fi จะเป็นคำขอ POST
(ลิงค์รหัส GitHub: https://github.com/mistval/premium_bot/blob/master/src/bot_step7.js )
const express = require('express'); const bodyParser = require('body-parser'); const EventEmitter = require('events'); const PORT = process.env.PORT || 80; const app = express(); app.use(bodyParser.json()); class WebhookListener extends EventEmitter { listen() { app.post('/kofi', (req, res) => { const data = req.body.data; const { message, timestamp } = data; const amount = parseFloat(data.amount); const senderName = data.from_name; const paymentId = data.message_id; const paymentSource = 'Ko-fi'; // The OK is just for us to see in Postman. Ko-fi doesn't care // about the response body, it just wants a 200. res.send({ status: 'OK' }); this.emit( 'donation', paymentSource, paymentId, timestamp, amount, senderName, message, ); }); app.listen(PORT); } } const listener = new WebhookListener(); listener.listen(); module.exports = listener;
ต่อไปเราต้องให้บอทฟังเหตุการณ์ตัดสินใจว่าผู้ใช้รายใดบริจาคและกำหนดบทบาทให้พวกเขา ในการตัดสินใจว่าผู้ใช้รายใดบริจาคเราจะพยายามค้นหาผู้ใช้ที่มีชื่อผู้ใช้เป็นสตริงย่อยของข้อความที่ได้รับจาก Ko-fi ผู้บริจาคจะต้องได้รับคำสั่งให้ระบุชื่อผู้ใช้ (กับผู้เลือกปฏิบัติ) ในข้อความมากกว่าที่พวกเขาเขียนเมื่อทำการบริจาค
ที่ด้านล่างของ bot.js:
(ลิงค์รหัส GitHub: https://github.com/mistval/premium_bot/blob/master/src/bot_step7.js )
function findUserInString(str) { const lowercaseStr = str.toLowerCase(); // Look for a matching username in the form of username#discriminator. const user = bot.users.find( user => lowercaseStr.indexOf(`${user.username.toLowerCase()}#${user.discriminator}`) !== -1, ); return user; } async function onDonation( paymentSource, paymentId, timestamp, amount, senderName, message, ) { try { const user = findUserInString(message); const guild = user ? bot.guilds.find(guild => guild.members.has(user.id)) : null; const guildMember = guild ? guild.members.get(user.id) : null; return await updateMemberRoleForDonation(guild, guildMember, amount); } catch (err) { console.warn('Error handling donation event.'); console.warn(err); } } webhookListener.on('donation', onDonation); bot.connect();
ใน onDonation
ฟังก์ชั่นเราเห็นการเป็นตัวแทนของผู้ใช้สองแบบ: ในฐานะผู้ใช้และในฐานะสมาชิก ทั้งสองอย่างนี้แสดงถึงบุคคลคนเดียวกัน แต่ออบเจ็กต์สมาชิกมีข้อมูลเฉพาะของกิลด์เกี่ยวกับผู้ใช้เช่นบทบาทของพวกเขาในกิลด์และชื่อเล่นของพวกเขา เนื่องจากเราต้องการเพิ่มบทบาทเราจึงต้องใช้การเป็นตัวแทนสมาชิกของผู้ใช้ ผู้ใช้แต่ละคนใน Discord มีการเป็นตัวแทนสมาชิกหนึ่งคนสำหรับแต่ละกิลด์ที่พวกเขาอยู่
ตอนนี้ฉันใช้ Postman ทดสอบโค้ดได้แล้ว
ฉันได้รับรหัสสถานะ 200 และฉันได้รับบทบาทที่มอบให้ฉันในเซิร์ฟเวอร์
หากข้อความจาก Ko-fi ไม่มีชื่อผู้ใช้ที่ถูกต้อง อย่างไรก็ตามไม่มีอะไรเกิดขึ้น ผู้บริจาคไม่ได้รับบทบาทและเราไม่ทราบว่าเราได้รับการบริจาคที่เป็นเด็กกำพร้า มาเพิ่มบันทึกสำหรับบันทึกการบริจาครวมถึงเงินบริจาคที่ไม่สามารถนำมาประกอบกับสมาชิกกิลด์ได้
ก่อนอื่นเราต้องสร้างช่องบันทึกใน Discord และรับรหัสช่อง รหัสช่องสามารถพบได้โดยใช้เครื่องมือสำหรับนักพัฒนาซึ่งเปิดใช้งานได้ในการตั้งค่าของ Discord จากนั้นคุณสามารถคลิกขวาที่ช่องใดก็ได้แล้วคลิก“ คัดลอก ID”
ควรเพิ่มรหัสช่องบันทึกในส่วนค่าคงที่ของ bot.js
(ลิงค์รหัส GitHub: https://github.com/mistval/premium_bot/blob/master/src/bot_step8.js )
const LOG_CHANNEL_ID = '526653321109438474';
จากนั้นเราสามารถเขียน logDonation
ฟังก์ชัน
(ลิงค์รหัส GitHub: https://github.com/mistval/premium_bot/blob/master/src/bot_step8.js )
function logDonation(member, donationAmount, paymentSource, paymentId, senderName, message, timestamp) { const isKnownMember = !!member; const memberName = isKnownMember ? `${member.username}#${member.discriminator}` : 'Unknown'; const embedColor = isKnownMember ? 0x00ff00 : 0xff0000; const logMessage = { embed: { title: 'Donation received', color: embedColor, timestamp: timestamp, fields: [ { name: 'Payment Source', value: paymentSource, inline: true }, { name: 'Payment ID', value: paymentId, inline: true }, { name: 'Sender', value: senderName, inline: true }, { name: 'Donor Discord name', value: memberName, inline: true }, { name: 'Donation amount', value: donationAmount.toString(), inline: true }, { name: 'Message', value: message, inline: true }, ], } } bot.createMessage(LOG_CHANNEL_ID, logMessage); }
ตอนนี้เราสามารถอัปเดต onDonation
เพื่อเรียกใช้ฟังก์ชันบันทึก:
async function onDonation( paymentSource, paymentId, timestamp, amount, senderName, message, ) { try { const user = findUserInString(message); const guild = user ? bot.guilds.find(guild => guild.members.has(user.id)) : null; const guildMember = guild ? guild.members.get(user.id) : null; return await Promise.all([ updateMemberRoleForDonation(guild, guildMember, amount), logDonation(guildMember, amount, paymentSource, paymentId, senderName, message, timestamp), ]); } catch (err) { console.warn('Error updating donor role and logging donation'); console.warn(err); } }
ตอนนี้ฉันสามารถเรียกใช้ webhook ได้อีกครั้งโดยใช้ชื่อผู้ใช้ที่ถูกต้องก่อนจากนั้นจึงไม่มีหนึ่งชื่อและฉันได้รับข้อความบันทึกที่ดีสองข้อความในช่องบันทึก
ก่อนหน้านี้เราเพิ่งส่งสตริงไปยัง Discord เพื่อแสดงเป็นข้อความ วัตถุ JavaScript ที่ซับซ้อนมากขึ้นที่เราสร้างและส่งไปยัง Discord ใน logDonation
ใหม่ ฟังก์ชันเป็นข้อความชนิดพิเศษที่เรียกว่าไฟล์ ฝังรวย . การฝังช่วยให้คุณสามารถสร้างข้อความที่น่าดึงดูดเช่นเดียวกับที่แสดง เฉพาะบอทเท่านั้นที่สามารถสร้างการฝังผู้ใช้ไม่สามารถทำได้
ตอนนี้เราได้รับแจ้งเกี่ยวกับการบริจาคบันทึกข้อมูลและตอบแทนผู้สนับสนุนของเรา นอกจากนี้เรายังสามารถเพิ่มเงินบริจาคด้วยตนเองด้วยคำสั่ง addpayment ในกรณีที่ผู้ใช้ลืมระบุชื่อผู้ใช้เมื่อบริจาค ขอเรียกว่าวัน.
โค้ดที่สมบูรณ์สำหรับบทช่วยสอนนี้มีอยู่ใน GitHub ที่นี่ https://github.com/mistval/premium_bot
เราได้สร้างบ็อตที่สามารถช่วยติดตามการบริจาคได้สำเร็จ นี่คือสิ่งที่เราสามารถใช้ได้จริงหรือ? บางที ครอบคลุมพื้นฐาน แต่ไม่มาก นี่คือข้อบกพร่องบางประการที่คุณอาจต้องพิจารณาก่อน:
Premium Member
บทบาทและหากเข้าร่วมอีกครั้งก็จะไม่ได้รับคืน เราควรจัดเก็บการชำระเงินด้วยรหัสผู้ใช้ในฐานข้อมูลดังนั้นหากสมาชิกระดับพรีเมียมกลับเข้ามาอีกครั้งเราสามารถให้บทบาทของพวกเขากลับมาและอาจส่งข้อความต้อนรับกลับที่ดีหากเรามีแนวโน้มPremium Member
บทบาทเมื่อยอดชำระเงินทั้งหมดจากผู้ใช้ถึง $ 10 จะช่วยได้ที่นี่Premium Member
บทบาทฟรี ดูเหมือนว่า Ko-fi จะไม่ได้ลงนามในเว็บฮุกดังนั้นคุณจะต้องพึ่งพาทั้งคนที่ไม่รู้ที่อยู่เว็บฮุกของคุณ (ไม่ถูกต้อง) หรือรายการที่อนุญาตพิเศษของ IP (ดีกว่าเล็กน้อย)มีเว็บไซต์มากกว่าหนึ่งโหลที่แสดงรายการบอท Discord และเปิดให้บริการแก่สาธารณะโดยทั่วไปรวมถึง DiscordBots.org และ Discord.Bots.gg . แม้ว่าบอท Discord ส่วนใหญ่จะเป็นการจู่โจมของมือสมัครเล่นในช่วงเวลาเล็ก ๆ แต่บอทบางตัวก็ได้รับความนิยมอย่างมากและทำให้พวกมันกลายเป็นงานที่ซับซ้อนและมีความต้องการสูง
โดยการนับกิลด์ปัจจุบัน Rythm เป็นบอทที่แพร่หลายที่สุดใน Discord Rythm เป็นบอทเพลงที่มีคุณสมบัติพิเศษในการเชื่อมต่อกับช่องเสียงใน Discord และเล่นเพลงที่ผู้ใช้ร้องขอ ปัจจุบัน Rythm มีอยู่ในกิลด์กว่า 2,850,000 แห่งที่มีจำนวนผู้ใช้รวมกันราว 90 ล้านคนและที่จุดสูงสุดจะเล่นเสียงสำหรับผู้ใช้พร้อมกันประมาณ 100,000 คนใน 20,000 กิลด์แยกต่างหาก ImBursting ผู้สร้างและผู้พัฒนาหลักของ Rythm ตกลงที่จะตอบคำถามสองสามข้อเกี่ยวกับการพัฒนาและดูแลบอทขนาดใหญ่เช่น Rythm
ผู้สัมภาษณ์: คุณช่วยเล่าให้เราฟังเกี่ยวกับสถาปัตยกรรมระดับสูงของ Rythm และวิธีการโฮสต์ได้ไหม
ImBursting: Rythm ถูกปรับขนาดในเซิร์ฟเวอร์จริง 9 เซิร์ฟเวอร์แต่ละตัวมี 32 คอร์, RAM 96GB และการเชื่อมต่อ 10gbps เซิร์ฟเวอร์เหล่านี้ถูกจัดวางไว้ที่ศูนย์ข้อมูลด้วยความช่วยเหลือจาก บริษัท โฮสติ้งขนาดเล็ก GalaxyGate
ฉันจินตนาการว่าตอนที่คุณเริ่มทำงานกับ Rythm คุณไม่ได้ออกแบบให้มันปรับขนาดได้ใกล้เคียงกับที่มันมี คุณช่วยบอกเราได้ไหมว่า Rythm เริ่มต้นอย่างไรและวิวัฒนาการทางเทคนิคเมื่อเวลาผ่านไป
วิวัฒนาการแรกของ Rythm เขียนด้วย Python ซึ่งไม่ใช่ภาษาที่มีประสิทธิภาพมากนักในช่วงเวลาที่เราเข้าถึงเซิร์ฟเวอร์ 10,000 เครื่อง (หลังจากพยายามปรับขนาดหลายครั้ง) ฉันตระหนักว่านี่เป็นสิ่งกีดขวางที่ใหญ่ที่สุดดังนั้นฉันจึงเริ่มเขียนบอทใหม่เป็น Java ด้วยเหตุผล การเป็นไลบรารีเสียงของ Java ได้รับการปรับให้เหมาะสมกว่ามากและโดยทั่วไปแล้วเป็นภาษาที่เหมาะสมกว่าสำหรับแอปพลิเคชันขนาดใหญ่เช่นนี้ หลังจากการเขียนโค้ดใหม่ประสิทธิภาพการทำงานดีขึ้นเป็นสิบเท่าและยังคงมีปัญหาอยู่ชั่วขณะ และจากนั้นเราก็เข้าสู่ขั้นตอนสำคัญของเซิร์ฟเวอร์ 300,000 เครื่องเมื่อปัญหาเริ่มปรากฏขึ้นอีกครั้งเมื่อถึงจุดนั้นฉันก็ตระหนักว่าจำเป็นต้องมีการปรับขนาดให้มากขึ้นเนื่องจาก JVM เพียงตัวเดียวไม่สามารถจัดการได้ทั้งหมด ดังนั้นเราจึงเริ่มใช้การปรับปรุงและการเปลี่ยนแปลงที่สำคัญอย่างช้าๆเช่นการปรับตัวเก็บขยะและการแยกการเชื่อมต่อเสียงไปยังไมโครเซอร์วิสแยกกันโดยใช้เซิร์ฟเวอร์โอเพนซอร์สที่เรียกว่า Lavalink ประสิทธิภาพที่ดีขึ้นนี้ค่อนข้างน้อย แต่โครงสร้างพื้นฐานรอบสุดท้ายคือเมื่อเราแบ่งสิ่งนี้ออกเป็น 9 คลัสเตอร์แยกกันเพื่อทำงานบนเซิร์ฟเวอร์จริง 9 เซิร์ฟเวอร์และสร้างไมโครบริการเกตเวย์และสถิติที่กำหนดเองเพื่อให้แน่ใจว่าทุกอย่างทำงานได้อย่างราบรื่นเหมือนในเครื่องเดียว
ฉันสังเกตเห็นว่า Rythm มีเวอร์ชัน Canary และคุณได้รับความช่วยเหลือจากนักพัฒนาและทีมงานคนอื่น ๆ ฉันคิดว่าคุณและทีมของคุณต้องใช้ความพยายามอย่างมากในการทำให้แน่ใจว่าสิ่งต่างๆสำเร็จลุล่วงไปด้วยดี คุณช่วยบอกเราเกี่ยวกับกระบวนการที่เกี่ยวข้องกับการอัปเดต Rythm ได้หรือไม่?
Rythm canary เป็นอัลฟ่าบอทที่เราใช้เพื่อทดสอบคุณสมบัติที่สร้างขึ้นใหม่และการปรับปรุงประสิทธิภาพก่อนที่จะนำไปใช้กับ Rythm 2 เพื่อทดสอบในระดับที่กว้างขึ้นจากนั้นจึงทำการผลิต Rythm ปัญหาใหญ่ที่สุดที่เราพบคือเวลาในการรีบูตเครื่องที่ยาวนานมากเนื่องจากข้อ จำกัด ของอัตราความไม่ลงรอยกันและเป็นเหตุผลที่ฉันพยายามอย่างเต็มที่เพื่อให้แน่ใจว่าการอัปเดตพร้อมแล้วก่อนที่จะตัดสินใจผลักดัน
ฉันได้รับความช่วยเหลือมากมายจากนักพัฒนาอาสาสมัครและผู้ที่ต้องการช่วยเหลือชุมชนอย่างแท้จริงฉันต้องการให้แน่ใจว่าทุกอย่างเสร็จสิ้นอย่างถูกต้องและผู้คนมักจะได้รับคำตอบสำหรับคำถามและได้รับการสนับสนุนที่ดีที่สุดซึ่งหมายความว่าฉันจะทำงานอย่างต่อเนื่อง มองหาโอกาสใหม่ ๆ
วันของการเป็นเด็กใหม่ในบล็อกของ Discord นั้นผ่านพ้นไปแล้วและตอนนี้มันก็เป็นหนึ่งในแพลตฟอร์มการสื่อสารแบบเรียลไทม์ที่ใหญ่ที่สุดในโลก ในขณะที่บอท Discord ส่วนใหญ่เป็นการโจมตีของมือสมัครเล่นในช่วงเวลาเล็ก ๆ แต่เราอาจเห็นโอกาสทางการค้าเพิ่มขึ้นเนื่องจากจำนวนประชากรของบริการยังคงเพิ่มขึ้น บาง บริษัท เช่น Patreon ดังกล่าวได้เข้ามาแล้ว
ในบทความนี้เราได้เห็นภาพรวมระดับสูงของอินเทอร์เฟซผู้ใช้ของ Discord ภาพรวมระดับสูงของ APIs บทเรียนที่สมบูรณ์เกี่ยวกับการเขียนโปรแกรมบอท Discord และเราได้ทราบว่าการใช้งานบอทในระดับองค์กรเป็นอย่างไร ฉันหวังว่าคุณจะสนใจเทคโนโลยีนี้และรู้สึกว่าคุณเข้าใจพื้นฐานของวิธีการทำงาน
โดยทั่วไปแล้วแชทบอทเป็นเรื่องสนุกยกเว้นเมื่อพวกเขาตอบคำถามที่ซับซ้อนของคุณจะมีความรู้เกี่ยวกับความลึกของถ้วยน้ำ เพื่อให้แน่ใจว่ามี UX ที่ยอดเยี่ยมสำหรับผู้ใช้ของคุณ แชทล่ม - เมื่อ Chatbot ล้มเหลว โดย ApeeScape Design Blog สำหรับ 5 ปัญหาการออกแบบที่ควรหลีกเลี่ยง
ที่เกี่ยวข้อง: แนวทางปฏิบัติที่ดีที่สุดของ JS: สร้าง Discord Bot ด้วย TypeScript และ Dependency Injectionบอท Discord คือแชทบอทอัตโนมัติที่ทำงานบน Discord ซึ่งเป็นแพลตฟอร์มการสื่อสารด้วยข้อความและเสียงยอดนิยม บอทมีอยู่ทั่วไปใน Discord และสามารถตั้งโปรแกรมเพื่อให้บริการต่างๆได้มากมาย
บทบาททั่วไปบางประการที่บอทตอบสนอง ได้แก่ การดูแลการเล่นเกมกับผู้ใช้การเล่นเพลงในช่องเสียงการค้นหาทางอินเทอร์เน็ตและการประมวลผลการชำระเงิน บอทเติมเต็มบทบาททั่วไปและเฉพาะกลุ่มอื่น ๆ อีกนับไม่ถ้วนเช่นกัน
Eris (https://abal.moe/Eris/) และ discord.js (https://discord.js.org/#/) เป็นไลบรารี JavaScript ที่ได้รับการตรวจสอบอย่างเป็นทางการสองรายการ บางครั้งคุณอาจเห็นรหัสบอทที่ขึ้นอยู่กับไลบรารีรุ่นเก่าที่ไม่ได้รับการดูแลหรือในไลบรารีที่เปิดเผย โดยทั่วไปควรหลีกเลี่ยง
ไลบรารีบอทจะดูแลรายละเอียดของการโต้ตอบกับ WebSocket และ REST API ของ Discord เพื่อให้คุณสามารถเขียนโค้ดในระดับที่สูงขึ้นของนามธรรมได้ ไลบรารีจำนวนมากยังมีคุณลักษณะระดับสูงกว่าเช่นกรอบคำสั่ง
A + ถ้าคุณพูดว่า 'สร้างใหม่ทันทีใน Discord Developer Portal' การรั่วไหลของโทเค็นเป็นเหตุการณ์ที่เกิดขึ้นบ่อยครั้งโดยเฉพาะในหมู่นักพัฒนามือใหม่และผลที่ตามมาอาจรุนแรง โปรแกรมรวบรวมข้อมูลเว็บเฝ้าดู GitHub เพื่อหาโทเค็นบ็อตที่รั่วไหลและบอทที่ถูกบุกรุกจะถูกใช้เพื่อวัตถุประสงค์ที่ชั่วร้าย
ทุกคนที่มีบัญชี Discord สามารถเข้าถึง Discord’s Developer Portal (https://discordapp.com/developers/applications/) ลงทะเบียนแอปพลิเคชันสร้างผู้ใช้บอทและรับโทเค็นบ็อต จากนั้นคุณสามารถใช้ไลบรารี Discord ที่คุณเลือกเพื่อตั้งโปรแกรมบอทของคุณ