封面图展示 Telegram 个人资料页中 agou 的心形数字 85 表情状态

Telegram 在 2022 年就推出了自定义表情状态 (Emoji Status) 功能,很多朋友都会将自己喜欢的表情挂到自己的名字旁边显示。但是,手动修改表情状态有些麻烦,更糟糕的是如果长按设置表情状态的过期时间,过期后表情状态会直接回退到 Premium 标记,而不是上一个状态。

再加上我总是想不起来改设置,表情状态基本无法反映我的状态。然而,一直显示相同的表情不是我想要的效果。为了让群友知道我有多生气,不经意间告诉对方我在睡觉请勿打扰,或者让我暗恋的人们看到我为他心跳加速,我决定要将我的心率放进我的表情状态中。

Telegram 个人资料页,用户名 agou 旁显示心形数字 85 的表情状态

自动更新表情状态

虽然很多朋友都设置了表情状态,但大多数人应该都不知道,表情状态实际上是可以全自动更新的,而且不需要通过 Userbot 等危险的奇技淫巧,也不需要连接原先商业功能中的聊天自动化。

答案藏在迷你 App 中:在 2024 年的迷你 App 大更新中,Telegram 为迷你 App 增加了更新用户表情状态的功能,设计初衷就是为了显示游戏进度和徽章这样的场景。这样我们就可以通过 Bot API 轻松地更新表情状态了,甚至都不需要自己的后端

有意思的是,虽然更新的步骤是通过 Bot API 完成的,但是更新表情状态的权限无法通过 Bot API 申请,必须要使用迷你 App 完成。因此,我们需要将一个简单的网页绑定为迷你 App 并打开一次获取权限。当然,我已经帮你准备好了授权网页

Heart Rate Status 授权页面,显示允许机器人更新表情状态的按钮

心率图标

作为实现的第一步,我们需要与心率对应的自定义图标。

为了显示精确的心率,我要求 Codex 绘制了 35-220 的所有心率图标。由于 Telegram 的表情数量限制,我创建了两个表情包,通过 Bot API 自动化上传了所有表情,并获取与心率对应的自定义表情 ID 备用。

Heart Rate 35-161 自定义表情包选择器,展示按心率排列的数字心形图标

自动化运行

到了封闭的 iOS 这边,问题就开始变得麻烦了。要实现自动上报信息的功能,除了“快捷指令”App 外,几乎没有任何其他方案。

而快捷指令虽然支持自动化,也有获取心率的接口,但在我构思这个任务时,发现存在几个影响我们达成目标的限制因素:

  • 自动化既不能在心率信息更新时触发,也不能间隔一段时间触发;
  • 如果你退而求其次采用打开 App 之类的事件来触发,那么当你不使用手机或这些事件不触发时,心率信息也将无法更新;
  • 唯一看起来有可行性的是按照固定时间触发,但是假设每十分钟触发一次,就必须添加 (60/10)*24=144 条自动化,这不仅会把人累死,而且会让自动化列表变得又臭又长,也不能快捷向其他人分享。

iOS 快捷指令自动化设置界面,展示每天按时间运行的触发条件

幸运的是,iOS 27 中快捷指令的“及时雨”更新给了我们继续实现的可能:

  • 在 iOS 27 中,自动化从单独的配置页面移动到了快捷指令内部
  • 而且,一个快捷指令中可以同时添加多个自动化触发条件
  • 但是添加 144 个条件还是很麻烦啊哦莫!不用担心,在 iOS 27 中,快捷指令可以通过内置 AI 来编辑了
    我直接说“让此快捷指令在每天 0:00, 0:10, ……, 23:40, 23:50 运行”,内置的 AI 就非常耍拉 (注:爽快) 地帮我添加好了这 144 个自动化条件。(然而测试发现,从 iCloud 分享链接获取快捷指令后所有自动化是默认关闭的。)

iOS 快捷指令编辑界面,展示添加多个每日时间触发条件的过程

上报逻辑

在我让 AI 添加了 144 个自动化条件之后,AI 编辑功能就趴窝了,我只好重操旧业,亲自完成剩余的部分。虽然有好几年没怎么搓快捷指令了,但这个简单的任务并没有花费我太多时间重新适应。

简单来说,这个快捷指令依次做了以下几件事情:

  • 从“健康”App 获取最新的心率并取整(因为 App 中的数据可能有离谱的小数);
  • 确认数据与上次更新不同后,从我们的对照表取出与心率对应的自定义表情 ID;
  • 调用 Telegram Bot API setUserEmojiStatus 接口设置用户的表情状态;
  • 保存本次心率信息供下次比较并退出。

实际上是一个很简单的逻辑,我就不赘述详细实现了。

iOS 快捷指令工作流,展示读取心率、查询表情 ID 并调用 Telegram API 的步骤

不过在实现过程中踩了一个坑:“健康”App 获取健康信息的接口有可能在编辑后莫名其妙的不返回信息,必须删除该项重新添加方可解决。

啊,一直在打健康,好想去建康路吃小郑酥烧饼 (左边那家) 啊。

限制

虽然这个项目看起来很酷,但实际上是意义不大的,因为显示的心率并不能做到及时更新

  • Apple Watch 或智能手表不可能始终实时监测心率。在大多数情况下,手表几分钟到几十分钟才会监测一次;
  • 手表监测到的心率数据也不是实时同步到手机上的,同步过程也需要几分钟到十几分钟时间,除非手动打开“健康”App 触发同步;
  • 我们的自动化每 10 分钟运行一次,而不是数据更新时立即运行,也放大了这个延迟;
  • 而且根据我的观察,这些自动化也不总能顺利运行,常常会出现“漏拍”的情况,表现不太稳定。

这些因素共同作用导致了心率数据的滞后。另外,这样做还带来了一些其他方面的影响:

  • 注意到自动化运行时,屏幕可能会短暂亮起;
  • 有时在锁屏环境下,即使已经提供了权限,还是会弹出确认弹窗;
  • 不过目前没有感知到这些自动化导致电量消耗过快或影响系统性能。

抛砖引玉

虽然我的心率显示并不是那么的准确,也不完美,不过希望它能让你了解到表情状态的可个性化程度。事实上围绕着它你还可以做更多自动化的事情,例如像 Discord 一样显示你正在使用的应用,显示你的专注模式状态等等。更多的创意就有待大家发掘啦!

部署

项目用到的有关资源和快捷指令可在 GitHub 上查看:https://github.com/agoudbg/Telegram-Heart-Rate-Status

自动化运行该快捷指令需要 iOS 27 或更高版本,以及可同步心率到”健康”App 的可穿戴设备。