GSM / SMS Integration
DailyDesk utilizes a custom GSM Gateway (Skyline) to send SMS notifications for marketing campaigns, appointment reminders, and reviews. This integration handles high-volume messaging by interfacing directly with a hardware or virtual GSM gateway via HTTP.
Network Configuration
The GSM Gateway is an on-premise hardware appliance. To expose it to the internet securely without opening inbound ports, a CloudFlare Tunnel is used via a cloudflared daemon running on the internal network.
There are two distinct endpoints exposed:
1. Administration Dashboard
- Public URL: https://gsm-admin.dailydesk.com/main_en.html
- Internal IP:
192.168.7.251
2. Backend API
- Public URL:
https://gsm.dailydesk.com/ - Internal IP:
192.168.7.250 - Usage: Used by the backend services to send SMS via HTTP requests.
Environment Variables & SSM Parameters
Secrets are managed in SSM Parameter Store and injected into the ECS containers.
SSM Path Pattern: /dailydesk/{stage}/{parameter}
| Variable | SSM Parameter Path | ARN (us-east-1) | Value |
|---|---|---|---|
SMS_BASE_URL |
/gsm/base-url |
arn:aws:ssm:us-east-1:858695866949:parameter/dailydesk/{stage}/gsm/base-url |
https://gsm.dailydesk.com |
SMS_USERNAME |
/gsm/username |
arn:aws:ssm:us-east-1:858695866949:parameter/dailydesk/{stage}/gsm/username |
root |
SMS_PASSWORD |
/gsm/password |
arn:aws:ssm:us-east-1:858695866949:parameter/dailydesk/{stage}/gsm/password |
(Secret) |
SMS_ENABLED |
/gsm/is-enabled |
arn:aws:ssm:us-east-1:858695866949:parameter/dailydesk/{stage}/gsm/is-enabled |
true |
Replace {stage} with dev or production.
Infrastructure (CDK)
The CdkBackendStack manages the scheduling of SMS tasks using EventBridge Rules:
- Review SMS: Triggers every 1 minute.
- Confirmation SMS: Triggers every 30 minutes.
- Campaign SMS: Triggers every 15 minutes.
These rules target the backend API endpoints (e.g., /crons/send-campaign) using an ApiDestination secured with an API Key.
Backend Implementation
Core Module: SmsGatewayModule
-
SmsGatewayService: The core service that abstracts the HTTP communication with the provider.- Method:
sendSMS(params, body) - Payload: Constructs a payload containing the
tasklist (phone numbers + message content) and asr_url(Status Report URL) where the gateway should send delivery receipts. - Events: Emits
ServerEvents.Logsupon success or failure for auditing.
- Method:
-
SmsGatewayController: Exposes endpoints for the gateway to call back:POST /sms-gateway/handle-serverless: The webhook endpoint that receives delivery status reports from the GSM gateway.
Application Logic
The SMS system is backend-driven, relying on scheduled tasks (Cron/EventBridge) or instant application triggers. The integration works by sending HTTP requests to a configured GSM Gateway URL.
1. Scheduled / Cron-Driven SMS
These messages are triggered by background jobs running on a fixed schedule (EventBridge).
sequenceDiagram
participant EventBridge
participant Backend as Backend (CampaignCronService)
participant Gateway as SmsGatewayService
participant GSM as Skyline GSM Gateway
participant User
EventBridge->>Backend: Trigger (e.g., Daily Campaign)
Backend->>Backend: Find Eligible Customers
Backend->>Gateway: sendSMS(payload)
Gateway->>GSM: HTTP POST /goip_post_sms.html
GSM->>User: Deliver SMS
GSM-->>Backend: Callback (Status Report)
Marketing Campaigns (CampaignCronService)
* Schedule: Every 15 minutes.
* Logic:
1. Selection: Queries CampaignRepository for Active campaigns (ONE_TIME or RECURRING) where nextCampaignDate matches today and sendTime has passed.
2. Audience: Aggregates all compatible target customers.
3. Execution: Formats batch payload and calls SmsGatewayService.sendSMS.
Review Requests (cronSendSMSReviewToCustomer)
* Schedule: Every 1 minute.
* Logic: Finds appointments checked-in X hours ago (setting: hoursAfterCheckInForTextMessages) that haven't received a request.
* Action: Sends a text with a review link and updates status to SENT.
Appointment Confirmations (cronSendSMSConfirmationToCustomer)
* Schedule: Every 30 minutes.
* Logic: Scans for upcoming appointments within a configured window (daysBeforeAppointment) that are not yet confirmed.
* Action: Sends a reminder/confirmation link.
2. Instant / Real-time SMS
These messages are triggered immediately by user actions in the application, bypassing the cron schedule.
sequenceDiagram
participant User
participant API as OnlineBookingService
participant Gateway as SmsGatewayService
participant GSM as Skyline GSM Gateway
User->>API: Book/Reschedule Appointment
API->>API: Process Booking
API->>Gateway: sendSMS(confirmation)
Gateway->>GSM: HTTP POST /goip_post_sms.html
GSM->>User: Deliver SMS
GSM-->>Gateway: Callback (Status Report)
Appointment Scheduled
* Trigger: Customer completes a booking via the Online Booking portal.
* Service: OnlineBookingService.createAppointment.
* Action: Sends an immediate confirmation text with booking details.
Appointment Rescheduled
* Trigger: Customer changes their appointment time.
* Service: OnlineBookingService.rescheduleAppointment.
* Action: Sends an immediate text with the new appointment details.
Maintenance
Updating Cloudflared on Raspberry Pi
To update the cloudflared daemon tunneling the GSM gateway:
- Connect to the local network hosting the GSM Gateway.
- SSH into the Raspberry Pi:
ssh pi@192.168.7.250 - Enter the Raspberry Pi password to connect.
- Run the update command:
sudo apt-get update && sudo apt-get install --only-upgrade cloudflared - Restart the service:
sudo systemctl restart cloudflared.service
Troubleshooting
Verification Steps
- Check Feature Flag: Ensure
SMS_ENABLEDis set totruein the environment's SSM parameters. - Check Logs: The backend logs
sendSMSevents. Search CloudWatch for#error: sendCampaignorsmsSending. - Gateway Status: Use the
getStatusmethod (exposed via API) to verify the backend can reach the GSM gateway.