Skip to main content

nonebot-adapter-discord

NoneBot-Adapter-Discord

✨ Discord 协议适配 ✨

安装

通过 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

参考 driver 配置项,添加 ForwardDriver 支持。

如:

DRIVER=~httpx+~websockets

DISCORD_BOTS

配置机器人帐号,如:

DISCORD_BOTS='
[
  {
    "token": "xxx",
    "intent": {
      "guild_messages": true,
      "direct_messages": true,
      "message_content": true
    },
    "application_commands": {"*": ["*"]}
  }
]
'

# application_commands的{"*": ["*"]}代表将全部应用命令注册为全局应用命令
# {"admin": ["123", "456"]}则代表将admin命令注册为id是123、456服务器的局部命令,其余命令不注册

⚠️ 关于 message_content Intent

message_content 是 Discord 的特权 Intent(Privileged Intent),默认关闭。 若未开启,Bot 仅在以下场景能收到消息内容,其余情况 event.content 为空:

  • 消息中 @ 了 Bot
  • 消息回复了 Bot
  • 私信(DM)消息

如需正常接收所有频道消息内容,需要:

  1. 前往 Discord Developer Portal → 你的应用 → Bot 页面,开启 Message Content Intent
  2. 在配置中将 message_content 设为 true

DISCORD_COMPRESS

是否启用数据压缩,默认为 False,如:

DISCORD_COMPRESS=True

DISCORD_API_VERSION

Discord API 版本,默认为 10,如:

DISCORD_API_VERSION=10

DISCORD_API_TIMEOUT

Discord API 超时时间,默认为 30 秒,如:

DISCORD_API_TIMEOUT=15.0

DISCORD_HANDLE_SELF_MESSAGE

是否处理自己发送的消息,默认为 False,如:

DISCORD_HANDLE_SELF_MESSAGE=True

DISCORD_PROXY

代理设置,默认无,如:

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://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]]
):
    # Discord 要求斜杠命令必须在 3 秒内给出首次响应,否则返回 404。
    # 如果处理逻辑耗时较长(如查询数据库),需要先调用 send_deferred_response()
    # 将命令转为「延迟响应」模式,获得最多 15 分钟的处理时间。
    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}")

Metadata

Release files for nonebot-adapter-discord 1.1.10

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for nonebot-adapter-discord 1.1.10
File Size Uploaded
nonebot_adapter_discord-1.1.10.tar.gz 114.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for nonebot-adapter-discord 1.1.10
File Interpreter ABI Platform
nonebot_adapter_discord-1.1.10-py3-none-any.whl Python 3 none any Details

Total release size: 235.3 kB

Release files / nonebot_adapter_discord-1.1.10.tar.gz

Download URL nonebot_adapter_discord-1.1.10.tar.gz
Size 114.0 kB
Tags Source
SHA-256 checksum
How to use checksums
61cae5ac49d8c0171c8c673bd14cd4cb45e14b3a1e25e77e826d3bccf1aa8e6c
BLAKE2b-256 checksum
How to use checksums
5132990ceba038f2ab9fb8141c8863e1f01c477cf3c3050d07f294e3b5fedf14
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.13 {"installer":{"name":"uv","version":"0.12.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / nonebot_adapter_discord-1.1.10-py3-none-any.whl

Download URL nonebot_adapter_discord-1.1.10-py3-none-any.whl
Size 121.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c4d5a41d84884521e5fbd448427757989f98e73760a39f4df7c66aff8f9ccdad
BLAKE2b-256 checksum
How to use checksums
ffbb3f2821a67344a6b80429fa721a0f3b76473aceab0518025c1845cf8557b5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.13 {"installer":{"name":"uv","version":"0.12.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page