Telegram Send
通过 Telegram 机器人发送语音、图片和文档文件 — 采用 Bot API 优先的投递策略,支持自动聊天 ID 解析,并提供本地端点回退机制用于文本通知和重试。
默认启用 通信
telegram-send 会自动注入到每个会话中,无需手动加载。当你说 "send via Telegram" 或 "텔레그램으로 보내줌" 时,技能将激活,代理会按照本页描述的投递策略执行操作。
快速参考
| 技能名称 | telegram-send |
| 分类 | 通信 |
| 默认启用 | 是 — 会话启动时自动注入 |
| SKILL.md 路径 | ~/.cli-jaw/skills/telegram-send/SKILL.md |
| 系统工具 | curl, jq |
| 配置来源 | ~/.cli-jaw/settings.json (telegram.token, telegram.allowedChatIds) |
| 主要 API | Telegram Bot API (https://api.telegram.org/bot<TOKEN>/...) |
| 回退 API | 本地端点 (http://localhost:3457/api/telegram/send) |
| 支持的类型 | photo, voice, document, text |
| 相关技能 | email-draft-polish, whatsapp, xurl |
| 相关指南 | Telegram 指南 |
投递策略(Bot 优先)
该技能遵循严格的两级投递策略。始终优先尝试 Telegram Bot API。本地 CLI-JAW 端点作为文本消息的便捷通道,以及 Bot API 失败时的回退方案。
| 消息类型 | 主要方式 | 回退方式 |
|---|---|---|
photo | Telegram Bot API (sendPhoto) | 本地端点(单次重试) |
voice | Telegram Bot API (sendVoice) | 本地端点(单次重试) |
document | Telegram Bot API (sendDocument) | 本地端点(单次重试) |
text | 本地端点(便捷方式) | Telegram Bot API (sendMessage) |
photo、voice 和 document 类型,代理始终优先尝试直接调用 Bot API。仅当 Bot API 调用失败时,才会通过本地端点进行单次重试回退。对于 text 状态通知,优先使用本地端点以方便操作。
必需输入
| 输入项 | 来源 | 适用场景 |
|---|---|---|
| Bot 令牌 | ~/.cli-jaw/settings.json → telegram.token | 所有 Bot API 调用 |
| 聊天 ID | ~/.cli-jaw/settings.json → telegram.allowedChatIds[-1] | 所有 Bot API 调用 |
| 文件路径 | 由用户提供或由前序任务生成 | photo, voice, document |
| 标题/文本 | 由用户提供(媒体类型可选) | text;媒体的可选标题 |
分步工作流
步骤 1:读取令牌和聊天 ID
代理从 CLI-JAW 设置文件中读取凭据。令牌仅保存在 shell 变量中 — 不会打印到标准输出或日志。
TOKEN=$(jq -r '.telegram.token' ~/.cli-jaw/settings.json)
CHAT_ID=$(jq -r '.telegram.allowedChatIds[-1]' ~/.cli-jaw/settings.json)
如果 CHAT_ID 解析为 null(没有之前的 Telegram 消息记录),代理会通过 ping 本地端点来恢复:
CHAT_ID=$(curl -sS -X POST http://localhost:3457/api/telegram/send \
-H "Content-Type: application/json" \
-d '{"type":"text","text":"chat_id check"}' | jq -r '.chat_id')
步骤 2:通过 Bot API 发送(主要方式)
代理根据消息类型构造一个 curl multipart 表单 POST 请求,发送到对应的 Telegram Bot API 端点。
发送图片
curl -sS -X POST "https://api.telegram.org/bot${TOKEN}/sendPhoto" \
-F "chat_id=${CHAT_ID}" \
-F "photo=@/tmp/chart.png" \
-F "caption=Analysis chart"
发送语音消息
curl -sS -X POST "https://api.telegram.org/bot${TOKEN}/sendVoice" \
-F "chat_id=${CHAT_ID}" \
-F "voice=@/tmp/reply.ogg" \
-F "caption=Voice response"
发送文档
curl -sS -X POST "https://api.telegram.org/bot${TOKEN}/sendDocument" \
-F "chat_id=${CHAT_ID}" \
-F "document=@/tmp/report.pdf" \
-F "caption=Weekly report"
步骤 3:本地端点(备用/回退)
本地 CLI-JAW 服务器在以下地址暴露了 Telegram 发送端点:
POST http://localhost:3457/api/telegram/send
Content-Type: application/json
接受参数:type, text, file_path, caption
文本消息(本地端点的主要用途)
curl -sS -X POST http://localhost:3457/api/telegram/send \
-H "Content-Type: application/json" \
-d '{"type":"text","text":"Deployment complete!"}'
通过本地端点回退发送媒体
curl -sS -X POST http://localhost:3457/api/telegram/send \
-H "Content-Type: application/json" \
-d '{"type":"photo","file_path":"/tmp/chart.png","caption":"Analysis chart"}'
步骤 4:验证投递
发送成功会返回包含 "ok": true 的 JSON 响应:
{"ok":true,"chat_id":8231528245,"type":"text"}
代理在向用户报告成功之前会检查此响应。如果响应表示失败,且主要方式为 Bot API,则会通过本地端点进行一次重试。
支持的消息类型
| 类型 | Bot API 方法 | 必填字段 | 可选字段 |
|---|---|---|---|
photo | sendPhoto | chat_id, photo(文件) | caption, parse_mode |
voice | sendVoice | chat_id, voice(文件,OGG 格式) | caption, duration |
document | sendDocument | chat_id, document(文件) | caption, parse_mode |
text | sendMessage / 本地端点 | chat_id, text | parse_mode, disable_notification |
配置
该技能从 ~/.cli-jaw/settings.json 读取所有配置,无需单独的配置文件。
// ~/.cli-jaw/settings.json (相关键)
{
"telegram": {
"token": "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11",
"allowedChatIds": [8231528245]
}
}
| 键 | 类型 | 描述 |
|---|---|---|
telegram.token | string | 从 @BotFather 获取的 Telegram Bot API 令牌 |
telegram.allowedChatIds | number[] | 允许的聊天 ID 数组。该技能默认使用最后一个条目。 |
allowedChatIds 可能为空。该技能将通过向本地端点发送探测消息并从响应中读取 chat_id 字段来自动发现你的聊天 ID。
依赖
该技能仅需要标准 Unix 工具,这些工具在 macOS 和大多数 Linux 发行版上已预装。
macOS 和 Linux 上已预装
brew install jq
验证依赖
# 检查 curl
curl --version
# 检查 jq
jq --version
# 如果缺少 jq 则安装(macOS)
brew install jq
# 如果缺少 jq 则安装(Ubuntu/Debian)
sudo apt-get install -y jq
安全规则
该技能围绕令牌处理强制执行严格的安全实践:
| 规则 | 详情 |
|---|---|
| 禁止打印令牌 | Bot 令牌绝不会被回显、打印或包含在代理文本输出中。它仅以 shell 变量形式存在。 |
| 仅存于 Shell | 令牌被读入 $TOKEN 并内联使用。不会写入临时文件或导出到环境变量。 |
| 无日志泄露 | 命令使用 -sS 标志来抑制进度条同时仍显示错误,避免在详细日志中意外暴露令牌。 |
| 单次重试限制 | 如果 Bot API 失败,仅允许通过本地端点进行一次回退尝试。不会无限重试循环。 |
| 允许的聊天 ID | 该技能仅向 telegram.allowedChatIds 中列出的聊天 ID 发送消息,防止意外发送到未授权的聊天。 |
快速验证
要测试 Telegram 集成是否正常工作,运行以下 ping 命令:
curl -sS -X POST http://localhost:3457/api/telegram/send \
-H "Content-Type: application/json" \
-d '{"type":"text","text":"ping"}'
预期响应:
{"ok":true,"chat_id":8231528245,"type":"text"}
如果收到错误,请检查:
- CLI-JAW 服务器是否正在运行(
jaw server status) - Bot 令牌是否已在
~/.cli-jaw/settings.json中配置 - 你是否已在 Telegram 上向机器人发送过至少一条消息(以建立聊天)
"~해줘" 用法示例
展示如何使用自然语言触发 telegram-send 技能的实际示例。韩语和英语均可使用。
sendPhoto 端点发送。代理会从当前任务上下文中定位图表文件并自动附加。sendVoice 发送。如果 TTS 生成可用,代理会先生成音频,然后进行投递。sendDocument 发送。标题设为文件的简要描述。代理会在 output/pdf/ 或用户指定的路径下查找文件。screen-capture 技能的输出与 telegram-send 组合使用。与其他技能的集成
telegram-send 技能通常是多技能工作流中的最后一步。它可以与任何生成输出文件或状态更新的技能自然配合。
| 工作流 | 涉及的技能 | 示例 |
|---|---|---|
| 报告生成 + 投递 | pdf + telegram-send | "보고서 PDF 만들어서 텔레그램으로 보내줌" |
| 图表 + 通知 | dev-data + telegram-send | "매출 차트 만들어서 텔레그램에 공유해줌" |
| 截图捕获 + 发送 | screen-capture + telegram-send | "화면 찍어서 텔레그램으로 바로 보내줌" |
| 语音回复 | video (TTS) + telegram-send | "이 내용 음성으로 변환해서 텔레그램에 보내줌" |
| 多渠道广播 | telegram-send + whatsapp + xurl | "이 공지사항 텔레그램, 왔츠앱, X 전부 보내줌" |
| 部署通知 | cloudflare + telegram-send | "Workers 배포하고 결과 텔레그램으로 알려줌" |
API 参考
使用的 Bot API 端点
| 端点 | 方法 | 用途 |
|---|---|---|
/bot<TOKEN>/sendPhoto | POST (multipart/form-data) | 发送图片文件 |
/bot<TOKEN>/sendVoice | POST (multipart/form-data) | 发送 OGG 语音消息 |
/bot<TOKEN>/sendDocument | POST (multipart/form-data) | 以文档形式发送任意文件 |
/bot<TOKEN>/sendMessage | POST (application/json) | 发送文本消息(text 类型的回退方式) |
本地端点
| 端点 | 方法 | 请求体 |
|---|---|---|
http://localhost:3457/api/telegram/send | POST | {"type": "photo|voice|document|text", "text": "...", "file_path": "...", "caption": "..."} |
响应格式
// 成功
{"ok": true, "chat_id": 8231528245, "type": "text"}
// 失败(示例)
{"ok": false, "error": "Bot token not configured"}
故障排除
聊天 ID 为 null
如果 jq -r '.telegram.allowedChatIds[-1]' 返回 null,说明机器人尚未收到你的任何消息。请先在 Telegram 上向机器人发送任意消息,然后聊天 ID 将被记录到设置中。或者,代理将通过探测本地端点自动恢复。
Bot API 返回 401 Unauthorized
Bot 令牌无效或已过期。请从 @BotFather 生成新令牌并更新 ~/.cli-jaw/settings.json。
Bot API 返回 400 Bad Request
常见原因:
- 无效的 chat_id: 聊天 ID 不对应与机器人的活跃对话。
- 文件过大: Telegram Bot API 限制上传文件最大为 50 MB。对于更大的文件,请使用可能支持分块上传的本地端点。
- 语音文件格式错误: 语音消息必须为 OGG 格式(OPUS 编码)。其他音频格式应作为
document发送。
本地端点连接被拒绝
CLI-JAW 服务器未运行。请使用以下命令启动:
jaw server start
# 或检查状态
jaw server status
找不到 jq
安装 jq 以解析设置文件:
# macOS
brew install jq
# Ubuntu/Debian
sudo apt-get install -y jq
# 验证
jq --version
与 Telegram 指南的对比
CLI-JAW 文档在两个地方涵盖了 Telegram 相关内容。它们用途不同:
| 本页(技能参考) | Telegram 指南 | |
|---|---|---|
| 侧重点 | telegram-send 技能的技术细节 — API 命令、投递策略、安全规则 | 将 Telegram 连接到 CLI-JAW 的端到端设置指南 |
| 目标读者 | 希望了解代理发送 Telegram 消息时具体执行了什么操作的用户 | 首次设置 Telegram 集成的新用户 |
| 涵盖内容 | SKILL.md 内部机制、Bot API 调用、回退逻辑、故障排除 | 机器人创建、令牌设置、初始消息配对、仪表盘配置 |