Mastodon | 不使用Webhook,将Mastodon同步到Memos

1345字

起因是看到了自动同步Mastodon到Memos,文中介绍了一种通过 Mastodon 的 Webhook 功能,自动同步 toots 到 Memos 的方法。但经过(在朋友的帮助下的)尝试,我发现 Mastodon 只有在 4.2.0版本以上才提供 status.created,折剑沉沙,铩羽而归,我好怨念。

重整旗鼓,更换思路,Mastodon 也提供了个人账户的 RSS 链接,被提醒可以通过 RSS 来触发 Webhook,n8nrsspush 都可以完成这项工作。另一个思路是改写脚本,设置 crontab 来定时触发。比较后前一种可能更优雅,但比较复杂,超过了技术能力,我选了第二种。

以下是脚本,由上文自动同步Mastodon到Memos 作者编写,我提出需求,Chatgpt 修改,尚未经长时间使用检测,尚在不断完善当中。

#!/bin/sh

# API 和 Token
API_HOST="https://填入自己的Memos地址/api/v1/memo"
AUTHORIZATION="Bearer Memos token"

# 原始内容
CONTENT_URL="https://Mastodon地址/api/v1/accounts/Mastodon ID/statuses?limit=5"
MESSAGES=(curl --connect-timeout 60 -s CONTENT_URL | jq '. | sort_by(.created_at)')

# 循环处理每条消息

echo "$MESSAGES" | jq -c '.[]' | while read -r MESSAGE; do

# 检查是否是回复消息

REPLY_TO_ACCOUNT_ID=(echo MESSAGE | jq -r '.in_reply_to_account_id')  
if [ "$REPLY_TO_ACCOUNT_ID" != "null" ]; then  
# 提取纯文本内容并计算中文字符数量(不包括换行符和URL)  
CONTENT_TEXT=(echo "MESSAGE" | jq -r '.content' | sed 's/<[^>]*>//g') # 去除HTML标签  
CHINESE_CHARACTER_COUNT=(echo "CONTENT_TEXT" | grep -oP '\p{Han}' | wc -l)  
if [ "$CHINESE_CHARACTER_COUNT" -gt 100 ]; then  
echo "Message contains more than 100 Chinese characters. Sending to Memos..."  
else  
echo "Message contains less than or equal to 100 Chinese characters. Skipping sync."  
echo ======================================================  
continue  
fi  
fi

# 提取 Mastodon URL

MASTODON_URL=(echo MESSAGE | jq -r '.url // empty')  
DUDU_CONTENT="[By Mastodon]($MASTODON_URL)"

# 判断是否有媒体内容

MEDIA=(echo MESSAGE | jq -r '.media_attachments // []')  
if [ "$MEDIA" != "null" ]; then  
MEDIAS=(echo MESSAGE | jq -r '.media_attachments[] | select(.type=="image") | .url')  
# 拼接图片  
images=""  
for url in $MEDIAS; do  
images="images![image](url)\n"  
done  
TEXT=(echo "MESSAGE" | jq -r '.content' | sed 's/ +/ /g' | lynx -dump -stdin -nonumbers -nolist | tr -d '\n' | sed '//N;s/\n\n/\n/g' | sed 's/^[[:space:]]*//;s/[[:space:]]*//')  
if [ ! -z "$TEXT" ]; then  
TEXT="TEXT\nDUDU_CONTENT"  
TEXT="TEXT\nimages"  
else  
echo "Message content is empty. Skipping..."  
echo ======================================================  
continue  
fi  
else  
# 普通内容  
TEXT=(echo "MESSAGE" | jq -r '.content' | sed 's/ +/ /g' | lynx -dump -stdin -nonumbers -nolist | tr -d '\n' | sed '//N;s/\n\n/\n/g' | sed 's/^[[:space:]]*//;s/[[:space:]]*//')  
if [ ! -z "$TEXT" ]; then  
TEXT="{TEXT}\nDUDU_CONTENT"  
else  
echo "Message content is empty. Skipping..."  
echo ======================================================  
continue  
fi  
fi

# 检查消息是否已经存在于 Memos 中

EXISTING=(curl -s -X GET -H "Authorization: AUTHORIZATION" API_HOST | jq -r '.[] | select(.content == '\""TEXT""')')  
if [ ! -z "$EXISTING" ]; then  
echo "Message already exists in Memos! $(TZ=UTC-8 date +"%Y-%m-%d"" ""%T")"  
echo ======================================================  
continue  
fi

# 发送到 Memos

curl -X POST  
-H "Accept: application/json"  
-H "Authorization: $AUTHORIZATION"  
-d "{ "content": "$TEXT" }"  
$API_HOST

echo Sync Mastodon to Memos Successful! $(TZ=UTC-8 date +"%Y-%m-%d"" ""%T")  
echo ======================================================  
done

其中 API_HOST 填入 Memos 的 API,格式为: https://自建的Mmeos的地址/api/v1/memoAUTHORIZATION 填入 Memos 的 Token,注意要保留 Bearer (后有空格)的部分。

CONTENT_URL 需要改写为自己的 Mastodon API URL,其中 Mastodon ID 获得方式为:在浏览器地址栏中输入 https://INSTANCE/api/v1/accounts/lookup?acct=USERNAME,返回 "id": 的一串数字即是 ID。Limit=5 是要求返回最近的5条嘟嘟。

相较原作者的脚本,我修改了两处。原作者的脚本只会同步原创并公开的 toot,我删去了过滤回复 toot 的部分,增加了一个条件判断,大于一定字数回复 toot 同样会被同步,可以根据自身需要修改字数限制。此外,增加了检查消息是否已存在于 Memos 的中的判断,防止脚本不断同步同样的 toot。

最后设置一个 crontab 定时执行脚本就完成了。

很久之前我就意识到我实际上是在 Mastodon 中记录生活、想法和思考的。比起额外设置一个信息收集的“Inbox”,在 Mastodon 中直接写嘟嘟更简单,更轻松。那么我为什么不直接将 Mastodon 作为 Daily notes 的内容源呢?Mastodon 内容同步到 Memos,再从 Memos 同步到思源笔记,我就拥有了一个按照年月日来分组记录的 Mastodon,也可以对 toot 内容进行再整理和编辑,非常完美的流程!