# discord bot
---
# 設定教學
---
## 創建一個機器人
---
- https://discord.com/developers/applications 進去此網址到discord的開發者介面
- 注意:這個機器人你只能放在你有管理權限的伺服器裡
---
- 點這個$New Application$

---
- 這邊給他一個名字

---
- 點進側邊這個叫$bot$的東西

---
- 把這三個開啟 這樣到時候才能讓它跟$python$程式碼連接起來

---
- 請記得下方這個$token$碼,因為這個寄一次他就不會再給你了,忘了就只能按右邊的按鈕重設$token$碼,重設後下面的步驟都要再做一次

- 到這邊你已經成功創建一個$bot$了,再來就是如何把它放到你的伺服器以及你要給他的權限
- 若沒有出現click to reveal token,就直接reset
---
- 首先,先點$Oauth2$,再來點進$URL$ $Generator$

---
- 再來把$bot$這個選項勾起來

---
- 再來是給這個機器人權限

- 這邊建議是直接給他$Administrator$就是最高權限,這樣以後想要給這個機器人增加別的功能就不需要一個一個權限給它
---
- 複製這個連結 貼到google上

---
- 再來選你想讓它進去的伺服器,如果你沒有你自己有管利權限的伺服器,這邊就不會有伺服器給你選

---
### 前置module
```python
pip install discord
pip install pynacl
pip install pytube
```
---
### 啟動機器人
---
- 引入函式庫
```python=
from pytube import YouTube #從pytube函式庫中引入youtube類,這是用來提供跟youtube影片相關的功能跟操作
import os #引入os函式庫,這是用來調用操作系統命令,來達成建立文件,刪除文件,查詢文件等
import discord #下載discord.py
from discord.ext import commands
```
---
- client:連接Discord
- intent:要求權限
```python=
intents = discord.Intents.default() #intents是要求機器人的權限
intents.message_content = True #讓機器人有傳送訊息的權限
client = discord.Client(intents=intents) #將intents參數 = intents變數
```
---
```python=
@client.event #調用 event 函式庫
async def on_ready(): #on_ready 為一個事件處理器的名子--當機器人完成啟動時的事件
print('目前登入身份:', client.user)
```
---
- 排除自己的訊息,避免陷入無限循環
```python=
@client.event
async def on_message(message):
if message.author == client.user:
#if訊息是自己發的就不要處理這段訊息
return
```
---
- 執行(永遠放在你的程式最後面)
```python=
client.run('你的機器人 TOKEN')
```
---
### 讓機器人上線
```python=
@client.event
async def on_ready(): #on_ready 當機器人完成啟動時的事件
print('目前登入身分', client.user)
#機器人上線後列印 "目前登入身分 (你的機器人的名子)"
game = discord.Game('學習python中')
#更改機器人目前在玩的遊戲
await client.change_presence(status=discord.Status.online,
activity=game) #設定線上狀態
client.run('你的機器人 TOKEN')
```
---
### 互動測試

---
### 機器人說話
#### 這段放剛剛的東西後面 記得token放最後面
```python=
@client.event
async def on_message(message):
if message.author == client.user:
#if訊息是自己發的就不要處理這段訊息
return
if message.content.startswith('說'):
#分割訊息成兩份
tmp = message.content.split(" ")[1:]
#如果分割後串列長度只有1
if len(tmp) == 0:
await message.channel.send("你要我說什麼啦?")
else:
response=" ".join(tmp)
await message.channel.send(response)
```
---
https://hackmd.io/@NLPC5th2/benny1234
上次的進度
```python
pip install discord
pip install pynacl
pip install pytube
```
```python=
from pytube import YouTube
import os
import discord
from discord.ext import commands
intents=discord.Intents.default()
intents.message_content=True
client = discord.Client(intents=intents)
@client.event
async def on_ready():
print('目前登入身分', client.user)
game = discord.Game('學習python中')
await client.change_presence(status=discord.Status.online
,activity=game)
@client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.startswith('說'):
tmp = message.content.split(" ")[1:]
if len(tmp) == 0:
await message.channel.send("你要我說什麼?")
else:
response= " ".join(tmp)
await message.channel.send(response)
client.run("你的機器人token")
```
---
### 讓機器人上線並進入語音頻道
---
- 引入pytube中的youtube函式庫,用來提供與youtube影片相關的功能和操作
- 引入os函式庫,用來處理youtube影片或文件跟目錄
```python=
from pytube import YouTube
import os
from discord.ext import commands
```
---
- 設定指令符號
```python=
client = commands.Bot(command_prefix = "!", intents = intents)
```
---
- 設定指令(進入語音頻道)
```python=
@client.command()
async def join(ctx):
#這裡的指令會讓機器人進入call他的人所在的語音頻道
voice = discord.utils.get(client.voice_clients, guild=ctx.guild) #獲取機器人在的語音頻道
if ctx.author.voice == None:
await ctx.send("你沒有加入任何語音頻道")
elif voice == None:
voiceChannel = ctx.author.voice.channel
await voiceChannel.connect()
else:
await ctx.send("已經在語音頻道裡面了")
```
---
### 讓機器人播放音樂
---
- 設定指令(播放音樂)
```python=
@client.command()
async def play(ctx, url :str = ""):
voice = discord.utils.get(client.voice_clients,
guild=ctx.guild)
#如果機器人在語音頻道裡面 回傳頻道ip,否則回傳"None"
```
---
- 刪除之前播放過的音樂檔
```python=
@client.command()
async def play(ctx, url :str = ""):
voice = discord.utils.get(client.voice_clients,guild=ctx.guild)
#如果機器人在語音頻道裡面 回傳頻道ip,否則回傳"None"
song_there = os.path.isfile("song.mp4")
try:
if song_there:
os.remove("song.mp4")
except PermissionError:
await ctx.send("等待這首歌播完或是使用'!stop'命令")
YouTube(url).streams.first().download()
for file in os.listdir("./"):
if file.endswith(".3gpp"):
os.rename(file,"song.mp4")
voice.play(discord.FFmpegPCMAudio(executable="解碼器路徑",source="song.mp4"))
```
---
### 安裝ffmpeg
[]
---
### 下載
[]
---
### 解壓縮並複製路徑

---
### 將路經放到"解碼器路徑"裡

---
### 音樂暫停
```python=
@client.command()
async def pause(ctx):
voice = discord.utils.get(client.voice_clients, guild=ctx.guild)
if voice.is_playing():
voice.pause()
else:
await ctx.send("目前沒有在播放任何東西")
```
---
### 音樂繼續
```py=
@client.command()
async def resume(ctx):
voice = discord.utils.get(client.voice_clients, guild=ctx.guild)
if voice.is_paused():
voice.resume()
else:
await ctx.send("已經在播放了")
```
---
### 退出語音頻道
```python=
@client.command()
async def disconnect(ctx):
voice = discord.utils.get(client.voice_clients, guild=ctx.guild)
if voice == None:
await ctx.send("我現在不在語音頻道裡面")
else:
await voice.disconnect()
```
---
## 完成程式碼
```python=
from pytube import YouTube
import os
import discord
from discord.ext import commands
intents=discord.Intents.default()
intents.message_content=True
client = commands.Bot(command_prefix = "!", intents = intents)
@client.event
async def response(message): #當有訊息,排除自己的訊息,避免陷入無限循環
if message.author == client.user:
return
@client.event
async def on_ready(): #on_ready 為一個事件處理器的名子--當機器人完成啟動時的事件
print('目前登入身分', client.user) #機器人上線後列印 "目前登入身分 (你的機器人的名子)"
game = discord.Game('學習python中') #更改機器人目前在玩的遊戲
await client.change_presence(status=discord.Status.online, activity=game) #設定線上狀態
@client.command()
async def join(ctx):
#這裡的指令會讓機器人進入call他的人所在的語音頻道
voice = discord.utils.get(client.voice_clients, guild=ctx.guild) #獲取機器人在的語音頻道
if ctx.author.voice == None: #ctx.author.voice表示你所在的語音頻道
await ctx.send("你沒有加入任何語音頻道")
elif voice == None:
voiceChannel = ctx.author.voice.channel
await voiceChannel.connect()
else:
await ctx.send("已經在語音頻道裡面了")
@client.command()
async def disconnect(ctx):
voice = discord.utils.get(client.voice_clients, guild=ctx.guild)
if voice == None:
await ctx.send("我現在不在語音頻道裡面")
else:
await voice.disconnect()
@client.command()
async def play(ctx, url :str = ""):
#取得目前機器人狀態
voice = discord.utils.get(client.voice_clients, guild=ctx.guild)
#如果還有找到之前已經被播放過的音樂檔, 進行刪除
song_there = os.path.isfile("song.mp4")
try:
if song_there:
os.remove("song.mp4")
except PermissionError:
await ctx.send("Wait for the current playing music to end or use the 'stop' command")
#找尋輸入的Youtube連結, 將目標影片下載下來備用
YouTube(url).streams.first().download()
#將目標影片改名, 方便找到它
for file in os.listdir("./"):
if file.endswith(".3gpp"):
os.rename(file,"song.mp4")
#找尋要播放的音樂並播放, 結束後依照after部分的程式進行後續步驟
voice.play(discord.FFmpegPCMAudio(executable="路徑", source="song.mp4"))
@client.command()
async def pause(ctx):
voice = discord.utils.get(client.voice_clients, guild=ctx.guild)
if voice.is_playing():
voice.pause()
else:
await ctx.send("目前沒有在播放任何東西")
@client.command()
async def resume(ctx):
voice = discord.utils.get(client.voice_clients, guild=ctx.guild)
if voice.is_paused():
voice.resume()
else:
await ctx.send("現在正在播放了")
client.run('你的機器人token')
```
{"metaMigratedAt":"2023-06-18T05:28:36.227Z","metaMigratedFrom":"YAML","title":"discord bot","breaks":true,"slideOptions":"{\"theme\":\"white\"}","contributors":"[{\"id\":\"b405d87d-0698-478c-9009-9939bd969d2c\",\"add\":6439,\"del\":958},{\"id\":\"4d8ac2d3-29c7-4a8e-a906-e7cdf0999b25\",\"add\":1212,\"del\":0},{\"id\":\"83f5b3e0-d6bd-4eaf-bceb-fc6a8dfdeecf\",\"add\":2156,\"del\":0}]"}