Kostenlos testen
Handbuch

Channels

Die sechs Kanäle der Inbox — Setup, Webhooks, Limits, Eigenheiten.

Die Inbox versteht heute sechs Kanäle. Jeder hat seinen eigenen Adapter (src/Service/Messaging/Adapter/...), eigene Webhook-Routen und kanalspezifische Eigenheiten — aber alle landen am Ende im selben Inbox-Thread.

Übersicht

Kanal Modus Webhook-Pfad Reply-Fenster Templates erforderlich
Email IMAP-Polling + SMTP-Versand /webhooks/email/{tenant} (Catch-All) unbegrenzt nein
Facebook Messenger Meta Webhook (Push) /webhooks/meta/{tenant}/messenger 24h Standard, 7d HSM Tags + HSM für >24h
Instagram-DM Meta Webhook (Push) /webhooks/meta/{tenant}/instagram 24h optional
WhatsApp Business Meta Cloud API (Push) /webhooks/meta/{tenant}/whatsapp 24h HSM-Templates zwingend für initiale Nachrichten
Facebook Comments Meta Webhook (Push) /webhooks/meta/{tenant}/page-feed unbegrenzt Public Reply + Private Reply
Web-Chat-Widget SSE-Verbindung direkt im Chat-Endpoint nur Session-Dauer nein

Email

Der älteste und am gründlichsten getestete Adapter. Eingang läuft über IMAP-Polling (alle 60 Sekunden), Versand über tenant-spezifisches SMTP oder Resend.

Setup:

  1. IMAP-Postfach (z. B. support@deine-firma.de) in config/tenants/<code>/email.php eintragen
  2. SMTP-Zugang einrichten oder Resend-API-Key hinterlegen
  3. Auto-Reply-Regeln + Klassifizierungs-Profil definieren (siehe Auto-Reply)

Eigenheiten:

  • Threading via In-Reply-To und References Header. Bei Mailclients, die Re:-Prefix mit ihrer eigenen Konvention überschreiben, kann Threading reißen — der Adapter hat einen Fuzzy-Fallback über Subject-Normalisierung + Email-Adresse.

  • Anhänge werden als Files persistiert und stehen dem Agenten als uploads zur Verfügung. Bilder werden bei Bedarf an das Vision-Modell weitergereicht.

  • HTML→Text-Konvertierung entfernt Marketing-Wrapper, Signaturen mit Trennlinien (-- ), Quoting-Blöcke (> Zitate). So sieht der Agent die eigentliche Nachricht.

  • Auto-Resolve für Bounces (Subject enthält „Delivery failed", X-Failed-Recipients-Header), Out-of-Office (Auto-Submitted-Header), Spam (X-Spam-Status, sender reputation).

  • Mehrere Postfächer, mehrere Firmen/Absender. channels.email.sender_profile ist der Default für den ganzen Kanal — reicht, solange alle konfigurierten Postfächer (auch mehrere aus Redundanzgründen, z. B. Bloomify mit Primary+Backup) am Ende denselben Absender benutzen sollen. Hat ein Workspace dagegen mehrere Postfächer verschiedener Firmen (z. B. 5 Strato-Postfächer wie bei Erdem Group), braucht JEDES Postfach sein eigenes sender_profile:

    // channels.php → channels.email
    'mailboxes' => [
        ['id' => 'ue',    'sender_profile' => 'ue',    /* host/username/password/... */],
        ['id' => 'admin', 'sender_profile' => 'admin', /* ... */],
    ],
    
    // email.php
    'email.senders' => [
        'ue'    => ['from' => ['ue@erdemgroup.de' => 'UE'], 'transport' => [...]],
        'admin' => ['from' => ['admin@erdemgroup.de' => 'Admin'], 'transport' => [...]],
    ],
    

    Beim Ingest merkt sich der Adapter, aus welchem Postfach eine Mail kam (_mailbox_id, landet in chat_message_emails.headers — keine eigene Tabelle). Beim Senden einer Antwort wählt EmailAdapter::resolveSenderProfile() darüber das passende email.senders-Profil. Fail-closed: hat mindestens eine Mailbox ein eigenes sender_profile, aber die Mailbox dieses Threads ist unbekannt oder selbst nicht zugeordnet, wird NICHT gesendet — der Mitarbeiter sieht einen Fehler statt dass die Antwort versehentlich von der falschen Firma raus geht. Ohne jede Mailbox-Zuordnung (Bestand: meco, bloomify) bleibt alles unverändert beim globalen sender_profile.

  • Speichergrenzen. Der Mailtext in der Chat-Nachricht (das, was Bots und Suche lesen) ist auf 64 KB gekappt (Inbox.email_content_max_bytes); der volle Text und das HTML stehen in der E-Mail-Ansicht. Große Bodies (> 32 KB, Inbox.email_body_offload_bytes) liegen gzip-komprimiert unter files/inbox/_bodies/ statt in der Datenbank und werden beim Lesen transparent nachgeladen.

  • System-Mails (Zahlungs-Webhooks, Noreply-Benachrichtigungen) werden als System markiert (Thread sofort erledigt, Kategorie z. B. webhook) und auf 8 KB gekürzt — oder gar nicht gespeichert:

    // channels.php → channels.email
    'system_mail' => [
        'action'           => 'truncate',   // oder 'skip' = gar nicht ingesten
        'max_bytes'        => 8192,
        'from_patterns'    => ['alerts@shop.example → monitoring'],
        'subject_patterns' => ['[Cron]'],
        'platform_defaults' => true,        // Plattform-Liste (Braintree/Stripe/PayPal-Webhooks) mitnehmen
    ],
    

    Muster sind Teilstrings (Groß/klein egal), muster → kategorie setzt die Thread-Kategorie. Die Plattform-Liste steht in config/email.php (TaskMonkey.system_mail). Bestand: bin/cake trim_email_content (Probelauf, --apply schreibt).

Facebook Messenger

Setup:

  1. Facebook App im Meta-Developer-Dashboard anlegen
  2. Page-Token für die Seite generieren
  3. Webhook-URL https://app.taskmonkey.de/webhooks/meta/{tenant}/messenger mit dem Verify-Token aus der Tenant-Config registrieren
  4. messages, messaging_postbacks, message_reactions als Events abonnieren

Eigenheiten:

  • 24-Stunden-Antwortfenster: Nach 24 Stunden ohne User-Interaktion brauchst du ein Message Tag oder Human Agent Tag, um eine Nachricht zu senden, ohne dass Meta sie ablehnt. Die Plattform setzt das Tag automatisch, wenn du via Inbox-UI antwortest und das Fenster abgelaufen ist.
  • PSID (Page-Scoped User ID) statt User-Profil: du siehst keinen echten Namen, sondern Vorname + Nachname, wie der User sie für Messenger eingestellt hat. Über User Profile API kannst du Profilbild + öffentliche Daten nachladen.
  • Threading ist trivial: PSID = Thread.

Instagram-DM

Setup analog Facebook Messenger, aber:

  • Instagram Business Account muss mit einer Facebook-Seite verknüpft sein (sonst keine API-Permission)
  • Webhook-Event: messages auf dem instagram Subscription Object
  • Comments und DMs sind getrennte Webhook-Events — DMs kommen über den Instagram-Adapter, Comments über den Facebook-Adapter (Page-Feed)

Eigenheiten:

  • Nur Text + ein Bild pro Nachricht
  • Reactions (Herz, Lachen, …) lösen ebenfalls Webhook-Events aus — die Inbox blendet sie als Status-Update im Thread ein, aber der Agent reagiert nicht darauf
  • Story-Replies werden als reguläre DM zugestellt, mit Reference auf die Story

WhatsApp Business

Über die Meta WhatsApp Cloud API.

Setup:

  1. Meta Business Account mit WhatsApp Business API aktivieren (Phone Number Verification)
  2. Phone-Number-ID und Access Token in config/tenants/<code>/apis.php hinterlegen
  3. Webhook auf https://app.taskmonkey.de/webhooks/meta/{tenant}/whatsapp registrieren

Eigenheiten:

  • 24-Stunden-Antwortfenster wie bei Messenger. Außerhalb dieses Fensters darfst du nur HSM-Templates (Pre-approved Templates mit Variablen) senden — Freitext ist verboten und wird von Meta abgelehnt.
  • Templates musst du im Meta Business Manager anlegen und genehmigen lassen. Die Plattform unterstützt das Senden via Template-Name + Variablen-Map (siehe Templates).
  • Kostenmodell: Konversationsbasiert. Jede Konversation (= 24-Stunden-Fenster) kostet je nach Region 0.005–0.07 €. Die Plattform aggregiert das pro Tenant für die spätere Abrechnung.
  • Antwort-Buttons: Setzt der Assistant bei der automatischen Antwort (autoReplyChannel) Vorschläge per setSuggestions, gehen sie als WhatsApp-Antwort-Buttons raus — höchstens 3, Titel höchstens 20 Zeichen, Text höchstens 1024 Zeichen. Passt das nicht, stehen die Vorschläge als Liste unter dem Text. Ein Klick kommt als normale Nachricht mit dem Button-Titel zurück (z. B. „Ja, live schalten“).
  • Bilder und Sprachnachrichten: Fotos landen als Upload im Chat (für Tools über $ctx['uploads'], z. B. contaoUploadImage), Sprachnachrichten werden transkribiert (Deepgram, DEEPGRAM_API_KEY) und kommen als Text „🎤 …“ beim Assistant an.

Facebook Comments

Kommentare unter Posts deiner Facebook-Seite. Anders als DMs sind sie öffentlich und tauchen unter dem Post auf — was ein Standard-Customer-Service-Tool damit machen kann, ist begrenzt.

Setup:

  • Standard-Meta-Webhook, Subscription auf feed Event
  • Filter: nur Comments auf eigenen Posts, nicht eigene Comments

Eigenheiten:

  • Public Reply: öffentlicher Kommentar als Antwort. Alle sehen sie.
  • Private Reply: Meta erlaubt einmal pro Comment, dem User eine private Messenger-Nachricht zu schicken (nur einmal!). Das ist nützlich für „Wir helfen dir gerne — schreib uns bitte privat".
  • Threading: ein Comment-Thread wird in der Inbox als ein Thread dargestellt, mit post_id:psid als Thread-Key.
  • Hide/Delete: Spam-Comments kann der Agent automatisch ausblenden (nicht löschen — Deletion ist destruktiv und nicht reversibel).

Web-Chat-Widget

Das TaskMonkey Chat-Widget auf deiner eigenen Website. Im Gegensatz zu den Social-Channels ist es direkt mit dem Chat-System integriert — keine externen Webhooks nötig.

Setup:

  • Widget per <script>-Tag einbinden (siehe Widget-Embedding)
  • Public-Chat-Config mit eigenem Assistant + erlaubten Tools
  • Branding via Widget-Theme

Eigenheiten:

  • Anonyme Sessions: kein Login. User wird über ein gehashtes Cookie identifiziert (max. 30 Tage), Reload startet neue Session.
  • Realtime via SSE: Antworten streamen direkt ohne Polling, gleicher Mechanismus wie der eingeloggte Chat.
  • Lead-Erfassung optional: Wenn ein User Kontakt aufnehmen will, fragt der Agent nach Name/Email/Telefon und legt einen Lead in Supabase an.
  • Cross-Channel-Bridge: Mit der gleichen Email-Adresse, mit der ein User später per Mail schreibt, wird der Web-Widget-Thread mit dem Email-Thread automatisch zusammengeführt (falls Auto-Merge aktiviert ist).

Adapter-Architektur

Jeder Channel hat einen Adapter im Verzeichnis src/Service/Messaging/Adapter/. Der Adapter ist verantwortlich für:

  • Inbound: Webhook-Payload entgegennehmen, validieren (Signature-Check), in ein generisches InboundMessage-Objekt überführen
  • Outbound: Generisches Reply-Objekt entgegennehmen, kanalspezifisch (Tag, Template, Public/Private) ausliefern
  • Threading: chat_id deterministisch ableiten (PSID, Email-Adresse, Phone-Number)
  • Profil-Lookup: User-Daten lazy laden (Avatar, Name)

Das InboundMessage-Objekt ist generisch — ab dem Punkt, an dem es übergeben wird, kennt der nachgelagerte Code (Klassifizierung, Auto-Reply, LLM-Aufruf) den Channel nicht mehr. Das bedeutet: ein neuer Channel = neuer Adapter, der Rest funktioniert ohne Änderung.

Aktuell vorhanden:

src/Service/Messaging/Adapter/
├── EmailAdapter.php
├── FacebookAdapter.php
├── FacebookCommentAdapter.php
├── InstagramAdapter.php
├── MetaMessagingAdapter.php   # gemeinsame Basisklasse
└── WhatsAppAdapter.php

Geplante Channels (siehe Roadmap): Telegram, Slack, Microsoft Teams, LinkedIn-DMs.

Zuletzt aktualisiert: 2026-09-27