Blog

通过 FCM 接收最新的推文

2025-10-09

#FCM
#Twitter
#Twitter Monitor

早在 2023 年,我在 通过 Web Push 接收最新的推文 就研究过怎么被动接收来自 twitter 的推送,当时留了一个坑,就是通过手机的 FCM 来接收,现在是时候填上了

优劣

Webpush 已经很完美了,那模拟手机接收还有什么好处?

  • 可以接收到回复的推文,这是 webpush 做不到的
  • 带图推文可以接收到第一张图
  • 没有 4096 字数限制,所以可以尽可能长地获取内容

好处说完了,那坏处呢

  • 供应商锁定,只有 FCM 可选,而经过测试 FCM 的速度并不快(一般会在推文发送的 1~2 秒后接收到消息)
  • 转推的接收随缘
  • 打断方式简单粗暴,可能是文本遇到链接就直接打断,导致能接收到的推文的内容的长度飘忽不定,经常拿不到完整内容,只能根据 tweet_id 自行获取(只能说比暴力轮询要好吧……嗯)

注册 FCM

这次我没再从零开始,而是找了一个现成的 Golang 库 BRUHItsABunny/go-android-firebase 来解决掉大部分跟 FCM 相关的工作

然后就可以通过抓包提取出需要的信息:

JSON
{
  "X-Android-Package": "com.twitter.android",
  "X-Android-Cert": "40F3166BB567D3144BCA7DA466BB948B782270EA",
  "x-goog-api-key": "AIzaSyBvWKFq3NUWbwUXoEOC-io9wHRuDKJ_oxg",
  "appid": "1:49625052041:android:cc5f6af4987e5c02",
  "app_version": "11.9.0-release.0",
  "app_version_build": "311100000",
  "project_id": "api-project-49625052041"
}

然后模仿 func TestNativePushNotifications(t *testing.T) 注册自己的设备,获得 notificationToken 以及 checkinAndroidID

Twitter 推送

参考 细说 Twitter 的登录流程 登录取得各种凭证,至于这里的 AndroidID 跟前面的要不要一样我不确定,反正我是一样的

先请求一次接口获取推送的 push_settings_template.checksumpush_settings,以及关于 push_settings 要怎么填的模板 push_settings_template

JS
const UID = ''// a bigint number
const kdt = '...'
const oauth_token = '...'
const oauth_token_secret = '...'
const AndroidID = '...'
const notificationToken = '...'

const method = "POST";
const url = "https://global.dev.cftls.t.co/1.1/notifications/settings/checkin.json";

const authorization = getOauthAuthorization(...);// https://banka2017.github.io/twitter-monitor/apps/online_tools/oauth_signature_builder.html

let body = JSON.stringify({
  user_id: "$UID",
  client_application_id: 258901,
  push_device_info: {
    udid: AndroidID,
    token: notificationToken,
    locale: "en_US",
    env: 3,
    protocol_version: 20,
    os_version: "28",
  },
});
body = body.replace('"$UID"', uid);// `user_id` should be a bigint, but here is js, so...

const getSettings = await fetch(url, {
  method,
  headers: {
    "X-Twitter-Client-DeviceID": AndroidID,
    Authorization: authorization,
    kdt,
    "Content-Type": "application/json",
    ...
  },
  body,
});

console.log(await getSettings.text())

然后根据自己的需求调整 push_settings 里面各项的值,最后再提交一遍就好了,其他部分都是一样的我就省略了,只有 body 要加两项

JS
...
let body = JSON.stringify({
  user_id: "$UID",
  client_application_id: 258901,
  push_device_info: {
    udid: AndroidID,
    token: notificationToken,
    locale: "en_US",
    env: 3,
    protocol_version: 20,
    os_version: "28",

    // add
    checksum: getSettings.push_settings_template.checksum,
    settings: getSettings.push_settings
  },
});
...

如果懒得思考可以先直接提交,然后再在其他登录了这个账号的设备调整即可,push_settings 会在设备间同步

登出

登出只需要向 https://api.twitter.com/1.1/notifications/settings/logout.json 发一个一样 bodyPOST 请求即可

其他

本文本应在几个月以前就能发出来的,但卡在提交了 token 然后死活接收不了推送很久,一点头绪都没有

直到这几天用 fiddler 抓包发现被 Cloudflare 屏蔽了,只好换到使用 mitmproxy,然后才发现最后的这个提交 checksumsettings 的请求

这个差不多两年的坑,终于也是填上了

哦对了,Truth Social 也可以这么玩,至于跟它自己的那个 WebSocket 流比哪种办法更快,那就不好说了……

为什么没有同步放出代码?因为懒得整理,根据我说的去自行操作即可。未来可能会做个相关的网页小工具,敬请期待 (画大饼)

参考


评论区