MINARA
使用 Minara客户端与界面消息平台

消息与通知

介绍 19 种消息服务,帮助你选择、配置并在 Agent 中使用它们。

Minara 可将消息从 Agent 循环推送到外部平台。 Autopilot 交易通知、定时工作流的监控告警,以及离开 REPL 时的消息触达,均依赖这套机制。

19 个平台开箱即用,按类别分组。每个平台均有独立配置页,涵盖凭证步骤、入站 webhook 格式、签名方案及平台限制。

其中 7 个通道已在产品中开放。其余通道在「设置 → 消息」中显示为即将推出:底层传输已经就绪,运维者仍可通过 CLI 或环境变量配置,因此下面的配置页依然准确,但 Web UI 暂不提供连接表单,也无法作为通知通道选择。

当前开放:

  • Telegram,推荐入门;支持流式编辑
  • Discord,bot + 频道;支持流式编辑(限速 1 秒)
  • Lark / 飞书,tenant token + 可选 AES-256 webhook
  • Email,SMTP;仅发送,主题自动截断
  • Email (Gmail OAuth),Gmail API,OAuth 鉴权;支持流式编辑与回复
  • Signal,通过本地 signal-cli 子进程;仅发送
  • Home Assistant,任意 notify.* 服务;仅发送

即将推出,企业 IM:

即将推出,消费者 / 社交:

即将推出,联邦 / 小众:

  • Matrix,Client-Server API + 长轮询守护进程(不支持 E2EE)
  • BlueBubbles (iMessage),通过自托管 Mac 桥接 iMessage
  • WhatsApp,Meta Cloud API;仅发送,收件人须为 E.164 格式

最简方式:直接告诉 Minara

配置消息通道最快的方式是在对话中告诉 Minara。Agent 会引导你完成凭证配置、发送测试消息,并将配置保存到 ~/.minara/credentials.json(messaging 槽)。

set up Telegram notifications — I want trade alerts

connect Slack to channel #trades using my bot token

configure email alerts — I'll give you the SMTP settings

send me a test message on Telegram to make sure it works

what notification channels are configured right now?

turn off the discord gateway, I'm not using it anymore

when ETH breaks $4000, alert me on Telegram

最后一条提示词会让 Minara 建立后台工作流,使用已配置的消息通道发送告警。Agent 一步完成告警条件、通道和工具集白名单的配置。

Minara 在保存前会确认凭证写入(修改 ~/.minara/credentials.json 属于第三级操作),回显时脱敏处理,并在通道配置完成后自动发送测试消息。

手动配置

以下三个入口共享同一配置存储,均支持热重载;任何改动无需重启即可生效。

通过 Shell(minara auth messaging

minara auth messaging list                     # show configured providers
minara auth messaging add                      # interactive picker, all 19 platforms
minara auth messaging add <provider>           # interactive wizard, masks tokens
minara auth messaging test <provider>          # send a test message
minara auth messaging remove <provider>        # strip credentials

不带 provider id 运行 minara auth messaging add 会进入交互菜单,列出全部支持平台,显示已配置项,并引导你完成所选平台的凭证配置。保存后可发送 ping 测试、配置其他平台或退出。完整流程见 CLI 子命令

在 REPL 中(/connect

/connect                       # numbered chooser
/connect telegram              # interactive credential entry
/connect slack --test          # test ping
/connect telegram --remove     # wipe credentials

当对话进行到一半才意识到需要接入某个平台时,斜杠命令是最合适的入口。可选字段留空时自动跳过;重新配置时每个已有字段会显示 (currently set, blank to keep)。斜杠命令的 token 输入当前明文显示(CLI 子命令会脱敏);对于敏感凭证,建议使用 CLI 或在 shell rc 中设置环境变量。

在 Web UI 中(Settings → Messaging

Web UI 在单一面板中展示所有提供方:

  • 每个提供方的状态标签(runtime ready / configured / not connected / coming soon)。
  • 每行的 Save / Test / Disconnect 按钮。
  • 点击 Test 按钮会发送真实 ping;消息会出现在 IM / 邮件客户端中,行标签自动变为 last test ✓
  • 输入框留空后点击 Save 会清除该字段(与常规设置表单的 Save = 清除语义一致)。可用此方式将 Slack 从 bot-token 模式切换为 webhook-only 模式,无需执行 --remove

凭证存储在 ~/.minara/credentials.json(权限 0600,已加入 git ignore),重装后仍可保留,不会泄漏到代码仓库。三个入口写入后均会热重载运行中 Agent 的网关映射,无需重启进程。

工作流:send_message 步骤类型

工作流可将消息发送作为一等步骤类型,而不必通过 tool_call: send_message 形式:

{
  "name": "notify_team",
  "kind": "send_message",
  "provider": "slack",
  "channel": "#alerts",
  "text": "BTC crossed ${trigger.threshold}"
}

调度时的提供方解析顺序:

  1. step.provider(单步显式指定)。
  2. definition.delivery.provider(工作流级默认值)。
  3. 恰好只有一个已连接提供方时,自动使用该提供方。
  4. 否则,激活拒绝,返回结构化错误,提示前往 /connect <platform>(REPL)或 Settings → Messaging(Web UI)。

激活检查独立于 Autopilot 开关。发送通知不涉及资金操作,因此 autopilotEnabled=false 时工作流同样可激活并正常运行。定时消息和 Autopilot 自身的成功通知也遵循同样的独立逻辑。

当目标平台未连接导致激活失败时,Web UI 会弹出模态框,提供一键 Connect <provider> 按钮,跳转到 Settings → Messaging 并展开对应行;保存后页面自动返回工作流并重试激活。

workflow_test 验证消息工作流

workflow_test 是端到端验证新平台配置的推荐方式。它用示例触发器运行 DAG,并通过与生产相同的通道发送一条真实消息,让你在启用工作流前先确认告警能到达手机。若目标提供方未连接,测试会拒绝并返回结构化 messaging_not_configured 错误,提示前往 /connect <provider>(REPL)或 Settings → Messaging(Web UI)。同一工作流中涉及资金及其他破坏性操作的工具仍为模拟执行,仅消息步骤实际发送。完整流程见工作流页的"在部署前本地测试工作流"一节。

一次性提醒

对于"满足条件 X 后通知一次即停止"的工作流,在 send_message 后追加 deactivate 步骤。工作流发送完成后会将自身 active 置为 false,触发器不再重复触发。完整 JSON 模板见工作流页的"一次性提醒"一节。

能力矩阵

所有平台均支持纯文本发送,这是基准能力,矩阵不单独标注。下列各列描述叠加在基准之上的高级能力

提供方流式图片文件语音话题输入状态表情回应富文本入站字符上限
telegram✅ (OGG)未接入未接入4 096
discord未接入2 000
slack未接入40 000
email未接入未接入未接入未接入1 000 000
whatsapp未接入未接入未接入未接入未接入4 096
signal未接入未接入未接入4 096
home_assistant未接入未接入未接入未接入未接入4 096

图例:✅ 当前版本已支持,❌ 平台本身不支持,未接入 = 尚未实现(后续 PR 跟进)。Slack 的输入状态列为空,因为现代 Slack Web / Events API 不提供 bot 输入触发接口(原 RTM API 已废弃)。

"富文本"指超出共享文本及附件能力的平台原生富消息发布。目前已支持 Slack Block Kit、临时消息(chat.postEphemeral)、定时消息(chat.scheduleMessage),以及通过 send_message 上的 provider_options.slack 通道传入的 metadata。其他提供方或无对应能力(WhatsApp / Signal / HomeAssistant / webhook 模式 Slack),或尚未接入(Telegram 内联键盘回复标记、Discord 组件、邮件 HTML 正文)。具体 API 见 slack 页面。

Slack 集成模式。 矩阵展示推荐的 bot-token 模式,可使用完整 Slack Web API,包括 chat.postMessagechat.updatefiles.v2reactions.add 及 Events API webhook。Minara 同时支持更简单的 webhook-URL 模式,适用于无法安装 Slack 应用的部署场景。该模式能力较窄(不支持流式、文件上传、表情回应、输入状态、临时消息及定时消息),但仍支持纯文本、Block Kit blocks 和话题回复。两种配置路径及各模式能力对比见 Slack 页面

Home Assistant 所有列均为 ❌,原因类似:其 notify.<service> API 在所有已调研的具体 notify 平台上均为纯文本接收器。如需附加图片,可将其上传至 CDN,在消息正文中附上 URL。

"流式"指 Agent 逐 token 的响应以单条消息展示,通过原地编辑持续更新。不支持流式的平台会缓冲完整响应,在最终完成时一次性发送,通过 apps/agent/src/messaging/stream-helpers.ts 中的共享辅助函数 createStreamSink 实现。

附件

send_message({attachments: [...]}) 可附加 Agent 在沙盒内生成的图片、文档或语音(通过 image_generateaudio_generatewrite_file、代码执行等)。LLM 通过沙盒相对路径引用这些文件:

send_message({
  provider: "telegram",
  text: "BTC/USD daily with key levels",
  attachments: [
    { kind: "image", sandbox_path: "images/btc-2026-04-19.png" },
    { kind: "file", sandbox_path: "files/levels.csv", caption: "CSV of levels" },
  ],
})

附件类型:

  • image:图片。路由到平台的图片专用接口(Telegram sendPhoto、WhatsApp image 等)。
  • file:通用文档附件,适用于 PDF、CSV、压缩包。
  • voice:短语音。Telegram 要求 OGG/Opus 格式;发送非 OGG 格式时解析器会返回明确错误。
  • audio:音乐 / 播客 / 长音频。Telegram 使用 sendAudio;对于无独立语音界面的平台,处理方式与 voice 相同。

安全策略:

  • 仅接受沙盒路径。解析器在上传前会拒绝 .. 路径穿越、绝对路径和指向沙盒外的符号链接,攻击者无法将 send_message 用作数据渗出通道。
  • 单附件上限 50 MB(可通过 MESSAGING_MAX_ATTACHMENT_BYTES 调整)。提供方 API 会独立执行各自的大小限制。
  • 提供方支持受能力门控:若所选提供方不支持某 kind(如向 WhatsApp 发送 voice),工具边界会返回明确错误,而非在 API 层返回 400。

话题

send_message 传入 thread 可发送到话题对话:

send_message({
  provider: "slack",
  text: "follow-up",
  thread: "1700000000.000100",  // parent message's ts
})

各提供方语义(自动处理,调用方只需传入 thread):

  • Telegrammessage_thread_id,用于论坛话题(超级群组及私聊)。
  • Discord:话题即频道,话题 id 替换 URL 中的频道 id,适用于活跃和归档话题。
  • Slackthread_ts,即父消息的时间戳。仅 bot 模式支持(webhook 模式会被拒绝)。
  • Email:该值同时写入 In-Reply-ToReferences 头部。传入父邮件的 Message-ID(通常带尖括号,如 <abc@host>)。

不支持话题的提供方(whatsapp、signal、home_assistant)在传入 thread 时,工具边界会返回明确错误。

输入状态与表情回应

set_typingadd_reaction 是两个额外工具,用于对话内的即时反馈。权限等级为第二级 CONFIRM_ONCE(装饰性信号,不涉及数据出站),独立于 send_message 的第三级确认。

// Let the user know the bot is thinking before a long reply.
set_typing({ provider: "telegram", on: true })

// Acknowledge an inbound message with an emoji instead of composing text.
add_reaction({
  provider: "discord",
  message_id: "1234567890",
  emoji: "👍",
})

输入状态持续性:Telegram 和 Discord 的指示约 5~10 秒后过期。apps/agent/src/messaging/typing-heartbeat.ts 中的 typing-heartbeat 辅助函数会自动续发,可在长轮次 LLM 响应期间保持"正在输入……"状态。

能力支持(见上方矩阵):输入状态支持 telegram / discord / signal;表情回应支持 discord / slack(bot 模式)/ signal。其他提供方在工具边界拒绝这两个操作。

入站消息:双向对话

Minara 也能接收消息并回复,因此你可以直接在聊天应用里与 Agent 对话,而不必使用 CLI。消息抵达 Agent 有两种方式,平台采用哪一种,决定了在没有公网 IP 的机器上能否进行双向对话。

客户端外连 daemon(默认)

对多数平台,Agent 主动向外建立并保持一条长连接(HTTP 长轮询或 WebSocket),消息顺着这条连接推送下来。Agent 充当客户端,因此在 NAT 之后、个人笔记本上、没有公网地址、没有隧道、没有第三方的情况下都能工作。这是默认行为:当平台的出站凭据已配置且未为其配置公网 webhook 时,对应 daemon 会自动启动。可用 MESSAGING_<PLATFORM>_* 开关按平台覆盖(见 环境变量);开关为三态(留空 = 自动,1 = 强制开启,0 = 强制关闭)。

具备客户端外连 daemon 的平台:Telegram(getUpdates)、Discord(Gateway)、Slack(Socket Mode)、Mattermost(v4 WebSocket)、QQ(v2 网关)、DingTalk(Stream Mode)、Lark(长连接),以及 Matrix(/sync)和 Signal(signal-cli)。

Webhook 监听器(平台要求时)

部分平台只能通过向公网 HTTPS 端点 POST 来投递入站消息。对这些平台,Minara 运行一个 HTTP webhook 服务器(见 apps/agent/src/messaging/inbound/server.ts),由 MESSAGING_INBOUND_ENABLED 控制。它默认绑定 127.0.0.1,因此没有公网 IP 的主机需要一个反向代理或隧道来终止 TLS 并转发请求。为某个平台设置 webhook 签名密钥,会让该平台切回 webhook 入站,daemon 随之让位。

安全策略:

  • 每个请求在分发前都经过签名验证(Telegram 的 X-Telegram-Bot-Api-Secret-Token、Slack 的 HMAC-SHA256(v0:{ts}:{body})、Discord 与 QQ 的 Ed25519、Lark 的 AES 信封、Teams 与 Google Chat 的 JWT)。无法验证的请求返回 401。
  • 带时间戳方案设有 5 分钟重放窗口。
  • 请求体大小上限(默认 4 MB),超出返回 413。

可达性:哪些平台可完全本地运行

入站模型平台无公网 IP 时能否双向对话
客户端外连 daemonTelegram、Discord、Slack、Mattermost、QQ、DingTalk、Lark、Matrix、Signal可以,无需隧道
仅 webhook(平台主动连入)WhatsApp、LINE、WeCom、WeChat OA、Teams不可以,需要公网 webhook(隧道 / 反向代理)
仅发送(无入站)Email、Gmail、Home Assistant仅出站通知

Google Chat(Cloud Pub/Sub 拉取)和 BlueBubbles(连接到自托管服务器的 socket)也可改为客户端外连;目前它们仍以 webhook 入站方式发布。

语音转写:配置 MESSAGING_INBOUND_TRANSCRIBE=1 且设置 OPENAI_API_KEY 后,入站语音消息会通过 OpenAI Whisper 转写后再分发。转写结果写入 InboundMessage.text,原始音频保留在 attachments 供回放。

Minara 如何使用消息通知

配置好提供方后,以下三种路径可向其发送消息:

1. send_message 工具:从 Agent 内部调用

LLM 判断需要发送通知时,会调用:

send_message({
  provider: "telegram",
  text: "BTC drawdown 5% triggered the watch",
})

Agent 在对话中途即可触发。例如"当 ETH 突破 4000 美元时在 Telegram 提醒我"会建立定时工作流,条件触发时调用 send_message

2. 自主交易:交易执行报告

Autopilot 启用后,每次执行完成会发送摘要:

🟢 Bought $100 of SOL @ $167.23
   Position: +$100 | Slippage: 0.04% | Gas: $0.12
   Reason: momentum > 3σ on 1h chart

消息发送至 ~/.minara/settings.json 中配置的默认通知目标提供方。

3. 工作流:定时告警

定时监控以只读加消息权限在后台运行:

you: watch the top 20 tokens by 24h volume, alert me on >5% moves every 15 min

agent: [sets up a cron workflow with tool set "read, memory, messaging"]

工作流只能观察和通知。白名单会阻止交易操作,LLM 在运行途中改变决策也无法绕过。

覆盖目标通道

send_message 接受 channel 覆盖参数,一个提供方可扇出到多个目标:

send_message({
  provider: "telegram",
  channel: "-1009876543210",    // different chat from the default
  text: "Critical: position liquidation imminent",
})

适合将紧急告警路由到独立手机或群组,同时保持常规通知在默认通道。

安全策略

  • 凭证存储在 ~/.minara/credentials.json,位于代码仓库和项目目录之外
  • minara auth messaging list 会脱敏显示密钥,格式为 12***xyz (46 chars),不显示原始 token
  • 消息发送属于第三级操作(ALWAYS_CONFIRM),交互式调用时每次 send_message 均会提示确认。自主轮次(cron / autopilot)仅在 safetyConfig.autopilotEnabled 已设置时才可执行第三级工具,否则该路径下消息发送会被拒绝。通过 minara auth messaging add 写入凭证的操作在交互向导内完成(无需单独的工具级确认提示,向导本身即确认流程)
  • 消息通知无法执行交易。工具集白名单将"可查看和通知"与"可交易"严格分离;就算 LLM 尝试调用涉及资金的工具,消息启用型工作流也不具备该能力

下一步

从上方选择一个平台,按步骤完成配置。Telegram 最为简便,配置环节最少,流式网关经过充分验证,完整测试流程(/newbot → 获取 chat id → minara auth messaging test telegram)三分钟内即可完成。

本页目录