Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Mastodon 同步到 Memos

Mastodon 同步到 Memos

作者头像
eallion
发布于 2024-03-10 01:22:43
发布于 2024-03-10 01:22:43
2460
举报
文章被收录于专栏:大大的小蜗牛大大的小蜗牛

最新脚本:https://gist.github.com/eallion/bf8861eb3292c2351c1067fba3198c26

Update:添加宝塔面板的示例。

TL;DR

直接跳转到本页 脚本内容 查看脚本代码。

前言

不知道是我运气好还是不好,在我准备把 Memos 当成主力工具加入到我的工作流中的时候,遇上了 v0.19.0 的版本更新,这次版本更新带来了一系列大坑。除了 Memos 新版本的鲁棒性备受质疑,甚至连搭载它的服务器本身也被影响,我在 64G 内存的物理机上都跑不动它。就像网友所说,Memos 只像是一个练手的项目。果断弃之。Google Keep、Obsidian 这些工具哪里不好了吗?不把所有事务约束在一个工具里确实是麻烦了一点,但是 All in one 基本上也等于是 All in boom。 现在我对 Memos 的定位是用来备份我的 Mastodon(方式之一)。

我一直喜欢 Webhook 这种主动式 Push 的方案,比 RSS、Cron 计划任务这些被动式 Pull 的方案简洁低碳环保,更具有即时性。主要是掌握主动的感觉让人觉得很爽。

下面开始介绍一下 Mastodon 利用 Webhook 同步嘟文到 Memos 的方法。我用的是 Shell Script 脚本,是一个很简单的脚本,只作了一些常识性的逻辑判断,可能不完美。用 Node.js、Python 等都可以实现。

已测试版本

Mastodon 需要自己的实例,或者具有管理员权限能创建 Webhook 的账号才能使用此方法。

安装工具

请在服务器上安装工具,若有报错,请根据错误日志安装其他对应工具

  • sudo apt install jq
  • sudo apt install lynx

Webhook 工具

Mastodon 前往 https://{INSTANCE}/admin/webhooks 创建一个 Webhook。 事件可以只选 status:created,回复和转嘟也都算此事件喔。 目的地 URL 就填自己部署的 Webhook 的链接,如:https://webhook.example.com/hooks/mastodon-sync-to-memos 宝塔的是:https://webhook.mybtserver.com:8888/hook?access_key=ACCESSKEY Mastodon 的 Webhook 目的地 URL 建议绑定域名,不然 Sidekiq 可能处理不了。

/assets/images/posts/2024/03/mastodon-webhook.png
/assets/images/posts/2024/03/mastodon-webhook.png

脚本内容

把下方的脚本内容保存到服务器上的一个 .sh 文件中,如当前用户的 Home 目录(~)的 ~/mastodon_sync_to_memos.sh 文件中,并配置以下内容,请注意替换:

  • MEMOS_HOST=""
  • MEMOS_ACCESS_TOKEN=""
  • MEMOS_VISIBILITY=""
  • MASTODON_INSTANCE=""
  • MASTODON_ID=""
  • SKIP_MASTODON_REPLY=
  • SKIP_MASTODON_REBLOG=
  • HOME_DIR=~
  • FILE_PATH=$HOME_DIR/.mastodon_memos_id.json

查找 Mastodon ID: https://INSTANCE/api/v1/accounts/lookup?acct=USERNAME

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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169

#!/bin/bash # 已测试版本: # Memos: v0.18.2 # Mastodon: v4.2.8 # ====================================================== # 配置开始 # Memos Host MEMOS_HOST="" # Memos Access Token MEMOS_ACCESS_TOKEN="" # 发布 Memos 的可见性 ('PUBLIC', 'PROTECTED', 'PRIVATE') 三选一 MEMOS_VISIBILITY=PUBLIC # Mastodon Instance MASTODON_INSTANCE="" # Mastodon ID, Find ID: https://INSTANCE/api/v1/accounts/lookup?acct=USERNAME MASTODON_ID="" # 跳过回复和转嘟 SKIP_MASTODON_REPLY=true SKIP_MASTODON_REBLOG=true # 获取当前用户的 Home 目录路径及保存 ID 的文件,保持默认,不用更改 HOME_DIR=~ FILE_PATH=$HOME_DIR/.mastodon_memos_id.json # 配置结束 # ====================================================== # 以下内容不用更改 # 检查 ID 文件是否存在 if [ ! -f "$FILE_PATH" ]; then # 如果文件不存在,则创建文件并写入 JSON 数据 echo ' { "latest_memos_id": "0", "latest_mastodon_id": "0", "bind": [] } ' > "$FILE_PATH" echo "Data file created: $FILE_PATH" else # 如果文件存在,则跳过并进行后续步骤 echo "Local data exist, skipping..." fi # 拼接 API 和 Token if [[ "$MEMOS_HOST" != */ ]]; then MEMOS_HOST="$MEMOS_HOST/" fi MEMOS_API_HOST="${MEMOS_HOST}api/v1/memo" AUTHORIZATION="Bearer ${MEMOS_ACCESS_TOKEN}" # Memos 获取最新的 Memos ID MEMOS_URL="${MEMOS_API_HOST}?creatorId=101&rowStatus=NORMAL&limit=1" LATEST_MEMOS_ID=$(curl --connect-timeout 60 -s $MEMOS_URL | jq -r '.[0].id') # Mastodon 的 API if [[ "$MASTODON_INSTANCE" != */ ]]; then MASTODON_INSTANCE="$MASTODON_INSTANCE/" fi CONTENT_URL="${MASTODON_INSTANCE}api/v1/accounts/${MASTODON_ID}/statuses?limit=1&exclude_replies=${SKIP_MASTODON_REPLY}&exclude_reblogs=${SKIP_MASTODON_REBLOG}" # Mastodon 最新 Status 的 ID LATEST_MASTODON_ID=$(curl --connect-timeout 60 -s $CONTENT_URL | jq -r '.[0].id') # 定义 LOCAL_MEMOS_ID 变量 LOCAL_MEMOS_ID=$(cat "$FILE_PATH" | jq -r '.latest_memos_id') LOCAL_MASTODON_ID=$(cat "$FILE_PATH" | jq -r '.latest_mastodon_id') # Webhook 触发时,判断 Mastodon 最新 ID 是否为暂存 ID,防止重复同步 if [ "$LATEST_MASTODON_ID" == "$LOCAL_MASTODON_ID" ]; then echo "Mastodon no updated, skipping..." echo "Skipped: $(TZ=UTC-8 date +"%Y-%m-%d"" ""%T")" echo "=============================" exit 0 fi CONTENT=$(curl --connect-timeout 60 -s $CONTENT_URL | jq -r '.[0]') MEDIA=$(echo $CONTENT | jq -r '.media_attachments') # 判断 Media 的内容 if [ "$MEDIA" != "null" ]; then MEDIAS=$(echo $CONTENT | jq -r '.media_attachments[] | select(.type=="image") | .url') # 拼接图片 images="" for url in $MEDIAS; do images="$images![image]($url)\n" done TEXT=$(echo "$CONTENT" | jq -r '.content' | lynx -dump -stdin -nonumbers -nolist | tr -d '\n' | sed '/^$/N;s/\n\n/\n/g' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | sed -E 's/ {2,}/ /g') TEXT="$TEXT\n$images" else # 普通内容 TEXT=$(echo "$CONTENT" | jq -r '.content' | lynx -dump -stdin -nonumbers -nolist | tr -d '\n' | sed '/^$/N;s/\n\n/\n/g' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | sed -E 's/ {2,}/ /g') fi # 判断内容是否为空 if [ -z "$TEXT" ] || [ "$TEXT" == "\\n" ]; then echo "Content is empty, skipping..." echo "Skipped: $(TZ=UTC-8 date +"%Y-%m-%d"" ""%T")" echo "=============================" exit 0 fi # 双引号转义 TEXT=$(echo "$TEXT" | sed 's/"/\\"/g') # Webhook 触发时,判断 Memos 最新 ID 是否为暂存 ID # 当 Memos 单方面有更新后,验证 Mastodon 和 Memos 的 ID 绑定关系(Todo) #if [ "$LATEST_MEMOS_ID" == "$LOCAL_MEMOS_ID" ]; then # echo "Memos no updated, skipping..." # echo "Skipped: $(TZ=UTC-8 date +"%Y-%m-%d"" ""%T")" # echo "=============================" # exit 0 #fi # 对比 Matodon 和 Memos 的 Content 内容的 MD5 值(不一定精确) # 后期尝试引入 GPT 对比内容 CONTENT_MEMOS=$(curl --connect-timeout 60 -s $MEMOS_URL | jq '.[0].content') CONTENT_MASTODON=$TEXT # 获取最新 Memos 的 MD5 LATEST_MEMOS_MD5=$(echo $CONTENT_MEMOS | tr -d '"' | md5sum | cut -d' ' -f1) # 获取最新 Mastodon 的 MD5 LATEST_TEXT_MD5=$(echo $TEXT | tr -d '"' | md5sum | cut -d' ' -f1) # 通过 MD5 判断内容是否重复 if [ "$LATEST_TEXT_MD5" == "$LATEST_MEMOS_MD5" ]; then echo "Content is duplicate, skipping..." echo "Skipped: $(TZ=UTC-8 date +"%Y-%m-%d"" ""%T")" echo "=============================" exit 0 fi # 替换 NeoDB 的评分 Emoji TEXT=$(echo "$TEXT" | sed "s/:star_empty:/🌑/g; s/:star_half:/🌗/g; s/:star_solid:/🌕/g") # 去掉最末尾的空行 TEXT=$(echo "$TEXT" | sed 's/\\n$//') # 发布 Memos 并获取返回的 JSON 数据 RESPONSE=$(curl -s -X POST \ -H "Accept: application/json" \ -H "Authorization: $AUTHORIZATION" \ -d "{ \"content\": \"$TEXT\", \"visibility\": \"$MEMOS_VISIBILITY\"}" \ $MEMOS_API_HOST) # 从返回的 JSON 数据中提取 Memos 的 id 值 NEW_MEMOS_ID=$(echo "$RESPONSE" | jq -r '.id') # 更新 JSON 文件中的 latest_memos_id 的值 jq ".latest_memos_id = \"$NEW_MEMOS_ID\"" "$FILE_PATH" > "${FILE_PATH}.tmp" && mv "${FILE_PATH}.tmp" "$FILE_PATH" # 更新 JSON 文件中的 latest_mastodon_id 的值 jq ".latest_mastodon_id = \"$LATEST_MASTODON_ID\"" "$FILE_PATH" > "${FILE_PATH}.tmp" && mv "${FILE_PATH}.tmp" "$FILE_PATH" # 更新 Mastodon 和 Memos 的 ID 的绑定关系,并确保 "bind" 中的数组保留唯一键,键也只有唯一值 jq ".bind += [{\"$LATEST_MASTODON_ID\": \"$NEW_MEMOS_ID\"}] | .bind = (.bind | unique)" "$FILE_PATH" > "${FILE_PATH}.tmp" && mv "${FILE_PATH}.tmp" "$FILE_PATH" echo "Sync Mastodon to Memos Successful!" echo "Done: $(TZ=UTC-8 date +"%Y-%m-%d"" ""%T")" echo "============================="

宝塔面板

宝塔面板如果用 Webhook 插件,可以直接把上面的脚本内容复制到 Webhook 插件的脚本中。不用另外在服务器中手动创建 .sh 文件。

/assets/images/posts/2024/03/bt-webhook.png
/assets/images/posts/2024/03/bt-webhook.png

JSON 数据文件内容

初次运行脚本,它会在当前用户的 Home 目录 ~ 新建一个文件 ~/.mastodon_memos_id.json 并初始化,后续此文件会记录 Mastodon ID 和 Memos ID 的绑定关系。如果不想在 Home 目录创建,就需要修改 HOME_DIR=FILE_PATH= 这两个参数。

1 2 3 4 5

{ "latest_memos_id": "", "latest_mastodon_id": "", "bind": [] }

生产环境产生数据后,示例:

1 2 3 4 5 6 7 8 9 10 11 12

{ "latest_memos_id": "6231", "latest_mastodon_id": "112061852482921394", "bind": [ { "112059053750743781": "6230" }, { "112061852482921394": "6231" } ] }

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-03-092,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Mastodon 同步到 Memos
不知道是我运气好还是不好,在我准备把 Memos 当成主力工具加入到我的工作流中的时候,遇上了 v0.19.0 的版本更新,这次版本更新带来了一系列大坑。除了 Memos 新版本的鲁棒性备受质疑,甚至连搭载它的服务器本身也被影响,我在 64G 内存的物理机上都跑不动它。就像网友所说,Memos 只像是一个练手的项目。果断弃之。Google Keep、Obsidian 这些工具哪里不好了吗?不把所有事务约束在一个工具里确实是麻烦了一点,但是 All in one 基本上也等于是 All in boom。 现在我对 Memos 的定位是用来备份我的 Mastodon(方式之一)。
eallion
2024/08/06
1570
Mastodon 同步到 Memos
shell脚本+webhook实现联动一键联动删除异常大小的文件
现通过简单的实践案例介绍shell脚本+webhook实现联动一键联动删除异常大小的文件
yuanfan2012
2024/07/29
2811
shell脚本+webhook实现联动一键联动删除异常大小的文件
Zabbix告警分析新革命:DeepSeek四大创新场景助力智能运维
【导读】⾯对⽇益复杂的IT环境,如何⾼效分析监控数据并快速响应已成为运维工作中的关键挑战。本文深入探讨了DeepSeek与Zabbix结合的创新性应用,包括一键式智能告警分析、Zabbix文档知识库助手功能以及钉钉告警增强功能。通过详尽的部署指南和实用脚本,展示了DeepSeek如何助力提升故障排查效率,为运维工程师与系统管理员提供高效解决方案。
Zabbix
2025/03/11
6560
Zabbix告警分析新革命:DeepSeek四大创新场景助力智能运维
使用rsync+nxlog同步+采集应用日志并接入到GrayLog5.1【优化篇】
在上一篇文章《业务服务器免装插件,使用rsync+nxlog同步+采集应用日志并接入到GrayLog5.1》中,使用rsync同步业务服务器日志文件有些异常日志文件过大,需要进行屏蔽处理
yuanfan2012
2023/06/23
5060
使用rsync+nxlog同步+采集应用日志并接入到GrayLog5.1【优化篇】
NeoDB API 创建观影页面
几个月之前在 长毛象联邦宇宙 里问过 NeoDB 官方有没有 API,得到肯定回答后,我就着手计划把观影页面的 API 搬到 NeoDB 了。前几天豆瓣的图片挂掉之后,加快了这一进程。 感谢豆瓣以前提供的无偿服务。不过这也印证了 SaaS 服务不可信 的观点。
eallion
2023/10/18
7080
NeoDB API 创建观影页面
k8s运维记 - 如何让部署到k8s的kong网关托管自定义静态资源?
使用kong作为目录/data/reports的静态资源服务器,为了测试,已于目录/data/reports下创建文件report.html,如下:
justmine
2019/10/16
2K0
k8s运维记 - 如何让部署到k8s的kong网关托管自定义静态资源?
shell脚本实现文件自动清理并推送钉钉机器人告警
当磁盘空间超过阈值时,这时需要人为去清理一些不需要的历史大日志文件,那能否做成自动化呢?
yuanfan2012
2024/03/21
2320
shell脚本实现文件自动清理并推送钉钉机器人告警
【实践】GrayLog4.2使用webhook成功推送日志告警到钉钉群机器人
发送POST请求到http://192.168.31.127:8080/hooks/push2dingtalk
yuanfan2012
2021/12/21
2.6K0
【实践】GrayLog4.2使用webhook成功推送日志告警到钉钉群机器人
Linux、docker、kubernetes、MySql、Shell、kafka运维快餐
lsof -i:[port] netstat -anp |grep [port]
justmine
2019/02/15
1.1K0
系统监控及钉钉机器人告警脚本
一、背景 当前不同的公司服务器较多,在项目开发、部署和演示过程多次遇到服务器无故宕机的情况,另外各服务器上部署的中间件也存在无故下线的情况,如果出现以上情况就特别棘手,而技术人员无法第一时间感知。
IT运维技术圈
2022/10/24
6320
发送钉钉消息 Shell 脚本
由于跑批任务大概在凌晨 2:15 分左右完成,故设置 2:20 开始检测,每 30 分钟(可调整)钉钉告警一次未获取到,之后一直检测,直到检测到文件生成。
叨叨软件测试
2020/06/16
1.9K0
使用ELK辅助监控开发测试环境服务质量和问题定位
ELK 是 elasticsearch + logstash + kibana的缩写。这一套是现在比较流行的日志全文索引系统了。我之前的项目也有用它来做过日志分析,这次主要是拿来搭建开发测试环境的监控和分析系统,顺带记录一下部署脚本和流程。
owent
2018/12/14
1.2K0
使用ELK辅助监控开发测试环境服务质量和问题定位
Memos API 调用渲染页面
*更新:已把 Memos 剥离出一个完整的应用,可独立部署,到 eallion/memos.top 这个仓库下载部署到网站根目录即可。 *HUGO:如果使用的是 Hugo 博客框架,可以参考本站的方法:layouts/_default/memos.html
eallion
2023/03/07
3.6K0
搭建k8s的开发调试环境
最近准备阅读一下k8s的源码,为了辅助理解代码运行逻辑,顺手搭一个k8s的开发调试环境,后面就可以结合断点调试掌握代码的运行脉络。
jeremyxu
2019/03/13
4.9K2
搭建k8s的开发调试环境
linux 下强大的 JSON 解析命令 jq
jq 可以对 JSON 数据进行切片、过滤、映射和转换,和sed, awk, grep 命令一样简单好用。
叨叨软件测试
2020/04/14
6.3K0
嘀咕(哔哔)Memos 简介
本文介绍了 Memos 的部署,数据导入,公告栏 API 调用,和 “ 嘀咕” 页面通过 API 渲染 Memos。
eallion
2022/12/20
2.9K0
嘀咕(哔哔)Memos 简介
代码持续自动发布 原
(adsbygoogle = window.adsbygoogle || []).push({});
阿dai学长
2019/05/10
6040
【shell脚本】Graylog服务状态异常监测与告警
之前有写过类似脚本 【优化篇】使用Keepalived实现简单的GrayLog高可用
yuanfan2012
2023/09/06
7060
【shell脚本】Graylog服务状态异常监测与告警
​Kubernetes 两步验证 - 使用 Serverless 实现动态准入控制
Admission 是在用户执行 kubectl 通过认证之后,在将资源持久化到 ETCD 之前的步骤,Kubernetes 为了将这部分逻辑解耦,通过调用 Webhook 的方式来实现用户自定义业务逻辑的补充。而以上过程,都是在用户执行 kuberctl 并等待 API Server 同步返回结果的生命周期内。
腾讯云 CODING
2020/07/01
1.3K0
​Kubernetes 两步验证 - 使用 Serverless 实现动态准入控制
Linkerd服务网格安装部署
Linkerd 是 Kubernetes 的一个完全开源的服务网格实现。它通过为你提供运行时调试、可观测性、可靠性和安全性,使运行服务更轻松、更安全,所有这些都不需要对你的代码进行任何更改。
王先森sec
2023/10/17
3980
Linkerd服务网格安装部署
推荐阅读
相关推荐
Mastodon 同步到 Memos
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档