sfeed_mastodon/sfeed_mastodon

167 lines
4.9 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/sh
#―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
# Name: sfeed_mastodon
# Desc: Post feed data from sfeed to the fediverse.
# Reqs: curl, xargs
# Date: 2023-11-16
# Lisc: GPLv3
# Auth: @jadedctrl@jam.xwx.moe
#―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
# Print a friendly usage message.
usage() {
echo "usage: $(basename $0) [-h] [-a FEDI_AUTH] SERVER_URL"
echo "Posts sfeed(1) feed data from stdin to Mastodon-compatible servers."
echo ""
echo " -h print this message and exit"
echo " -a the authorization token for your account"
echo " -s the scope for posts, one of: public/unlisted/private/direct"
echo " -t template for post contents"
echo ""
echo "To find your authorization token, you can snoop through request headers in"
echo "your web-browser. In Firefox, this can be done through:"
echo ' Developer Tools (F12) → Network → Headers'
echo 'Look for your $FEDI_AUTH value in the Authorization header like so:'
echo ' Authorization: Bearer $FEDI_AUTH'
echo 'Either place this value in your $FEDI_AUTH environment variable, or pass it'
echo "with -a."
echo ""
echo "The template (-t) is an HTML value for this scripts post format."
echo "Post-related variables go within {{double-braces}}, and the following"
echo "variables are recognized: title, url, desc, desc_short, unix_date."
echo "By default, the template used is:"
echo " <b>{{title}}</b><br>{{url}}<br><br><blockquote>{{desc_short}}</blockquote>"
}
# Deescape a URL-escaped string (percent-encoded), passed over stdin.
url_deescape() {
sed 's@+@ @g;s@%@\\x@g' \
| xargs -0 printf "%b"
}
# Takes a posts contents and create the corresponding client-API JSON.
post_json() {
local message_text="$1"
printf '{ "content_type": "text/html", "visibility": "%s",' "$FEDI_SCOPE"
printf '"status": "%s" }\n' "$message_text"
}
# Post a status with HTML content to the given Mastodon-compatible server.
post_status() {
local server="$1"
local auth_token="$2"
local message_text="$3"
curl --request POST \
--header "Authorization: Bearer $auth_token" \
--header "Content-Type: application/json" \
--data "$(post_json "$message_text" | tr -d '\n')" \
"${server}/api/v1/statuses"
}
# Print an sfeed post line as per $TEMPLATE, with the following variables:
# {{title}}, {{unix_date}}, {{url}}, {{desc}}, {{desc_short}}
sfeed_post_text() {
local sfeed_line="$1"
local unix_date="$(echo "$line" | awk --field-separator '\t' '{print $1}')"
local title="$(echo "$line" | awk --field-separator '\t' '{print $2}')"
local url="$(echo "$line" | awk --field-separator '\t' '{print $3}' | url_deescape)"
local desc="$(echo "$line" | awk --field-separator '\t' '{print $4}')"
local desc_short="$(echo "$desc" | head -c250)"
# Show that the description was truncated.
if test "$(echo "$desc_short" | wc -c)" -gt 250; then
desc_short="$desc_short […]"
fi
if test -z "$title"; then
title="$url"
fi
# If there is nothing to post, then dont stdout anything.
if test -z "$url"; then
return
fi
printf "$TEMPLATE" \
| tr -d '|' \
| sed "s|{{title}}|$title|g" \
| sed "s|{{unix_date}}|$unix_date|g" \
| sed "s|{{url}}|$url|g" \
| sed "s|{{desc}}|$desc|g" \
| sed "s|{{desc_short}}|$desc_short|g" \
| sed 's|\\n||g' \
| sed 's|"|\\"|g' \
| tr -d ' \n'
}
# Post an sfeed feed entry, by line, to a Mastodon-compatible fedi server.
post_sfeed_line() {
local server="$1"
local auth="$2"
local line="$3"
local message_text="$(sfeed_post_text "$line")"
if test -n "$line" -a -n "$message_text"; then
post_status "$server" "$auth" "$message_text"
fi
}
TEMPLATE='<b>{{title}}</b><br>{{url}}<br><br><blockquote>{{desc_short}}</blockquote>'
while getopts 'ha:t:' arg; do
case $arg in
h)
usage
exit 0
;;
s)
FEDI_SCOPE="$OPTARG"
;;
a)
FEDI_AUTH="$OPTARG"
;;
t)
TEMPLATE="$OPTARG"
;;
esac
done
shift $((OPTIND-1))
SERVER_URL="$1"
if test -z "$FEDI_AUTH"; then
1>&2 echo 'You need to set the environment variable $FEDI_AUTH!'
1>&2 echo 'You can find your auth key by examining the "Authentication: Bearer" header'
1>&2 echo "used in requests by your server's web-client."
1>&2 echo 'In Firefox, F12→Network.'
1>&2 echo ""
exit 2
fi
if test -z "$SERVER_URL"; then
1>&2 echo "No server specified!"
1>&2 echo "Make sure to provide a server base URL (like https://fedi.server) as the last argument."
1>&2 echo ""
1>&2 usage
exit 3
fi
if test -z "$FEDI_SCOPE"; then
FEDI_SCOPE="public"
fi
IFS="
"
while read -r line; do
post_sfeed_line "$SERVER_URL" "$FEDI_AUTH" "$line"
done