Skip to main content

Booking Event Triggers

Overview

Booking activity — creation, cancellation, status changes, reminders coming due — should be able to drive workflows. For example: when a customer books service A, send them preparation instructions; when they cancel, add them to a "cancelled customers" audience so a promotion can be sent later.

This job is the bridge between the appointment domain and the trigger engine: it matches rules, enriches the data, and publishes work onto the action_execute queue.

Business Flow

  1. Receive a BookingEventPayload containing the identifying fields — bookingId, userId, lineOaId, organizationId — plus optional detail such as journeyId, serviceId, staffId, locationId, status, dates and times, and the service, staff, location and customer names.

  2. Enrich the payload — any field the producer left empty is filled in from the database: service name, staff name, location name, dates and times. Values are only filled in when the original really is absent.

  3. Resolve which source types to match based on the event type.

    Event typeSource types matched
    booking_createdbooking_created
    booking_cancelledbooking_cancelled and booking_status_changed
    booking_reminderbooking_reminder
    booking_status_changedbooking_status_changed
  4. Query trigger_rule for rules with any of those source types, belonging to the same OA and organisation, enabled, and not soft-deleted.

  5. Each rule is filtered a second time against the conditions in its source config — the journey, service, location or staff member must match. Rules that do not match are skipped.

  6. Build the action payload by merging the enriched booking data into the action config, so downstream actions can use booking details as merge tags (sending a booking link, for example).

  7. Publish onto the action_execute queue.

  8. Merge the appt_* values, such as appt_service and appt_date, into line_user.custom_attribute so they become available for segmentation.

  9. The service swallows all of its own errors rather than propagating them, so the handler always acknowledges the message.

Key Files & Functions

FileResponsibility
internal/appointment/booking_event.goBookingEventService.ProcessEvent covers the whole flow, supported by getSourceTypes, matchesSourceConfig, enrichPayload and updateCustomAttributes. BookingEventPayload uses pointers for optional fields so "sent as null" can be told apart from "not sent at all".
internal/appointment/consumer.goConsumer.HandleBookingEvent
internal/appointment/helpers.gocollectRows, asMap, nullableAny
cmd/worker/main.gorunCronScheduler — constructs the service and wires its target queue to action_execute

Queues: consumes booking_event_trigger and publishes action_execute, both on the cron-scheduler profile.

Connections to Other Services

  • Receives jobs from the pg-listener via pg_notify('booking_event'), emitted by a trigger on appointment.booking. The real origin is client-api-go or cms-api-go modifying a booking.
  • Database tablestrigger_rule (the rules being matched); the appointment tables booking, journey, service, staff and location (used for enrichment); and line_user (the appt_* custom attributes).
  • RabbitMQ — publishes to action_execute, handing off to Action Execution.
  • No direct LINE API calls: messages are actually sent by the action executor or by Appointment Notifications.