起因
我一开始只是想把 Telegram Bot 收到的消息分开看。用户一多,Bot 会话很容易混在一起,回消息时经常要先确认上一句到底是谁发来的。
后来又碰到另一个问题:真正需要处理这些消息的人,不一定一直挂在 Telegram 上,很多时候还是在企业微信里。这样一来,消息就开始在 Telegram、群组和企业微信之间来回搬,效率很低,也很容易把上下文弄丢。
我最后把这件事接成了现在这条链路:用户先和 Bot 一对一会话,消息按用户进 Telegram 群组的独立 Topic;需要同步时,再把指定用户的消息送到企业微信,企业微信里的回复也能回到原来的 Bot 会话。
示例: @FungitPMBot
先讲清一个词:下面说的“私聊”,都指“用户与 Telegram Bot 的一对一会话”,不是人与人的个人私聊。
我最后接成了什么样
整条链路落下来以后,日常用到的其实就是这几步:
- 用户给 Telegram Bot 发消息,按用户落到群组里的独立 Topic。
- 在 Topic 里回复,消息会回到对应用户的 Bot 会话,不会串人。
- 某些用户如果要同步到企业微信,可以单独打开。
- 企业微信里的回复,可以顺着显式路由或临时上下文回到原会话。
这份代码目前能处理文本、图片、语音这些常见消息,reply 关系也会保留下来,不会变成一堆上下文断掉的转发记录。
另外还带了两件我自己会用到的东西:
- owner 侧可以用
/wx_add、/wx_del、/wx_list管哪些用户要同步到企业微信。 TG -> WeCom这条链路上有敏感词拦截,用户和 Bot 的一对一入口也做了限流。
先准备什么
要把它跑起来,前面要先准备这些:
- 一个 Telegram Bot Token。
- 一个开了 Forum Topic 的 Telegram 群组,并拿到
group_id(-100...)。 - 一台能跑 Python 3 的环境。
- 最好装上
ffmpeg,语音转码会完整一些。 - 如果还要接企业微信应用,就把
corpid、corpsecret、agentid、回调 token、EncodingAESKey、receive_id` 和回调地址也提前备好。
最小启动
如果只是先把 Telegram Bot -> 群组 Topic 这一步跑起来,命令很简单:
pip install -r requirements.txt
python main.py -token "<BOT_TOKEN>" -group_id "-100xxxxxxxxxx"
如果数据库路径想自己指定,再加一个 -db_path:
python main.py -token "<BOT_TOKEN>" -group_id "-100xxxxxxxxxx" -db_path "./data/forwarder.db"
企业微信这边怎么接
如果企业微信也要一起打通,参数会多一些:
python main.py \
-token "<BOT_TOKEN>" \
-group_id "-100xxxxxxxxxx" \
-owner_tg_id "123456789" \
-wecom_enabled \
-wecom_corpid "wwxxxx" \
-wecom_corpsecret "xxxx" \
-wecom_agentid "1000002" \
-wecom_touser "@all" \
-wecom_token "xxxx" \
-wecom_encoding_aes_key "43charsEncodingAESKey" \
-wecom_receive_id "wwxxxx" \
-wecom_callback_host "0.0.0.0" \
-wecom_callback_port 58090 \
-wecom_callback_path "/wecom/callback"
企业微信应用回调 URL 配成:
http://<your-host>:58090/wecom/callback
如果当前网络环境本身要走代理,还可以加 -proxy、-get_updates_proxy、-wecom_proxy。
企业微信里的回复怎么回去
这一步我自己平时主要用两种方式。
一种是直接在企业微信里显式指定路由:
#TGROUTE:<tg_user_id> 你的消息
另一种是先绑定上下文,再直接回复。企业微信里有 /list、/bind <tg_user_id>、/status、/unbind 这几个命令。绑好以后,在有效期内直接回文本就行,不用每一条都再带一次 id。
如果是日常处理,后面这种会方便很多。
哪些消息会进企业微信
默认情况下,用户发给 Telegram Bot 的消息会先进入群组 Topic。企业微信不会一上来就同步所有用户,不然很快就会被刷屏。
只有当 owner 对某个用户执行了 /wx_add <tg_user_id> 之后,这个用户发给 Telegram Bot 的一对一消息才会同步过去。常见消息的处理方式大概是这样:
- text -> WeCom text
- photo -> WeCom image
- voice -> 优先转码后发语音,失败时回退为文件
- video/document -> 能直接发就直接发,不行再回退为文件
这个开法更适合重点用户、值班消息或者需要跟进的会话,不然企业微信里会全是普通消息。
常用命令
Telegram 侧常用的主要是这些:
/start:帮助/call <text>:把当前 Bot 会话内容手动转发到企业微信/ball <text>:/call的兼容别名/wx_add <tg_user_id>:开启自动同步/wx_del <tg_user_id>:关闭自动同步/wx_list:查看自动同步列表
企业微信侧则是:
/status/list/bind <tg_user_id>/unbind
另外还有一处最好别忘:-owner_tg_id 最好配上。命令权限控制和白名单豁免,后面都会省事很多。
最后
我把这套做法留下来,主要是因为它把会话和回复关系都放到了看得见的地方。谁接班、谁继续回,都不用先猜上一句到底是在跟谁说话。
如果你手上也有“Bot 接待 + Topic 分流 + 企业微信协同回复”这种场景,这套接法至少能把来回复制消息的时间省掉一大半。
Comments