Agapi Platform Documentation
Central Backend Engine

Email, SMS, Push, and Background Delivery

Why each channel follows a different path and how to tell business success from message delivery success.

Notifications keep members and staff informed after booking, payment, account, and operator actions. The Symfony backend supports three channels, but it does not send all of them in the same way.

Why delivery is separate from the business action

A booking or payment should not always wait for a slow mail or messaging provider. The platform records the business change and then asks the appropriate channel to deliver a message.

This creates an important distinction:

  • business success means the booking, payment, or account change was saved;
  • delivery success means the provider accepted or delivered the message.

One can succeed while the other fails.

Email: queued work

Email is prepared from a known message type and template, then placed on AWS SQS when mail is enabled. The app:send-email command receives queued messages, builds the email, sends it through the configured mailer, and removes successfully handled messages from the queue.

flowchart LR
    A[Booking, payment, or account event] --> B[Prepare recipient, subject, and template data]
    B --> C[AWS SQS]
    C --> D[app:send-email worker]
    D --> E[Mail provider]

The queue prevents the original HTTP request from depending on immediate mail delivery. It also means a successful enqueue is not the same as a delivered email.

If mail is disabled, the service logs that it did not enqueue the message.

SMS: provider batch and later status

SMS is used for short member messages and booking-related notices. The service checks configuration, recipient numbers, sender name, allowed sending time, and message length before calling the SMS provider.

For newsletter/batch work, the provider can return a send-session ID. The newsletter remains in progress until later status checking classifies its results. The app:check-sms-sent command looks up in-progress sessions and creates success or failure records.

This is why “request accepted” and “SMS delivered” are different states.

Push: direct FCM request

Push notifications are sent directly to Firebase Cloud Messaging using the configured service-account data. The member must have a current device token.

The platform records provider response/error information and can build booking links for relevant messages. Push is not placed on the email SQS queue by the inspected service.

If one member has several device tokens, delivery can be attempted to more than one device. Old tokens can produce failures even when a newer device succeeds.

Broadcasts and event messages

The admin notification API supports:

  • create/list/send newsletter records;
  • send push to selected members;
  • send SMS to selected members;
  • list successful and failed SMS work;
  • list push reports;
  • list notification records.

Other services create event-specific messages, for example around booking or payment changes. The existence of a template does not prove that every possible event sends it; follow the actual producer.

External integration notifications

The notification service can also call a configured external integration URL for supported events. This is separate from SMS, push, and email and should be treated as another provider boundary with its own authentication and error result.

Scheduling and ownership

Symfony registers the email and SMS-status commands. Registration makes them available; it does not schedule them. Production frequency must be confirmed in the deployment scheduler or runner configuration.

The older agapi-member-booking service also has reminder jobs. See Background Jobs, Files, and Integrations for that separate path.

Investigating a missing message

ChannelCheck in this order
EmailProducer called → mail enabled → SQS message created → worker received it → mailer result.
SMSRecipients and text valid → provider batch/session created → status command ran → success/failed record.
PushCurrent device token → FCM request → provider response → push log/report.
External integrationIntegration enabled/configured → outbound request → response/error log.

Never repeat a broadcast until the original audience and provider result are known. A retry can send the same message twice to everyone who succeeded the first time.

Technical reference

Main services are NotificationService, EmailService, SmsService, PushService, and SqsService. Commands are app:send-email and app:check-sms-sent. Admin routes are grouped under /api/v1/notifications.

On this page