news 2026/9/10 6:03:54

AIRI Discord Bot 集成指南:将 AIRI 接入 Discord 实现文字与语音对话

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AIRI Discord Bot 集成指南:将 AIRI 接入 Discord 实现文字与语音对话

AIRI Discord Bot 集成指南:将 AIRI 接入 Discord 实现文字与语音对话

【免费下载链接】airi💖🧸 Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into our worlds, wishing to achieve Neuro-sama's altitude. Capable of realtime voice chat, Minecraft, Factorio playing. Web / macOS / Windows supported.项目地址: https://gitcode.com/GitHub_Trending/ai/airi

导读

本指南基于 AIRI 仓库中的 integrations/discord-bot 集成服务与官方文档 docs/content/en/docs/integrations/discord.md,完整讲解如何把 AIRI 作为语音与消息机器人接入 Discord 服务器。读完本文,你将掌握:在 Discord Developer Portal 创建应用与 Bot、配置 Bot Token 与 AIRI Auth Token、通过 AIRI 桌面端的Settings → Modules → Discord面板下发配置、使用/ping/summon命令完成文字回复与语音对话,以及语音转写(STT)与文本回复背后依赖 AIRI 自身聊天配置的原理。

架构总览:一个独立的 Discord 适配服务

AIRI 的 Discord 集成不是一个直接嵌入 AIRI 客户端的插件,而是一个独立的 Node.js 服务,通过 WebSocket 与 AIRI 主程序通信。整体调用链如下:

  1. Discord 侧:使用 discord.js 建立 Gateway 连接,监听消息(MessageCreate)、斜杠命令交互(InteractionCreate)与语音状态(GuildVoiceStates)。
  2. AIRI 侧:通过@proj-airi/server-sdkServerChannel客户端建立 WebSocket 通道,订阅input:textinput:text:voiceinput:voicemodule:configureoutput:gen-ai:chat:message等事件(见 airi-adapter.ts)。
  3. 配置下发:AIRI 桌面端把 Bot Token 与启用状态经module:configure事件推送给服务;服务收到后动态登录或重连 Discord 客户端。
  4. 回复回传:AIRI 生成回复后经output:gen-ai:chat:message事件回传,服务按 channelId 找到对应频道并发送文本。

因此,Discord 文本回复使用的是 AIRI 当前激活的聊天提供方与模型(chat provider 和 model),而不是 Discord Bot 自身的任何模型配置。

前置条件

在开始之前,请确认以下条件:

  • 在仓库根目录执行pnpm i安装依赖。
  • 在 Discord Developer Portal 创建 Application 与 Bot。
  • 在 Bot 设置中启用Message Content Intent(消息内容意图)。
  • 在 AIRI 中配置一个可用的聊天提供方(chat provider)与模型。

::: warning 凭据安全 Bot Token 与 AIRI Auth Token 只能存放在 AIRI 本地设置或 Bot 服务本地的.env.local文件中,切勿提交到版本库、截图或分享这些凭据。 :::

配置 Bot 服务

1. 创建本地环境变量文件

cp integrations/discord-bot/.env integrations/discord-bot/.env.local

2. 获取并填写 AIRI 凭据

在桌面版 AIRI 中打开Settings → Connection,显示并复制Auth Token,然后写入integrations/discord-bot/.env.local

AIRI_URL=ws://localhost:6121/ws AIRI_TOKEN=<Auth Token from Settings → Connection>
  • AIRI_URL:AIRI WebSocket 服务地址,默认ws://localhost:6121/ws(端口 6121 是 AIRI 本地服务的默认端口)。
  • AIRI_TOKEN:用于向 AIRI 服务鉴权的 Auth Token。

3. 关于其他环境变量的说明

DISCORD_TOKEN是可选的启动回退(startup fallback),可以留空,服务连接后由 AIRI 通过配置通道下发 Bot Token。以下变量虽然出现在模板.env中,但不会被服务使用

  • DISCORD_BOT_CLIENT_ID
  • OPENAI_MODELOPENAI_API_KEYOPENAI_API_BASE_URL
  • ELEVENLABS_API_KEYELEVENLABS_API_BASE_URL

原因在于 Discord 文本回复直接使用 AIRI 的激活聊天配置。不过,如果要用语音输入,则必须配置一个 OpenAI 兼容的转写端点:

OPENAI_STT_API_BASE_URL=<your transcription endpoint base url> OPENAI_STT_API_KEY=<your api key> OPENAI_STT_MODEL=<model name, e.g. whisper-1>

这三项对于文本频道不是必需的,但没有它们语音转写无法完成。从源码看,语音转写通过openaiTranscribe调用createOpenAI(env.OPENAI_STT_API_KEY, env.OPENAI_STT_API_BASE_URL)并使用generateTranscription生成文本(见 tts.ts)。

启动服务

pnpm -F @proj-airi/discord-bot start

该命令在integrations/discord-bot包中定义:tsx --env-file=.env --env-file-if-exists=.env.local src/index.ts(见 package.json)。tsx负责直接运行 TypeScript 源码,--env-file-if-exists=.env.local.env.local中的值覆盖.env

入口文件 src/index.ts 创建DiscordAdapter并启动,同时注册SIGINT/SIGTERM优雅关闭钩子。start()会先尝试用环境变量中的DISCORD_TOKEN登录;若没有 Token,则进入“等待 UI 下发配置”状态(见 airi-adapter.ts)。

在 AIRI 中配置 Discord

  1. 打开Settings → Modules → Discord
  2. 将 Bot Token 粘贴到Bot Token字段。
  3. 打开Enable Discord Integration
  4. 点击Save

保存后,AIRI 会通过配置通道(module:configure事件)把启用状态与 Token 下发给已认证的 Bot 服务。源码中的isDiscordConfig类型守卫会校验token(string)与enabled(boolean)字段,并据此执行三种分支(见 airi-adapter.ts):

  • enabled === false:销毁当前 Discord 客户端。
  • enabled但无 Token:记录警告并停止 Bot。
  • 有 Token 且与当前不同或客户端未就绪:销毁旧客户端并重新login

注意:如果服务没有运行,或服务的 AIRI Auth Token 缺失/错误,仅保存这些字段不会启动 Discord Bot。此外,配置处理期间设有isReconnecting锁,正在重连时会忽略新的配置事件,避免并发重连。

在 Discord 中安装与使用 Bot

安装与权限

  1. 在 Discord Developer Portal 配置Guild Install,使用botscope 将 Bot 安装到服务器。botscope 默认包含applications.commands
  2. 只授予功能所需的最小权限:
    • 文字回复:View ChannelsSend Messages
    • 语音输入:View ChannelsConnect
    • 语音播放:Speak

文字聊天

向 Bot 发送私信(DM),或在服务器频道中 @提及 Bot。Bot 不会响应服务器中的每一条消息——源码中的MessageCreate处理器明确判断isMentioned || isDM才响应(见 airi-adapter.ts)。

提及时的处理细节值得注意:Bot 会把@提及从消息中剥离(/<@!?\d+>/g正则),只把纯文本内容发送给 AIRI。同时构建包含channelIdguildIdguildNameguildMember的 Discord 上下文,并计算会话 ID:

  • 服务器内消息 →discord-guild-<guildId>
  • 私信 →discord-dm-<memberId>

这样同一个服务器频道的多轮对话可以共享同一会话(见 airi-adapter.ts)。

AIRI 的回复经output:gen-ai:chat:message事件回传后,服务按channelId取频道并发送文本;超过 Discord 单条消息 2000 字符上限时会按换行、空格边界分块发送(见 airi-adapter.ts)。

语音对话

  1. 加入一个语音频道。
  2. 运行/summon,Bot 会加入你所在的语音频道。
  3. 服务在 Bot 登录后自动注册/ping/summon两个斜杠命令(见 commands/index.ts)。

/ping简单回复 "Pong!";/summonVoiceManager.handleJoinChannelCommand处理:先检查调用者是否在语音频道,不在则回复 "Please join a voice channel first.",否则调用joinChannel加入频道(见 summon.ts)。

语音转写与播放的实现原理

从源码看,语音处理链路相当完整(见 summon.ts):

  • 加入与状态管理joinVoiceChannel建立连接,通过entersState等待Ready/Signalling状态(20 秒超时);断线时尝试 5 秒内重连,否则销毁连接并清理(见 [summon.ts](https://link.gitcode.com/i/fd2e40741cfa1cf7511f355c9717923c#L96-L128, L165-L221))。
  • 说话检测connection.receiver.speaking监听start/end事件,对非 Bot 用户启动音频监控(monitorMember)。
  • 音频解码OpusDecoder以 16 kHz 单声道解码(DECODE_SAMPLE_RATE = 16000,见 constants/audio.ts),随后convertOpusToWav生成 44 字节 WAV 头并拼接 PCM 数据(见 utils/audio.ts)。
  • 防重叠(barge-in)monitorMember在播放期间持续监测用户音量,30 帧滑动窗口平均音量超过 0.05 阈值时立即停止当前播放,实现用户说话打断 AI(见 summon.ts)。
  • 转写去抖:语音数据按用户缓存进userStates,说话结束后等待 1.5 秒静默(DEBOUNCE_TRANSCRIPTION_THRESHOLD = 1500)才触发转写,减少碎片转写(见 summon.ts)。
  • 转写结果处理:有效转写(不含[BLANK_AUDIO]标记)通过input:text:voiceinput:text两个事件发送给 AIRI,实现"听"与"说"的闭环(见 summon.ts)。
  • 语音播放createAudioPlayerNoSubscriberBehavior.Pause)+createAudioResourceStreamType.Arbitrary)播放 AIRI 返回的音频流(见 summon.ts)。

常见问题排查

  • 部分频道可用、部分不可用:检查频道级权限覆盖(channel-level permission overrides),确保目标频道授予了所需权限。
  • 服务已运行但 Bot 不响应:确认 AIRI 侧Enable Discord Integration已开启、Auth Token 正确;保存配置时留意服务日志中的module:configure处理记录。
  • 语音转写无结果:检查OPENAI_STT_API_BASE_URLOPENAI_STT_API_KEYOPENAI_STT_MODEL三项是否配置完整,转写端点是否 OpenAI 兼容。
  • 多频道会话混乱:会话按 guild 隔离,同一服务器的文本对话共享上下文,跨服务器互不干扰。

安全注意事项

  • 将 Bot 的访问范围限制在其所需频道与能力上,遵循最小权限原则。
  • 若 Bot Token 丢失或泄露,立即在 Discord Developer Portal 重置,并同步更新 AIRISettings → Modules → Discord中的 Bot Token。
  • Bot Token 与 AIRI Auth Token 仅存放于.env.local与 AIRI 本地设置,避免提交、截图或分享。

总结

AIRI 的 Discord 集成由 integrations/discord-bot 这个独立服务承载:它在 AIRI 与 Discord 之间充当桥梁,文本回复复用 AIRI 的聊天配置与模型,语音侧则依靠 OpenAI 兼容 STT 端点完成转写,再通过@discordjs/voice完成解码、播放与打断(barge-in)。整个体系的核心配置只有寥寥几个环境变量与一个 UI 开关,但底层涵盖了语音流式处理、会话隔离、断线重连等工程细节,可以作为二次开发与自托管部署的直接参考。

【免费下载链接】airi💖🧸 Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into our worlds, wishing to achieve Neuro-sama's altitude. Capable of realtime voice chat, Minecraft, Factorio playing. Web / macOS / Windows supported.项目地址: https://gitcode.com/GitHub_Trending/ai/airi

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 5:59:43

fastlane gym 如何配置 ad-hoc 导出方法生成企业内部分发包

fastlane gym 如何配置 ad-hoc 导出方法生成企业内部分发包 【免费下载链接】fastlane &#x1f680; The easiest way to automate building and releasing your iOS and Android apps 项目地址: https://gitcode.com/GitHub_Trending/fa/fastlane 如果你的 iOS 应用不…

作者头像 李华
网站建设 2026/9/10 5:58:19

轻量级规则流路由引擎ruflo:从零实现的架构设计与实践

这几年在折腾后端服务的时候&#xff0c;我越来越觉得&#xff0c;很多逻辑本质上都是在处理同一件事&#xff1a; 根据一堆条件&#xff0c;决定一条数据接下来往哪儿走。 不管是订单状态流转、工单分配、消息推送&#xff0c;还是风控里那一长串“如果...就...”的判断&am…

作者头像 李华
网站建设 2026/9/10 5:55:17

AI妖股狂飙550倍背后:从算力到应用的产业机会与落地实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/10 5:54:59

Next AI Draw.io 如何从 URL 链接提取网页内容生成图表

Next AI Draw.io 如何从 URL 链接提取网页内容生成图表 【免费下载链接】next-ai-draw-io A next.js web application that integrates AI capabilities with draw.io diagrams. This app allows you to create, modify, and enhance diagrams through natural language comman…

作者头像 李华
网站建设 2026/9/10 5:54:03

寒假四周复盘:从失控到稳定输出的时间管理实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/10 5:53:57

概率论期末冲刺:联合分布、边缘密度与独立性判定全解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华