← Back to cookbook

Event Registration

Handles registrations with confirmation emails and waitlist overflow.

switchstreamresend

Source

/**
 * Event registration with confirmation email and waitlist handling.
 */

form event_registration {
  label: "Event Registration"
  schema: @json {
    {
      "type": "object",
      "required": ["name", "email", "event_name"],
      "properties": {
        "name": { "type": "string", "title": "Full Name" },
        "email": { "type": "string", "format": "email", "title": "Email" },
        "event_name": { "type": "string", "title": "Event" },
        "company": { "type": "string", "title": "Company" },
        "dietary_restrictions": { "type": "string", "title": "Dietary Restrictions" }
      }
    }
  }
}

workflow register_attendee {
  label: "Register Attendee"

  root {
    type: code
    label: "Extract registration"
    code: @ts { return context.nodes.root.input }
    outputSchema: @json {
      {
        "type": "object",
        "properties": {
          "name": { "type": "string" },
          "email": { "type": "string" },
          "event_name": { "type": "string" },
          "company": { "type": "string" },
          "dietary_restrictions": { "type": "string" }
        }
      }
    }
  }

  node check_capacity {
    type: stream
    label: "Check current registrations"
    stream: registrations
    version: v1
    filter: @ts {
      return {}
    }
  }

  node route {
    type: switch
    label: "Route by capacity"
    cases: ["registered", "waitlisted"]
    router: @ts {
      const rows = context.nodes.check_capacity.output || []
      const count = Array.isArray(rows) ? rows.length : 0
      if (count < 100) return "registered"
      return "waitlisted"
    }
  }

  node confirm_registration {
    type: email
    label: "Send confirmation"
    from: @ts { return "[email protected]" }
    to: @ts { return context.nodes.root.output.email }
    subject: @ts { return "Confirmed: " + context.nodes.root.output.event_name }
    text: @ts {
      const reg = context.nodes.root.output
      return "Hi " + reg.name + ",\n\nYou are confirmed for " + reg.event_name + ". We look forward to seeing you there!"
    }
  }

  node waitlist_notification {
    type: email
    label: "Send waitlist notice"
    from: @ts { return "[email protected]" }
    to: @ts { return context.nodes.root.output.email }
    subject: @ts { return "Waitlisted: " + context.nodes.root.output.event_name }
    text: @ts {
      return "Hi " + context.nodes.root.output.name + ",\n\nThe event is currently at capacity. You have been added to the waitlist. We will notify you if a spot opens up."
    }
  }

  flow {
    root -> check_capacity
    check_capacity -> route
    route -["registered"]-> confirm_registration
    route -["waitlisted"]-> waitlist_notification
  }
}

stream registrations {
  label: "Event registrations"
  workflow: register_attendee
  version: v1

  versions: {
    v1 {
      schema: @json {
        {
          "type": "object",
          "required": ["name", "email", "event_name", "status"],
          "properties": {
            "name": { "type": "string" },
            "email": { "type": "string" },
            "event_name": { "type": "string" },
            "company": { "type": "string" },
            "status": { "type": "string" }
          }
        }
      }

      condition: @ts { return true }

      prepare: @ts {
        const reg = context.nodes.root.output
        const status = context.output.confirm_registration != null ? "registered" : "waitlisted"
        return {
          name: reg.name,
          email: reg.email,
          event_name: reg.event_name,
          company: reg.company || "",
          status: status
        }
      }
    }
  }
}

trigger on_register {
  form:event_registration -> register_attendee
  enabled: true
}

Flow

Trigger to workflow

Workflow nodes