Read it Later - Sende Artikel aus Newsboat direkt an Wallabag
Newsboat kann über die API Artikel direkt an Wallabag senden. Dort können die Beiträge bequem und übersichtlich verwaltet und mit den entsprechenden Apps auf allen Endgeräten gelesen werden.
In Newsboat werden wie gewohnt alle Feeds abgerufen und entsprechend den eigenen Vorlieben verwaltet. Bei der Speicherung als Bookmark 🔖 wird ein Shell Skript verwendet, dass die Weiterleitung der Artikel-URL an Wallabag übernimmt. Dabei werden die Zugangsdaten mit dem eigenen GPG-Schlüssel ver- und entschlüssel, welcher vorzugweise auf einem YubiKey oder Nitrokey hinterlegt ist und anschließend über OAuth2 an Wallabag gesendet wird.
Der Prozess sieht kurz zusammengefasst so aus:
Newsboat ----> & / Nitrokey ----> OAuth2 ----> Wallabag
Alle Newsboat Beiträge
- The Newsboat RSS Feedreader - RSS-Reader für die CLI
- YouTube-Channels in Newsboat abonnieren - So geht’s mit RSS-Feeds
- Moonlander Mark I - Eine Reise zum Mond!
- iTerm2-Profile für Newsboat mit Shortcut starten
- Newsboat kann RSS Feed von Wallabag abrufen
- Read it Later - Sende Artikel aus Newsboat direkt an Wallabag
Wie funktionierts?
- Newsboat ist der RSS Reader der die Beiträge abruft und auf der CLI darstellt. Es können für unterschiedliche Themengebiete mehrere Newsboat-Instanzen genutzt werden.
- In Newsboat werden Lesezeichen mit Strg + b gespeichert (👉 zum Beitrag )
- Lesezeichen werden fortlaufend in eine Markdown-Datei geschrieben.
- Lesezeichen werden fortlaufenden in eine txt-Datei geschrieben.
- Lesezeichen werden an Wallabag geschickt und dort als ungelesener Artikel mit Schlagwort angezeigt.
Das ganze hört sich simpel an, erfordert jedoch ein wenig Vorbereitung und Konfiguration, da eine Anbindung über OAuth2 erfolgt.
Was ist OAuth und was macht das?
OAuth21 stellt zwei unterschiedliche Tokens zur Verfügung
access_token, dieser erlaubt einen Zugriff auf Wallabag. Er hat jedoch ein Ablaufdatum von 3600 Sekunden, dann verliert er seine Gültigkeit. Eine regelmäßige Aktualisierung (= refresh) ist notwendig.referesh_token, mit diesem Token kann man denaccess_tokenwieder aktivieren und einen Zugriff auf Wallabag erhalten.
Zusätzlich zu den Token werden
client-idclient-secret
benötigt.
Login Credentials und Tokens mit GnuPG schützen
Die Login Credentials und die Token sind wichtige Daten, die nicht ungeschützt abgespeichert werden sollten.
Deshalb werden diese Informationen in einder json-Datei abgespeichert und mit dem eigenen GPG-Schlüssel verschlüsselt.
Wallabag
Wallabag nutzt OAuth2 um Anwendungen, also dem Skript zur Lesezeichenspeicherung, eine sichere Möglichkeit der Anmeldung zu bieten.
Wallabag-Backup anlegen
Ein Backup im JASON-Format aller Inhalte sollte für den Notfall erstellt und heruntergeladen werden.
Client hinzufügen
Wallabag bietet die Möglichkeit über OAuth2 2 einen Token abzurufen. Mit diesem lässt sich die API steuern.
Damit man die API nutzen kann, ist ein Client anzulegen. Dadurch erhält man die beiden Credentials Client-ID und Client-Secret die für die nachfolgenden Befehle benötigt werden.
Client anlegen
Client anlegen
Client-ID und Client-Secret werden angezeigt
Token - Anfordern - 1. Versuch
Zum Anfordern des Tokens ist ein Befehl über ein Terminal an die Wallabag-API zu senden. Die folgenden Zeilen sind anzupassen.
wallabag.example.com= durch die eigene URL ersetzenclient_id= Client-IDclient_secret= Client-Secretusername= Wallabag-Benutzerpassword= Passwort des Wallabag-Benutzers
In einem Terminal gibt man den angepassten Befehl ein. Auf meinem Apple-Rechner verwende ich dafür iTerm2.
http POST https://wallabag.example.com/oauth/v2/token \
grant_type=password \
client_id=11_xxxxxxxxxxxxx \
client_secret=lyyyyyyyyyyyy \
username=wallabag \
password=passwordpassword
zsh: command not found: http
Der Fehler zsh: command not found: http ist nicht wirklich aussagekräftig. Es besagt aber, dass zsh keine Verbindung zur eigenen Wallabag-Installation herstellen kann, um den Token abzurufen.
httpie installieren
Abhilfe schafft die Installation des Tools httpie, das mithilfe von Homebrew geholt werden kann:3
brew install httpie
Token - Anfordern - 2. Versuch
http POST https://wallabag.example.com/oauth/v2/token \
grant_type=password \
client_id=11_xxxxxxxxxxxxx \
client_secret=lyyyyyyyyyyyy \
username=wallabag \
password=passwordpassword
Die Verbindung zu Wallabag war erfolgreich. Neben einigen Metadaten werden auch die Tokens angezeigt.
HTTP/1.1 200 OK
Cache-Control: no-store, private
Connection: keep-alive
Content-Encoding: gzip
Content-Type: application/json
Date: Thu, 09 Oct 2025 19:01:29 GMT
Keep-Alive: timeout=20
Pragma: no-cache
Server: nginx
Transfer-Encoding: chunked
Vary: Accept-Encoding
{
"access_token": "accesstoken-accesstoken-accesstoken-accesstoken-accesstoken-accesstoken",
"expires_in": 3600,
"refresh_token": "refresh-token-refresh-token-refresh-token-refresh-token-refresh-token",
"scope": null,
"token_type": "bearer"
}
Artikel an Wallabag senden mit cURL
Eine URL kann man damit direkt über die CLI mit cURL an Wallabag senden. Es wird dafür der access_token benötigt. Die Wallabag API-Dokumentation gibt Aufschluss über die verfügbaren Endpoints.
curl -X POST https://wallabag.example.com/api/entries.json \
-H "Authorization: Bearer accesstoken-accesstoken-accesstoken-accesstoken-accesstoken-accesstoken" \
-H "Content-Type: application/json" \
-d '{"url":"https://strobelstefan.de/blog/2025/04/13/the_newsboat_rss_feedreader_-_rss-reader_f%C3%BCr_die_cli.html?h=newsboat"}'
Möchte man mehr Informationen mitgeben, dann lässt sich der cURL-Befehl erweitern:
curl -X POST https://wallabag.example.com/api/entries.json \
-H "Authorization: Bearer accesstoken-accesstoken-accesstoken-accesstoken-accesstoken-accesstoken" \
-H "Content-Type: application/json" \
-d '{
"url": "https://strobelstefan.de/blog/2025/04/13/the_newsboat_rss_feedreader_-_rss-reader_f%C3%BCr_die_cli.html?h=newsboat",
"tags": "RSS,Newsboat,Software",
"starred": 1,
"archive": 0
}'
Der Artikel erscheint sofort in Wallabag.
Artikel in Wallabag
Artikel aus Newsboat an Wallabag
Das Senden des Artikels von der CLI an Wallabag funktioniert. Nun kann der Artikel direkt aus Newsboat heraus gesendet werden.
Dafür wird das Shell Script bookmark.sh aus dem Artikel 👉 The Newsboat RSS Feedreader -RSS-Reader für die CLI verwendet und ein wenig erweitert.
Die gekennzeichneten Zeilen sind anzupassen.
#!/usr/bin/env bash
url="$1"
title="$2"
description="$3"
feed_title="$4"
date_time=$(date "+%Y-%m-%d") # Get only the current date
# Bookmark files
bookmarks_file_md="$HOME/newsboat-bookmarks/bookmarks-finance.md"
# bookmarks.txt - relevant if you wanna convert article to PDF file
bookmarks_file_txt="$HOME/newsboat-bookmarks/bookmarks-finance.txt"
# Check if the last entry in the file already has today's date
last_date=$(tail -n 1 $bookmarks_file_md | cut -d' ' -f2)
# If the last date in the file is different from today's date, add today's date as a header
if [[ "$last_date" != "$date_time" ]]; then
echo "## Date: ${date_time}" >> $bookmarks_file_md
fi
# Add the feed details
echo "- ***${feed_title}***; [${title}](${url}); ${date_time}; 📝 ${description}" >> $bookmarks_file_md
# If the last date in the file is different from today's date, add today's date as a header
if [[ "$last_date" != "$date_time" ]]; then
echo "Date: ${date_time}" >> $bookmarks_file_txt
fi
# Add the feed details
echo "- ${feed_title}; ${title}; ${url}; 📝 ${description}; ${date_time}" >> $bookmarks_file_txt
#url title description feed_title
# Send article from Newsboat to Wallabag
curl -X POST https://wallabag.example.com/api/entries.json \
-H "Authorization: Bearer accesstoken-accesstoken-accesstoken-accesstoken-accesstoken-accesstoken" \
-H "Content-Type: application/json" \
-d '{
"url": "'"${url}"'",
"tags": "Newsboat",
"starred": 1,
"archive": 0
}'
exit 0
Die Datei enthält den Access Token, der einen Zugriff auf Wallabag ermöglicht.
Das Problem 🚨, der access_token Token hat nur eine Gültigkeit von 3600 Sekunden. Danach muss es wieder mit dem Refresh Token erneuert werden.
wallabag_token.json.gpg
Benutzername, Passwort und die Tokens sind besonders sensibel und werden geschützt. Die Datei wallabag_token.json wird mit dem eigenen GPG Default Key verschlüsselt.
gpg --encrypt --default-recipient-self --output ~/.newsboat/wallabag_token.json.gpg
# oder mit der direkten Nennung des GPG-Schlüssel
gpg --encrypt --recipient <Schlüssel-ID> ~/.newsboat/wallabag_token.json
# oder mit der direkten Nennung der E-Mail-Adresse
gpg --encrypt --recipient mail@example.com ~/.newsboat/wallabag_token.json
Es wird die Datei wallabag_token.json.gpg erstellt und alle sensiblen Informationen sind ab sofort mit dem GPG-Schlüssel abgesperrt.
Die Verwendung eines Hardwaretoken, wie dem YubiKey oder Nitrokey, macht den ganzen Prozess der Ver- und Entschlüsselung sehr einfach und komfortable. Hier im Blog gib es umfangreiche Anleitungen zum Einrichten und Konfigurieren von YubiKeys und Nitrokeys.
YubiKey Themenseite
Hier geht es zur 👉 YubiKey Themenseite, dort findest du noch mehr Beiträge rund um den YubiKey.
GPG Default Key
Der Standardschlüssel wird in der Datei ~/.gnupg.gpg.conf in der Zeile default-key global festgelegt.
Die Abfrage des Standardschlüssels erfolgt mit.
echo "test" | gpg --sign --verbose
Im Skript wird der Schlüssel expliziet angegeben. Soll immer der globale Standardschlüssel verwendet werden, dann sind die enstprechenden Zeilen aus dem Code zu entfernen.
Gib mir gerne einen Kaffee ☕ aus 😀
Gib mir gerne einen Kaffee ☕ aus !
Wenn dir meine Beiträge gefallen und geholfen haben, dann kannst du mir gerne einen Kaffee ☕️ ausgeben.
Das fertige Skript
Es werden zwei Skripte angelegt:
bookmark.sh, das bereits verwendet wird. Im Skript sind ein paar kleine Anpassungen vorzunehmen. ( 👉 The Newsboat RSS Feedreader - RSS-Reader für die CLI)wallabag_token.json.gpg= verschlüsselte Datei mitclient_id,client_secret,access_tokenundreferesh_token.
Alle Dateien werden direkt im Verzeichnis ~/.newsboat/ abgespeichert.
In der Newsboat-Konfigurationsdatei ist die Zeile bookmark-cmd einzufügen. Der Pfad muss auf die Datei bookmark.sh verweisen.
bookmark-cmd "$HOME/.newsboat/bookmark.sh"
bookmark.sh
#!/usr/bin/env bash
# Created by https://www.strobelstefan.de
# Hosted on https://codeberg.org/sst/
# If you like this script, feel free to buy me a coffee.
# PayPal https://www.paypal.com/donate?hosted_button_id=BNV5XKAAXK6TJ
# Bitcoin - bc1qfuz93hw2fhdvfuxf6mlxlk8zdadvnktppkzqzj
#####################
# Newsboat variables
#####################
# The values for the variables get populated directly from Newsboat.
# Therfor it is necessary to call this script from the Newsboat config file.
url="$1"
title="$2"
description="$3"
feed_title="$4"
date_time=$(date "+%Y-%m-%d") # Get only the current date
#####################
# Bookmarks variables
#####################
# Bookmark Markdown file
bookmarks_file_md="$HOME/newsboat-bookmarks/bookmarks.md"
# Bookmark TXT file - relevnat if you wanna convert article to PDF file
bookmarks_file_txt="$HOME/newsboat-bookmarks/bookmarks.txt"
#####################
# Wallabag variables
#####################
# Wallabag URL
wallabag_url="https://wallabag.example.com"
# Standard tag for Wallabag
tags="it,tag2,tag3"
#####################
# GPG variables
#####################
# Your GPG key ID (replace with your actual key ID)
gpg_key_id="<Schlüssel-ID>"
# Encrypt your file
# gpg --encrypt --default-recipient-self --output ~/.newsboat/wallabag_token.json
# gpg --encrypt --recipient mail@example ~/.newsboat/wallabag_token.json
# gpg --encrypt --recipient key-id ~/.newsboat/wallabag_token.json
# Encrypted file containing the tokens (path to your encrypted token file)
encrypted_file="$HOME/.newsboat/wallabag_token.json.gpg"
#Log File
response_body_txt="$HOME/.newsboat/response_body.txt"
###################################
# Newsboat Bookmarking
###################################
# See Newsboat documentation for more details
# https://newsboat.org/releases/2.41/docs/newsboat.html#_bookmarking
# Check if the last entry in the file already has today's date
last_date=$(tail -n 1 $bookmarks_file_md | cut -d' ' -f2)
# Markdown file
# If the last date in the file is different from today's date, add today's date as a header
if [[ "$last_date" != "$date_time" ]]; then
echo "## Date: ${date_time}" >> $bookmarks_file_md
fi
# Add feed details
echo "- ***${feed_title}***; [${title}](${url}); ${date_time}; 📝 ${description}" >> $bookmarks_file_md
# TXT file
# If the last date in the file is different from today's date, add today's date as a header
if [[ "$last_date" != "$date_time" ]]; then
echo "Date: ${date_time}" >> $bookmarks_file_txt
fi
# Add the feed details
echo "- ${feed_title}; ${title}; ${url}; 📝 ${description}; ${date_time}" >> $bookmarks_file_txt
###################################
# Send article from Newsboat to Wallabag
###################################
set -euo pipefail
#####################
# Variables
#####################
backup_file="wallabag_token.gpg.bak"
response_body_txt=$(mktemp)
# Backup original encrypted token
cp "$encrypted_file" "$backup_file"
echo "Backup created: $backup_file"
# Decrypt token file
decrypted_data=$(gpg --decrypt --recipient "$gpg_key_id" "$encrypted_file" 2>/dev/null)
if [ -z "$decrypted_data" ]; then
echo "Error: Failed to decrypt the token file."
exit 1
fi
# Extract tokens and credentials
access_token=$(echo "$decrypted_data" | jq -r .access_token)
refresh_token=$(echo "$decrypted_data" | jq -r .refresh_token)
client_id=$(echo "$decrypted_data" | jq -r .client_id)
client_secret=$(echo "$decrypted_data" | jq -r .client_secret)
wallabag_username=$(echo "$decrypted_data" | jq -r .username)
wallabag_password=$(echo "$decrypted_data" | jq -r .password)
# Check access token validity
echo "Checking access token..."
response=$(curl -s -w "%{http_code}" -o "$response_body_txt" \
-H "Authorization: Bearer $access_token" "$wallabag_url/api/user")
http_status="${response: -3}"
echo "DEBUG: HTTP status $http_status"
if [ "$http_status" -eq 401 ]; then
echo "Access token invalid, attempting to refresh..."
# Refresh token
response=$(curl -s -X POST "$wallabag_url/oauth/v2/token" \
-d "grant_type=refresh_token" \
-d "client_id=$client_id" \
-d "client_secret=$client_secret" \
-d "refresh_token=$refresh_token")
echo "DEBUG: Refresh response: $response"
# If refresh worked
if echo "$response" | jq -e '.access_token' >/dev/null 2>&1 && \
[ "$(echo "$response" | jq -r .access_token)" != "null" ]; then
access_token=$(echo "$response" | jq -r .access_token)
refresh_token=$(echo "$response" | jq -r .refresh_token)
echo "Token refreshed successfully."
else
# Fallback: full reauthentication
echo "Refresh token invalid. Performing full reauthentication..."
response=$(curl -s -X POST "$wallabag_url/oauth/v2/token" \
-d "grant_type=password" \
-d "client_id=$client_id" \
-d "client_secret=$client_secret" \
-d "username=$wallabag_username" \
-d "password=$wallabag_password")
echo "DEBUG: Reauth response: $response"
if echo "$response" | jq -e '.access_token' >/dev/null 2>&1 && \
[ "$(echo "$response" | jq -r .access_token)" != "null" ]; then
access_token=$(echo "$response" | jq -r .access_token)
refresh_token=$(echo "$response" | jq -r .refresh_token)
echo "Reauthentication successful."
else
echo "Error: Failed to reauthenticate. Response:"
echo "$response"
exit 1
fi
fi
# Update and re-encrypt token file
updated_data=$(echo "$decrypted_data" | jq \
--arg access_token "$access_token" \
--arg refresh_token "$refresh_token" \
'.access_token = $access_token | .refresh_token = $refresh_token')
echo "$updated_data" | gpg --batch --yes --encrypt --recipient "$gpg_key_id" > "$encrypted_file"
echo "Encrypted file updated with new tokens."
fi
# Send article to Wallabag
echo "Sending article to Wallabag..."
curl -s -X POST "$wallabag_url/api/entries.json" \
-H "Authorization: Bearer $access_token" \
-H "Content-Type: application/json" \
-d '{
"url": "'"${url}"'",
"tags": "'"${tags}"'",
"starred": 1,
"archive": 0
}' >/dev/null
# Cleanup
trap 'rm -f "$response_body_txt"' EXIT
echo "Article sent successfully."
exit 0
wallabag_token.json
Die Zugangsdaten werden in der Datei wallabag_token.json gespeichert. Es kann dafür einfach der Block aus Token - Anfordern - 2. Versuch in die Datei kopiert und angepasst werden.
~/.newsboat/wallabag_token.json
Dort den Abschnitt einfügen.
{
"client_id": "...",
"client_secret": "...",
"username": "...",
"password": "...",
"access_token": "...",
"refresh_token": "..."
}
Mehrere Newsboat Instanzen
Es ist möglich mehrere Newsboat für unterschiedliche Themen zu nutzen. Dabei ist darauf zu achten, dass
entweder
alle Instanzen die gleiche wallabag_token.json.gpg verwenden
oder
für jede Instanz ein eigener Wallabag Client (eigenes Client-ID und eigene Client-Secret) mit eigener wallabag_token.json.gpg angelegt wird.
Beispiel
In diesem Beispiel werden zwei Newsboat-Instanzen verwendet.
~/.newsboat= 1. Instanz~/.newsboat-music/newsboat/= 2. Instanz
Die Dateistruktur je Instanz
1. Newsboat-Instanz
|
|- bookmark.sh
|
|- config
|
|- styles.css
|
|- urls
|
|- wallabag_token.gpg.bak
|
|- wallabag_token.json.gpg
2. Newsboat-Instanz
|
|- bookmark.sh
|
|- config
|
|- styles.css
|
|- urls
Beide Instanzen teilen sich die Datei wallabag_token.json.gpg.
Jede Instanz hat eine eigene bookmark.sh. Es sind in der Datei lediglich die folgenden Zeilen angepasst worden:
...
# Bookmark Markdown file
bookmarks_file_md="$HOME/newsboat-bookmarks/xxx.md"
# Bookmark TXT file - relevnat if you wanna convert article to PDF file
bookmarks_file_txt="$HOME/newsboat-bookmarks/xxx.txt"
...
# Standard tag for Wallabag
tags="xxx"
...
Verbesserungen und Optimierungen
Das Skript ist auf Codeberg.org verfügbar. Jeder ist herzlich eingeladen, zur Weiterentwicklung beizutragen. Falls du Verbesserungsvorschläge hast oder das Skript optimieren möchtest, kannst du gerne Pull Requests einreichen oder offene Issues melden. Dein Feedback ist wertvoll und trägt dazu bei, das Projekt kontinuierlich zu verbessern.
Gib mir gerne einen Kaffee ☕ aus 😀
Gib mir gerne einen Kaffee ☕ aus !
Wenn dir meine Beiträge gefallen und geholfen haben, dann kannst du mir gerne einen Kaffee ☕️ ausgeben.
Follow Me
Source
- Photo by Artak Petrosyan on Unsplash







