OpenClaw Telegram 本地 Bot API 下载修复:3 个关键改进
概述:解决本地 Bot API 的文件下载难题
OpenClaw 最新合并的 PR #59544 彻底修复了 Telegram 本地 Bot API 服务器 场景下的文件下载问题。本次更新不仅解决了缓冲消息中 apiRoot 配置丢失的 bug,还对媒体解析代码进行了深度重构,提升了可维护性。
如果你正在使用 Telegram Bot API 本地服务器 处理大文件,或遇到文件下载 URL 构造错误,这篇文章将帮助你理解修复细节和最佳实践。
—
问题背景:为什么需要这个修复?
本地 Bot API 的典型场景
Telegram 官方提供 Bot API 本地服务器 方案,允许开发者:
- 下载超过 20MB 的文件
- 使用自定义域名访问文件
- 提升文件传输速度和隐私控制
配置方式通常如下:
openclaw 配置示例
channels:
telegram:
token: "YOUR_BOT_TOKEN"
apiRoot: "http://localhost:8081" # 本地 Bot API 地址
问题 #59512 的核心症状
在修复前,缓冲消息(buffered messages) 场景存在严重不一致:
| 场景 | 是否传递 apiRoot | 结果 |
|:—|:—|:—|
| 实时消息处理 | ✅ 是 | 文件下载正常 |
| 缓冲消息回复 | ❌ 否 | URL 构造错误,下载失败 |
这导致使用本地 Bot API 时,回复历史消息中的媒体文件会出现 404 或无法访问 的错误。
—
修复详解:5 个关键改进
1. 核心修复:缓冲消息的 apiRoot 传递
问题定位:bot-handlers.buffers.ts 中的 resolveMedia() 调用缺少 telegramCfg.apiRoot 参数。
修复代码:
// bot-handlers.buffers.ts (修复后)
const telegramCfg = cfg.channels?.telegram; // 新增:提取配置
// 第 150-159 行:回复文档媒体
const media = await resolveMedia(
ctx,
message.document,
{
fileRef: message.document.file_id,
fileName: message.document.file_name,
mimeType: message.document.mime_type,
},
telegramCfg?.apiRoot // 新增:传递 apiRoot
);
// 第 189 行:回复贴纸媒体
const stickerMedia = await resolveMedia(
ctx,
message.sticker,
stickerMetadata,
telegramCfg?.apiRoot // 新增:传递 apiRoot
);
> 关键细节:使用 telegramCfg?.apiRoot 可选链操作符,避免配置未定义时的运行时错误。
—
2. 代码重构:媒体元数据解析统一化
遵循 KISS(保持简单)和 YAGNI(你不会需要它)原则,将三个分散函数合并:
// 重构前:三个独立函数
resolveMediaFileRef()
resolveTelegramFileName()
resolveTelegramMimeType()
// 重构后:单一函数返回结构化数据
interface MediaMetadata {
fileRef: string; // 文件引用 ID
fileName: string; // 原始文件名
mimeType: string; // MIME 类型
}
function resolveMediaMetadata(media: TelegramMedia): MediaMetadata {
// 统一解析逻辑,消除代码重复
}
收益:
- 减少 ~40% 的重复代码
- 类型安全提升(
fileRef从unknown改为明确联合类型) - 单测覆盖率更易维护
—
3. SSRF 安全策略增强
本地 Bot API 引入了新的安全风险:攻击者可能构造恶意 URL 访问内网服务。修复方案:
// buildTelegramMediaSsrfPolicy() 增强
function buildTelegramMediaSsrfPolicy(apiRoot?: string): SsrfPolicy {
const allowedHosts = ['api.telegram.org'];
if (apiRoot) {
try {
const parsed = new URL(apiRoot);
allowedHosts.push(parsed.hostname); // 添加自定义域名
} catch (err) {
// 新增:解析失败时记录日志,便于调试配置错误
logger.warn({ apiRoot, err }, 'Failed to parse custom apiRoot URL');
}
}
return { allowedHosts };
}
—
4. 回归测试覆盖
新增测试用例确保问题不再复发:
// test/telegram/url-construction.test.ts
describe('Telegram file download URL construction', () => {
it('should use custom apiRoot for document downloads', () => {
const apiRoot = 'http://local-api:8081';
const url = buildFileUrl(apiRoot, 'BQACAgIAAxkBAAIBZ...');
expect(url).toBe('http://local-api:8081/file/bot/BQACAgIAAxkBAAIBZ...');
});
it('should use custom apiRoot for sticker downloads', () => {
// 贴纸文件同样适用
});
it('should include custom hostname in SSRF policy', () => {
const policy = buildTelegramMediaSsrfPolicy('http://local-api:8081');
expect(policy.allowedHosts).toContain('local-api');
});
});
—
5. 类型安全与健壮性
| 修复项 | 说明 |
|:—|:—|
| telegramCfg 定义检查 | 避免 ReferenceError 未定义变量 |
| fileRef: unknown → 联合类型 | 保留下游 file_id 访问的类型信息 |
| 可选链操作符 ?. | TypeScript strict 模式兼容 |
—
升级指南
检查当前配置
验证是否使用本地 Bot API
grep -n "apiRoot" your-config.yaml
升级步骤
1. 更新 OpenClaw 版本:
npm update @openclaw/core
# 或
docker pull openclaw/openclaw:latest
2. 验证配置完整性:
channels:
telegram:
token: "${TELEGRAM_BOT_TOKEN}"
apiRoot: "${TELEGRAM_API_ROOT:-}" # 可选,本地服务器时设置
3. 测试文件下载:
– 发送文档到 Bot
– 回复该消息触发缓冲处理
– 检查日志确认 URL 构造正确
—
FAQ
Q1: 什么情况下需要使用 Telegram 本地 Bot API?
当你需要下载超过 20MB 的文件,或对文件传输有隐私合规要求时。本地服务器将文件存储在你的基础设施内,避免经过 Telegram 云端。
Q2: 如何确认 apiRoot 配置已生效?
启用调试日志后,查找包含 buildTelegramMediaSsrfPolicy 的日志条目。若看到 apiRoot 被解析的 hostname,说明配置生效。若看到警告 Failed to parse custom apiRoot URL,请检查 URL 格式。
Q3: 缓冲消息和实时消息有什么区别?
实时消息:用户发送后立即处理,通过 bot-handlers.runtime.ts 处理。缓冲消息:回复历史消息时触发,通过 bot-handlers.buffers.ts 处理。本次修复前,两者在 apiRoot 传递上存在不一致。
Q4: 这次重构会影响现有功能吗?
不会。所有更改保持向后兼容。未配置 apiRoot 时,系统默认使用 https://api.telegram.org,行为与之前完全一致。
Q5: SSRF 策略中的 hostname 白名单如何工作?
系统维护允许访问的 hostname 列表。默认包含 api.telegram.org,配置 apiRoot 后自动追加解析出的自定义 hostname。任何不在白名单内的 URL 请求都会被阻止,防止内网探测攻击。
—
总结
PR #59544 通过 3 个层面的改进 完善了 Telegram 本地 Bot API 支持:
1. 功能修复:确保缓冲消息场景正确传递 apiRoot
2. 代码质量:重构媒体解析逻辑,提升可维护性
3. 安全加固:增强 SSRF 防护和配置验证
建议所有使用 Telegram 集成的 OpenClaw 用户升级至此版本,特别是部署了本地 Bot API 服务器的场景。
—
下一步行动
- 📖 阅读 OpenClaw Telegram 集成文档 了解完整配置选项
- 🔧 查看 本地 Bot API 部署指南 搭建私有文件服务器
- 💬 在 GitHub Discussions 分享你的使用经验
—