lecturer: 乘一
~基本介紹與實作
其實就是Discord上的Robot
有沒有想要每天一份問候?
有沒有想要在Discord裡聽音樂?
有沒有想要在Discord中玩RPG?
主要還是因為它很好玩
我絕對沒有在推銷
各種Bot
音樂機器人
管理機器人
抓寶機器人
當然還有各種不好說功能機器人
為什麼要自己寫一個Bot?
都有那麼多強大的Bot了,幹嘛自己寫一個?
因為可以客製化自己的需求!
本次使用之開發環境
創建一個機器人
創建一個機器人
創建一個機器人
創建一個機器人
創建一個機器人
把機器人加進你的伺服器
把機器人加進你的伺服器
Bot基本架構
import discord #導入 Discord.py
from discord.ext import commands #導入 commands 雖然目前不會用到
import os #導入os模組
intents = discord.Intents.all()
bot = commands.Bot(command_prefix='你想要的指令前綴', intents = intents)
#透過bot與dicord連結,並設定command的前綴(但還不會用到)
@bot.event #這是裝飾器
async def on_ready(): #當機器人完成啟動時
print('目前登入身份:', bot.user)
try:
bot.run('機器人TOKEN') #就是你剛剛拿到的TOKEN
except:
os.system("kill 1") #修正程式錯誤(repl會莫名其妙出錯)
Bot基本架構
import discord #導入 Discord.py
from discord.ext import commands #導入 commands 雖然目前不會用到
import os #導入os模組
intents = discord.Intents.all()
bot = commands.Bot(command_prefix='你想要的指令前綴', intents = intents)
#透過bot與dicord連結,並設定command的前綴(但還不會用到)
@bot.event #這是裝飾器
async def on_ready(): #當機器人完成啟動時
print('目前登入身份:', bot.user)
try:
bot.run('機器人TOKEN') #就是你剛剛拿到的TOKEN
except:
os.system("kill 1") #修正程式錯誤(repl會莫名其妙出錯)
Event
#當...的時候要做甚麼->event!
@bot.event #裝飾器
async def function_name(parameters):
#async 異步協程
...
讓機器人說話
@bot.event
async def on_message(msg): #當偵測到訊息
if msg.author == bot.user: #避免無限循環
return
if msg.content.startswith("say"): #偵測msg的開頭
tmp = msg.content.split(" ", 1) #將msg切開
if len(tmp)==1: #如果長度只有1,代表後面沒東西
await msg.channel.send("Pardon me?")
else:
await msg.channel.send(tmp[1])
當機器人被mention
import asyncio
@bot.event
async def on_message(message):
if bot.user.mentioned_in(message): #當Bot被提及
delmsg = await message.channel.send(message.author.mention+"幹嘛啦!?")
#將訊息存入delmsg方便之後刪除
await asyncio.sleep(3) #停止3秒
await delmsg.delete() #刪除訊息
await message.channel.send(message.author.name+"對不起我不該這麼兇\n")
使用機器人來打招呼
@bot.event
async def on_member_join(member): #當有成員加入
print(f'{member}join!')
joinchannel = bot.get_channel("channel ID") #獲得特定頻道ID
await joinchannel.send(member.mention+' 歡迎加入!') #在特定頻道發言
@bot.event
async def on_member_remove(member): #當有成員離開
print(f'{member}leave~')
leavechannel=bot.get_channel("channel ID")
await leavechannel.send(member.mention+'再見!')
或是驅逐他們
當然也可以弄得炫一點
Event
Command
@bot.event
async def on_message(msg):
await bot.process_commands(msg)
#解決on_message 與 command 衝突的問題
@bot.command()
async def command_name(ctx):
#ctx上下文
#包含各種訊息,如:發送者、頻道...
#...
Ping Pong
@bot.command()
async def ping(ctx):
await ctx.send(f'{round(bot.latency*1000, 2)}ms')
#bot.latency 機器人延遲
Command
我懶得備課
Cog 是啥?
on_message
on_member
ping
Cog 是啥?
on_message
on_member
ping
Cog 是啥?
on_message
on_member
ping
Cog 是啥?
on_message
on_member
ping
Cog
Cog
Command
#原本
import discord
from discord.ext import commands
@bot.command()
async def ping(ctx):
await ctx.send(f'{round(self.bot.latency*1000, 2)}ms')
Command
#改成cog
import discord
from discord.ext import commands
class Cmd(commands.Cog): #繼承commands.Cog
def __init__(self, bot):
self.bot = bot
@commands.command() #記得改
async def ping(self, ctx): #記得加self
await ctx.send(f'{round(self.bot.latency*1000, 2)}ms')
async def setup(bot):
await bot.add_cog(Cmd(bot))
Event
#原本event
import discord #導入 Discord.py
from discord.ext import commands
import asyncio
@bot.event
async def on_message(msg): #當偵測到訊息
if msg.author == bot.user: #避免無限循環
return
if msg.content.startswith("say"): #偵測msg的開頭
await msg.channel.send("hello")
Event
#改成cog
import discord
from discord.ext import commands
import asyncio
class Event(commands.Cog): #繼承commands.Cog
def __init__(self, bot):
self.bot = bot
@commands.Cog.listener() #改
async def on_message(self, msg): #記得加self
if msg.author == self.bot.user: #避免無限循環
return
if msg.content.startswith("say"): #偵測msg的開頭
await msg.channel.send("hello!")
async def setup(bot):
await bot.add_cog(Event(bot))
Main
import discord #導入 Discord.py
from discord.ext import commands
import os #導入os模組
import asyncio
intents = discord.Intents.all()
bot = commands.Bot(command_prefix='(', intents=intents)
@bot.event #這是裝飾器
async def on_ready(): #當機器人完成啟動時
print('目前登入身份:', bot.user)
@bot.command()
async def load(ctx, ext):
await bot.load_extension(f'cogs.{ext}')
await ctx.send(f'{ext} loaded successfully.')
@bot.command()
async def unload(ctx, ext):
await bot.unload_extension(f'cogs.{ext}')
await ctx.send(f'{ext} unloaded successfully.')
@bot.command()
async def reload(ctx, ext):
await bot.reload_extension(f'cogs.{ext}')
await ctx.send(f'{ext} reloaded successfully.')
async def load_extensions(): #一開始要把所有cog載入
for filename in os.listdir("./cogs"):
if filename.endswith(".py"): #偵測有py的檔案
await bot.load_extension(f"cogs.{filename[:-3]}") #去除.py
async def main():
async with bot:
await load_extensions()
await bot.start(os.getenv("TOKEN"))
if __name__ == "__main__": #如果跑的是這個py
try:
asyncio.run(main()) #就是你剛剛拿到的TOKEN
except:
os.system("kill 1") #修正程式錯誤(repl會莫名其妙出錯)
然後做出一隻強大但沒什麼用的機器人
e.g.
import requests
from bs4 import BeautifulSoup
@bot.event
async def on_ready():
channel = bot.get_channel(***********)
url = "**********"
html = requests.get(url)
soup = BeautifulSoup(html.text, "html.parser")
results = soup.find_all("img", class_="post-item-img", limit=5)
image_links = list(result["src"] for result in results)
for link in image_links:
await channel.send(link)
await asyncio.sleep(24*60*60)
是不是很有趣呢?