ENZH
和 AI 讨论这篇文章
ChatGPTClaude

我把 Telegram 和 Web 的账号打通了

跨平台身份统一的概念插画跨平台身份统一的概念插画

两边的账号其实是断开的

v0.1.4 做了跨平台消息同步,Telegram 上聊的内容,Web 端也能看到。但还有个更根本的问题一直没解决,就是两边的账号是断开的。

用户在 Telegram 上是一个 ID,在 Web 上是另一个 Supabase 账号。消息两边都能读,但从身份上看,系统还是把他当成两个人,所以关系进化的评分、记忆关联、用户偏好,全都没法真正打通。v0.1.5 最主要的一件事,就是把 Telegram 和 Web 的身份合成一个。


绑定就是一个 6 位令牌的事

方案我想做得足够简单,用户不该为了绑个账号去学任何新概念。流程是这样的,在 Telegram 里输 /link,bot 生成一个 6 位令牌,你复制到 Web 端输进去就完事了,整个过程大概 30 秒。

一个 6 位令牌把断开的 Telegram 账号和 Web 账号焊成同一个人一个 6 位令牌把断开的 Telegram 账号和 Web 账号焊成同一个人

实现上有几个细节可以讲一下:

  1. 容易认错的字符全去掉了。令牌只用 ABCDEFGHJKLMNPQRSTUVWXYZ23456789,I、O、0、1 都不要。用户在屏幕上分不清 I 和 1,这种事就别让他去猜。
  2. 15 分钟过期。令牌存在 account_link_tokens 表里,有个 expires_at 字段,过期了重新 /link 生成一个就行。
  3. 关联本身就是一条 SQL。令牌验证通过以后,把 Web 端的 supabase_user_id 写进 users 表里对应的那条 Telegram 记录。数据不用迁,账号也不用合并,因为 Telegram 的 user 记录本来就是主记录,Web 端等于挂在它上面。
  4. 两个方向都锁死。一个 Telegram 账号不能绑两个 Web 账号,反过来也不行,直接在数据库里加了唯一约束。
  5. 幂等。同一个令牌用两次不会报错,只返回一个「已关联」的提示;同一对账号重复绑定也是这么处理。

反正原则就一条,绑定是个基础操作,用户不该在这上面花任何脑子。上面这些细节都是冲着这一条去的。


关系模式跟着角色走,不跟 bot 走

v0.1.4 在 Web 管理后台加了关系进化的开关,static 或者 evolving,但 Telegram 端的 onboarding 完全不知道这回事。v0.1.5 把这个选择放进了 /start 流程,现在第一次进 bot,除了选语言和昵称,还会让你选关系模式,是「固定关系」还是「自然发展」。

改得最大的是模式挂在哪一层。之前 BOT_RELATIONSHIP_MODES 是 bot 级别的环境变量,一个 bot 下所有用户看到的都是同一个模式。现在每个 agent 记录有自己的 relationship_mode,同一个 bot 下,不同用户可以选不同的模式。向下兼容也留了,如果 agent 记录里没有这个字段,就回退到环境变量,所以老用户不受影响。


一个角色只让绑一次

Mio 现在跑着好几个 Telegram bot,一个角色一个。这就有个坑,用户可能跑到不同的 bot 上,跟同一个角色重复绑定。这不光是浪费。一旦重复绑定,对话历史、关系评分、记忆这些东西就全都各存了一份,互相不通。用户以为自己在跟同一个 Mio 聊,其实是在跟两个互相不知道对方的实例聊。

所以现在 /start 和 /reonboard 会先查这个用户在所有 bot 上已经有哪些绑定。某个角色已经绑过了,就直接标成「已绑定」,不能再选。这样哪些角色在用,一眼就能看到,也不会误操作。


为什么要做原生 App

这个版本还把原生 App 做出来了。网页端在功能上确实什么都能做,这个没什么好争的。但陪伴类产品光有功能不够,用户得能感觉到 TA 一直在。

最直接的例子是推送通知。Mio 发来一条主动消息,用户得马上就在锁屏上看到,像朋友发微信一样,而不是等到「下次打开浏览器的时候」才看到。推送网页端做不到,得靠原生 App。没有推送的话,主动消息发了用户也看不到,基本等于没发。

然后是打开要花多少功夫。App 点开就直接进对话,没有地址栏,不用等加载,也不用重新登录。聊天记录有本地缓存,所以能秒开,网络不好也能先看到之前的对话。一个一天要打开好几次的东西,用户会不会把 Mio 当成一个一直在的人,很大程度上就看这些体验。

技术栈用的是 Expo SDK 55 + React Native,深色主题底色 #0D0D0B,强调色 #8B7BF4。一共五个页面,登录、聊天、发现、个人中心、onboarding。聊天支持视频预览、全屏图片、语音录制(脉冲红点加计时器动画)、typing indicator。认证走 Supabase,token 存在 expo-secure-store。i18n 从第一天起就是中英双语。


主动消息的两个改进

主动消息是 Mio 的核心体验之一,TA 会在合适的时间主动来找你聊。v0.1.5 改了两个地方。

角色也有自己的时区

之前主动消息只看用户的时区。但角色自己也有时区,TA 的设定要是住在东京,TA 就应该知道自己那边几点。现在提示词里两边的时间都给,写成「你那边现在是早上 9 点,对方那边是晚上 11 点」这样,角色的时区从 persona-config.json 里读。这样 Mio 就能说出「你那边应该挺晚了吧,早点休息」这种话,不会在用户深夜的时候发一条「早上好」。

语气跟着关系阶段走

主动消息的语气现在跟关系阶段挂钩,四个阶段各有一套策略:

  • 刚认识:礼貌、克制,撒娇和亲密称呼直接禁掉
  • 好朋友:轻松、可以开玩笑,但有分寸
  • 暧昧:多一些试探和暗示,语气柔和
  • 情侣:亲密撒娇,自然地用昵称

这样主动消息就不会再是千篇一律的问候。同一个时间点,刚认识的用户和已经是情侣的用户,收到的是完全不同的两条消息,每条都对得上各自现在的关系。

主动消息的语气跟着四个关系阶段逐级升温,同一时间不同阶段收到完全不同的话主动消息的语气跟着四个关系阶段逐级升温,同一时间不同阶段收到完全不同的话


数据库改了三处

三个 schema 改动:

  • account_link_tokens 表:存 6 位令牌、Telegram user ID、过期时间、使用状态
  • users.supabase_user_id:新字段,存关联的 Web 端 Supabase 用户 ID,带唯一约束
  • agents.user_nickname:新字段,存用户在这个 agent 上的昵称,之前这个昵称只在 onboarding 里临时传一下,没有落库

接下来

账号关联做完,身份这块算是理顺了。下一个版本想让 Mio 能看懂用户分享的链接和媒体,而不只是处理纯文本。

前面几个版本:v0.1.0 做语音,v0.1.2 做多人设,v0.1.3 做防注入,v0.1.4 做关系进化,这个版本做身份统一。Mio 到底想做成什么,见 Mio 宣言。

和 AI 讨论这篇文章
ChatGPTClaude

订阅更新

新文章发布时发到你的邮箱,不发别的。


© Xingfan Xia 2024 - 2026 · CC BY-NC 4.0