Crear microposts a partir de toots de Mastodon

Escribe en Mastodon pero publica en tu web
Últimamente estoy descubriendo ciertas ventajas de Mastodon sobre otras redes sociales. No es de extrañar el hecho de que al ser una red de microbloging de software libre, ofrezca gran flexibilidad. Así que decidí aprovechar algunos textos publicados en mi cuenta de Mastodon y replicarlos en el blog.
Los posibles enfoques para integrar Mastodon en un blog estático son variados, algunos de ellos podrían ser:
- Mostrar tu perfil o últimos toots (públicos) en el blog
- Enlazar desde tus entradas del blog a toots (o viceversa)
- Mostrar toots como microposts en tu blog
- Publicar en Mastodon desde tu blog (al subir contenido)
- Usar Webmentions para enlazar Mastodon como comentarios o interacciones
Me gusta la opción 3, es decir, escribir en Mastodon, adjuntar alguna foto y una etiqueta, por ejemplo, #micropost y que a partir de este toot luego se genere un micropost en el blog.
Esta idea está en línea con el espíritu “POSSE” (Publica en tu Propio Sitio, Syndica en Otro), pero al revés: usar Mastodon como tu “frontend” móvil y después traer eso al sitio web.
Flujo de trabajo
Escribe un toot -> Script que importa tus toots -> Se publica en el sitio web
La idea es escribir un toot con texto + foto (opcional) y un hashtag especial, por ejemplo, #micropost; y más tarde un script puede importar toots seleccionados y mostrarlos como contenido: Este script utiliza el API de Mastodon para leer tus toots, seleccionar algunos y convertirlos a archivos .md automáticamente.
Importar Toots de Mastodon a Hugo
Funcionalidad principal del script:
- Se conecta a Mastodon usando un token de acceso a mi cuenta en mastodon.social,
- Busca toots recientes (hasta 40) que contengan el hashtag #micropost.
- Filtra los toots que ya hayan sido importados previamente para evitar duplicados.
- Extrae el contenido HTML y lo convierte a texto plano
- Usa la primera línea como título del micropost y el resto como contenido
- Descarga cualquier imagen adjunta al toot y la guarda en una carpeta de imágenes estáticas
- Crea un archivo Markdown con frontmatter para Hugo con los metadatos relevantes
- Registra los IDs de los toots importados en un archivo JSON para evitar importarlos de nuevo en el futuro.
- Utiliza la fecha y hora del toot para crear nombres de archivo únicos con formato YYYY-MM-DD-HHMMSS.
Dependencias
Utiliza las bibliotecas frontmatter para manejar el formato YAML de Hugo, html2text para convertir HTML a Markdown, y mastodon.py para interactuar con la API de Mastodon.
Estructura de directorios:
- Crea microposts en
content/microposts/
- Guarda imágenes en
static/microposts/
- Mantiene un registro de importaciones en
content/microposts/imported.json
Entrada que generará:
---
title: Probando nuevos binoculares esta noche
date: 2025-04-25 23:15:11.087000+00:00
mastodon_url: https://mastodon.social/@javierinsitu/114401143100228737
image: 2025-04-25-231511.jpg
tag: ["Micropost"]
toc: false
---
Cielo despejado en el sur.
[](https://mastodon.social/tags/micropost)
Breve explicación del archivo generado:
- Título: extraído de la primera línea del toot
- Fecha: fecha de creación del toot en Mastodon
- URL original en Mastodon
- Imagen: nombre del archivo, si existe
- Etiquetas predeterminadas: “Microposts”
- Autor predefinido: “Javierinsitu”
- Deshabilita comentarios y TOC tabla de contenidos
Bibliotecas necesarias
Como comentaba más arriba en el apartado “Dependencias”, hay cierto software de Python que es necesario tener instalado para que el script haga su trabajo:
pip install Mastodon.py python-frontmatter requests html2text
El script en python
import os
import requests
import frontmatter
import html2text
from mastodon import Mastodon
from datetime import datetime
import json
# Configuración
INSTANCE_URL = "https://mastodon.social"
ACCESS_TOKEN = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
MICROPOST_TAG = "#micropost"
OUTPUT_DIR = "content/microposts/"
IMAGES_DIR = "static/microposts/"
TRACK_FILE = "content/microposts/imported.json"
# Autenticación
mastodon = Mastodon(access_token=ACCESS_TOKEN, api_base_url=INSTANCE_URL)
# Cargar toots ya importados
imported = set()
if os.path.exists(TRACK_FILE):
try:
with open(TRACK_FILE, "r") as f:
imported = set(json.load(f))
except json.JSONDecodeError:
print("⚠️ Advertencia: 'imported.json' estaba vacío o corrupto. Se reinicia.")
# Crear directorios si no existen
os.makedirs(OUTPUT_DIR, exist_ok=True)
os.makedirs(IMAGES_DIR, exist_ok=True)
# Obtener toots recientes
toots = mastodon.account_statuses(mastodon.me()["id"], limit=40)
nuevos = []
for toot in toots:
if toot["id"] in imported:
continue
raw_html = toot["content"]
text = html2text.html2text(raw_html).strip()
if MICROPOST_TAG not in text:
continue
text = text.replace(MICROPOST_TAG, "").strip()
# Separar la primera línea para título y el resto para contenido
lines = text.split('\n', 1)
title = lines[0].strip()
# Usar solo el resto del contenido sin incluir la primera línea (título)
body = lines[1].strip() if len(lines) > 1 else ""
date = toot["created_at"]
url = toot["url"]
media_attachments = toot["media_attachments"]
slug = date.strftime("%Y-%m-%d-%H%M%S")
image_filename = ""
if media_attachments:
media = media_attachments[0]
image_url = media["url"]
ext = os.path.splitext(image_url)[1]
image_filename = f"{slug}{ext}"
r = requests.get(image_url)
with open(os.path.join(IMAGES_DIR, image_filename), "wb") as img_file:
img_file.write(r.content)
post = frontmatter.Post(
body, # Aquí solo se usa el cuerpo sin incluir el título
**{
"title": title,
"date": date,
"toc": False,
"mastodon_url": url,
"image": image_filename if image_filename else "",
"tags": ["Microposts"],
"author": "Javierinsitu",
"comments": False,
"license": "All posts are licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International license.",
"draft": False
}
)
post_path = os.path.join(OUTPUT_DIR, f"{slug}.md")
with open(post_path, "w", encoding="utf-8") as f:
f.write(frontmatter.dumps(post))
nuevos.append(toot["id"])
# Guardar nuevos importados
if nuevos:
imported.update(nuevos)
with open(TRACK_FILE, "w") as f:
json.dump(list(imported), f, indent=2)
print(f"{len(nuevos)} microposts importados.")
Pasos siguientes
Quedaría configurar algunos detalles para que la nueva sección de “microposts” se integre visualmente con el tema que tengamos en nuestro blog.
Conclusión
Integrar automáticamente las publicaciones de Mastodon como microposts en tu sitio en Hugo optimiza el flujo de trabajo y permite mantener el control sobre tu contenido. Recomendable.
Eso es todo por hoy.