tg-support-bot · 多租户 Telegram 客服桥接
通用的多租户 Telegram 支持桥接服务:单个 Deployment 同时运行多个产品的 bot,每个 bot 把客户的私聊转成该产品管理 supergroup 里的「每客户一个 forum topic」,团队直接在 topic 内回复,无需独立的工单后台。它替代了部分产品原本基于 Chatwoot inbox 的工作流,面向希望在 Telegram 内用 topic 流程的产品。
镜像源自 github.com/yldm-tech/tg-support-bot,基于 python-telegram-bot v21,每个 bot 一个 asyncio 长轮询循环(getUpdates,无 webhook)。客户私聊 → bot → 支持群里的 forum topic(每客户一个);团队在 topic 内回复 → bot → 回到客户私聊。客户还能通过菜单按钮打开只读的 Telegram Mini App 查询自己的工单状态。
部署形态
- Name
- 命名空间
- Description
- app
- Name
- 工作负载
- Description
- Deployment,
strategy.type: Recreate
- Name
- 镜像
- Description
ghcr.io/yldm-tech/tg-support-bot,kustomizationimages:固定 newTag0.24.0(argocd-image-updater 按 semver 自动更新)
- Name
- 副本数
- Description
- 1(长轮询:每个 bot token 只能有一个 getUpdates 消费者,两个 poller 共用同一 token 会触发 Telegram 409 Conflict,绝不能 >1)
- Name
- 调度
- Description
- nodeSelector
workload: app
- Name
- 端口
- Description
- 容器
:8080(name http),承载 Mini App 页面、/api/status与/healthz
- Name
- 资源
- Description
- requests cpu 25m / memory 96Mi;limits memory 256Mi
- Name
- 镜像拉取
- Description
- imagePullSecret
ghcr-secret
部署无 PVC,所有状态都在外部 Redis 中,因此用 Recreate 策略而非滚动升级(避免短暂出现两个 poller 抢同一 token)。
配置与依赖
机密通过 ExternalSecret tg-support-bot-secrets 从 ClusterSecretStore vault-backend 拉取,remoteRef.key 为 yldm/production/tg-support-bot,refreshInterval: 1h,整体注入容器(envFrom.secretRef)。
| secretKey | Vault property | 说明 |
|---|---|---|
BOTS_JSON | bots | bot 的 JSON 数组 [{"id","token","greeting?"}, …],每个产品一条 |
REDIS_URL | redis_url | 共享集群 Redis(与 Chatwoot 用同一实例),含密码 |
状态存于共享集群 Redis(redis.redis),按 bot id 命名空间隔离:tgsupport:<id>:{group,u2t,t2u,closed,tinfo}。
显式 env:MINIAPP_URL=https://tg-support.yldm.tech,每个 bot 的菜单按钮打开 MINIAPP_URL?bot=<id>。
kustomization 给 Deployment 打了 reloader.stakater.com/auto: "true" 注解,bots / redis 机密变化时由 Reloader 自动重启 Pod。新增产品时只需向 Vault 的 bots 数组追加一条目(保留既有条目),external-secrets 刷新后 reloader 自动重启。
访问与监控
Service tg-support-bot 为 ClusterIP,port 80 → targetPort http(8080)。
Ingress tg-support-bot(ingressClassName traefik)暴露 host tg-support.yldm.tech,path / Prefix 指向该 Service。这是面向客户的 Telegram Mini App(工单状态查询)页面,作为共享 yldm 服务放在 yldm.tech 域名下。external-dns 通过两个注解把 tg-support.yldm.tech 建为指向 yldm Cloudflare Tunnel 的 proxied CNAME(target 2b822c22-21be-4d1e-98d4-c02a83f1cace.cfargotunnel.com,cloudflare-proxied: "true"),由 Tunnel 转发 *.yldm.tech → Traefik 按 Host 路由到此。TLS 在 Cloudflare edge 终结,因此没有 tls 块、不依赖 cert-manager。
三个探针(startup / readiness / liveness)都打 GET /healthz:startup periodSeconds 5、failureThreshold 12;readiness periodSeconds 10;liveness periodSeconds 20、failureThreshold 3。
该服务在 manifest 中没有 ServiceMonitor / PrometheusRule / HPA / VPA / PDB。
注意事项
副本数只能为 1。长轮询下每个 bot token 只允许一个 getUpdates 消费者,两个 poller 共用同一 token 会让 Telegram 返回 409 Conflict,所以严禁把 replicas 调到 >1,也因此使用 Recreate 策略。
/healthz 探针只存在于 Mini App 镜像中(≥ tg-support-bot#21 那次发布)。不要把上述探针配置滚动到更老的镜像上——老镜像不应答 /healthz,Pod 会进入 restart-loop。
每个 bot 启动时会执行 deleteWebhook,从而把 token 从此前可能绑定的 Chatwoot inbox 上释放出来。新增产品时除了改 Vault,还需在 Telegram 内:创建 supergroup、启用 Topics、把 bot 加为带 Manage Topics 权限的 admin,并在群里发送 /bind。当前已配置 fluxa(@fluxa_cash_bot,fluxa.cash 商户支持台)。
返回 app 服务总览