零成本把Markdown文章发到微信公众号

如何零成本把Markdown文章同步发到微信公众号,解决图片上传的问题

背景

首先我有一个托管于Github Pages个人网站,所以我想在写一篇文章的时候,能先发到我的个人网站,然后同步到微信公众号。这就是我最初的目的,但是很快我就发现这一过程并不顺利。

Markdown导入公众号

基于作为一个开发者的身份,再加上对排版的不太拿手,这里我首选的格式肯定是Markdown

Markdown到微信公众号排版的转换

很快第一个问题就摆在了我的面前,我的个人网站是基于 Hexo 搭建的静态网站,所以天然支持 Markdown 格式,出问题的是微信,微信的恶心向来是出了名,所以微信也必然不支持 Markdown 格式的文章,微信官方只支持使用它的富文本编辑器。

然而只能说 Markdown 相当受欢迎,所以即使官方不支持,但是在网络上随便一搜索仍然能找到如何用 Markdown 来排版微信公众号。

它的基本原理是,把 Markdown 内容使用 HTML 进行排版渲染,然后把 HTML 的内容写到剪切版,再复制到微信公众号的编辑器中即可。因为微信的富文本归根到底也是 HTML 渲染,所以这样是完全OK的。

Markdown导入微信公众号原理

推荐一下 这个站点,可以很方便的进行排版,排版出来的主题也很不错,已经在Github上开源。唯一有一点不好的是,它的默认主题会在两边有边距,导致复制到微信公众号发布后,只能显示窄窄的一条,所以需要使用它的自定义主题的能力,自定义一下css, 把边距给移除掉。

粘贴图片失败问题

图片上传到微信服务器的原理及失败原因

事情不会这么顺利,很快就遇到了把渲染后的内容后粘贴到微信后,微信出现了粘贴失败的情况。

粘贴后图片加载失败

这里刚开始我以为是我网络不好,导致图片上传失败了,但是打开控制台看了一下网络请求,才发现跟我网络没关系。

这里的原理是在粘贴的时候,微信会把原图片上传到微信的服务器,然后把图片地址替换成上传到微信服务器后的图片地址,而这一上传过程是前端把原图片的地址传给微信服务器后台,微信服务端去下载原图片,再上传到微信服务器的,所以这里的失败是微信服端下载原图的时候失败了,并不是前端直接获取原图后再上传到微信服务器的,所以跟我当前的网络没关系。

那这里微信服务端下载失败的原因就是因为我的原图片在 Github 的服务器上,而微信的服务器必然是在国内要经过 GFW 或经过微信严柯的校验,自然就下载失败了。

粘贴时图片失败的原因

解决思路

那这里我们就需要把原来的图片重新上传到国内的云服务中,让微信服务器能成功下载图片即可。经过实验,发现把图片上传到腾讯云的cos对象存储后,微信即可成功下载。腾讯云cos提供了10G的免费存储和流量,作为中转基本上也够用了。

为什么不直接把图片放到腾讯云COS上

这里要解释一下,为啥不直接把原图片直接放到腾讯云cos中,主要还是出于成本的考量。首先腾讯云cos虽然提供了10G的存储空间和每月10G的流量,但是相对来说,还是感觉还是太少。其次是必须要考虑到流量盗刷的可能性,如果把所有的图片都放在cos上,我觉得流量盗刷可能会导致更多的支出。接着就是稳定性,相比个人维护的cos,显然Github要稳定得多。总结来说就是穷,想白嫖,所以这些图片最好就是放在Github上,而不是在腾讯云cos。

这里的图片放在Github上,也并不是说把这些图片直接放在Github的仓库中,而是通过在issue的表单中上传图片获得图片地址,这样仓库中就没有图片了,仓库很小,就能承载更多的内容。

为什么不直接把图片上传到微信公众号上

这里也要解释一下为什么不直接把图片上传到微信公众号上,微信公众号有提供上传素材的接口,甚至提供了 上传图文消息内的图片获取URL 的接口。

但是,首先微信的上传接口需要 Access Token ,而 Acess Token 的获取需要在公众号后台添加IP白名单,是的,就是这么恶心,需要添加IP白名单,而IP白名单不能填写 CIDR 类型的IP地址范围,所以这也就决定了首先你得有一台服务器来获取 Access Token,无法使用IP地址不固定的 Github Actions 服务,也就意味着你要额外付费才行,不符合白嫖的原则。

其次即使直接把图片上传到微信公众号的素材库里面,但是上传后的图片也只能在腾讯系内使用,其它页面都不可使用,微信的防盗链真是天衣无缝,而我还要在我的个人网站使用,所以这显然不可行。

解决方案

再回到图片上传的问题,这里的解决方案已经比较清楚了:

  1. 把原 Markdown 文件中的图片上传至腾讯云cos中
  2. 然后替换 Markdown 中原图片的地址为对应的腾讯云cos地址
  3. 再把替换后图片地址的 Markdown 内容粘贴到排版页面,复制出排版后的内容
  4. 把排版后的内容粘贴到微信公众号编辑器中

这里如果是手动去操作第一步、第二步,显然是很耗费时间的,所以期望是能把第一步、第二步自动化。

于是 Github Actions 有了用武之地。

我开发了 replace-md-images-action Github Action,可以在把 Markdown 文件推送到 Github 后 把 Markdown 中的图片上传到腾讯云cos并替换图片地址,然后把替换后的 Markdown 文件通过通知送达,进行第三步、第四步的操作,具体的可以参考此仓库

解决方案

P.S. 这里我把cos上对应的目录设置为1天有效期,1天后上传的图片自动删除,彻底避免了流量盗刷的问题

后续优化

这里目前来看,还是有优化空间的。比如说:

  1. Markdown 内容渲染到粘贴到微信公众号这一过程仍然是手动,不够优秀,最好是能够把一流程再加上预览的能力也全部自动化,这是一个待优化的项

  2. 容灾的处理,虽然图片目前是放在Github上,但是毕竟不是放在仓库中,所以必须要考虑到图片被屏蔽的情况,要做好容灾处理,目前的想法是在个人网站仓库中写一个脚本,当运行此脚本时,就自动把远程图片下载下来放在仓库中,并自动修改Markdown中图片的引用地址