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. -
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 currently primarily triggered by Online Booking events and Cron Jobs. Manual actions performed by receptionists via the Scheduling Tab do not trigger SMS notifications in the current implementation.
For a business-process view of these flows (including the desired future state), please see SMS User Flows.
1. Current State Analysis
| Event | Online Booking Trigger | Manual Trigger (Receptionist) | SMS Sent? | Note |
|---|---|---|---|---|
| Scheduled | OnlineBookingService.createAppointment |
TicketsService.create |
YES (Online only) | Manual bookings are silent. |
| Rescheduled | OnlineBookingService.updateAppointment |
TicketsService.updateTicket |
YES (Online only) | Manual changes are silent. |
| Canceled | OnlineBookingService (Not Implemented) |
TicketsService.cancelTicket |
NO | No SMS is sent for cancellations from any source. |
| Confirmed | N/A | N/A | YES (Cron) | "Reminders" are sent via Cron job 1-3 days prior. |
2. Detailed Service Logic
A. Scheduled (New Appointment)
- Technical Implementation:
AppointmentNotificationService.sendSMSScheduledToCustomerexists but is only called byOnlineBookingService.
B. Rescheduled (Change Time/Date)
- Technical Implementation:
AppointmentNotificationService.sendSMSRescheduledToCustomerexists but is only called byOnlineBookingService.
C. Canceled
- Technical Implementation: No method exists for cancellation SMS.
D. Reminders / Confirmations (Cron)
- Trigger: Cron Job (
cronSendSMSConfirmationToCustomer) running every 30 minutes. - Logic:
- Finds appointments
Ndays in the future (configurable per salon). - Checks if
confirmationStatusis pending. - Sends SMS: "Please confirm your appointment at [Salon] on [Date]..."
- Updates status to
SENDING/SENT.
Maintenance
Remote Access via NordVPN
To access the Raspberry Pi remotely without being on the local network, you can use NordVPN's Meshnet feature. The account owner must first invite you to the Pi's Meshnet and ensure your access is restricted to the Pi only:
- Request an Invite: Ask the NordVPN account owner to send an invitation to join the Meshnet via your email address.
- Account Owner Instructions: SSH into the Raspberry Pi locally and run
nordvpn meshnet invite send <email@example.com>to send the invitation. Do not send this from the Windows App.
- Account Owner Instructions: SSH into the Raspberry Pi locally and run
- Restrict Local Access (Account Owner Only): To ensure the invited user cannot access the
192.168.x.xhome network, the account owner must explicitly disable their local network permissions.- Find the peer's Nord Name:
nordvpn meshnet peer list - Deny local access:
nordvpn meshnet peer local deny <their-nord-name>
- Find the peer's Nord Name:
- Accept and Connect: Ensure NordVPN is running, Meshnet is enabled, and accept the invitation in your app.
- SSH into the Raspberry Pi using its static Meshnet IP:
ssh pi@100.65.38.185 - Enter the Raspberry Pi password to connect.
Updating Cloudflared on Raspberry Pi
To update the cloudflared daemon tunneling the GSM gateway:
- Connect to the Raspberry Pi either via the local network or remotely using NordVPN.
- SSH into the Raspberry Pi:
- Local Network:
ssh pi@192.168.7.250 - Remote (NordVPN):
ssh pi@100.65.38.185
- Local Network:
- 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.