banner
老孙

老孙博客

资深网民孙先生
mastodon
email

Automatically sync Mastodon to Memos using webhooks.

Preface#

In order to synchronize content more conveniently and for backup purposes.

Declaration#

The code and functionality are derived from @大大的蜗牛. The principle is to use a webhook. When publishing content, the script is triggered to run.

Steps#

Synchronization Script#

In the script, API_HOST is the API for memos, AUTHORIZATION is the Token for memos, and 111363033003475492 in CONTENT_URL is the ID of the user on mastodon. The method to obtain the user ID can be found in

#!/bin/sh

# API and Token
API_HOST="https://memos.ee/api/v1/memo"
AUTHORIZATION="Bearer eyJhbGciOiJIUzI1NiIsImtpZCI6InYxIiwidHlwIjoiSldUIn0.eyJuYW1lIjoiamtqb3kiLCJpc3MiOiJtZW1vcyIsInN1YiI6IjEiLCJhdWQiOlsidXNlci5hY2Nlc3MtdG9rZW4iXSwiaWF0IjoxNjk3ODc0NTk2fQ.jNGMDE1YVX4Qj6hNhmrxb63WlRM5kGX10k_qRXH6ID4"

# Original content
CONTENT_URL="https://09j.cn/api/v1/accounts/111363033003475492/statuses?limit=1"
CONTENT=$(curl --connect-timeout 60 -s $CONTENT_URL | jq -r '.[0]')
# mastodon
MASTODON_URL=$(echo $CONTENT | grep -oP 'https:\/\/09j\.cn\/@[^\/]+\/\d+')
DUDU_CONTENT="[Automatically forwarded from my Mastodon]($MASTODON_URL)"

MENTIONS=$(echo $CONTENT | jq -r '.mentions[]')
if [ ! -z "$MENTIONS" ]; then
  echo "Skipping status mention! $(TZ=UTC-8 date +"%Y-%m-%d"" ""%T")"
  echo ======================================================
  exit 0
fi

MEDIA=$(echo $CONTENT | jq -r '.media_attachments')
# Determine the content of Media
if [ "$MEDIA" != "null" ]; then
  MEDIAS=$(echo $CONTENT | jq -r '.media_attachments[] | select(.type=="image") | .url')
  # Concatenate images
  images=""
  for url in $MEDIAS; do
    images="$images![image]($url)\n"
  done
  TEXT=$(echo "$CONTENT" | 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:]]*$//')
  TEXT="$TEXT\n$DUDU_CONTENT"
  TEXT="$TEXT\n$images"

else
   # Normal content
  TEXT=$(echo "$CONTENT" | 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:]]*$//')
  TEXT="${TEXT}\n$DUDU_CONTENT"
fi

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 ======================================================

I made some modifications. When publishing to memos, I also attach the original mastodon link. Since I don't know how to write rules, I randomly wrote a matching rule. My instance is 09j.cn. Delete the following if not needed:

MASTODON_URL=$(echo $CONTENT | grep -oP 'https:\/\/09j\.cn\/@[^\/]+\/\d+')
DUDU_CONTENT="[Automatically forwarded from my Mastodon]($MASTODON_URL)" 
TEXT="$TEXT\n$DUDU_CONTENT"

to

Deploy Webhook#

The Docker image adds Chinese support based on the official Dockerfile.

It is recommended to deploy using docker-compose. Edit the contents of docker-compose.yaml to:

services:
  webhook:
    image: jkjoy/webhook
    container_name: webhook
    command: -verbose -hooks=hooks.yml -hotreload
    environment:
      - TZ=Asia/Chongqing # China time zone
      - LANG=C.UTF-8  # Chinese support
    volumes:
      - ./config:/config:ro
    ports:
      - 9000:9000
    restart: always

Create a config directory in the root directory and create a hooks.yml file in the config directory and edit the contents to:

- id: memos
  execute-command: "/config/memos.sh"
  command-working-directory: "/"

Save the script content as memos.sh in the config directory.

Then, in the root directory where docker-compose.yaml is located, run docker compose up -d.

Using Webhook#

hooks.yaml is the configuration for the webhook.

The execute-command is the executable script.

The format of the webhook access address is:

Server IP:Port/hooks/ID

For example, using 127.0.0.1, access http://127.0.0.1:9000/hooks/memos.

Setting up Mastodon#

In the admin backend, go to Admin-Webhooks-Add Endpoint, fill in the Endpoint URL as http://127.0.0.1:9000/hooks/memos, select status.created for Enabled Events, and click Add. This will synchronize the content to memos when publishing a new toot.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.