SyncPost 是一个面向单人运营场景的轻量级 Telegram 同步机器人。你只需要向你的同步 Bot 发送一条消息,它就会把内容同步发布到 Telegram 频道和 Mastodon。
- 需要同时维护 Telegram 频道和 Mastodon 的个人创作者
- 想用 Telegram 私聊当作统一发布后台的用户
- 希望部署简单、依赖少、行为可预测的小型同步工具使用者
- 纯文本消息同步发布到 Telegram 频道和 Mastodon
- 支持单张或多张相册图片、文件形式的图片,以及单个视频
- 编辑私聊原消息时,同步更新已发布的平台内容
- 回复原消息并发送
/delete,删除已同步的平台内容 - 支持部分成功场景
- 某个平台发布失败时,成功的平台仍可继续编辑和删除
- 删除失败时保留映射,便于后续重试
- 管理员鉴权
- Postgres 映射存储与速率限制
- 健康检查接口
- 一键初始化 Webhook 和机器人命令
你在机器人私聊中发送纯文本、图片、视频或相册后,机器人会:
- 先回复一条"正在同步"的状态消息
- 发布到 Telegram 频道
- 如有附件,下载后上传到 Mastodon
- 发布到 Mastodon
- 保存消息映射关系
- 原地更新状态消息为最终结果
图片附件超过 10MB、视频超过 20MB 或 Mastodon 实例限制时会直接拒绝。图片相册超过 4 张时会拒绝。
你直接编辑私聊里的原消息,机器人会:
- 更新所有已成功发布的平台内容
- 自动跳过当时未发布成功的平台
你回复私聊中的原消息并发送 /delete,机器人会:
- 删除所有已成功同步的平台内容
- 删除你的私聊原消息和
/delete命令消息 - 只有在平台删除成功后才清理映射
- 如果某个平台删除失败,会保留映射,方便后续继续重试
syncpost/
├── api/
│ ├── __init__.py
│ ├── clients.py
│ ├── config.py
│ ├── db.py
│ ├── index.py
│ ├── messages.py
│ ├── repositories.py
│ └── services.py
├── tests/
├── .env.example
├── requirements.txt
├── vercel.json
└── README.md
或手动部署:
git clone https://github.com/Eyozy/syncpost.git
cd syncpost| 变量 | 说明 |
|---|---|
TG_TOKEN |
从 @BotFather 创建机器人后获取 |
ADMIN_ID |
从 @userinfobot 获取你的 Telegram 用户 ID |
TG_CHANNEL_ID |
你的频道用户名,如 @mychannel,并确保机器人已是管理员 |
TG_WEBHOOK_SECRET |
自定义随机字符串,用于校验 Telegram Webhook |
SETUP_TOKEN |
自定义随机字符串,用于保护 /setup 初始化接口 |
生成 TG_WEBHOOK_SECRET 和 SETUP_TOKEN 示例:
openssl rand -hex 32| 变量 | 说明 |
|---|---|
MASTO_INSTANCE |
你的 Mastodon 实例地址,例如 https://mastodon.social |
MASTO_TOKEN |
在 Mastodon 中进入“设置 -> 开发”,创建应用后复制访问令牌 |
建议授权范围:
writewrite:statuses
- 打开 Vercel 项目
- 进入 Storage
- 创建 Neon
- 连接到当前项目
Vercel 会自动注入 DATABASE_URL。
在 Vercel 项目的 Settings -> Environment Variables 中配置:
| 变量 | 示例 |
|---|---|
ADMIN_ID |
123456789 |
TG_TOKEN |
123456:ABC... |
TG_CHANNEL_ID |
@mychannel |
TG_WEBHOOK_SECRET |
9f4b8f7c... |
SETUP_TOKEN |
5f0f01e6... |
MASTO_INSTANCE |
https://mastodon.social |
MASTO_TOKEN |
abc123def456... |
DATABASE_URL |
postgresql://<user>:<password>@<host>/<database>?sslmode=require |
配置完成后重新部署。
部署完成后,访问:
https://<YOUR_DOMAIN>/setup?token=<SETUP_TOKEN>
其中:
<SETUP_TOKEN>是你在 Vercel 环境变量里配置的那个值- 只有 token 正确时,这个接口才会执行初始化
- 只在首次部署、重置 webhook、或重新注册命令时才需要访问
成功后会:
- 初始化数据库表
- 注册 Telegram Webhook
- 清理旧命令
- 注册
/start、/delete和编辑相关命令
显示欢迎信息;如果配置未完成,会提示缺失的环境变量,并展示检测按钮。
直接向机器人发送纯文本、图片、单个视频或相册(支持直接发图或以文件形式发送图片):
Hello, world
返回结果示例:
✅ 发布成功
已同步到:
• Telegram 频道
• Mastodon
⚠️ 部分发布成功
已同步到:
• Telegram 频道
未同步到:
• Mastodon
直接编辑你发给机器人的原消息。如果只有 Telegram 发布成功,那么编辑时只会更新 Telegram,不会因为 Mastodon 失败而中断。
如果 Telegram 已不再允许编辑原消息,可以按帖子类型使用备用命令:
/edit 新的文字
/edit 仅支持纯文本帖子。图片和视频使用独立命令:
/edit_image_text 新的图片文字
/replace_image
/replace_image_text 新的图片文字
/edit_video_text 新的视频文字
/replace_video
/replace_video_text 新的视频文字
命令行为:
| 命令 | 行为 |
|---|---|
/edit 新文字 |
只编辑纯文本帖子 |
/edit_image_text 新文字 |
纯图片新增文字;已有文字则修改 |
/replace_image |
发送新图片,只替换图片并保留原文字 |
/replace_image_text 新文字 |
发送新图片,同时替换图片和文字 |
/edit_video_text 新文字 |
纯视频新增文字;已有文字则修改 |
/replace_video |
发送新视频,只替换视频并保留原文字 |
/replace_video_text 新文字 |
发送新视频,同时替换视频和文字 |
替换图片或视频时,必须回复原帖子并附上新的媒体文件。视频文件不能超过 20MB,或不能超过 Mastodon 实例返回的更小限制。
返回结果示例:
✅ 编辑成功
已同步更新到:
• Telegram
回复原消息发送:
/delete
Telegram 和 Mastodon 都删除成功:
✅ 删除成功
已从以下平台删除此消息:
• Telegram、Mastodon
只有 Telegram 成功:
✅ 删除成功
已从以下平台删除此消息:
• Telegram
Telegram 删除失败:
⚠️ 部分删除失败:Telegram
这时映射会被保留,后续可以继续尝试删除。
- 不支持 GIF 图、音频、语音、贴纸、视频留言
- 图片附件不能超过 10MB;视频不能超过 20MB 或 Mastodon 实例的更小限制
- 不支持转发消息,默认每分钟最多 10 条操作
- 消息映射依赖 Postgres;如果数据库不可用,旧消息将无法继续编辑或删除
健康检查接口。
示例:
curl "https://your-domain.vercel.app/"返回示例:
{
"status": "ok",
"service": "SyncPost",
"version": "1.0.0",
"database": "connected",
"config": "complete",
"missing_config": [],
"timestamp": "2026-03-07T12:00:00"
}Telegram Webhook 入口。
这个接口通常由 Telegram 自动调用,不需要手动长期访问。如果要本地或线上排查,可以用一个最小示例请求验证服务是否正常:
curl -X POST "https://your-domain.vercel.app/webhook" \
-H "Content-Type: application/json" \
-H "X-Telegram-Bot-Api-Secret-Token: your-webhook-secret" \
-d '{
"update_id": 10001,
"message": {
"message_id": 1,
"text": "/start",
"from": {
"id": 123456789
}
}
}'说明:
X-Telegram-Bot-Api-Secret-Token必须与TG_WEBHOOK_SECRET一致from.id必须是你的ADMIN_ID- 正常情况下返回
OK - 校验失败时返回
401 Unauthorized
初始化数据库表、Webhook 和机器人命令。
示例:
curl "https://your-domain.vercel.app/setup?token=your-setup-token"成功响应示例:
✅ Webhook 已设置为 https://your-domain.vercel.app/webhook,命令已注册(旧命令已清除)
失败响应示例:
Unauthorized
运行测试:
python3 -m pytest testsMIT,详见 LICENSE。