Kostenlos testen
Handbuch

Reels auf Instagram und TikTok veröffentlichen

Fertige Reels (bin/reel) planen, per WhatsApp freigeben und zum Zeitpunkt auf Instagram (@taskmonkey.ai) und TikTok posten. Nur Workspace meco.

Plattform-intern (Workspace meco): Reels aus bin/reel (reel-editor) bzw. fertige MP4s gehen nach Marcus' Freigabe per WhatsApp automatisch raus. Keine KI-Avatar-Videos; das KI-Label-Feld (ai_generated, TikTok is_aigc) ist trotzdem vorgesehen und steht standardmäßig auf „nein“.

Ablauf

  1. Hochladen (Mac): reelStorageCreateUploadUrl liefert einen Objektnamen und eine signierte Upload-URL (2 h). Hochladen mit curl -sS -X PUT -H "Content-Type: video/mp4" --data-binary @reel.mp4 "<upload_url>". Ablage: privater Supabase-Bucket reels (meco-Speicher).
  2. Planen: scheduleReel(video_object, caption, platforms, publish_at, ai_generated=false) legt einen Eintrag in Supabase reel_schedule an (Status pending_approval).
  3. Freigabe: Marcus bekommt Video-Link (7 Tage gültig), Plattformen, Zeitpunkt und Caption per WhatsApp (Plattform-Nummer, nur im 24-h-Fenster) mit den Buttons Veröffentlichen / Nein, dazu immer eine Mail. Ist das Fenster zu, steht in der Mail der Befehl /reel ok <id> <code> zum Abschicken an die TaskMonkey-Nummer.
  4. Der Klick schickt /reel ok|nein <id8> <code>. Der ConversationRouter nimmt das nur von der Nummer des Reel-Empfängers an (Onboarding.alert.reel_recipients, sonst .recipients), ohne LLM, und legt den Job decideScheduledReel an. Der prüft Einmal-Code und Status und bestätigt per WhatsApp.
  5. Posten: Der Scheduled Task publish_reels (runScheduledReels, alle 5 min) postet freigegebene Reels ab publish_at. Danach kommt eine Meldung mit dem Ergebnis je Plattform.

Ohne „Veröffentlichen“ geht nichts raus. publishInstagramReel und publishTikTokVideo sind only_via: runScheduledReels, die Roh-Calls (igCreateReelContainer, igPublishContainer, tiktokInitVideoPost) nur über diese Hüllen. Eine Anfrage, die 24 h nach publish_at noch offen ist, wird expired.

Tools

Tool Was
reelStorageCreateUploadUrl, reelStorageSignUrl, reelStorageDelete Supabase Storage (apis.supabase_storage), je ein Call
reelProxyUrl signierte URL https://app.taskmonkey.de/media/reels/<objekt>.mp4?expires=…&token=… (ReelMediaController, Range-fähig)
igCreateReelContainer, igGetContainerStatus, igPublishContainer, igGetPublishingLimit Instagram Graph API über apis.meta_ads (System-User-Token)
metaCheckPublishPermissions liest me/permissions und zeigt, welche Rechte fehlen
publishInstagramReel Container → Status pollen bis FINISHED (ERROR/EXPIRED = Abbruch, Timeout apis.reels.instagram_max_wait) → media_publish. Prüft vorher das Limit von 50 Posts/24 h
tiktokGetCreatorInfo, tiktokInitVideoPost, tiktokGetPostStatus, tiktokGetUserInfo TikTok Content Posting API über apis.tiktok (Auth oauth_connection)
publishTikTokVideo creator_info → init (PULL_FROM_URL) → Status pollen. Ohne Audit immer SELF_ONLY
scheduleReel, decideScheduledReel, runScheduledReels Planung, Freigabe, Veröffentlichung
notifyReelApproval, notifyReelStatus Meldungen an Marcus (Core ReelMediaTools)

Wiederholung: Wenn Instagram nach dem Timeout noch verarbeitet oder media_publish fehlschlägt, versucht es der nächste Lauf noch einmal mit demselben Container (höchstens 3 Läufe). Was schon online ist, wird nie erneut gepostet. Ein TikTok-Timeout gilt als „übergeben“ und wird nicht wiederholt, sonst gäbe es einen Doppelpost. Ein Lauf, der über 1 h in publishing hängt, wird failed und gemeldet, aber nicht automatisch wiederholt.

Video-URL: warum zwei Wege

  • Instagram holt video_url von jeder öffentlichen URL. Wir nehmen eine signierte Supabase-URL (6 h).
  • TikTok holt nur von Domains oder URL-Präfixen, die in der TikTok-App verifiziert sind, und folgt keinen Redirects. Eine Supabase-Projekt-URL kann man dort nicht verifizieren. Deshalb liefert ReelMediaController das Objekt unter app.taskmonkey.de/media/reels/… aus (HMAC mit dem App-Salt, zeitlich begrenzt). In TikTok muss dafür die Domain taskmonkey.de verifiziert sein (DNS-TXT, gilt auch für app.).

Klickliste Meta (Instagram)

Stand 04.10. (metaCheckPublishPermissions, lesend): Der Token hat pages_show_list, pages_read_engagement, business_management, ads_management, ads_read, leads_retrieval, pages_manage_ads. Es fehlen instagram_basic und instagram_content_publish. content_publishing_limit antwortet mit „(#10) Application does not have permission for this action“.

  1. developers.facebook.com → App „TaskMonkey Ads“ → Anwendungsfälle → Anwendungsfall hinzufügen → „Nachrichten und Inhalte auf Instagram verwalten“ (Instagram API mit Facebook Login). Darin instagram_basic und instagram_content_publish hinzufügen. Standard-Zugriff reicht, weil es das eigene Business-Konto ist (kein App Review).
  2. business.facebook.com → Einstellungen → Konten → Instagram-Konten → prüfen, dass @taskmonkey.ai dem Business gehört und mit der Seite 108629875903438 verbunden ist (Seite → Verknüpfte Konten → Instagram).
  3. Dort bei @taskmonkey.ai: Personen/Partner zuweisen → Systemnutzer „Taskmonkey“ → Vollzugriff (mindestens „Inhalte“).
  4. Einstellungen → Konten → Seiten → 108629875903438 → Systemnutzer „Taskmonkey“ zugewiesen? Sonst zuweisen (Vollzugriff).
  5. Einstellungen → Nutzer → Systemnutzer → „Taskmonkey“ → Token generieren → App „TaskMonkey Ads“, Ablauf „Nie“. Häkchen: alles, was schon drin ist (ads_management, ads_read, business_management, leads_retrieval, pages_show_list, pages_read_engagement, pages_manage_ads), plus instagram_basic und instagram_content_publish.
  6. Den neuen Token an den Orchestrator geben. Er ersetzt META_ADS_ACCESS_TOKEN in tenants_untracked/meco/.env, lokal und auf Prod. Der alte Token bleibt gültig, bis man ihn widerruft.
  7. Prüfen: bin/cake test_tool -t meco --tool metaCheckPublishPermissions → ok: true, dann --tool igGetPublishingLimit → quota_usage.

Klickliste TikTok

  1. developers.tiktok.com → mit dem TikTok-Konto von TaskMonkey einloggen → Manage apps → Connect an app → Organisation „meco GmbH“ anlegen bzw. wählen, App „TaskMonkey“.
  2. App details: Icon (1024×1024), Name, Kategorie „Business“, Beschreibung („Plant und veröffentlicht die Reels von TaskMonkey nach Freigabe“), Platform Web, Website https://taskmonkey.de, Privacy https://taskmonkey.de/datenschutz, Terms of Service: die URL der Plattform-Nutzungsbedingungen bzw. AGB (TikTok verlangt beide Links; eine eigene AGB-Seite auf taskmonkey.de gibt es im Repo noch nicht).
  3. Products → Add products: Login Kit und Content Posting API. Bei Content Posting API Direct Post einschalten.
  4. Login Kit → Redirect URI: https://app.taskmonkey.de/manage/o-auth-connections/callback.
  5. Scopes: user.info.basic, video.upload, video.publish.
  6. URL properties → Verify domain → taskmonkey.de → TXT-Eintrag in Cloudflare (Zone taskmonkey.de) anlegen → Verify.
  7. Client key und Client secret an den Orchestrator geben: TIKTOK_CLIENT_KEY und TIKTOK_CLIENT_SECRET in config/.env auf Prod (und lokal zum Testen).
  8. Nach dem Deploy: app.taskmonkey.de/manage/o-auth-connections/add/tiktok (eingeloggt im Workspace meco) → „Videos veröffentlichen“ → TikTok-Login mit dem TaskMonkey-Konto → zustimmen. Der Token liegt danach verschlüsselt in oauth_connections und wird automatisch erneuert (Access 24 h, Refresh 365 Tage). Andere Workspaces bekommen den Provider nicht (only_tenants: meco).
  9. Test: bin/cake test_tool -t meco --tool tiktokGetUserInfo → display_name.
  10. Sandbox: Solange die App nicht live ist, im Tab Sandbox das TaskMonkey-Konto als Target User eintragen. Mit der Sandbox-App funktioniert der Login nur für diese Konten.
  11. Audit (für öffentliche Posts): Submit for review. Gebraucht wird:
    • ein Demo-Video des kompletten Ablaufs: Login über TaskMonkey, Freigabe-Anfrage, Post auf TikTok,
    • eine Erklärung je Scope,
    • die verifizierte Domain,
    • Datenschutz und AGB online.

Was ohne Audit geht (ehrlich)

  • Nicht auditierte Apps posten nur privat (SELF_ONLY, nur für das Konto selbst sichtbar). TikTok begrenzt außerdem, wie viele Konten in 24 h posten dürfen. publishTikTokVideo erzwingt SELF_ONLY, solange apis.tiktok.audited auf false steht. Erst nach bestandenem Audit audited => true und default_privacy => 'PUBLIC_TO_EVERYONE' setzen.

  • TikToks Richtlinien für Direct Post verlangen, dass der Nutzer jeden Post in der App sieht und bestätigt:

    • Konto-Name,
    • Sichtbarkeit wählen, ohne Vorauswahl,
    • Kommentare, Duett und Stitch,
    • Hinweis auf kommerzielle Inhalte,
    • Zustimmung zur Music Usage Confirmation.

    Unsere Freigabe per WhatsApp zeigt Video, Caption und Zeitpunkt, aber nicht diese Bedienelemente. Ein Audit für vollautomatisches Posten kann deshalb abgelehnt werden. Dann bleiben zwei Wege: eine kleine Freigabe-Seite mit diesen Elementen bauen, oder auf TikTok privat posten und von Hand auf öffentlich stellen.

  • Ein Post per API zählt bei TikTok wie ein normaler Post. Hashtags gehören in die Caption (title, max. 2200 Zeichen).

Nach dem Deploy

  1. Supabase-Migration db/supabase/meco_2026-10-04_reel_schedule.sql ausführen (Tabelle reel_schedule + Bucket reels, idempotent).
  2. Meta-Klickliste oben, neuen META_ADS_ACCESS_TOKEN setzen.
  3. TikTok-Klickliste, TIKTOK_CLIENT_KEY/TIKTOK_CLIENT_SECRET in config/.env, Verbindung anlegen.
  4. publish_reels in config/tenants/meco/scheduled.php auf enabled => true stellen. Das ist Code, also wieder Deploy.
  5. Erster Test: ein Reel mit platforms: ["instagram"] und publish_at in 10 Minuten planen, freigeben, Ergebnis abwarten.

Konfiguration

  • apis.meta_ads.instagram_user_id: 17841434304012708 (@taskmonkey.ai)
  • apis.supabase_storage: Storage-API mit dem Service-Key, bucket „reels“
  • apis.tiktok: audited, default_privacy
  • apis.reels: preview_ttl, fetch_ttl, *_max_wait, *_poll_interval
  • Onboarding.alert.reel_recipients (config/onboarding.php): Empfänger der Freigabe-Anfragen, leer = recipients
  • OAuthProviders.tiktok (config/oauth_providers.php): client_key, Scopes mit Komma, only_tenants, api_hosts
Zuletzt aktualisiert: 2026-10-04