早在 2023 年,我在 通过 Web Push 接收最新的推文 就研究过怎么被动接收来自 twitter 的推送,当时留了一个坑,就是通过手机的 FCM 来接收,现在是时候填上了
优劣
Webpush 已经很完美了,那模拟手机接收还有什么好处?
- 可以接收到回复的推文,这是 webpush 做不到的
- 带图推文可以接收到第一张图
- 没有 4096 字数限制,所以可以尽可能长地获取内容
好处说完了,那坏处呢
- 供应商锁定,只有 FCM 可选,而经过测试 FCM 的速度并不快(一般会在推文发送的 1~2 秒后接收到消息)
- 转推的接收随缘
- 打断方式简单粗暴,可能是文本遇到链接就直接打断,导致能接收到的推文的内容的长度飘忽不定,经常拿不到完整内容,只能根据
tweet_id
自行获取(只能说比暴力轮询要好吧……嗯)
注册 FCM
这次我没再从零开始,而是找了一个现成的 Golang 库 BRUHItsABunny/go-android-firebase 来解决掉大部分跟 FCM 相关的工作
然后就可以通过抓包提取出需要的信息:
{
"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.checksum
和 push_settings
,以及关于 push_settings
要怎么填的模板 push_settings_template
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
要加两项
...
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
发一个一样 body
的 POST
请求即可
其他
本文本应在几个月以前就能发出来的,但卡在提交了 token 然后死活接收不了推送很久,一点头绪都没有
直到这几天用 fiddler 抓包发现被 Cloudflare 屏蔽了,只好换到使用 mitmproxy,然后才发现最后的这个提交 checksum
和 settings
的请求
这个差不多两年的坑,终于也是填上了
哦对了,Truth Social 也可以这么玩,至于跟它自己的那个 WebSocket 流比哪种办法更快,那就不好说了……
为什么没有同步放出代码?因为懒得整理,根据我说的去自行操作即可。未来可能会做个相关的网页小工具,敬请期待 (画大饼)