用 Webmention 接收 Mastodon 互动

更新于2024-07-09:我其实准备删掉这个功能了。

原因:

  • 维护麻烦(大改了一下Stream页面后,没法正常同步fediverse上回应,跟这个issue差不多)
  • 用的人少(well, that’s what we called indie
  • 确实有一些ethical problem

什么是 webmention #

Webmention是由IndieWeb发起的W3C标准,用来实现网页间相互提及,不必借助平台或引入评论系统。它的工作流程如下:

  1. 我上传了一篇文章
  2. 文章被你引用
  3. 你向我的网站发送带有引用处url的webmention
  4. 我通过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传出去,后来:

  1. 尝试以<a href="https://fed.brid.gy" hidden="from-humans"></a>的方式,加到带class="e-content"的元素里面。但如果note不包含其他url,具有Link Preview功能的地方,还是会显示出fed.brid.gy的链接卡片。
  2. 在对Stream页面部署自动化时,分成了三个部分:
    • 固定以url#id作为source并以Bridgy作为target、
    • 检查这条note的类型并以相关url作为target(例如reply、like)
    • 检查这条note的内容并以相关url作为target(里面所有的<a href="..."

一些遗留的问题 #

  1. 如果fediverse上对博文的回应(回复、转发、喜爱)被修改或删除,无法触发Bridgy自动更新,即以回应为source,以博文为target重新发一次webmention
  2. 如果发出回应的用户更改了自己的个人信息,也无法触发Bridgy自动更新,这个应该更没法解决了。

Comment

Login via Github
No Login
Webmention

What is Webmention?

Hypothes.is