用 Webmention 接收 Mastodon 互动
更新于2024-07-09:我其实准备删掉这个功能了。
原因:
- 维护麻烦(大改了一下Stream页面后,没法正常同步fediverse上回应,跟这个issue差不多)
- 用的人少(well, that’s what we called indie)
- 确实有一些ethical problem
什么是 webmention #
Webmention是由IndieWeb发起的W3C标准,用来实现网页间相互提及,不必借助平台或引入评论系统。它的工作流程如下:
- 我上传了一篇文章
- 文章被你引用
- 你向我的网站发送带有引用处url的webmention
- 我通过webmention.io等服务或自行挂载,接收到你的webmention
现在你就可以试试,在自己的页面提及此页url,例如:
<p><a href="https://fanrongbin.com/hugo-webmention-bridgy-mastodon">I'm trying webmention!</a></p>
然后把你的页面url在文末输入框提交,大约一分钟后刷新此页,就会看到你的webmention。
接收 webmention #
这里给出使用webmention.io的步骤,你也可以自行挂载:
1. 用 IndieAuth 标识你的身份 #
Webmention.io使用IndieAuth登录,所以需要先设置IndieAuth。在index.html
中,对自己的帐号说明为rel="me"
,例如:
<a rel="me" href="mailto:your_email@email.com">Send me an email</a>
或者以隐藏的方式在<head>
说明:
<link rel="me" href="mailto:your_email@email.com">
这样一来,采用IndieAuth登录的地方,会通过这些方式验证你的身份,例如向邮箱发送邮件,或跳转Github登录。
2. 使用 webmention.io 挂载 #
在webmention.io登录后,你会看到一个Settings-Setup页面,给出了需要你在<head>
加入的tag:
<link rel="webmention" href="https://webmention.io/your_domain/webmention" />
这条tag说明你的页面能够接受别人的提及,你可以通过webmention.rocks测试能否接收到。
到此,你已经实现了webmention的接收。
你可以在webmention.io的Dashboard,或它提供的Mentions Feed,查看他人提及。
3. 借助 webmention.js 在博文页面显示 webmention #
Webmention.io提供API返回你接受到的具体内容,这里我们借助前人造好的轮子webmention.js,根据readme,在你的网站存放webmention.min.js
文件并用<script src=""></script>
引入,在需要展示webmention列表的地方插入:
<div id="webmentions"></div>
你可以新建一个测试页面,用来提及目标页,以测试是否能正常发出和显示。也可以在连接Mastodon后,通过发toot和回复的方式测试。webmention列表的样式可通过css
自定义。
发送 webmention #
很多支持webmention的站点,都会给出一个form方便你手动提交自己的链接。
你也可以用curl
发出webmention,发送前需检查对方收不收得到webmention,下面这条指令会进行检查。$your_url
替换为你自己的引用页,$target_url
替换为目标页。
curl -i -d "source=$your_url&target=$target_url" `curl -i -s $target_url | grep 'rel="http://webmention.org/"' | sed 's/rel="webmention"//' | grep -o -E 'https?://[^ ">]+' | sort | uniq`
也可以用telegraph.p3k.io(需要IndieAuth登录),或mention.tech(不需要登录)的在线服务。
使用 webmention.app 自动发送 #
你可能一次在博文中引用多个网页,但是不想再进行繁琐的手动发送webmention。Webmention.app可以读取页面class="h-entry"
中的链接,帮你一键发送。
可以使用Test页面检查(只会检查前10个h-entry
),也可以通过API。登录服务获得token后没有request限制。具体请参见官网。
将你的博文发送到社交平台 #
连接到 Bridgy #
Bridgy可将网站和社交平台相联,使得没有个人页面的用户,也能通过支持的平台进行回复,Bridgy会帮助进行webmention。
进入主页选择Mastodon,使用cross-post或直接连接联邦宇宙的方式均可。如果cross-post,你需要用验证过的帐号publish带有博文链接的toot,在这条toot下的回复、转发、喜爱才会作为webmention传过来。
如果直接连接(也就是我目前的做法),你会以@your-domain.com@your-domain.com
加入联邦宇宙,向Bridgy的每次update都会对应更新这个账号下的toot。
使用 Github Actions 自动化 #
我使用Hugo作为博客系统,希望实现根据我是否上传或更新.md
,自动发出webmention。tj-actions/changed-files能够找到repo下文件的修改情况,故可以先寻找是否有文件被修改,之后发出 curl
命令即可。
在之前的博文里,我设置了deploy.yml
用来自动部署Hugo、生成静态文件。故对应在此设置为在deploy
后才运行。
name: send webmentions to bridgy according to md changes
on:
workflow_run:
workflows: ["deploy"]
types:
- completed
branches:
- main
jobs:
changed_files_send_webmention:
runs-on: ubuntu-latest
name: send webmentions according to md changes
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: get changed files
id: changed-files
uses: tj-actions/changed-files@v41
with:
files: content/posts/*.md # 注意这里根据实际需要修改目录位置
- name: list all changed files
run: |
ALL_CHANGED_FILES="${{ steps.changed-files.outputs.all_changed_files }}"
for file in $ALL_CHANGED_FILES; do
echo "$file was changed"
done
- name: send webmentions
if: steps.changed-files.outputs.all_changed_files != '' # 判断不为空才运行
run: |
CHANGED_FILES=$(echo "${{ steps.changed-files.outputs.all_changed_files }}" | tr ',' '\n')
for FILE in $CHANGED_FILES; do
if [[ $FILE == content/posts/*.md ]]; then
POST_NAME=$(basename "$FILE" .md)
POST_URL="https://your-domain.com/${POST_NAME}"
echo "Sending Webmention for $POST_URL"
curl -i -d source=${POST_URL} -d target=https://fed.brid.gy https://fed.brid.gy/webmention
fi
done
你还可以接着使用${POST_URL}
trigger webmention.app的webhook。
最初是看到IndieWeb上关于webmention的介绍,于是想着要不要自己也折腾一下,搜索到Aaron Parecki的博文,以及Jayeless.net的博文后,觉得配置起来也不是很难嘛,然后就开始了……用第三方服务接收很简单,主要是一直卡在Bridgy这边。我新建了一个Stream页面,相当于有了自己的一条时间轴,为了传上联邦宇宙,需要把每条小note以锚点#id
的方式传到Bridgy。但,用webmention.app或者是telegraph.p3k.io始终没法发现到https://fed.brid.gy/
这条链接,导致我没法API传出去,后来:
- 尝试以
<a href="https://fed.brid.gy" hidden="from-humans"></a>
的方式,加到带class="e-content"
的元素里面。但如果note不包含其他url,具有Link Preview功能的地方,还是会显示出fed.brid.gy
的链接卡片。 - 在对Stream页面部署自动化时,分成了三个部分:
- 固定以
url#id
作为source并以Bridgy作为target、 - 检查这条note的类型并以相关url作为target(例如reply、like)
- 检查这条note的内容并以相关url作为target(里面所有的
<a href="..."
)
- 固定以
一些遗留的问题 #
- 如果fediverse上对博文的回应(回复、转发、喜爱)被修改或删除,无法触发Bridgy自动更新,即以回应为source,以博文为target重新发一次webmention
- 如果发出回应的用户更改了自己的个人信息,也无法触发Bridgy自动更新,这个应该更没法解决了。
Login via Github