Produkte, deren Schnittstelle Textnachrichten sind
Der Reiz ist real: Leute mögen es nicht, Apps zu installieren oder Websites zu besuchen, aber jeder kann texten. Der Haken ist, dass Sie den Kanal nicht besitzen. Die US-Carrier tun das, und sie haben eine Inhaltsrichtlinie und einen Genehmigungsprozess, der Sie dauerhaft ablehnen kann. Diese Hürde entscheidet, was das Produkt sein darf, und kommt daher zuerst.
Schritt 0 – die Hürde. Mach das vor dem Design, nicht danach.
Seit Februar 2025 blockieren US-Carrier nicht registrierten A2P-Verkehr vollständig, daher müssen eine Marke und eine Kampagne genehmigt werden, bevor auch nur eine Nachricht gesendet wird. Lies die aktuellen Fehlerdokumentationen jedes Mal neu; die Carrier-Richtlinie ändert sich.
| Code | Auslöser | Erneute Einreichung? |
|---|---|---|
| 30953 | explizite/anzügliche Sprache, oder eine verlinkte Seite, die „pornografische, Escort-, Dating- oder Erwachsenenunterhaltungsinhalte“ hostet | Nein |
| 30885 | „hohes Risiko“ – irreführendes Marketing oder eine Registrierung, die den Traffic falsch darstellt | Nein |
| 30898 | zu viele Marken auf einer EIN oder eine Registrierung, die wie eine Dublette aussieht | Ja, mit Begründung |
Regel: Nenne die Inhaltskategorie des Produkts in der ersten Antwort laut und sag, ob sie auf dieser Liste steht. Wenn die Kategorie (z. B. Dating) buchstäblich ein Schlüsselwort in einer Ablehnungsregel ist, ändert das Finden in Minute fünf die Architektur, den Landing-Text und den Ausweichplan. SHAFT ist die Abkürzung: Sex, Hate, Alcohol, Firearms, Tobacco – plus Cannabis, und Dating reitet mit.
Regel: Registriere ein Nebenprojekt als Einzelunternehmermarke, nicht unter der EIN eines bestehenden Unternehmens. Risikomuster folgen der Steuer-ID (30898), daher darf eine Ablehnung eines Nebenprojekts nicht die Sendebereitschaft deines Hauptgeschäfts beeinträchtigen. Einzelunternehmer ist auf Einzelpersonen ohne Steuer-ID beschränkt; der Durchsatz ist niedrig, und niedrig ist für eine Beta völlig ausreichend.
Regel: Baue niemals eine Tarn-Landingpage, um eine Kampagne genehmigt zu bekommen. Eine Seite, die verbirgt, was der Traffic tatsächlich ist, ist das 30885-Muster und verwandelt ein Ein-Nummern-Risiko in ein Risiko für jede jemals registrierte Nummer. Lege die Chancen klar dar und lass den Eigentümer entscheiden.
Beschreibe den Dienst danach, was er mechanisch tut, und nur, wenn das wahr ist (z. B. Journaling und Verantwortlichkeit in kleinen Gruppen, wenn das ist, was die Nachrichten sind). Wenn keine wahre Beschreibung die Hürde passiert, ist die Antwort ein anderer Kanal, nicht ein besserer Euphemismus.
Die Prüfung belohnt Fakten, auf die man zeigen kann: Nur-Inbound-Opt-in, Gesprächsvolumen, keine Links in wiederkehrenden Nachrichten, STOP vor allem anderen behandelt, explizite Inhalte an der Tür abgewiesen.
Schritt 0.5 – lies das Briefing nach ZAHLEN und OBJEKTEN, nicht nach Absicht
Behalte das Briefing des Gründers wörtlich als README.md und sag in CLAUDE.md, dass es über jedem Engineering-Dokument steht.
Regel: Bevor du eine Zustandsmaschine schreibst, liste jede Dauer im Briefing und jedes Nomen, auf das sie wirkt. Wenn zwei Dauern existieren, sind sie zwei Features. Ein Briefing mit einer einwöchigen Verzögerung für Antworten von Freunden, die den Autor erreichen und einer zweiwöchigen Sperre für das eigene Update des Autors ist leicht zu einem einzigen siebentägigen Halt auf den Eintrag zusammenzufassen – das eine Objekt, um das es bei keiner der Verzögerungen ging – und jeder nachgelagerte Fehler folgt aus dieser Zusammenlegung.
Regel: Benenne das Objekt jeder Verzögerung – „gehalten VOR wem“. Vor Freunden gehalten und vor dem Autor gehalten sind gegensätzliche Produkte.
Regel: Wenn das wörtliche Design des Briefings auf dem Kanal nicht erzwungen werden kann, sag es und nenne die Alternativen – wähle nicht stillschweigend das Erzwingbare. (Der Ersteller eines Gruppenchats ist ein Mitglied davon, daher kann kein Code die Antworten der Gruppe von ihm zurückhalten.) Das ist eine Prämissenentscheidung, und Prämissenentscheidungen gehören dem Eigentümer.
Ein kohärentes Fehllesen fühlt sich nicht wie eines an. Behalte einen ersetzten Designabsatz durchgestrichen an Ort und Stelle, anstatt ihn zu löschen; es zeigt einer späteren Sitzung, wie das Briefing falsch gelesen wurde.
Schritt 1 – was der Kanal kann und was nicht
- Gruppen-SMS aus Code funktioniert. Twilio Conversations macht Gruppen-MMS nur auf +1-Langcodes – nicht gebührenfrei, nicht auf Kurzcodes – begrenzt auf 10 Teilnehmer inklusive deiner eigenen Nummer. Behaupte nichts anderes aus dem Gedächtnis.
- Gruppen-MMS-SMS-Teilnehmer haben eine Adresse und keine ProxyAddress, daher bedient eine Nummer jeden Raum – aber die Teilnehmer/Proxy-Eindeutigkeitsregel (50425) hat kein dokumentiertes Verhalten für teilnehmer ohne Proxy. Gestalte niemals viele gleichzeitige Räume, die sich eine Nummer und einen Teilnehmersatz teilen. Ein dauerhafter Raum pro Person hat einen stabilen Teilnehmersatz.
- Eine Webseite kann kein iPhone-Adressbuch lesen. Die Contact-Picker-API ist nur Chrome-auf-Android. „Kontakte synchronisieren“ ist tot bei Ankunft; ersetze es durch eine Zeile, die der Benutzer weiterleitet – die eingehende SMS des Empfängers ist der Einwilligungsnachweis, den die Carrier ohnehin wollen.
- Ein Telegram-Bot kann keine Gruppe erstellen oder jemanden zu einer hinzufügen, und mit aktiviertem Datenschutzmodus hört er nur auf Befehle, die an ihn adressiert sind. Beides hilft: Der Ersteller fügt den Bot zu dem Chat hinzu, den er bereits hat, und allgemeines Geplauder kann nicht mit Eingaben verwechselt werden. Das Erstellen eines Bots erfordert einen Menschen in @BotFather (keine API); frage nach dem Token.
- WhatsApp Cloud API hat kein Gruppen-Messaging.
- iMessage-APIs (Sendblue, LoopMessage) machen blaue Blasen und echte Gruppenchats, kosten aber etwa 100 $/Leitung/Monat zuzüglich Einrichtungsgebühren.
Schritt 2 – Architektur, die den Verlust des Kanals überlebt
Weil der Kanal abgelehnt werden kann, muss der Transport eine Datei sein:
machine.js pure: (context, event) -> {replies, effects} kein I/O, keine Uhr
engine.js Kontextaufbau -> machine -> effects der gesamte Pfad
effects.js createEffects({db, channel}) führt Entscheidungen aus
twilio.js / telegram.js austauschbar
api/*.js dünne Shim-Dateien über engine.js ~10 Zeilen jede
sim/ In-Memory-DB + Konsolenkanal
- Der Entscheidungskern nimmt
nowals Argument und berührt kein Netzwerk. Jeder Fehler in dieser Produktklasse ist ein Sequenzierungsfehler (eine Erinnerung, die zweimal feuert, eine Nachricht an einen leeren Raum, ein gehaltener Gegenstand, der nie ankommt), und keiner ist gegen ein Live-Netzwerk und einen Sieben-Tage-Timer testbar. - Adapter sind Argumente, niemals Importe, in der Effektebene – derselbe Refaktor, den der Simulator und der Ausweichkanal benötigen.
- Keine Logik innerhalb eines HTTP-Handlers. Kanalspezifisches Onboarding, das in
api/telegram.jsgeschrieben ist, ist nicht testbar; extrahiere es.
Schritt 3 – treibe es an, test es nicht nur
node sim/drive.js skriptbasiert: der gesamte Zyklus, eine Woche übersprungen, die Wächter
node sim/drive.js --repl tippe als beliebige Zahl; /as <n> /jump <Tage> /state
- Der Simulator muss den Produktionspfad ausführen, keine parallele Kopie.
- Erwarte, dass eine erste Fahrt mehrere echte Fehler aufdeckt, die Unit-Tests nicht erreichen können: ein Raum, der sich selbst begrüßt, bevor jemand drin ist, ein nackter Wochentag für ein Datum eine Woche entfernt, eine Erinnerung, die nicht sagt, auf welches Element sie sich bezieht, ein Raum, dessen Mitglieder alle gegangen sind.
- Wenn ein Test rot wird, überprüfe zuerst den Test (ein Datumsregex, der das Komma in „Sun, Aug 30“ nicht erlaubt; ein
doesNotMatch, das auf eine andere, legitime Nachricht feuert). - Entscheide oder drucke niemals von einem Store-gestempelten Zeitstempel. Der Store schreibt
created_atvon der echten Uhr, nicht der injiziertennowdes Engines, also lügt er unter einer übersprungenen Uhr (und druckt Daten in der Vergangenheit). Entscheide nur aus Spalten, die die Maschine geschrieben hat, und hänge verwandte Daten an einen gespeicherten Anker.
Schritt 4 – Text für einen Sperrbildschirm
Eine Datei enthält jeden ausgehenden String.
- Keine Emojis, keine Ausrufezeichen, kein Marketing.
- Niemals ein nackter Wochentag für ein Datum, das mehr als einen oder zwei Tage entfernt ist.
Sun Aug 30. - Vergib Zeichensetzung und Groß-/Kleinschreibung bei jedem Schlüsselwort –
Wait.undYes!müssen ankommen. - Prosa, die ein Schlüsselwort enthält, ist immer noch Prosa: „we should wait and see“ ist nicht WAIT. Vergleiche die gesamte kanonisierte Nachricht, niemals eine Teilzeichenfolge.
- STOP / HELP / START werden vor dem gesamten Anwendungszustand und vor jedem Modellaufruf geparst, damit ein Opt-out nicht durch einen Fehler woanders oder einen API-Ausfall unterbrochen werden kann.
- Wenn ein Modell Inhalte überwacht, schließe bei Fehler ab: wenn die Prüfung nicht ausgeführt werden kann, sende nichts und sag es.
Schritt 5 – wenn ein Modell Benutzerinhalte umschreibt, führe es aus, bevor du ihm vertraust
Ein Wächter, der Drittanbieternamen aus Benutzereinträgen entfernt, kann perfekt lesen und trotzdem:
- Eine Tatsache erfinden – gebeten, „Jane Doe“ durch „einen natürlichen Handle“ zu ersetzen, schrieb es „das Mädchen aus der App“, obwohl nichts eine App erwähnte; Empfänger lasen eine Erfindung als Tatsache.
- Überkorrigieren und echte Details löschen – „Jane vom Laufclub“ wurde zu „ihr“.
Regel: Die Anweisung muss sagen, was das Modell NICHT erfinden darf und was es NICHT löschen darf. Die funktionierende Form: Verankere die Ersetzung in der Quelle, ersetze das Token, nicht die Phrase darum herum, und bevorzuge einen neutralen Fallback gegenüber der Wiederverwendung eines Details, das der Satz bereits angibt.
Regel: Pinne jeden Live-Modell-Fehler als einen Opt-in-Test, der ohne API-Schlüssel übersprungen wird, damit Prompt-Änderungen sie nicht stillschweigend verschlechtern können, ohne bei jedem Testlauf Kosten zu verursachen. Budgetiere 2-5s pro Wächteraufruf.
Kosten (Größenordnung; live bestätigen)
Eine +1-Langcode kostet ein oder zwei Dollar pro Monat; SMS unter einem Cent pro Segment pro Richtung; MMS ein paar Cent. Die Einzelunternehmer-Registrierung kostet ein paar Dollar einmalig plus eine kleine monatliche Kampagnengebühr. Telegram ist kostenlos.
Fragen vs. Entscheidungen
- Fragen: ob man eine ehrliche Registrierung einreicht, wohlwissend, dass sie dauerhaft abgelehnt werden könnte, oder auf Telegram startet (Geld und ein irreversibles Ergebnis); alles, was das Wesen des Produkts ändert.
- Entscheiden: Architektur, Textstimme, die Zustandsmaschine, Testabdeckung, welcher Adapter zuerst, Datumsformate, Wächterverhalten.
Bevor du etwas als blockiert meldest, zähle jeden möglichen Berechtigungsnachweis auf (ein erschöpfter API-Schlüssel auf der Festplatte bedeutet nicht, dass es nicht einen anderen gibt, der funktioniert).
Siehe auch: build-remote-mcp-server (ein weiteres „natives Oberflächen“-Muster).