利用微信同步文章到Bear

如果圖片失效:見(jiàn)【教程&工具】微信同步文章到Bear

在我日常工作中,我會(huì)將各種互聯(lián)網(wǎng)以及生活中產(chǎn)出的信息匯總到Bear,再通過(guò)Bear的云同步使我各個(gè)終端的信息保持一致。

以前在使用有道云筆記的時(shí)候,有個(gè)功能我很喜歡,就是當(dāng)看到一篇想收藏的文章的話(huà),就可以直接右上角發(fā)送到有道云筆記,如下圖:

image

順便一提:熊掌記是一款優(yōu)雅、靈活的寫(xiě)作筆記應(yīng)用。
回到正題,我現(xiàn)在面臨的需求是能不能在看到喜歡的文章的時(shí)候,也通過(guò)類(lèi)似于右上角分享一下就可以直接將文章同步到我各個(gè)終端上的Bear,最終成果如下:

image

解決方案

要實(shí)現(xiàn)上述的需求,我大概思考了如下的解決方案:

  1. 準(zhǔn)備一個(gè)微信號(hào)(這里直接稱(chēng)作小號(hào))專(zhuān)門(mén)接收待收藏到Bear的文章
  2. 編寫(xiě)一個(gè)服務(wù)監(jiān)控小號(hào)的消息,比如收到推文類(lèi)型的消息就進(jìn)行內(nèi)容提取
  3. 監(jiān)控服務(wù)將提取后的內(nèi)容發(fā)送到Bear(這里要求服務(wù)運(yùn)行在Mac OS上)

所以在繼續(xù)之前,你需要有以下條件:

  • 基本的Python基礎(chǔ)知識(shí)(寫(xiě)小腳本Python真的很方便)
  • 一臺(tái)裝有Bear的Mac OS

方案調(diào)研

上面的解決方案看起來(lái)還是挺好實(shí)現(xiàn),第一步不用多說(shuō),這年頭誰(shuí)沒(méi)個(gè)小號(hào),第二點(diǎn)的話(huà),我印象中Python是有個(gè)第三方庫(kù)可以直接監(jiān)聽(tīng)微信對(duì)應(yīng)賬號(hào)的消息。

因?yàn)檫@些第三方庫(kù)都是基于Web版的微信,所以在使用之前我想驗(yàn)證下此方案是否可行,剛準(zhǔn)備登錄網(wǎng)頁(yè)版微信,就直接提示:

<error><ret>1203</ret><message>To protect your account, logging in to WeChat via the web has been suspended. Use WeChat for Windows or WeChat for Mac to log in on a computer. Download WeChat for Windows or Mac at http://wechat.com.</message></error>

[圖片上傳失敗...(image-1157a-1571723347291)]

果不其然現(xiàn)在微信準(zhǔn)備加強(qiáng)Web版本的限制了,心里涼涼的,第二步還沒(méi)開(kāi)始就已經(jīng)被宣判死刑。

只能換個(gè)思路了,怎么辦。其實(shí)這一步走不通我還是能接受的,因?yàn)槲乙恢庇X(jué)得依賴(lài)Web版總有一天會(huì)掛掉,畢竟多了個(gè)依賴(lài)總是會(huì)增加復(fù)雜度。

能不能依靠客戶(hù)端?

我們知道,微信數(shù)據(jù)是有同步功能的,開(kāi)發(fā)過(guò)客戶(hù)端的都知道,這就意味著微信的數(shù)據(jù)必然保存一份在客戶(hù)端本地系統(tǒng)上。

所以對(duì)于第二點(diǎn)的解決思路就轉(zhuǎn)換成了如何獲取微信保存在客戶(hù)端本地的數(shù)據(jù),找到某個(gè)軟件的數(shù)據(jù)文件夾自然是很簡(jiǎn)單的事情,比如微信客戶(hù)端的數(shù)據(jù)就存放在:

# howie6879是我的用戶(hù)名,請(qǐng)自行替換
/Users/howie6879/Library/Containers/com.tencent.xinWeChat/Data/Library/Application Support/com.tencent.xinWeChat/2.0b4.0.9

具體有如下目錄:

├── 988eebd1078a0d794bff2b6f5c8d5176
├── Avatar
├── CGI
├── CrashReport
├── KeyValue
├── MMResourceMgr
├── checkVersionFile
├── d41d8cd93400b204e9800998ecf8427e
├── f965739b566114f907dc394322e1e826
├── topinfo.data
├── upgradeHistoryFile
├── whatsNewVersionFile
└── wx.dat

8 directories, 5 files

不知道上面那三個(gè)32位的字符串大家看起來(lái)熟悉不熟悉:

image

一想到32,就是md5加密,我第一反應(yīng)就是對(duì)于每個(gè)登錄賬號(hào)的id加密值,我們先不管,直接進(jìn)去看更深一層的文件夾:

├── Account
├── Avatar
├── Contact
├── Favorites
├── FileStateSync
├── FunctionMsg
├── Group
├── Message
├── RevokeMsg
├── Session
├── Stickers
├── Sync
├── complexSearch
├── mmexpt
└── newabtest

15 directories, 0 files

Message出來(lái)了,這是不是我們想要的呢?再往下看里面的目錄:

├── MessageTemp
├── fts
├── msg_0.db
├── msg_0.db-backup
├── msg_0.db-shm
├── msg_0.db-wal
├── msg_1.db

如果你登錄過(guò)該臺(tái)電腦并同步過(guò)信息,那么不出意外會(huì)有挺多*.db后綴的文件。大膽地猜測(cè)一下,這是不是我們想要的聊天數(shù)據(jù)存放路徑呢?

不要管太多,先看看總不會(huì)錯(cuò),一般本地存儲(chǔ)的數(shù)據(jù)庫(kù),咱們程序員第一反應(yīng)應(yīng)該就是SQLite,要不要試試?

sqlite3 Message/msg_0.db
sqlite> .schema
Error: file is not a database
sqlite>

??提示不是數(shù)據(jù)庫(kù),此時(shí)陷入了瓶頸,怎么就不是數(shù)據(jù)庫(kù)了呢。反思一下,是不是打開(kāi)的姿勢(shì)不對(duì)。

會(huì)不會(huì)是加密了?依照這個(gè)思路,我了解到有一款基于SQLite的擴(kuò)展數(shù)據(jù)庫(kù)[SQLCipher](https://github.com/sqlcipher/sqlcipher,SQLCipher是一個(gè)在SQLite基礎(chǔ)之上進(jìn)行擴(kuò)展的開(kāi)源數(shù)據(jù)庫(kù),它主要是在SQLite的基礎(chǔ)之上增加了數(shù)據(jù)加密功能。

實(shí)踐證明,我猜想的是對(duì)的,接下來(lái)主要做的怎么打開(kāi)Message/msg_0.db這個(gè)文件并成功讀取里面的數(shù)據(jù)。

最后我參考到一份有意思的問(wèn)答,我就是參考這個(gè)問(wèn)答對(duì)數(shù)據(jù)庫(kù)進(jìn)行解密,這里我復(fù)述一下:

  • 打開(kāi)微信,但是先不登錄
  • 打開(kāi)終端,輸入lldb -p $(pgrep WeChat)
  • 會(huì)看到進(jìn)入了lldb,然后輸入br set -n sqlite3_key,按回車(chē)
  • lldb中,輸入c,按回車(chē)
  • 打開(kāi)微信并掃碼登錄
  • 然后回到lldb中,輸入memory read --size 1 --format x --count 32 $rsi

此時(shí)就會(huì)得到以下類(lèi)似的輸出:

0x600003888340: 0xd1 0x05 0x29 0x04 0x75 0xc5 0x45 0x05
0x600003888348: 0x92 0x26 0xa1 0x65 0x95 0xe5 0x15 0x3f
0x600003888350: 0xf3 0xc7 0x43 0x85 0x05 0x35 0x45 0x3d
0x600003888358: 0x84 0xc8 0x64 0xe5 0x35 0x65 0x45 0xe2

去掉冒號(hào)前面的那一串,后面是四行八列的數(shù)據(jù),再去除掉0x、空格、\n等,就會(huì)得到一串64位的字符串,舉個(gè)例子:

df012f587cc546000025a56599e81530f9cc49800329423d8ec460e1386549e2

這就是我們進(jìn)入數(shù)據(jù)庫(kù)的鑰匙,接下來(lái),請(qǐng)安裝sqlcipher的相關(guān)軟件,如:

brew install sqlcipher
brew cask install db-browser-for-sqlite

讓我們用db-browser-for-sqlite打開(kāi)db后綴的文件看看有什么不一樣吧:

image

image

點(diǎn)擊OK,成功打開(kāi)!

image

隨便進(jìn)入一個(gè)表:


image

很顯然,我們成功獲取了本地的聊天記錄,總算將第二步流程打通了,如今我們可以監(jiān)控發(fā)送收藏文章的微信賬戶(hù)的聊天記錄,只要收到此賬號(hào)發(fā)來(lái)的推文消息,此時(shí)監(jiān)控服務(wù)可以立馬反應(yīng)過(guò)來(lái)并解析發(fā)送到Bear。

有個(gè)小問(wèn)題,怎么知道發(fā)推文的賬號(hào)在哪個(gè)庫(kù)哪個(gè)表呢?可以這樣看,在電腦上登錄發(fā)推文的賬號(hào),打開(kāi)文件userinfo.data

cd /Users/howie6879/Library/Containers/com.tencent.xinWeChat/Data/Library/Application Support/com.tencent.xinWeChat/2.0b4.0.9/988eebd1023a0d794bff2b6f5c8d5176/Account
cat userinfo.data

大概輸出如下:

":BHPpx??127417592694754732??wxid_epXXXXXXXfj12?    Howie6879?老胡的儲(chǔ)物柜?

這里很明顯我的wxid就是:wxid_epXXXXXXXfj12,那么對(duì)應(yīng)需要監(jiān)控的表名就是:Chat_md5(wxid_epXXXXXXXfj12),形式如同這樣

Chat_f965739xxxx114fxxxxc394322exxxx

隨后實(shí)現(xiàn)在庫(kù)里面找到對(duì)應(yīng)的表即可,我本機(jī)發(fā)現(xiàn)對(duì)應(yīng)賬戶(hù)的表存在于庫(kù) msg_5.db中。

接下來(lái)要做的事情就很簡(jiǎn)單了,就是將提取后的內(nèi)容發(fā)送到Bear,這里可以利用X callback url Scheme documentation,比如你在終端輸入:

open 'bear://x-callback-url/create?title=Test%20Bear&text=Hello%20Bear'

立馬就可以看到Bear自動(dòng)建立了一篇筆記

編碼實(shí)現(xiàn)

終于到了編碼階段,好心酸:

image

第一步,拿到必須要的常量:

  • S_ACCOUNT_ID:微信發(fā)送賬戶(hù)ID,可以在Account/userinfo.data下查看
  • R_ACCOUNT_ID:微信接收賬戶(hù)ID,同上
  • RAW_KEY:解密Key,就是上面介紹的64位字符串
  • DB_PATH_TEM:定義的是消息DB路徑,比如:"/Users/howie6879/Library/Containers/com.tencent.xinWeChat/Data/Library/Application Support/com.tencent.xinWeChat/2.0b4.0.9/{0}/Message/"

定義這四個(gè)常量,接下來(lái)的事情就一帆風(fēng)順了哈,我將項(xiàng)目開(kāi)源在Github,地址見(jiàn)w2b,接下來(lái)我直接說(shuō)說(shuō)怎么用:

git clone https://github.com/howie6879/w2b
cd w2b
# 推薦使用pipenv 你也可以使用自己中意的環(huán)境構(gòu)建方式
pipenv install --python=/Users/howie6879/anaconda3/envs/python36/bin/python3.6  --skip-lock
# 運(yùn)行前需要填好配置文件
pipenv run python w2b/run.py

隨后,會(huì)有日志輸出:

[w2b] pipenv run python w2b/run.py                                                                                                
Loading .env environment variables…
[2019:09:13 09:16:35] INFO  w2b  目標(biāo)表 Chat_f965739b676114fxxxxc394322e1e826 存在于庫(kù) msg_5.db

好,代碼跑起來(lái)后,接下來(lái)電腦上登錄你的小號(hào)(也就是接收微信文章的微信號(hào)),然后在手機(jī)上登錄發(fā)送文章的微信號(hào),最終成功就和文章一開(kāi)始的動(dòng)圖一樣了~

搞定收工,有興趣歡迎關(guān)注我的公眾號(hào):

image
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 簡(jiǎn)介 最近接到公司的一個(gè)任務(wù),要獲取微信聊天記錄,心想,這應(yīng)該不太可能吧,畢竟微信這么多人用,要是能夠輕易導(dǎo)出聊天...
    拔蘿卜占坑閱讀 56,381評(píng)論 2 16
  • 你好,WCDB WCDB是一個(gè)高效、完整、易用的移動(dòng)數(shù)據(jù)庫(kù)框架,基于SQLCipher,支持iOS, macOS和...
    he15his閱讀 6,066評(píng)論 4 4
  • 我幸福嗎?我經(jīng)常會(huì)自己?jiǎn)栕约骸2恍腋#医?jīng)常會(huì)這么回答,那我怎樣才能幸福?于是腦海里思緒萬(wàn)千。 剛畢業(yè)時(shí)沒(méi)有...
    拔云見(jiàn)日閱讀 321評(píng)論 0 0
  • 其實(shí)很困,沒(méi)有失眠。 只是寶寶不舒服,哭了,還吐了,所以,我摟著他睡,知道他不哭鬧。 他睡著啦,應(yīng)該吐了要舒服點(diǎn)。...
    戀楓林閱讀 331評(píng)論 0 2

友情鏈接更多精彩內(nèi)容