Featured image of post Openresty实现Memos的Webhook

Openresty实现Memos的Webhook

利用Openresty,为Memos实现Webhook

简介

我现在有两个写作工具,一个是Obsidian,用于写长文,一个是Memos,用来记录一些琐碎的事物。

我有个需求,需要用Webhook把Memo同步到个人网站,但是Memos的Webhook支持还在计划中,我只能自己想办法实现。

思路

我的目的本质是这样的:把Memo实时同步到个人网站(Cloudflare D1)。

脑海里首先有了两个方案:

  • 数据库同步
  • Webhook

Memos用的SQLite,要实时同步到Cloudflare D1,看起来比较麻烦,而且难于管理;Webhook很合理,但是官方不支持。

接下来想,无论使用什么方式,我本质是要截取Memos从网页上传到服务器的数据,有点儿类似于MITM,那么怎么办呢?有三种方案:

  • 从浏览器获取
  • 从Memos的反向代理获取
  • 从Memos服务器获取

这是一条Memo的三个数据中转站,首先排除从Memos服务器获取,需要抓包,过于麻烦;从浏览器获取稍微简单,但是要配合浏览器插件,我还要在不同设备之间同步插件,维护麻烦;从Memos的反向代理获取,正好我的反向代理是Openresty,写一些Lua就解决了。

代码实现

有了解决思路,接下来就是具体的实现,废话不多说,直接上代码吧:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
access_by_lua_block {
	local json = require("cjson")
	local http = require("resty.http")
	
	local uri = ngx.var.request_uri
	local method = ngx.req.get_method()

	if uri == "/api/v1/memo" and method == "POST" then
		ngx.req.read_body()
		local memo = json.decode(ngx.req.get_body_data())
		if memo.visibility == "PUBLIC" then
			local webhook_data = { type = "memos", data = memo }
			-- modify your webhook url here
			local webhook_url = ""
			local http_client = http.new()
			local res, err = http_client:request_uri(webhook_url, {
				method = "POST",
				headers = {
					["Content-Type"] = "application/json",
				},
				body = json.encode(webhook_data)
			})
			if not res then
				ngx.log(ngx.ERR,err)
			end
		end
	end
}

最后

说到这里,想谈谈HTTP服务器。在服务器领域,Nginx的市场份额绝对是老大,其次是Apache,但是除此之外,可以试试Caddy/Kong/Traefik等新兴的服务器,灵活性和可扩展性太强大了。

更新

Memos官方已经支持Webhook了。

使用 Hugo 构建
主题 StackJimmy 设计