Telegram
推荐的起始方案,三分钟完成配置,支持流式传输的网关,经过最充分验证的提供商。
🟢 运行就绪:网关内置流式编辑能力(暂无生产调用者接入,详见下文),是大多数 Minara 运营者首选的提供商。无需外部二进制文件,无需商业账户审批,只需一个 bot token 和一个 chat id。
功能概览
- 流式编辑(网关就绪):
TelegramGateway先发送一条占位消息,随后在文本到达时以 750 ms 节流间隔持续编辑该消息。可通过apps/agent/src/messaging/stream-helpers.ts中的createStreamSink驱动;send_message工具本身为一次性发送。 - 富文本(默认开启):Markdown 回复会渲染为 Telegram 格式(加粗、标题、表格、任务列表、代码块)。设置
TELEGRAM_RICH_TEXT=false可改为纯文本。 - 附件:图片(
sendPhoto)、文件(sendDocument)、语音(sendVoice,需 OGG/Opus 格式)、音频(sendAudio)。来源必须是 Agent 在沙盒内生成的文件(详见概览页面)。 - 群聊与私聊:两种场景流程相同;群聊的 chat id 为负数。
- 每条消息上限 4096 字符。
send_message在工具边界拒绝超长文本;流式接收器会在中途截断并附加… (truncated)标记。
配置步骤
1. 创建 bot
- 打开 Telegram,找到 @BotFather
- 发送
/newbot,按提示填写名称和用户名 - 保存 BotFather 返回的 token(格式类似
123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11)
2. 获取 chat id
- 与新建的 bot 开始对话并发送任意消息。若聊天未由用户主动发起,Telegram 会屏蔽 bot 发出的消息
- 在浏览器中访问
https://api.telegram.org/bot<TOKEN>/getUpdates,在返回结果中找到"chat":{"id":...}
如需在群组中使用:将 bot 添加到群组,在群组中发送一条消息,再通过 getUpdates 查询。群组 id 为负数(例如 -1001234567890)。
3. 配置 Minara
简易方式:在对话中直接告知 Agent:
"set up Telegram notifications"
Minara 会提示输入 token 和 chat id,写入 ~/.minara/credentials.json(messaging 槽),并发送测试 ping。
手动方式:
minara auth messaging add telegram或直接在项目根目录的 .env 文件中设置环境变量:
TELEGRAM_BOT_TOKEN=123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
TELEGRAM_CHAT_ID=-10012345678904. 测试
minara auth messaging test telegram正常情况下,测试消息会在一两秒内到达。
流式传输行为
Telegram 的 editMessageText 接口在不触发频率限制的情况下,每条消息最多支持约 30 次编辑。TelegramGateway 提供 startStream() 会话,先发送占位消息,随后在新文本到达时持续编辑;createStreamSink 将编辑节流设置为 750 ms,既能保持实时感,又能充分控制在单聊频率限制以内。累计文本超过 4096 字符时,会在中途截断并附加 … (truncated) 标记。
节流间隔和长度上限通过 createStreamSink(gw, msg, { intervalMs, maxLength }) 在调用方设置,而非 send_message 的参数。工具路径本身为一次性发送,LLM 发送完整消息;流式传输存在于工作流/Autopilot 代码中(生产环境暂未接入)。
富文本
回复默认渲染为 Telegram 富文本。Agent 生成 Markdown,网关在发送前将其转换为 Telegram 支持的 HTML 子集:
- 标题变为加粗,列表保留项目符号,任务列表显示 ☐ / ☑,表格渲染为等宽对齐文本,代码块保留语言标签。
- 如果 Telegram 拒绝该 HTML(极少发生),网关会用相同内容重试 MarkdownV2,再退回纯文本。消息不会因为格式错误而丢失。
- 流式输出时,每次编辑只显示已闭合的格式,因此不会在解析完成前闪现半截的
**bold。
关闭后会原样发送 Agent 的文本:
TELEGRAM_RICH_TEXT=false可识别的"关闭"取值为 0、false、no、off;未设置即为开启。该设置在启动时读取一次,修改后需重启网关。也可以在 Web UI 的 设置 → 消息平台 → Telegram 富文本 中切换。
附件
附件引用的是 Agent 已在沙盒内生成的文件(通过 image_generate、audio_generate、write_file、代码执行等方式)。LLM 传入沙盒相对路径:
send_message({
provider: "telegram",
text: "BTC/USD daily — key levels marked",
attachments: [
{ kind: "image", sandbox_path: "images/btc-2026-04-19.png" },
],
})类型路由:
| kind | Telegram 接口 | 说明 |
|---|---|---|
image | sendPhoto | 支持 caption |
file | sendDocument | 支持任意文件类型 |
voice | sendVoice | 需要 OGG/Opus 格式,非 OGG 文件会被拒绝 |
audio | sendAudio | mp3 / m4a / flac,以音乐播放器样式展示 |
多个附件按顺序逐条发送;若第一条的 msg.text 足够短(不超过 1024 字符),则作为 caption 附在第一条消息上,否则文本单独作为引导消息先行发送,附件随后跟上。详见 apps/agent/src/messaging/telegram.ts。
覆盖通道
将紧急提醒路由到不同聊天,同时保持常规通知走默认通道:
send_message({
provider: "telegram",
channel: "-1009876543210",
text: "Critical: position liquidation imminent",
})故障排查
"测试消息未收到"
- 是否已主动向 bot 发送过消息?Telegram 会屏蔽未经用户发起的聊天中 bot 发出的消息
- 检查
TELEGRAM_CHAT_ID的符号,群聊 id 为负数 - 确认 bot 仍在群组中:BotFather → 你的 bot →
Bot Settings→Group Privacy
"流式传输感觉慢或卡顿"
- 属于正常现象:
TelegramGateway内置 750 ms 基准节流。调用方可通过createStreamSink(gw, msg, { intervalMs: 500 })覆盖此值,这是调用方参数,不是send_message工具的参数 - 超长响应会在 4096 字符处截断,可考虑将工作流拆分为多条消息
"Chat not found (400)"
- bot 已被移出群组,或 chat id 有误
- 在目标聊天中发送一条新消息后,重新执行
getUpdates步骤