通过 nb adapter install nonebot-adapter-discord 安装本适配器。
或在 nb create 创建项目时选择 Discord 适配器。
可通过 pip install git+https://github.com/nonebot/adapter-discord.git@master 安装开发中版本。
由于 Discord 文档存在部分表述不清的地方,并且结构复杂,存在很多 partial object, 需要更多实际测试以找出问题,欢迎提出 ISSUE 反馈。
修改 NoneBot 配置文件 .env 或者 .env.*。
参考 driver 配置项,添加 ForwardDriver 支持。
如:
DRIVER=~httpx+~websockets配置机器人帐号,如:
DISCORD_BOTS=' [ { "token": "xxx", "intent": { "guild_messages": true, "direct_messages": true }, "application_commands": {"*": ["*"]} } ] ' # application_commands的{"*": ["*"]}代表将全部应用命令注册为全局应用命令 # {"admin": ["123", "456"]}则代表将admin命令注册为id是123、456服务器的局部命令,其余命令不注册是否启用数据压缩,默认为 False,如:
DISCORD_COMPRESS=TrueDiscord API 版本,默认为 10,如:
DISCORD_API_VERSION=10Discord API 超时时间,默认为 30 秒,如:
DISCORD_API_TIMEOUT=15.0是否处理自己发送的消息,默认为 False,如:
DISCORD_HANDLE_SELF_MESSAGE=True代理设置,默认无,如:
DISCORD_PROXY='http://127.0.0.1:6666'以下是一个简单的插件示例,展示各种消息段:
import datetime from nonebot import on_command from nonebot.params import CommandArg from nonebot.adapters.discord import Bot, MessageEvent, MessageSegment, Message from nonebot.adapters.discord.api import * matcher = on_command('send') @matcher.handle() async def ready(bot: Bot, event: MessageEvent, msg: Message = CommandArg()): # 调用discord的api self_info = await bot.get_current_user() # 获取机器人自身信息 user = await bot.get_user(user_id=event.user_id) # 获取指定用户信息 ... # 各种消息段 msg = msg.extract_plain_text() if msg == 'mention_me': # 发送一个提及你的消息 await matcher.finish(MessageSegment.mention_user(event.user_id)) elif msg == 'time': # 发送一个时间,使用相对时间(RelativeTime)样式 await matcher.finish(MessageSegment.timestamp(datetime.datetime.now(), style=TimeStampStyle.RelativeTime)) elif msg == 'mention_everyone': # 发送一个提及全体成员的消息 await matcher.finish(MessageSegment.mention_everyone()) elif msg == 'mention_channel': # 发送一个提及当前频道的消息 await matcher.finish(MessageSegment.mention_channel(event.channel_id)) elif msg == 'embed': # 发送一个嵌套消息,其中包含a embed标题,nonebot logo描述和来自网络url的logo图片 await matcher.finish(MessageSegment.embed( Embed(title='a embed', type=EmbedTypes.image, description='nonebot logo', image=EmbedImage( url='https://v2.nonebot.dev/logo.png')))) elif msg == 'attachment': # 发送一个附件,其中包含来自本地的logo.png图片 with open('logo.png', 'rb') as f: await matcher.finish(MessageSegment.attachment(file='logo.png', content=f.read())) elif msg == 'component': # 发送一个复杂消息,其中包含一个当前时间,一个字符串选择菜单,一个用户选择菜单和一个按钮 time_now = MessageSegment.timestamp(datetime.datetime.now()) string_select = MessageSegment.component( SelectMenu(type=ComponentType.StringSelect, custom_id='string select', placeholder='select a value', options=[ SelectOption(label='A', value='a'), SelectOption(label='B', value='b'), SelectOption(label='C', value='c')])) select = MessageSegment.component(SelectMenu( type=ComponentType.UserInput, custom_id='user_input', placeholder='please select a user')) button = MessageSegment.component( Button(label='button', custom_id='button', style=ButtonStyle.Primary)) await matcher.finish('now time:' + time_now + string_select + select + button) else: # 发送一个文本消息 await matcher.finish(MessageSegment.text(msg))以下是一个 Discord 斜杠命令的插件示例:
import asyncio from typing import Optional from nonebot.adapters.discord.api import ( IntegerOption, NumberOption, StringOption, SubCommandOption, User, UserOption, ) from nonebot.adapters.discord.commands import ( CommandOption, on_slash_command, ) matcher = on_slash_command( name="permission", description="权限管理", options=[ SubCommandOption( name="add", description="添加", options=[ StringOption( name="plugin", description="插件名", required=True, ), IntegerOption( name="priority", description="优先级", required=False, ), ], ), SubCommandOption( name="remove", description="移除", options=[ StringOption(name="plugin", description="插件名", required=True), NumberOption(name="time", description="时长", required=False), ], ), SubCommandOption( name="ban", description="禁用", options=[ UserOption(name="user", description="用户", required=False), ], ), ], ) @matcher.handle_sub_command("add") async def handle_user_add( plugin: CommandOption[str], priority: CommandOption[Optional[int]] ): await matcher.send_deferred_response() await asyncio.sleep(2) await matcher.edit_response(f"你添加了插件 {plugin},优先级 {priority}") await asyncio.sleep(2) fm = await matcher.send_followup_msg( f"你添加了插件 {plugin},优先级 {priority} (新消息)" ) await asyncio.sleep(2) await matcher.edit_followup_msg( fm.id, f"你添加了插件 {plugin},优先级 {priority} (新消息修改后)" ) @matcher.handle_sub_command("remove") async def handle_user_remove( plugin: CommandOption[str], time: CommandOption[Optional[float]] ): await matcher.send(f"你移除了插件 {plugin},时长 {time}") @matcher.handle_sub_command("ban") async def handle_admin_ban(user: CommandOption[User]): await matcher.finish(f"你禁用了用户 {user.username}")