Varia

... von Ihren Experten für eigentlich eh fast alles.


Blogposts tröten!

Wie ich Artikel dieses Blogs automatisch via Mastodon veröffentliche.

Inhalt

Den Versuch, eigene Artikel via RSS ins Fediverse zu tröten, habe ich abgebrochen. Besser geht das mit einem kleinen Skript bei Veröffentlichung. Damit lassen sich auch gleich andere Multiplikatoren wie Suchmaschinen benachrichtigen. Wordpress (WP) bietet dafür ein fertiges Plugin an. Doch was wenn ohne WP geschrieben wird? Tröts werden die Status-Nachrichten im sozialen Netzwerk »Mastodon« genannt – also in etwa das, was bei Twitter eine Tweet wäre. Damit lassen sich für das eigene Blog leicht neue Leser gewinnen.


Schreibe ich einen Artikel hier im Blog, bekamen bis heute meine Follower auf Mastodon davon nichts mit. Es sei denn, ich fabrizierte händisch einen Tröt in der Mastodon-App, ich welchen ich den Titel, die Zusammenfassung und die Tags hineinbastle – plus natürlich den Link zum Artikel. Aber das ist eines Menschen unwürdiges Mausgefummel.

Mein erster Gedanke war den ohnedies vorhandene RSS-Feed des Blogs automatisiert auszulesen und dann über die REST-API von Mastodon einen Tröt zu generieren. Das wollte ich mit einem Shell-Script machen – so einfach hatte ich mir das vorgestellt. Übersehen hatte ich, dass RSS bei den meisten Blogs den gesamten Bestand an Artikeln widerspiegelt. Artikel, die ich schon gesehen habe, versteckt mein RSS-Reader vor mir. Er merkt sich, was alt und was neu ist. Diese Logik müsste ich also erst einmal schreiben und dafür ist ein Shell-Script nicht wirklich ideal.

Tools wie die beiden Python-Projekte feediverse und feed2toot scheinen auf den ersten Blick geeignet. Ersteres, feediverse ist das schlankere und kommt ohne Datenbank aus. Es merkt sich das Datum der letzten Abfrage und verhindert so, alte Artikel immer wieder zu tröten. Mir erschien das etwas riskant. Weiters störte mich, dass ich die Sprache des Tröts nicht einstellen konnte. Das etwas mächtigere feed2toot war mir unheimlich, weil sich die Autorisierung in Mastodon nur über ein vom Hersteller mitgeliefertes Skript einstellen lässt. Ich weiß dann nicht, welche Rechte diese App sich geben hat lassen. Auch, dass ich das Passwort – wenn auch nur einmalig – diesem Skript geben soll, passt mir nicht wirklich.

Darüberhinaus gibt es zumindest eine Webseite https://mastofeed.org , bei der ich mittels GUI beliebige RSS-Feeds mir liefern und tröten lassen kann. Die habe ich gar nicht erst ausprobiert, denn klarer Weise könnte diese Website irgendwas in meinem Namen publizieren. Das geht mit einem seriöse Auftritt nicht zusammen.

Killer-Feature Tagline

Was mir aber vor allem gefehlt hat: Ich kann mit keinem der bisher erwähnten Werkzeuge die Tags des Blogposts in den Tröt schreiben, weil der RSS-Feed diese nicht mitliefert. Was schon möglich ist, einen oder auch mehrere den gesamten Feed beschreibende Hashtags zu zu tröten. Bei einem monothematischen Blog mag das ausreichen.

    <item>
      <title>Die Tricks mit den Studien</title>
      <link>https://ingo.lantschner.name/post/2022-04-02-tricks-mit-studien/</link>
      <pubDate>Fri, 08 Apr 2022 00:00:00 +0000</pubDate>
      
      <guid>https://ingo.lantschner.name/post/2022-04-02-tricks-mit-studien/</guid>
      <description>Am Beispiel „Ivermectin“: Klinischen Studien lesen und einordnen.</description>
    </item>

Typische Angaben in einem RSS-Feed – Tags suchen wir vergeblich.

Hashtags sind aber das um und auf, um im Fediverse gefunden und gelesen zu werden. Tröts ohne Hashtags werden fast nur in der Blase der eigenen Follower ventiliert und verlieren so an Reichweite und Bedeutung.


Ich musste daher vollkommen umdenken und bin nunmehr der Ansicht, dass bei einem Blog der Ankündigungs-Tröt Teil des Veröffentlichen-Prozesses sein sollte. Wordpress bietet dafür schon ein Plugin an, das eben auch Tags veröffentlichen kann. 🌐 Mastodon Autopost

Ich verwende Hugo und dafür gibt es noch keine fertige Lösung. Daher hab ich ein kleines Perl-Skript geschrieben, welches diese Aufgabe übernimmt. Selbstverständlich ist dies auch in jeder anderen Programmier- oder Skriptsprache möglich, selbst ein Shell-Script sollte das können. Mensch nehme einfach jene Sprache, die ihm am leichtesten von der Hand geht.

Zwei Fliegen mit einer Klappe

Dieses von mir in Perl geschrieben Master-Script liest den Quelltext des zu veröffentlichenden Posts. Die Hugo-Posts werden in Markdown geschrieben mit einem TOML-Absatz als Frontmatter. In genau diesem befinden sich die relevanten Angaben wie Titel, Zusammenfassung und Tags.

+++
draft = false
author = "Ingo Lantschner, Dr. med. Lisbeth Eischer"
date = "2022-04-08"
hidereadtime = false
hasMath = false
title = "Die Tricks mit den Studien"
subtitle = "Am Beispiel „Ivermectin“: Klinischen Studien lesen und einordnen."
summary = "Am Beispiel „Ivermectin“: Klinischen Studien lesen und einordnen."
toc = true
categories = ["Gesellschaftspolitik" ]
tags = [ "COVID-19", "Fakten", "Wissenschaft" ]
+++

Frontmatter eines Hugo-Posts im TOML-Format.

Damit lassen sich nun nicht nur automatisierte Tröts ins Fediverse versenden, sondern auch Suchmaschinen indizieren → Indexnow oder anderes automatisiert erledigen. Für jede dieser Aufgaben hab ich ein kleines Shell-Script geschrieben, das die jeweilige Aufgaben ausführt und dafür vom Master-Script mit den nötigen Daten aufgerufen wird. So kann ich eine zuvor auf der Kommandozeile getestetes curl-Kommando direkt in ein Shell-Script einfügen, damit nochmals weiter testen und wenn alles funktioniert den Aufruf in das Master-Script einbinden.

Wer genau schaut, findet im Perl-Code auch eine Zeile, welche das Frontmatter des Blogposts auf TODOs absucht und die Ankündigung abbricht, wenn eines gefunden wurde.

#!/usr/local/bin/perl -w
use warnings;
use strict;
use feature ":5.10";
use autodie;

use Data::Dumper;
use File::Slurp;

=pod

=encoding utf8

=head1 NAME

announce.pl - announce one blogpost to several services

=head1 SYNOPSIS

perl announce.pl posts-filename

e.g. 

    $ ./announce.pl content/post/2023-01-13-gender-petition/

=cut

my $DRYRUN = 0; # do not act but print what would be done

my $path = $ARGV[0] // die "missing path to blogpost\n";

my ($post_name, $content_type);
if ( lc $path =~ m|^content/([a-z0-9-]+)/([a-z0-9-]+)/$|i ) {
    $content_type = $1;
    $post_name = $2;
} else {
    die "invalid input file name  or path\n"
}

my $url="https://ingo.lantschner.name/$content_type/${post_name}/";
my $http_code = qx{curl "$url" -w "%{http_code}" -s -o /dev/null };
die "STOP – HTTP resultcode $http_code for $url is not 200!\n" if $http_code != 200 ;

# parse content of file (TOML frontmatter)

my @content = read_file("$path/index.md", chomp => 1);
my ($title, $tagline, $summary);

# TOML-frontmatter sections are enclosed by lines with +++
my $fm_enclose = qr{^\+\+\+};
my $is_frontmatter = 0;
foreach (@content) {
    $is_frontmatter++ if /$fm_enclose/; # begining frontmatter enclouser
    next if not $is_frontmatter;
    last if $is_frontmatter > 1; # ending frontmatter enclouser
    $title   = $1 if /^title\s*=\s*"(.+)"/;
    $tagline = $1 if /^tags\s*=\s*(.+)/;
    $summary = $1 if /^summary\s*=\s*"(.+)"/;
    die "STOP - found TODO in frontmatter!\n" if /TODO/;
}

# parse (cleanup) tags into an array
$tagline =~ s/\[//g;
$tagline =~ s/\]//g;
$tagline =~ s/\s+//g;
$tagline =~ s/\"//g;
my @tags = split /,/, $tagline;

if ($DRYRUN) {
    say "URL: $url";
    say "TITLE: $title";
    say "SUMMARY: $summary";
    say "TAGS:\n" . Dumper (@tags);
    
    exit 1;
}

# indexnow
my $r = `/bin/bash announce/indexnow.sh $url`;
say "ERROR in indexnow.sh – HTTP resultcode $r does not match 200!" if $r != 200 ;

# troet
my $message="$title\n\n$summary\n$url\n\n";
$message .= "#$_ " foreach (@tags);
system ('/bin/bash', 'announce/troet.sh', $message) == 0 or say "ERROR in troet.sh: $!";

__END__

Perl-Code des Master-Skripts. Anmerkung zum »TOML-Parsing«: Ich hätte natürlich auch ein TOML-Modul nehmen können.

Shell-Scripts

Diese zwei Shell-Scripts werden vom Master-Skript aufgerufen.

indexnow.sh

#!/bin/sh
url=$1
key='********************'
curl "https://api.indexnow.org/indexnow?url=$url&key=$key" -w "%{http_code}\n" -s

troet.sh

#!/bin/sh
message=$1
token="********************"
curl https://troet.fediverse.at/api/v1/statuses -H "Authorization: Bearer $token" -F "status=$message" -F 'language=de' -F 'visibility=public' -o /dev/null -s


Mastodon Account konfigurieren

Damit das troet-Skript in meinem Namen tröten darf, muss ich es am Mastodon-Server entsprechend berechtigen. In den Einstellungen meines Mastodon-Kontos lege ich bei Entwicklung eine Neue Anwendung an. Als Berechtigung wird nur write:statuses benötig! Den Zugangs-Token kopiere ich dann ins tröt.sh. Ab jetzt ist das Skript scharf geschalten – also vielleicht am Anfang besser mit einem Test-Account laufen lassen, dem niemand folgt. Oder die visibility in troet.sh auf private umstellen.

Danksagungen

Danke an Cymaphore für die Erklärung der Konfiguration seines orf.at-Bots – das war ein sehr hilfreicher Einstieg in das Thema!


Texttrenner

Weitere Artikel aus der
Kategorie Medien

»Digital Detox« mit dem Fediverse
Das Fediverse macht uns ein maßgeschneidertes Angebot für die digitale Entgiftungskur: Soziale Medien ohne Suchtgefahr.

Finger weg von Facebook & Co!
Warum wir als Demokraten auf zentralisierten sozialen Medien nichts (mehr) verloren haben.

Alles in Butter?
Laut ORF wirken soziale Medien sich gar nicht auf's reale Leben aus.

Ein Forum für das Strombad
Foren bieten eine interessante Alternative zu den zentralisierten, kommerziell getriebenen »Sozialen Medien«.