Freedom

淡泊以明志,宁静以致远。

不在微信里聊微信

这是个有点葛的标题,效果类似于「当我们谈论 XXX 时我们在谈论什么」。请问不在微信里聊还能在哪聊呢?为啥要不在微信里聊呢?我并不是阿里或者字节派来的奸细,让我先来讲讲这件事情的缘起。

缘起

由于工作的原因,我的微信里已经累积了数量可观的微信群,微信好友数也噌噌往上涨,已经逼近 1000 大关1。日常工作很大一部分都是在微信中进行,因此很长一段时间我都是严重依赖微信客户端来工作的,准确说是桌面版的微信客户端,应该没人想用手机 app 来处理工作。但一直有几个问题困扰着我,这些问题其实在我之前在某家公司工作时也有过,当时这家公司的内部聊天工具也是微信2。具体来说有这么几个问题。

公私不分

我对于微信的定位主要还是一个私人的聊天工具,因此我一直强烈反对用微信来工作。当年在知乎工作时就大力推广 Slack,虽然 Slack 在国内的体验一直不太好。就算不用 Slack,现在国内也已经有各种企业聊天工具可供选择。但为什么还是有很多人用微信来工作呢?很多时候不是不想选,而是没得选。我就属于这种情况,虽然公司内部以 Slack 沟通为主,但是与很多外部客户沟通就只能通过微信。

功能过盛以及缺失

这个问题和上一个问题互相关联,本质上微信并不是为工作场景设计,因此它提供的很多功能是「多余」的,甚至是一种干扰,同时又「缺失」了很多在工作场景中需要的功能。举个例子,我希望把不同类型的沟通分组便于快速查找和消息隔离(比如客户群是一个分组,私聊是另一个分组),同时我还希望能够针对这些工作相关的聊天信息单独设置通知(比如在非工作时间关闭推送,因为大部分消息都是不需要立即回复的)。再比如一直被呼唤了很久的聊天历史记录及多设备消息同步,前几天还看到一个传闻说微信可能推出付费方案来帮你保存历史聊天记录3

精力分散

国内的大厂都有一个「坏毛病」,喜欢在一个应用里塞各种莫名其妙的功能,关于这一点已经在我之前的一篇文章中吐槽过。自认我不是一个自制力特别强的人,如果呈现太多难免分心,所谓眼不见心不烦,那些与工作沟通不相干的东西还是暂时不看比较好(或者说没必要非得在工作时间看)4

没法自动化

用过 Slack 的人都知道,一个有开放 API、能够集成各种自动化组件的聊天工具将会变得非常强大,微信显然不是一个开放的应用,腾讯也不希望针对个人用户开放这样的功能。

所以该怎么办?

作为一个依然怀揣 DIY 念想的中年人5,还是想靠一些外部工具来实现我的需求,如果没有现成的那就自己鼓捣一个。一个显而易见的事实是,微信官方肯定不提供 API,因此只能依赖民间力量。所幸经过不太长时间的搜索我发现了 Wechaty 这个开源项目,简单讲 Wechaty 做的事情就是提供由一群热心网友维护的非官方微信 API,当然现在 Wechaty 已经不仅限于支持微信,也支持很多其它聊天工具,但我关注的主要还是微信。

Wechaty 的一个核心概念是「Puppet」,你可以把它理解为一个代理,负责帮你和实际的聊天工具通信。同一个聊天工具可能有多种 Puppet 实现,比如微信,可以是基于微信网页版来实现,也可以是基于 Pad 版来,亦或是基于 Windows 版。因此你可以看到其实我们并不能完全脱离微信客户端,只不过通过把微信客户端封装起来用对程序更友好的方式呈现。目前我用的是基于微信网页版的 puppet

需要注意的是,Wechaty 并不能让同一个微信帐号在多个客户端登录,也就是不能同时在 Wechaty 及常规的客户端中登录。另外由于微信的限制,不同的 puppet 实现可能存在功能差异,关于这一点后面会讲到。

能做什么?

既然有了 API,那就可以开开脑洞了。

首先所有微信消息都可以任意转发到任何聊天工具,因此我根据一些特定的关键词把所有与工作有关的消息都转发到了 Slack 上,再通过 Slack 中不同的频道来对消息进行分组管理。除了文本消息,微信还有一些其它类型的消息,如图片、文件,这些也可以转发到 Slack 上,只不过相比文本消息需要做一些特殊处理(如通过 Slack 的 files.upload API 上传文件)。

一些特殊的字符或者内容也需要做特别处理,如微信表情、emoji、换行符、微信公众号文章,避免在 Slack 上看到一串 HTML 标签。微信还会自作主张把一些并不是 URL 的文本封装成 <a> 标签,导致一些显示问题,也需要单独处理。

接收到消息以后是否可以在 Slack 中直接回复呢6?当然可以,但这里就得依赖 Slack 的一些 API 来实现了,在经过一番研究和权衡以后我决定还是用最原始的 message API 来实现,有点类似于早年的 IRC,通过某些关键词来触发机器人做特定的事情。举个栗子,当在一个 Slack thread 中发送以 re: 开头的消息时,就代表这是一条回复,会根据这个 thread 的父消息来判断具体回复给谁(某个人或者某个群)。也可以直接发送消息不依赖 Slack thread,我定义的语法是类似 to: [张三] XXX 这样的格式。这种方式相比直接回复消息稍微麻烦一些,但有一个好处是可以实现群发,也就是刚才命令中的接收者可以是多个。

如果想在回复的时候同时 @ 某个人呢?继续修改上面的命令,以 re: 为例,在后面可以加上你想要 @ 的人,也就是变成 re: @[张三] 这样的格式。

如果想发送图片或者文件呢?也没问题,Slack 的 file 对象包含很多信息,最主要的是 url_privatename,有了这两个就可以把文件下载下来,然后通过 Wechaty 的 API 上传到微信。一个额外功能是 Slack 支持在一条消息中附带多个文件,也就能实现一次发送多个文件到微信。

怎么知道消息是否发送成功呢?感谢 Slack,每条消息都可以有 reaction,这些 reaction 其实就是 emoji,因此我们可以根据不同的发送状态添加不同的 emoji,比如发送成功就用一个绿色的勾,发送失败就用一个红色的叉。

至此基本的聊天功能其实已经实现了,剩下的就是一些高级功能,比如搜索联系人、搜索群、修改联系人的备注、修改群名称、邀请人入群、查看群成员等,这些也都可以通过 Wechaty 来实现。

甚至可以脑洞再开大一些,女儿的学校老师每天都会发一些当天的照片和视频到微信群里,这些内容我都想永久保存下来。常规的做法只能是通过微信客户端手动一个一个下载,如果是在手机上保存的,可能还需要再备份到远端的存储。有了 Wechaty 以后我可以直接将这些文件自动保存都家里的 NAS,并且可以根据日期自动归类整理。

不能做什么?

说完能做什么,我们来说说不能做什么。首先最大的前提是任何功能都一定是限定在微信可以实现的假设之下的,常规微信客户端没有办法做到的你也不能做到,比如通过某种方式加一个好友并且在微信中隐藏。

其次某个功能是否能实现就取决于你用的具体是哪个 puppet,拿我用的微信网页版 puppet 为例,就没有办法通过群加好友,以及某个人通过了你的好友申请以后只能重启程序才能看到这个新好友。每次重启以后也不是所有微信群都能看到,只能看到近期活跃的群。

需要注意的是 Wechaty 社区还提供了一些 Puppet Service,这些服务都是必须付费才能使用的,好处是能实现某些免费 puppet 不能实现的功能。但是出于隐私安全7以及灵活性的考虑,我没有使用这些服务。

不要用来做什么?

最后讲讲不要用来做什么,技术可以推动进步,也可以成为「害人」的工具。你的所有行为都不能违反微信对于一个正常用户的判定,否则你将会面临微信对你的惩处,请遵守一个普通用户应有的行为规范。

P.S. 最新一期 Maybe News 已经鸽了很久了,其实内容很早就已经确定下来,只是一直没有完工,在这里就不做承诺,只希望能够尽快完成。


  1. 假装加了很多金主爸爸投资人

  2. 曾经跟老板建议过多次换到企业微信

  3. 这都 1202 年了还要付费同步聊天记录?

  4. 真相是该分心时还是会分心

  5. 所谓「念念不忘,必有回响」

  6. 如果不能回复那就太蛋疼了

  7. 你的消息都需要经过一个第三方的服务中转

Comments