Skip to content

Exercise 1

Replace the No Operation node with Slack Send Message (to your ops channel):

⚠️ Onboarding for {{ $json.client_name }} is incomplete ({{ $json.failed_steps.length }} step(s) failed)
{{ $json.steps.filter(s => !s.ok).map(s => '• ' + s.step + ': ' + s.detail).join('\n') }}
Fix the issue, then re-run the same request (partial onboardings aren't blocked).

Exercise 2

New workflow 16b - Stripe → Onboarding:

  1. Stripe Trigger: event checkout.session.completed (Stripe credential with webhook permissions; test mode while building).
  2. Edit Fields Map Customer:
    • client_name = {{ $json.data.object.customer_details.name }}
    • contact_name = same (or a custom checkout field)
    • contact_email = {{ $json.data.object.customer_details.email }}
    • package = {{ $json.data.object.metadata.package ?? 'starter' }} (set metadata.package on your Payment Link / Checkout Session)
  3. HTTP Request: POST http://localhost:5678/webhook/onboarding/new-client, JSON body {{ $json }}. Use your public URL in production.

Stripe retries deliveries; the second delivery hits the registry and gets 409, so nothing is duplicated. Check the exact payload paths in the Stripe Trigger's output for your API version before relying on them (not tested against a live Stripe account).

Exercise 3

Asana example: replace Create ClickUp Tasks with Asana → Task → Create, Workspace and Project from Settings, Name {{ $json.name }}, Additional Fields → Due On {{ $json.due }}, Notes with owner role. Keep On Error → Continue. In report.js, rename the step to tasks and read $('Create Asana Tasks'). Plan, registry and email are untouched; that's the point of plan-then-act.

Exercise 4

  1. In Check Registry, expose what already succeeded:
    const doneSteps = (prev?.steps ?? []).filter(s => s.endsWith(':ok')).map(s => s.split(':')[0]);
    return [{ json: { ...plan, already_onboarded: blocked, previous: prev ?? null, done_steps: doneSteps } }];
    
  2. Before each step add an IF Skip <step>? on {{ $('Check Registry').first().json.done_steps.includes('slack_channel') }}. True → an Edit Fields node that outputs { id: 'previously-done', skipped: true } so the report still counts it as OK; false → the real node.
  3. In report.js, keep the detail readable: detail: j.skipped ? 'already done' : ….

On the re-run only the failed steps execute. Keep force: true for "redo everything". (Not run yet; verify it with fake-success nodes as in the README’s verification approach.)