{"id":20390255,"url":"https://github.com/nonebot/adapter-discord","last_synced_at":"2026-03-14T21:27:10.516Z","repository":{"id":151735649,"uuid":"624000196","full_name":"nonebot/adapter-discord","owner":"nonebot","description":"NoneBot2 Discord 适配器 / Discord adapter for nonebot2","archived":false,"fork":false,"pushed_at":"2026-02-25T21:34:05.000Z","size":649,"stargazers_count":23,"open_issues_count":2,"forks_count":12,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-02-26T00:36:24.591Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nonebot.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"open_collective":"nonebot","custom":["https://afdian.com/@nonebot"]}},"created_at":"2023-04-05T14:32:03.000Z","updated_at":"2026-02-21T17:09:54.000Z","dependencies_parsed_at":"2023-09-22T13:47:13.775Z","dependency_job_id":"8bc22e54-c554-4cf0-8e98-d2982d977d3f","html_url":"https://github.com/nonebot/adapter-discord","commit_stats":{"total_commits":51,"total_committers":7,"mean_commits":7.285714285714286,"dds":"0.33333333333333337","last_synced_commit":"5794c0b53b4fe1f41726fd09b4db1a5239ef965b"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":"yanyongyu/python-poetry-template","purl":"pkg:github/nonebot/adapter-discord","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nonebot%2Fadapter-discord","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nonebot%2Fadapter-discord/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nonebot%2Fadapter-discord/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nonebot%2Fadapter-discord/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nonebot","download_url":"https://codeload.github.com/nonebot/adapter-discord/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nonebot%2Fadapter-discord/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29872818,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-26T21:05:00.265Z","status":"ssl_error","status_checked_at":"2026-02-26T20:57:13.669Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-15T03:23:53.917Z","updated_at":"2026-02-26T21:20:22.600Z","avatar_url":"https://github.com/nonebot.png","language":"Python","funding_links":["https://opencollective.com/nonebot","https://afdian.com/@nonebot"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://nonebot.dev/\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/nonebot/adapter-discord/master/assets/logo.png\" width=\"200\" height=\"200\" alt=\"nonebot-adapter-discord\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n# NoneBot-Adapter-Discord\n\n_✨ Discord 协议适配 ✨_\n\n\u003c/div\u003e\n\n## 安装\n\n通过 `nb adapter install nonebot-adapter-discord` 安装本适配器。\n\n或在 `nb create` 创建项目时选择 `Discord` 适配器。\n\n可通过 `pip install git+https://github.com/nonebot/adapter-discord.git@master` 安装开发中版本。\n\n由于 [Discord 文档](https://discord.com/developers/docs/intro)存在部分表述不清的地方，并且结构复杂，存在很多 `partial object`，\n需要更多实际测试以找出问题，欢迎提出 ISSUE 反馈。\n\n## 配置\n\n修改 NoneBot 配置文件 `.env` 或者 `.env.*`。\n\n### Driver\n\n参考 [driver](https://v2.nonebot.dev/docs/tutorial/configuration#driver) 配置项，添加 `ForwardDriver` 支持。\n\n如：\n\n```dotenv\nDRIVER=~httpx+~websockets\n```\n\n### DISCORD_BOTS\n\n配置机器人帐号，如：\n\n```dotenv\nDISCORD_BOTS='\n[\n  {\n    \"token\": \"xxx\",\n    \"intent\": {\n      \"guild_messages\": true,\n      \"direct_messages\": true\n    },\n    \"application_commands\": {\"*\": [\"*\"]}\n  }\n]\n'\n\n# application_commands的{\"*\": [\"*\"]}代表将全部应用命令注册为全局应用命令\n# {\"admin\": [\"123\", \"456\"]}则代表将admin命令注册为id是123、456服务器的局部命令，其余命令不注册\n```\n\n### DISCORD_COMPRESS\n\n是否启用数据压缩，默认为 `False`，如：\n\n```dotenv\nDISCORD_COMPRESS=True\n```\n\n### DISCORD_API_VERSION\n\nDiscord API 版本，默认为 `10`，如：\n\n```dotenv\nDISCORD_API_VERSION=10\n```\n\n### DISCORD_API_TIMEOUT\n\nDiscord API 超时时间，默认为 `30` 秒，如：\n\n```dotenv\nDISCORD_API_TIMEOUT=15.0\n```\n\n### DISCORD_HANDLE_SELF_MESSAGE\n\n是否处理自己发送的消息，默认为 `False`，如：\n\n```dotenv\nDISCORD_HANDLE_SELF_MESSAGE=True\n```\n\n### DISCORD_PROXY\n\n代理设置，默认无，如：\n\n```dotenv\nDISCORD_PROXY='http://127.0.0.1:6666'\n```\n\n## 插件示例\n\n以下是一个简单的插件示例，展示各种消息段：\n\n```python\nimport datetime\n\nfrom nonebot import on_command\nfrom nonebot.params import CommandArg\n\nfrom nonebot.adapters.discord import Bot, MessageEvent, MessageSegment, Message\nfrom nonebot.adapters.discord.api import *\n\nmatcher = on_command('send')\n\n\n@matcher.handle()\nasync def ready(bot: Bot, event: MessageEvent, msg: Message = CommandArg()):\n    # 调用discord的api\n    self_info = await bot.get_current_user()  # 获取机器人自身信息\n    user = await bot.get_user(user_id=event.user_id)  # 获取指定用户信息\n    ...\n    # 各种消息段\n    msg = msg.extract_plain_text()\n    if msg == 'mention_me':\n        # 发送一个提及你的消息\n        await matcher.finish(MessageSegment.mention_user(event.user_id))\n    elif msg == 'time':\n        # 发送一个时间，使用相对时间（RelativeTime）样式\n        await matcher.finish(MessageSegment.timestamp(datetime.datetime.now(),\n                                                      style=TimeStampStyle.RelativeTime))\n    elif msg == 'mention_everyone':\n        # 发送一个提及全体成员的消息\n        await matcher.finish(MessageSegment.mention_everyone())\n    elif msg == 'mention_channel':\n        # 发送一个提及当前频道的消息\n        await matcher.finish(MessageSegment.mention_channel(event.channel_id))\n    elif msg == 'embed':\n        # 发送一个嵌套消息，其中包含a embed标题，nonebot logo描述和来自网络url的logo图片\n        await matcher.finish(MessageSegment.embed(\n            Embed(title='a embed',\n                  type=EmbedTypes.image,\n                  description='nonebot logo',\n                  image=EmbedImage(\n                      url='https://v2.nonebot.dev/logo.png'))))\n    elif msg == 'attachment':\n        # 发送一个附件，其中包含来自本地的logo.png图片\n        with open('logo.png', 'rb') as f:\n            await matcher.finish(MessageSegment.attachment(file='logo.png',\n                                                           content=f.read()))\n    elif msg == 'component':\n        # 发送一个复杂消息，其中包含一个当前时间，一个字符串选择菜单，一个用户选择菜单和一个按钮\n        time_now = MessageSegment.timestamp(datetime.datetime.now())\n        string_select = MessageSegment.component(\n            SelectMenu(type=ComponentType.StringSelect,\n                       custom_id='string select',\n                       placeholder='select a value',\n                       options=[\n                           SelectOption(label='A', value='a'),\n                           SelectOption(label='B', value='b'),\n                           SelectOption(label='C', value='c')]))\n        select = MessageSegment.component(SelectMenu(\n            type=ComponentType.UserInput,\n            custom_id='user_input',\n            placeholder='please select a user'))\n        button = MessageSegment.component(\n            Button(label='button',\n                   custom_id='button',\n                   style=ButtonStyle.Primary))\n        await matcher.finish('now time:' + time_now + string_select + select + button)\n    else:\n        # 发送一个文本消息\n        await matcher.finish(MessageSegment.text(msg))\n```\n\n以下是一个 Discord 斜杠命令的插件示例：\n\n```python\nimport asyncio\nfrom typing import Optional\n\nfrom nonebot.adapters.discord.api import (\n    IntegerOption,\n    NumberOption,\n    StringOption,\n    SubCommandOption,\n    User,\n    UserOption,\n)\nfrom nonebot.adapters.discord.commands import (\n    CommandOption,\n    on_slash_command,\n)\n\nmatcher = on_slash_command(\n    name=\"permission\",\n    description=\"权限管理\",\n    options=[\n        SubCommandOption(\n            name=\"add\",\n            description=\"添加\",\n            options=[\n                StringOption(\n                    name=\"plugin\",\n                    description=\"插件名\",\n                    required=True,\n                ),\n                IntegerOption(\n                    name=\"priority\",\n                    description=\"优先级\",\n                    required=False,\n                ),\n            ],\n        ),\n        SubCommandOption(\n            name=\"remove\",\n            description=\"移除\",\n            options=[\n                StringOption(name=\"plugin\", description=\"插件名\", required=True),\n                NumberOption(name=\"time\", description=\"时长\", required=False),\n            ],\n        ),\n        SubCommandOption(\n            name=\"ban\",\n            description=\"禁用\",\n            options=[\n                UserOption(name=\"user\", description=\"用户\", required=False),\n            ],\n        ),\n    ],\n)\n\n\n@matcher.handle_sub_command(\"add\")\nasync def handle_user_add(\n    plugin: CommandOption[str], priority: CommandOption[Optional[int]]\n):\n    await matcher.send_deferred_response()\n    await asyncio.sleep(2)\n    await matcher.edit_response(f\"你添加了插件 {plugin}，优先级 {priority}\")\n    await asyncio.sleep(2)\n    fm = await matcher.send_followup_msg(\n        f\"你添加了插件 {plugin}，优先级 {priority} (新消息)\"\n    )\n    await asyncio.sleep(2)\n    await matcher.edit_followup_msg(\n        fm.id, f\"你添加了插件 {plugin}，优先级 {priority} (新消息修改后)\"\n    )\n\n\n@matcher.handle_sub_command(\"remove\")\nasync def handle_user_remove(\n    plugin: CommandOption[str], time: CommandOption[Optional[float]]\n):\n    await matcher.send(f\"你移除了插件 {plugin}，时长 {time}\")\n\n\n@matcher.handle_sub_command(\"ban\")\nasync def handle_admin_ban(user: CommandOption[User]):\n    await matcher.finish(f\"你禁用了用户 {user.username}\")\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnonebot%2Fadapter-discord","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnonebot%2Fadapter-discord","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnonebot%2Fadapter-discord/lists"}