Pushizo Docs

Journey'ler (Faz 11)

Journey, kullanıcıyı bir tetikleyiciyle içeri alıp bekleme, koşul, dallanma ve gönderim adımlarından geçiren otomatik akıştır (OneSignal Journeys eşdeğeri). Tasarım kararları: ADR-0018. Şema ve doğrulama:…

Journey, kullanıcıyı bir tetikleyiciyle içeri alıp bekleme, koşul, dallanma ve gönderim adımlarından geçiren otomatik akıştır (OneSignal Journeys eşdeğeri). Tasarım kararları: docs/adr/0018-journey-motoru.md. Şema ve doğrulama: packages/shared/src/journeys.ts.

Yaşam döngüsü

DurumAnlamı
draftHiç yayınlanmadı; silinebilir.
activeYayında; yeni girişler kabul edilir, run'lar ilerler.
pausedYeni giriş yok, bekleyen run'lar bekletilir; resume ile devam eder.
archivedKalıcı kapalı; açık run'lar journey_archived nedeniyle çıkarılır.

Düzenleme her zaman taslak sürüm üzerinde yapılır (PUT …/draft, PATCH …/nodes/:nodeId). publish taslağı yeni bir sürüm olarak yayınlar. Aktif run'lar girdikleri sürümde kalır (sürüm sabitleme); yeni girişler en son sürümü kullanır. Yayınlamadan önce yapısal ve anlamsal doğrulama çalışır; sorun varsa 400 ve details.issues döner.

Graf biçimi

React Flow uyumludur:

{
  "nodes": [{ "id": "t", "type": "trigger", "position": { "x": 0, "y": 0 }, "data": { "trigger": { "kind": "event", "event_name": "signup" } } }],
  "edges": [{ "id": "e1", "source": "t", "target": "w", "sourceHandle": "next" }]
}

Kurallar:

  • Tam olarak bir trigger düğümü olur ve döngü kurulamaz.
  • Her düğüm tetikleyiciden erişilebilir olmalıdır.
  • Her çıkış kolu (handle) en fazla bir kenara bağlanır; bağlanmamış kol, run'ın o noktada completed olması demektir.
  • Sınırlar JOURNEY_LIMITS içindedir: en fazla 100 düğüm, 200 kenar ve 5 dal; bekleme 60 sn ile 365 gün arasıdır.

Düğüm türleri

TürVeriKollar
triggertrigger.kind: event (+property_filters), segment_enter, api, schedule (segment_id, 5 alanlı cron, timezone)next
waitwait.mode: duration (seconds), until_time (HH:MM, user/app saat dilimi), until_date (at)next
wait_untilconditions[]: event, segment_enter, message (node_id + olay) ve timeout_secondscond_0…cond_n, timeout
time_windowwindows[] (days 0=Pazar…6, start, end) ve saat dilimi; pencere dışındaysa bir sonraki pencereye kadar beklernext
conditionrule: segment, filters (segment AST), message (yukarı akıştaki gönderimin olayı), event (within_days)yes, no
splitbranches[] (id, percent; toplam 100). Atama run_id üzerinden deterministiktir (FNV-1a)dal kimlikleri
send_push / send_email / send_smstemplate_id veya satır içi contentnext
send_in_appin_app_message_id, expires_secondsnext
webhookurl, headers, Liquid body (yalnızca POST)next
update_tagstags (null değeri tag'i siler)next
exit——

Mesaj olayları: sent, delivered, opened, clicked, failed, bounced, complained, unsubscribed.

Push → SMS yedeği örneği: send_push → wait_until [message (push düğümü, delivered), zaman aşımı 1 saat] → timeout kolu → send_sms.

Gönderim adımları

  • Her gönderim, source = journey ve journey_run_id alanlarıyla bir messages kaydı oluşturur. Gönderim normal teslimat hattından geçer, kampanya analitiği de bu kayıtla çalışır.
  • Kullanıcının o kanalda aktif aboneliği yoksa adım skipped olur ve run devam eder.
  • Sessiz saatler ve frekans sınırı uygulanır; settings.quiet_hours_exempt ve frequency_cap_exempt ile muaf tutulabilir.
  • send_in_app, kullanıcıya süreli bir gösterim hakkı (in_app_journey_grants) verir. journey_only: true olan in-app mesajlar yalnızca bu hakkı olan kullanıcılara gösterilir.
  • webhook düğümünün gövdesi Liquid ile yazılır; kapsamda user, journey, run ve context (giriş bağlamı) bulunur.
    • Gövde verilmezse varsayılan JSON gövde gönderilir: {type: "journey.webhook", journey_id, node_id, run_id, user, context}.
    • Her istek idempotency-key: <run_id>:<node_id> başlığını taşır.
    • SSRF koruması uygulanır.
    • Başarısız istek run'ı durdurmaz; sonuç adım istatistiğine yazılır.

Ayarlar (settings)

AlanAçıklama
re_entry.modenever (varsayılan), after_exit, after_days (+days)
only_new_usersSegment tetiklerinde yalnızca yayından sonra segmente girenler
exit_rules[]event, segment_enter, segment_exit, unsubscribed, became_active
exit_tagsÇıkışta (kural, hedef, exit düğümü) yazılacak tag'ler
goals[], exit_on_goalHedef olayı/segmenti; dönüşüm oranı istatistiği
schedule.start_at / end_atYeni girişlerin kabul edildiği aralık
quiet_hours_exempt, frequency_cap_exemptGönderim kısıtlarından muafiyet

Yürütme ve güvenilirlik

  • Doğruluk kaynağı veritabanıdır. Her adım step_seq üzerinde iyimser kilitle sahiplenilir; aynı işin iki kez çalışması etkisizdir.
  • Bekleyen run'lar next_action_at ile gecikmeli BullMQ işine bağlanır.
  • Kurtarma: her 10 sn'de vadesi gelmiş run'lar taranır. Worker yeniden başlasa veya Redis işleri kaybolsa da run'lar devam eder.
  • Segment ve takvim tetikleri: Redis kilidi altında her 60 sn'de taranır.
  • Sinyaller: olaylar (/v1/.../events) tetik, çıkış kuralı, hedef ve wait_until koşullarını işler. Teslimat olayları da (delivered, clicked …) run'lara sinyal olarak gelir.
  • Webhook olayları: journey.entered, journey.step_completed, journey.completed, journey.exited (webhooks.md).
  • Saklama: biten run'lar teslimat saklama süresi (deliveries) dolunca silinir; süresi geçmiş in-app hakları da temizlenir. Kullanıcı silindiğinde kullanıcının run'ları ve hakları da silinir.

API

Dashboard (oturum) uçları internal/v1/apps/:appId/journeys/… altındadır. Public uçlar aynı yolları v1/apps/:appId/journeys/… altında sunar.

YöntemYolKapsam
GET/journeys, /journeys/:id, /journeys/:id/versions, /journeys/:id/stats, /journeys/:id/runs, /journeys/:id/runs/:runIdanalytics:read
POST/PATCH/DELETE/journeys, /journeys/:id, PUT /journeys/:id/draft, PATCH /journeys/:id/nodes/:nodeIdadmin
POST/journeys/:id/publish, pause, resume, archive, duplicateadmin
POST/journeys/:id/runs (API ile giriş: external_id / user_id / alias, context)notifications:write
DELETE/journeys/:id/runs/:runId (run'dan çıkar)admin
GET/users/by/:label/:value/journeysanalytics:read

Run tetikleme yanıtı {entered, run, reason} biçimindedir. Giriş reddedilirse reason şu değerlerden biri olur: inactive, outside_schedule, re_entry, already_active, unknown_user.

SDK: Node hs.journeys.*, PHP $client->journeys() (sdk/node.md, sdk/php.md).

Örnek: kayıt → satın alma hatırlatma

trigger(event: signup) → wait(1 gün) → condition(event: purchase):

  • yes kolu: exit
  • no kolu: send_push → wait(3 gün) → send_email

Bu akış, zaman hızlandırmalı kabul testinde doğrulanır (apps/worker/src/__tests__/journeys.int.test.ts).

Bu sayfada