# PecuLab WEB3 LiveCoding (2022-06-09) ## Discord運作機制及機器人程式開發 ### **前置作業** >* [雙重身分驗證](https://support.discord.com/hc/zh-tw/articles/219576828-%E9%9B%99%E9%87%8D%E9%A9%97%E8%AD%89%E8%A8%AD%E5%AE%9A) >* [Vscode Download](https://code.visualstudio.com/download) >* `pip discord.py ` > >![](https://i.imgur.com/2Mt1RBs.png) >* [**Discord Develope** -申請Token](https://discord.com/developers/applications) >* 邀請你的discord bot 進入你的頻道 ## 開始撰寫discord bot程式! ### 先建置基礎架構 > ![](https://i.imgur.com/lqUxB2H.png) >* cmds-副程式放置區 >* core-屬性定義放置 >* pic-照片放置 >* setting.json-將資料存在json檔以方便提取 ### 主程式 chat.py ```python=1 import discord from discord.ext import commands import json import random import os with open('setting.json',mode = 'r',encoding='utf8') as jfile: jdata = json.load(jfile) intents = discord.Intents.default() intents.members = True #discord 1.5之更新 bot = commands.Bot(command_prefix="==",intents = intents) @bot.event #bot有無開啟 async def on_ready(): print('>> Bot is online <<') @bot.command() async def load(ctx,extension): bot.load_extension(f'cmds.{extension}') await ctx.send(f'Loaded {extension} done.') @bot.command() async def unload(ctx,extension): bot.unload_extension(f'cmds.{extension}') await ctx.send(f'Un-Loaded {extension} done.') @bot.command() async def reload(ctx,extension): bot.reload_extension(f'cmds.{extension}') await ctx.send(f'Re-Loaded {extension} done.') for filename in os.listdir("./cmds"): if filename.endswith('.py'): bot.load_extension(f'cmds.{filename[:-3]}') if __name__ == "__main__": bot.run(jdata["TOKEN"]) ``` ### setting.json ```json=1 { "TOKEN": "", "guild": "", "Welcome_channel": "", "Leave_channel": "", "pic": [ "C:\\Users\\DC\\discord bot\\test_chat\\pic\\01.jpg", "C:\\Users\\DC\\discord bot\\test_chat\\pic\\02.jpg", "C:\\Users\\DC\\discord bot\\test_chat\\pic\\03.jpg", "C:\\Users\\DC\\discord bot\\test_chat\\pic\\04.jpg" ], "url_pic": [ "https://i.kfs.io/playlist/global/67074264v1/cropresize/600x600.jpg", "https://i.imgur.com/zvhwqXl.png" ] } ``` ### event.py [discord_event](https://discordpy.readthedocs.io/en/stable/api.html?highlight=event#event-reference) ```python=1 from ast import keyword import discord from discord.ext import commands from core.classes import Cog_Extension import json with open('setting.json',mode = 'r',encoding='utf8') as jfile: jdata = json.load(jfile) class Event(Cog_Extension): @commands.Cog.listener() #成員加入 async def on_member_join(self,member): channel = self.bot.get_channel(int(jdata['Welcome_channel'])) #ID await channel.send(f'{member} 歡迎你加入!') #DC回應 @commands.Cog.listener() #成員退出 async def on_member_remove(self,member): channel = self.bot.get_channel(int(jdata['Leave_channel'])) await channel.send(f'{member} QQ有緣再相見:(') @commands.Cog.listener() #關鍵字 async def on_message(self,msg): keyword = ['apple','banana'] if msg.content in keyword and msg.author != self.bot.user: await msg.channel.send('hi') @commands.Cog.listener() #按貼圖獲得身分組 async def on_raw_reaction_add(self,data): if data.message_id == 984082202205778021: #選擇訊息ID if str(data.emoji) == '🦉': guild = self.bot.get_guild(data.guild_id)#取得當前伺服器 role = guild.get_role(970685526040510524)#取得伺服器內指定身分組 await data.member.add_roles(role) await data.member.send(f'你取得了{role}身分組') #私訊 @commands.Cog.listener() #按貼圖離開身分組 async def on_raw_reaction_remove(self,data): if data.message_id == 984082202205778021: #選擇訊息ID if str(data.emoji) == '🦉': guild = self.bot.get_guild(data.guild_id)#取得當前伺服器 role = guild.get_role(970685526040510524)#取得伺服器內指定身分組 user = guild.get_member(data.user_id) # 下面remove_roles無.member可調用所以需自行抓取使用者 await user.remove_roles(role) await user.send(f'你失去了{role}身分組') #私訊 #處裡"指令"發生之錯誤 Error Handler #也可做獨立"指令"的錯誤訊息(EP15 29:00) @commands.Cog.listener() async def on_command_error(self,ctx,error): if isinstance(error,commands.errors.MissingRequiredArgument): await ctx.send('記得輸入參數喔!') elif isinstance(error,commands.errors.BadArgument): await ctx.send('參數型態錯了啦!') elif isinstance(error,commands.errors.CommandNotFound): await ctx.send('沒有這個指令喔!') else: await ctx.send('發生錯誤,再注意一下哪錯了!') def setup(bot): bot.add_cog(Event(bot)) ``` ### react.py ```python=1 import discord from discord.ext import commands from core.classes import Cog_Extension import random import json with open('setting.json',mode = 'r',encoding='utf8') as jfile: jdata = json.load(jfile) class React(Cog_Extension): @commands.command() #本機端上傳隨機圖片 async def 本機圖片(self,ctx): random_pic = random.choice(jdata['pic']) pic = discord.File(random_pic) await ctx.send(file=pic) @commands.command() #網址上傳隨機圖片 async def 網路圖片(self,ctx): random_pic = random.choice(jdata['url_pic']) await ctx.send(random_pic) def setup(bot): bot.add_cog(React(bot)) ``` ### main.py [嵌入式訊息製造器](https://cog-creators.github.io/discord-embed-sandbox/) ```python=1 import discord from discord.ext import commands from core.classes import Cog_Extension import datetime import random class Main(Cog_Extension): @commands.command() #機器人之延遲(秒→毫秒→四捨五入) async def ping(self,ctx): #ctx=上下文 await ctx.send(f'{round(self.bot.latency*1000)}(ms)') @commands.command() #做出內嵌訊息 async def em(self,ctx): embed=discord.Embed(title="嗨大家好這是一隻柴犬", url="https://cdn.hk01.com/di/media/images/2889837/org/4ef07fed4a8836f3ed6df68bbfc7d0c9.jpg/nAAal3F-2QSZICGJCFefX31f_bD3NTZhM-WgQjPloEI?v=w1920", description="柴犬", color=0x2099b1) embed.set_author(name="柴柴", url="https://cdn.hk01.com/di/media/images/2889837/org/4ef07fed4a8836f3ed6df68bbfc7d0c9.jpg/nAAal3F-2QSZICGJCFefX31f_bD3NTZhM-WgQjPloEI?v=w1920", icon_url="https://cdn.hk01.com/di/media/images/2889837/org/4ef07fed4a8836f3ed6df68bbfc7d0c9.jpg/nAAal3F-2QSZICGJCFefX31f_bD3NTZhM-WgQjPloEI?v=w1920") embed.set_thumbnail(url="https://cdn.hk01.com/di/media/images/2889837/org/4ef07fed4a8836f3ed6df68bbfc7d0c9.jpg/nAAal3F-2QSZICGJCFefX31f_bD3NTZhM-WgQjPloEI?v=w1920") embed.add_field(name="年紀", value="3", inline=False) embed.add_field(name="體重", value="20", inline=False) embed.set_footer(text="大家好") await ctx.send(embed=embed) @commands.command() #複誦訊息 async def sayd(self,ctx,*,msg): await ctx.message.delete() await ctx.send(msg) @commands.command() #刪除N筆訊息 async def clean(self,ctx,num:int): await ctx.channel.purge(limit = num+1) def setup(bot): bot.add_cog(Main(bot)) ``` ## 學習資料! >* [Discord Api](https://discordpy.readthedocs.io/en/stable/index.html) >* [Proladon Youtube](https://www.youtube.com/playlist?list=PLSCgthA1Anif1w6mKM3O6xlBGGypXtrtN) >* [音樂機器人檔案](https://github.com/Raptor123471/DingoLingo)