文章目录
前言
要做好海外产品需要更好个性化运营社群,discord目前是比较成熟的解决方案
一、Discord Bot
1. 获取 Token
# link: discord.com/developers
1. Go Developer
# 新建项目
2. New Application -> Creat Project Name
# 设置机器人权限获取链接
3. OAuth2 - > URL Generator -> bot(select)- > permission(select) -> copy URL
# 打开链接关联Topic
4. Open URL and authorize
# 添加机器人获取Token
6. Back to developoer Menu -> Bot -> Add Bot -> Copy Token
2. 连接API测试
!pip3 install discord # 安装模块
import discord
Token = ‘’
client = discord.Client(intents=discord.Intents.all())
client.run(Token)
注:需要租用海外服务器,否则无法连接discord登录
3. Bot自动回复
# django .view
def discord_bot(request):
import discord,os
TOKEN = 'xxxx-xxxx'
client = discord.Client(intents=discord.Intents.default())
@client.event
async def on_ready():
print('Long time no see , my friend')
@client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.startswith('hello'):
await message.channel.send('Welcome!')
client.run(TOKEN)
return HttpResponse('Bot Success')
4. Bot音频播放
view.py
def discord(request):
key = request.POST.get('key')
if key == '****':
if request.method == 'POST':
import discord,os,random,urllib.request,re,time,threading
from discord.ext import commands
# 验证码
TOKEN = ''
# 建立对话客户端,指定命令启动符为/,开放所有的意图
# ⚠️ 此处一定需要打开Discord Develope - Bot - “Privileged Gateway Intents” 的选项
client = commands.Bot(command_prefix="/",intents=discord.Intents.all())
# 当接收「/play」播放指令
@client.command()
async def play(ctx):
# 指定语音播放的频道
voiceChannel = discord.utils.get(ctx.guild.voice_channels, name='General')
# 添加机器人并建立链接
try:
await voiceChannel.connect()
except:
await ctx.send("Bot already connected")
# 指定公会
voice = discord.utils.get(client.voice_clients, guild=ctx.guild)
# 音频地址 | http外链可能会要求不同的ffmpeg内插件,需要补充安装
mp3_path = 'demo.mp3'
# 如果找不到ffmpeg,可以指定安装位置,添加executable
ffmpeg_path = '/root/ffmpeg-3.1/ffmpeg'
voice.play(discord.FFmpegPCMAudio(executable=ffmpeg_path,source=mp3_path)
# 当接收「/leave」退出指令
@client.command()
async def leave(ctx):
voice = discord.utils.get(client.voice_clients, guild=ctx.guild)
if voice.is_connected():
await voice.disconnect()
else:
await ctx.send("The bot is not connected to a voice channel.")
# 当接收「/pause」暂停指令
@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("Currently no audio is playing.")
# 当接收「/resume」继续播放指令
@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("The audio is not paused.")
# 当接收「/stop」暂停播放指令
@client.command()
async def stop(ctx):
voice = discord.utils.get(client.voice_clients, guild=ctx.guild)
voice.stop()
# 运行程序
try:
# runtime
client.run(TOKEN)
return HttpResponse('BOT CLOSED')
except:
return HttpResponse('Discord connect failed')
client.run(TOKEN)
return HttpResponse('')
else:
return HttpResponse('')
用户prompt功能
import discord, random
from discord.ext import commands
from discord import app_commands
client = commands.Bot(command_prefix="/",intents=discord.Intents.all())
@client.event
async def on_ready () :
print ("Bot is Up and Ready!")
try:
synced = await client.tree.sync ()
print (f"Synced {len (synced)} command(s)")
except Exception as e:
print(e)
@client.tree.command (name="say")
@app_commands.describe (thing_to_say="What should I say?")
async def say(interaction: discord. Interaction, thing_to_say: str):
await interaction.response.send_message(f"{interaction.user.name} said: '{thing_to_say}'")
安装FFmpeg
Linux系统安装FFmpeg
# 下载ffmpeg
1. wget http://www.ffmpeg.org/releases/ffmpeg-3.1.tar.gz
# 解压缩
2. tar -zxvf ffmpeg-3.1.tar.gz
# 指定安装目录
3. cd ffmpeg-3.1
4. ./configure --prefix=/usr/local/ffmpeg
5. sudo make install
# 开启修改配置 (“i” 修改 | “esc + ’:' + 'wq' 保存退出)
6. vi /etc/profile
# 配置最后填入路径
7. export PATH=$PATH:/usr/local/ffmpeg/bin
# 设置生效
8. source /etc/profile
# 查看版本
9. ffmpeg -version
* 若报错「 nasm/yasm not found or too old 」
# 安装yasm编译器
10. wget http://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz
11. tar -zxvf yasm-1.3.0.tar.gz
12. cd yasm-1.3.0
13. ./configure
14. sudo make install
# 安装成功后进入到ffmpeg的文件夹下设置更新
15.find / -name ffmpeg
15. ./configure
16. make
17. sudo make install
# PyNaCL安装
18. /path/~_venv/bin/pip3 install PyNaCL
5. Bot回复Button
import discord
class Menu(discord.ui.View):
def _init_(self):
super()._init_()
self.value = None
@discord.ui.button(label="Send Message", style=discord.ButtonStyle.grey)
async def menu1(self, interaction: discord.Interaction, button: discord.ui.Button):
await interaction.response.send_message("Clicke Me")
@discord.ui.button(label="Edit Message", style=discord.ButtonStyle.green)
async def menu2(self, interaction: discord.Interaction, button: discord.ui.Button):
await interaction.response.edit_message(content="Edit Me")
@discord.ui.button(label="Edited Embed", style=discord.ButtonStyle.blurple)
async def menu3(self, interaction: discord.Interaction, button: discord.ui.Button):
embed = discord.Embed(color=discord.Color.random())
embed.set_author(name=f"Embed Me")
embed.add_field(name="Civo", value="Subscribe")
await interaction.response.edit_message(embed=embed)
@discord.ui.button(label="Quit", style=discord.ButtonStyle.red)
async def menu4(self, interaction: discord.Interaction, button: discord.ui.Button):
embed = discord.Embed(color=discord.Color.random())
embed.set_author(name=f"Goodbye kid")
embed.add_field(name="Bye bye", value="Make sure to Subscribe")
await interaction.response.edit_message(embed=embed)
self.value = False
self.stop()
@client.command()
async def menu(ctx):
view = Menu()
view.add_item(
discord.ui.Button(label="URL Button", style=discord.ButtonStyle.link, url="https://www.glissando.info"))
await ctx.reply("This is menu", view=view)
6. Bot 接入ChatGPT
# chatgptbot
@client.tree.command(name="lyrics")
async def GPTprompt(interaction: discord.Interaction, prompt: str):
async with aiohttp.ClientSession() as session:
API_KEY = ""
payload = {
"model": "text-davinci-003",
"prompt": prompt,
"temperature": 0.5,
"max_tokens": 100,
"presence_penalty": 0,
"frequency_penalty": 0,
}
headers = {"Authorization": f"Bearer {API_KEY}"}
await interaction.response.defer(ephemeral=True)
async with session.post("https://api.openai.com/v1/completions", json=payload, headers=headers) as resp:
response = await resp.json()
embed = str(response["choices"][0]["text"])
await interaction.response.send_message(f"{embed}")
7. Bot 显示个人简介
@client.tree.context_menu(name="whothis")
async def whothi![请添加图片描述](https://img-blog.csdnimg.cn/b6c1b7d1b6f8466eb515584fb537fcbe.png)
s(interaction: discord.Interaction, member: discord.Member):
embed = discord.Embed(title=f"{member.name}#{member.discriminator}", description=f"ID: {member.id}")
embed.add_field(name="Joined Discord", value=member.created_at.strftime("%d/%m/%Y %H:%M:%5"), inline=False)
embed.add_field(name="Roles", value="".join([role.mention for role in member.roles]), inline=False)
embed.add_field(name="Badges", value="".join([badge.name for badge in member.public_flags.all()]), inline=False)
embed.add_field(name="Activity", value=member.activity)
embed.set_thumbnail(url=member.avatar.url)
await interaction.response.send_message(embed=embed, ephemeral=True)
8. Bot 发送附件/Coin限制/内容信息板
@client.tree.command(name="Attachment")
@app_commands.describe(prompt="prompt")
async def prompt(interaction: discord.Interaction, prompt: str, ):
coins = 100
if coins > 1:
embed = discord.Embed(title=f"Mini Love", description=f"USID: 032506304932")
embed.add_field(name="Owner", value=f"{interaction.user.name} | {interaction.user.id}", inline=False)
embed.add_field(name="Birthday", value='06/06/2023 15:30', inline=False)
embed.set_thumbnail(url='..')
file_path = '../1.mid'
filename = file_path.split('/')[-1]
with open(file_path, 'rb') as file:
linkfile = discord.File(file, filename=filename)
await interaction.response.send_message(file=linkfile, embed=embed, ephemeral=True)
else:
embed = discord.Embed(title=f"Out of coins", description=f"")
embed.add_field(name="more coin", value='https://...', inline=False)
await interaction.response.send_message(embed=embed, ephemeral=True)
10. 特别笔记
1) 同时使用@client.event和@client.command
# Discord.py的问题,需要在on_message结尾处加入process_commands
@client.command():
async def play(ctx):
...
@client.event
async def on_message(message):
...
await client.process_commands(message)