Wenn es um Social-Media-Automatisierung geht, bleibt das Gespräch oft bei „jeden Morgen um 9 Uhr posten" oder „die KI den Beitragstext schreiben lassen" stehen.
Aber das wirklich Schwierige ist nicht der Posten-Knopf.
Nur die richtigen Artikel ausliefern. Nichts doppelt posten. Nicht alles anhalten, nur weil ein Dienst ausfällt. Kein CAPTCHA mit Gewalt umgehen. An Menschen nur das weitergeben, was nur Menschen können. Und nach der Auslieferung aus den Ergebnissen ableiten, wie man das nächste Mal ausliefert.
Erst wenn das alles verbunden ist, kann man sagen, dass die Verteilung automatisiert ist.
Wer 12 Sprachen, mehrere soziale Netzwerke und sogar einen Newsletter betreut, hat bei der Verteilung längst keine Funktion zum Planen von Beiträgen mehr. Es ist ein kleines verteiltes System.
1. Das Ziel ist nicht „völlig menschenleer", sondern „Menschen bearbeiten nur die Ausnahmen"
Wenn man als Automatisierungsziel „kein Mensch fasst etwas an" ausgibt, wird der Entwurf schief.
Echte externe Dienste haben CAPTCHAs, die prüfen, ob man ein Mensch ist, SMS-Verifizierung, Zwei-Faktor-Authentifizierung (2FA), Identitätsprüfungen, ausdrückliche Zustimmung zu den Nutzungsbedingungen, Prüfungen von Entwickler-Apps und so weiter. Das ist kein Defekt. Es ist eine Grenze, die der Dienst absichtlich gesetzt hat: „Hier kommt nur der Kontoinhaber durch."
Die Zielform sieht deshalb so aus:
Artikel erzeugen → Qualitätsprüfung → Fassung jeder Sprache → Veröffentlichung in Produktion → Produktions-HTML zurücklesen → Verteilungskandidat → Beitragstext jeder Sprache → Social Media und Newsletter → Ergebnisse einsammeln → Entscheidung über die nächste Verteilung
Taucht unterwegs etwas auf, das nur ein Mensch erledigen kann, gibt man ihm genau diesen einen Fall.
Wenn zum Beispiel nur X auf Japanisch ein CAPTCHA verlangt, wartet nur X auf Japanisch. Bluesky auf Englisch, Facebook auf Französisch, der Newsletter, die Zugriffsanalyse und die Erzeugung des nächsten Artikels müssen nicht mit auf der Strafbank sitzen.
Wegen eines einzigen CAPTCHAs müssen nicht alle 12 Sprachen Trauer tragen.
Auch Produkte für dauerhafte Workflows (Durable Workflows) wie Cloudflare Workflows sind dafür gedacht, Zustände lange zu halten, fehlgeschlagene Schritte zu wiederholen und auf externe Ereignisse oder menschliche Freigaben zu warten. Wichtig ist nicht, ein bestimmtes Produkt zu nutzen, sondern „Warten auf einen Menschen" als einen Zustand zu führen und nicht als Systemstillstand.
2. „Der Artikel ist fertig" und „darf verteilt werden" trennen
Wenn man die Verteilungsschicht direkt an die Artikelerzeugung hängt, passieren leicht Unfälle.
Das Markdown ist gespeichert. Die Übersetzung ist fertig. Der Build ist durchgelaufen.
Nichts davon garantiert, dass „der Leser diese URL jetzt öffnen und richtig lesen kann".
Deshalb ist die verteilbare Einheit nicht der Artikelname, sondern
articleId × locale × contentSha
Und bei Social Media wird noch feiner unterteilt:
articleId × locale × contentSha × platform × campaignType
Wichtig ist hier contentSha. Auch bei gleicher URL ist es eine andere Revision, sobald der Text aktualisiert wurde. Ein Beitrag, der für den alten Text erstellt wurde, darf nicht als Ankündigung des neuen Textes hinausgehen.
Und die Bedingung, etwas an die Verteilung zu übergeben, lautet nicht „es liegt auf GitHub", sondern das Produktions-HTML genau dieses Locales und dieses contentSha wurde tatsächlich zurückgelesen und bestätigt.
Was der Eingang der automatischen Veröffentlichung braucht, ist nicht „gibt es ein Manuskript?", sondern „gibt es ein fertiges Ergebnis, das der Leser jetzt öffnen kann?".
3. Ein Timeout ist kein Fehlschlag: Wer das verwechselt, erzeugt Zwillingsbeiträge
Bei externen APIs sind nicht die eindeutigen Fehler das Gefährliche, sondern die mehrdeutigen.
Der Beitrag wurde an die API gesendet. Auf unserer Seite gab es einen Timeout. Keine Antwort.
Wenn man dann denkt:
„Sieht nach Fehlschlag aus. Ich sende noch mal",
und der erste Versand in Wahrheit geklappt hatte, entstehen zwei gleiche Beiträge.
„Die API hat nicht geantwortet, also habe ich sicherheitshalber denselben Artikel dreimal gepostet" ist die Gruselgeschichte der Automatisierung.
Cloudflare Queues arbeitet standardmäßig mit At-least-once-Zustellung (mindestens einmal), sodass dieselbe Nachricht selten auch mehrfach zugestellt werden kann. Deshalb empfiehlt auch die offizielle Dokumentation, mit einer eindeutigen ID oder einem Idempotenzschlüssel (Idempotency Key) zu deduplizieren.
Also bildet man für jede Auslieferung einen deterministischen Schlüssel:
sha256(articleId + locale + contentSha + platform + campaignType)
In der Quittungstabelle wird dieser Schlüssel UNIQUE.
Bei einem Timeout wird nicht sofort neu gesendet, sondern in dieser Reihenfolge vorgegangen:
- Den Quittungseintrag prüfen
- Wenn man beim Provider zurücklesen kann, prüfen, ob schon gepostet wurde
- Nur wiederholen, wenn bestätigt ist, dass noch nicht gepostet wurde
Die Warteschlange (Queue) ist keine „Magie, die genau einmal ausführt". Der Entwurf besteht darin, das Ergebnis auch bei Dubletten auf genau eine Ausführung zusammenlaufen zu lassen.
4. Störungen im „kleinstmöglichen Bereich" einsperren, nicht im „ganzen System"
Das Ärgerlichste an der Automatisierung ist, einen einzelnen Fehler zur Gesamtstörung zu befördern.
Mindestens teilt man die Fehlerdomäne (Failure Domain) in
platform × locale × account
Läuft die Authentifizierung von X auf Japanisch ab, ist nur dieser Kanal BLOCKED.
Gibt Bluesky auf Englisch einen 429 zurück, geht nur dieser in RETRY_WAIT.
Wartet eine Facebook-Seite auf eine Identitätsprüfung, geht nur diese in HUMAN_ACTION_REQUIRED.
Alles andere läuft weiter.
Auch die Zustände sollten nicht nur „Erfolg / Fehler" sein. Die Wirklichkeit lässt sich besser abbilden, wenn man sie etwa so aufteilt:
- READY
- ACTIVE
- DEGRADED_BUT_RUNNING
- HUMAN_ACTION_REQUIRED
- BLOCKED_PROVIDER
- RETRY_WAIT
- DISABLED_BY_POLICY
Wenn von insgesamt 15 Strecken 14 laufen und nur eine auf einen Menschen wartet, ist der Gesamtzustand nicht „Totalausfall". Er kommt DEGRADED_BUT_RUNNING näher.
Gegen einen 429 hilft Durchhaltewille nicht. Gibt es ein Retry-After, hält man sich daran. Bei 5xx gilt exponentielles Backoff mit Obergrenze. Bei 401/403 repariert man einmal, wenn es einen legitimen Weg zur Erneuerung der Zugangsdaten gibt; hilft das nicht, stoppt man nur das betroffene Konto.
CAPTCHAs und menschliche Prüfungen gehören nicht in eine automatische Wiederholungsschleife. Keine API entwickelt sich nach 100 Schlägen zum Menschen.
5. Die Human Handoff Queue soll ein Arbeitsauftrag sein, kein „Hilfe!"
Ist der Mechanismus zur Übergabe an Menschen schlampig, bleibt am Ende der Automatisierung ein riesiger Berg Handarbeit übrig.
Eine schlechte Übergabe sieht so aus:
„Social Media steht still. Bitte prüfen."
Was prüfen? Wo? Nur anmelden? Müssen auch Einstellungen geändert werden? Und was dann, wenn es erledigt ist?
Eine gute Übergabe enthält mindestens pro Fall:
- platform
- locale
- account
- blockerType
- Zeitpunkt der Erkennung
- Zeitpunkt, ab dem ein neuer Versuch möglich ist
- die zu öffnende URL
- was der Mensch tun soll
- was der Mensch nicht tun darf
- was das automatische System danach erneut prüft
- den Bereich, den dieser Blocker anhält
- ob die übrige Arbeit weiterlaufen kann
Zum Beispiel:
„Melde dich beim offiziellen Konto dieser Sprache an und erledige nur das angezeigte CAPTCHA. Ändere weder Beitragseinstellungen noch das Profil. Danach liest das System bei der nächsten Runde den Anmeldestatus zurück und macht mit einem Testbeitrag (Canary) weiter."
Damit versteht man es auf Anhieb.
Und wichtig: Das Lösen von CAPTCHAs wird nicht automatisiert.
Einen Solver einzusetzen, die Aufgabe zu fälschen oder über inoffizielle Wege zu umgehen, ist keine Automatisierung, sondern geht in Richtung eines Bruchs der von der Gegenseite gesetzten Grenze.
Menschen nimmt man aus der täglichen Veröffentlichung heraus und überlässt ihnen nur die Grenze, die die Maschine nicht legitim überschreiten kann.
Passwörter, OAuth-Zugriffs- und Refresh-Token, Sitzungs-Cookies, SMS-/2FA-Codes, Wiederherstellungscodes und private API-Geheimnisse bleiben weder auf GitHub noch in normalen Logs. Auf GitHub bleibt nur, was nicht geheim und zum Fortsetzen nötig ist: öffentlicher Handle, Status, bereinigter (sanitized) Fehler, Quittungs-ID, öffentliche Beitrags-URL und Ähnliches.
6. Automatisches Posten nicht mit Engagement-Bots vermischen
Dass ein offizielles Konto die Artikel der eigenen Website automatisch postet, ist etwas anderes, als Likes, Follows, Antworten und sogar Direktnachrichten zu automatisieren.
Die Automation Rules von X in der Fassung vom April 2026 erlauben regelkonforme, nützliche und informierende automatische Beiträge, verbieten aber das Umgehen von API-Ratenbegrenzungen (Rate Limits), Nicht-API-Automatisierung, die Websites per Skript bedient, sowie spamartige oder doppelte Beiträge. Automatische Likes sind ebenfalls verboten.
Die Anfangswerte dürfen deshalb ruhig nüchtern sein:
- AUTO_PUBLISH = true
- AUTO_LIKE = false
- AUTO_FOLLOW = false
- AUTO_UNFOLLOW = false
- AUTO_REPLY = false
- AUTO_DM = false
Zuerst beschränkt man die Verantwortung auf „offizielle Artikel korrekt zustellen".
Auch Bluesky erlaubt es, Beiträge über die offizielle API zu erstellen, und jeder Beitrag kann eine Sprachangabe tragen. Im mehrsprachigen Betrieb ist es also natürlicher, Text und Sprach-Metadaten pro Locale abzustimmen, als den englischen Text überallhin zu schicken.
Browser-Automatisierung bleibt auf Hilfsdienste beschränkt, etwa bei der Ersteinrichtung von Konten, wo es keine offizielle API gibt oder manuelle Bedienung erlaubt ist. Für die laufende Verteilung stützt man sich so weit wie möglich auf offizielle APIs und offizielle Authentifizierung.
Die Startkanäle legt man pro Locale fest, zum Beispiel: ja→X, en→X/Bluesky, ko→X, zh-Hans→Weibo, zh-Hant→Facebook/Threads, es・pt-BR・id・th・vi・fr→Facebook, de→Facebook/X. Bild- und videozentrierte Flächen wie Instagram, TikTok und Reels verschiebt man in die zweite Phase, wenn Kartenerzeugung und Medien-Qualitätssicherung (Media QA) stabil laufen. Die APIs, Automatisierungsrichtlinien und Nutzungsbedingungen jeder Plattform muss man zum Zeitpunkt der Umsetzung immer neu prüfen.
7. Der Betrieb in 12 Sprachen ist kein „Übersetzungswettbewerb japanischer Beiträge"
Auf mehrsprachigen Websites passiert gern Folgendes.
Der japanische Artikel wurde in 12 Sprachen übersetzt. Ein einziger japanischer Social-Media-Text wurde erstellt. Der wurde auch in 11 Sprachen übersetzt. Fertig.
So verliert es an Sinn, den Haupttext in 12 Sprachen gebracht zu haben.
Den Beitragstext schreibt man, indem man den tatsächlich veröffentlichten Text dieses Locales liest, als würde das offizielle Konto der Website in dieser Sprache eine kurze Bemerkung fallen lassen.
Die Grundform ist kurz:
Genau das ist unscheinbar, aber am nervigsten. 🫠 URL
oder auch:
Das lässt sich auch automatisieren? 👀 URL
Lange Zusammenfassungen oder „Muss man gesehen haben", „schockierend" und „jetzt ansehen" braucht es nicht. Und bei einem Beitrag der Website selbst wäre ein gefälschtes Zeugnis, als hätte ein Dritter sie zufällig entdeckt und sei begeistert, schlicht seltsam.
Die Markenpersönlichkeit ist gemeinsam, doch die Formulierung wird in jeder Sprache natürlich. Man tut nicht so, als würden die Konten von verschiedenen Personen betrieben.
Außerdem wechseln Medizin, Recht, Geldanlage, große Geldbeträge, Katastrophen, Verbrechen, Todesfälle, Selbstverletzung, Gewalt, sexuelle Gewalt, Minderjährige, Sicherheit, Politik und Wahlen sowie heftige Konflikte in den Serious Mode.
Dann gilt grundsätzlich: keine Emojis, keine Stimmungsmache, keine Behauptungen, die über den Artikel hinausgehen. Bei einem politischen Artikel fügt man nicht automatisch eine Unterstützungsbekundung (Endorsement) hinzu.
Der „Vollgas-Spaßmodus" ist keine Universaleinstellung. Bei einem Artikel über Krankenwagen braucht es kein 🫠.
8. Der Newsletter ist keine „E-Mail-Version von Social Media", sondern dieselbe Verteilungsidee auf einem anderen Adapter
Auch der Newsletter darf nicht direkt aus der Textgenerierung heraus versendet werden.
Mindestens führt man
- explicit opt-in
- locale
- topics
- consentAt
- status
- unsubscribeAt
- createdAt
und sendet denselben Artikel nicht mehrfach.
Die E-Mail-Adresse für Anfragen und die Infrastruktur für Massenversand werden außerdem logisch getrennt.
Als Antwortadresse für Leser kann man die bestehende Anlaufstelle nutzen, aber die Versandbasis sollte ein Adapter sein, den man später gegen einen spezialisierten Provider austauschen kann.
Gmail verlangt von Massenversendern Versandauthentifizierung, das Vermeiden von Spam und unerwünschten Mails sowie einen einfachen Abmeldemechanismus, und behandelt die Abmeldung bei Abonnement-Nachrichten als wichtige Anforderung.
Die Abmeldung heißt nicht „stoppt wahrscheinlich im nächsten Batch", sondern: Die Person fliegt sofort aus der Empfängerliste.
Der Wert eines Newsletters liegt nicht im Sammeln von Adressen. Er liegt darin, dem Leser die Informationen zu geben, um die er gebeten hat, in der Häufigkeit, um die er gebeten hat, und ihn aufhören zu lassen, sobald er will.
9. Ist der KPI „Likes", baut man eine Maschine, die Likes jagt
Wer automatische Verbesserung einführt, muss genau überlegen, was er als Zielfunktion setzt.
Wenn man nur die Likes in Social Media maximiert, gewinnen reißerische Titel, extreme Behauptungen und Themen mit Hang zum Shitstorm.
Was eine Artikel-Website wirklich will, ist aber etwas anderes.
Die Prioritäten könnten zum Beispiel so lauten:
- site visit
- meaningful reading
- next article
- return visit
- newsletter signup
Schwer gewichtet wird also: „Ist die Person über diesen Beitrag auf die Website gekommen?", „Hat sie wirklich gelesen?", „Ist sie zum nächsten Artikel weitergegangen?" und „Ist sie wiedergekommen?".
Auch die Verteilungskampagnen teilt man auf in
- NEW
- UPDATED
- TRENDING
- POPULAR
- EVERGREEN
Man postet nicht mit „großes Update!" neu, nur weil ein einzelner Buchstabe korrigiert wurde. UPDATED gilt nur für wesentliche Aktualisierungen (Material Update).
Auch für POPULAR und TRENDING nutzt man vorhandene echte Zugriffsmessungen weiter. Man muss keine eigene Beliebtheitsrangliste für die Verteilung bauen und zwei Zahlen gegeneinander in den Krieg ziehen lassen.
Die Versandzeit bestimmt man ebenfalls nicht nach einem Vorurteil wie „Japanisch, also 20 Uhr", sondern indem man die tatsächlichen locale × country × platform × weekday × hour erkundet. Am Anfang probiert man mehrere Zeitfenster (Slots) und konzentriert sich, sobald Daten vorliegen.
10. In der Praxis: nicht „posten", sondern den Zustand weiterschieben
Der echte Betrieb lässt sich am besten als Folge von Zustandsübergängen verstehen.
- Der Artikel des Ziel-Locales geht in Produktion.
- Das Produktions-HTML des exakten contentSha wird zurückgelesen und auf PRODUCTION_VERIFIED gesetzt.
- Der Verteilungskandidat wird mit articleId × locale × contentSha × platform × campaignType erstellt.
- Der Text dieses Locales wird gelesen und ein kurzer Beitragstext erzeugt.
- Hype-Verbot, Serious Mode, Länge, URL und Sprache werden geprüft.
- Der Beitrag kommt mit dem Idempotency Key in die Outbox.
- Er wird über die offizielle API des Providers gesendet.
- Über die API-Quittung hinaus wird, wenn möglich, der öffentliche Beitrag zurückgelesen.
- Website-Besuche, vollständiges Lesen, nächster Artikel und Wiederkehr werden eingesammelt.
- Das fließt in die nächste Entscheidung zwischen NEW / UPDATED / TRENDING / POPULAR / EVERGREEN ein.
Erscheint unterwegs ein CAPTCHA, geht nur dieser Bereich in HUMAN_ACTION_REQUIRED.
Bei 429 in RETRY_WAIT.
Ist der Provider ausgefallen, in BLOCKED_PROVIDER.
Der Rest macht weiter.
Man feuert auch nicht von Anfang an auf einmal auf 15 Konten. Pro Adapter geht man zuerst durch
Zurücklesen der Authentifizierung (Auth Readback) → Probelauf (Dry Run) → Canary mit einem echten Artikel → Quittung → öffentliches Zurücklesen (Public Readback) → Locale-Prüfung → Prüfung der Dublettenunterdrückung → Prüfung der Zuordnung in der Zugriffsanalyse
und erweitert erst danach.
Der Einstieg, den die Betreiber sehen, wird in einem einzigen current-status gebündelt.
Auch bei der Umsetzung ist es schwerer, die Quellen der Wahrheit zu vermehren, wenn man nicht eine zweite Artikelfabrik und einen zweiten Scheduler für die Verteilung hochzieht, sondern sich als Post-Publication-Child (Kindprozess nach der Veröffentlichung) nach PRODUCTION_VERIFIED an den bestehenden Veröffentlichungs-Owner hängt und die vorhandene Durable Runtime samt State Store wiederverwendet.
Wenn ein Mensch auf die Frage „Wie ist der Stand?" 15 JSON-Dateien und Logs ausgraben muss, gibt die Automatisierung in dem Moment die Arbeit an den Menschen zurück.
Am wichtigsten bei automatischer Verteilung ist nicht, „dass nichts fehlschlägt".
Sondern dass man auch bei einem Fehlschlag weiß, wo es stockt, dass der Stillstand klein bleibt, dass nur das an Menschen geht, was nur Menschen können, dass der Rest von selbst weiterläuft und dass man sich nach der Wiederherstellung dort fortsetzt, wo man aufgehört hat, ohne etwas doppelt auszuführen.
Den Posten-Knopf abzuschaffen ist nur der Prolog.
Echte Automatisierung heißt, auch den Betrieb am Tag des Fehlschlags zu automatisieren.
