利用微信同步文章到Bear

如果图片失效:见【教程&工具】微信同步文章到Bear

在我日常工作中,我会将各种互联网以及生活中产出的信息汇总到Bear,再通过Bear的云同步使我各个终端的信息保持一致。

以前在使用有道云笔记的时候,有个功能我很喜欢,就是当看到一篇想收藏的文章的话,就可以直接右上角发送到有道云笔记,如下图:

image

顺便一提:熊掌记是一款优雅、灵活的写作笔记应用。
回到正题,我现在面临的需求是能不能在看到喜欢的文章的时候,也通过类似于右上角分享一下就可以直接将文章同步到我各个终端上的Bear,最终成果如下:

image

解决方案

要实现上述的需求,我大概思考了如下的解决方案:

  1. 准备一个微信号(这里直接称作小号)专门接收待收藏到Bear的文章
  2. 编写一个服务监控小号的消息,比如收到推文类型的消息就进行内容提取
  3. 监控服务将提取后的内容发送到Bear(这里要求服务运行在Mac OS上)

所以在继续之前,你需要有以下条件:

  • 基本的Python基础知识(写小脚本Python真的很方便)
  • 一台装有Bear的Mac OS

方案调研

上面的解决方案看起来还是挺好实现,第一步不用多说,这年头谁没个小号,第二点的话,我印象中Python是有个第三方库可以直接监听微信对应账号的消息。

因为这些第三方库都是基于Web版的微信,所以在使用之前我想验证下此方案是否可行,刚准备登录网页版微信,就直接提示:

<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)]

果不其然现在微信准备加强Web版本的限制了,心里凉凉的,第二步还没开始就已经被宣判死刑。

只能换个思路了,怎么办。其实这一步走不通我还是能接受的,因为我一直觉得依赖Web版总有一天会挂掉,毕竟多了个依赖总是会增加复杂度。

能不能依靠客户端?

我们知道,微信数据是有同步功能的,开发过客户端的都知道,这就意味着微信的数据必然保存一份在客户端本地系统上。

所以对于第二点的解决思路就转换成了如何获取微信保存在客户端本地的数据,找到某个软件的数据文件夹自然是很简单的事情,比如微信客户端的数据就存放在:

# howie6879是我的用户名,请自行替换
/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

不知道上面那三个32位的字符串大家看起来熟悉不熟悉:

image

一想到32,就是md5加密,我第一反应就是对于每个登录账号的id加密值,我们先不管,直接进去看更深一层的文件夹:

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

15 directories, 0 files

Message出来了,这是不是我们想要的呢?再往下看里面的目录:

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

如果你登录过该台电脑并同步过信息,那么不出意外会有挺多*.db后缀的文件。大胆地猜测一下,这是不是我们想要的聊天数据存放路径呢?

不要管太多,先看看总不会错,一般本地存储的数据库,咱们程序员第一反应应该就是SQLite,要不要试试?

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

??提示不是数据库,此时陷入了瓶颈,怎么就不是数据库了呢。反思一下,是不是打开的姿势不对。

会不会是加密了?依照这个思路,我了解到有一款基于SQLite的扩展数据库[SQLCipher](https://github.com/sqlcipher/sqlcipherSQLCipher是一个在SQLite基础之上进行扩展的开源数据库,它主要是在SQLite的基础之上增加了数据加密功能。

实践证明,我猜想的是对的,接下来主要做的怎么打开Message/msg_0.db这个文件并成功读取里面的数据。

最后我参考到一份有意思的问答,我就是参考这个问答对数据库进行解密,这里我复述一下:

  • 打开微信,但是先不登录
  • 打开终端,输入lldb -p $(pgrep WeChat)
  • 会看到进入了lldb,然后输入br set -n sqlite3_key,按回车
  • lldb中,输入c,按回车
  • 打开微信并扫码登录
  • 然后回到lldb中,输入memory read --size 1 --format x --count 32 $rsi

此时就会得到以下类似的输出:

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

去掉冒号前面的那一串,后面是四行八列的数据,再去除掉0x空格\n等,就会得到一串64位的字符串,举个例子:

df012f587cc546000025a56599e81530f9cc49800329423d8ec460e1386549e2

这就是我们进入数据库的钥匙,接下来,请安装sqlcipher的相关软件,如:

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

让我们用db-browser-for-sqlite打开db后缀的文件看看有什么不一样吧:

image

image

点击OK,成功打开!

image

随便进入一个表:


image

很显然,我们成功获取了本地的聊天记录,总算将第二步流程打通了,如今我们可以监控发送收藏文章的微信账户的聊天记录,只要收到此账号发来的推文消息,此时监控服务可以立马反应过来并解析发送到Bear。

有个小问题,怎么知道发推文的账号在哪个库哪个表呢?可以这样看,在电脑上登录发推文的账号,打开文件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�老胡的储物柜�

这里很明显我的wxid就是:wxid_epXXXXXXXfj12,那么对应需要监控的表名就是:Chat_md5(wxid_epXXXXXXXfj12),形式如同这样

Chat_f965739xxxx114fxxxxc394322exxxx

随后实现在库里面找到对应的表即可,我本机发现对应账户的表存在于库 msg_5.db中。

接下来要做的事情就很简单了,就是将提取后的内容发送到Bear,这里可以利用X callback url Scheme documentation,比如你在终端输入:

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

立马就可以看到Bear自动建立了一篇笔记

编码实现

终于到了编码阶段,好心酸:

image

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

  • S_ACCOUNT_ID:微信发送账户ID,可以在Account/userinfo.data下查看
  • R_ACCOUNT_ID:微信接收账户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/"

定义这四个常量,接下来的事情就一帆风顺了哈,我将项目开源在Github,地址见w2b,接下来我直接说说怎么用:

git clone https://github.com/howie6879/w2b
cd w2b
# 推荐使用pipenv 你也可以使用自己中意的环境构建方式
pipenv install --python=/Users/howie6879/anaconda3/envs/python36/bin/python3.6  --skip-lock
# 运行前需要填好配置文件
pipenv run python w2b/run.py

随后,会有日志输出:

[w2b] pipenv run python w2b/run.py                                                                                                
Loading .env environment variables…
[2019:09:13 09:16:35] INFO  w2b  目标表 Chat_f965739b676114fxxxxc394322e1e826 存在于库 msg_5.db

好,代码跑起来后,接下来电脑上登录你的小号(也就是接收微信文章的微信号),然后在手机上登录发送文章的微信号,最终成功就和文章一开始的动图一样了~

搞定收工,有兴趣欢迎关注我的公众号:

image
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,911评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,014评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,129评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,283评论 1 264
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,159评论 4 357
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,161评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,565评论 3 382
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,251评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,531评论 1 292
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,619评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,383评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,255评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,624评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,916评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,199评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,553评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,756评论 2 335

推荐阅读更多精彩内容

  • 简介 最近接到公司的一个任务,要获取微信聊天记录,心想,这应该不太可能吧,毕竟微信这么多人用,要是能够轻易导出聊天...
    拔萝卜占坑阅读 54,284评论 2 16
  • 你好,WCDB WCDB是一个高效、完整、易用的移动数据库框架,基于SQLCipher,支持iOS, macOS和...
    he15his阅读 5,732评论 4 4
  • 我幸福吗?我经常会自己问自己。不幸福,我经常会这么回答,那我怎样才能幸福?于是脑海里思绪万千。 刚毕业时没有...
    拔云見日阅读 250评论 0 0
  • 其实很困,没有失眠。 只是宝宝不舒服,哭了,还吐了,所以,我搂着他睡,知道他不哭闹。 他睡着啦,应该吐了要舒服点。...
    恋枫林阅读 266评论 0 2