Skip to main content

Twilio SMS Integration

The ticket system sends SMS alerts via Twilio for critical-urgency tickets. The integration includes deduplication, rate limiting, opt-out management, and delivery status tracking.


Overview

ComponentDetails
ServiceTwilio Programmable SMS
Key Fileinclude/class.twilio-sms.php
TriggersAI urgency set to CRITICAL
RecipientsAssigned staff + PMs
Cleanup Croncron-twilio-cleanup.php

SMS Alert Flow

Gemini AI sets urgency = CRITICAL
→ Check ost_ticket_sms_alert (dedup — one SMS per ticket)
→ If not already sent:
→ Check ost_twilio_daily_counter (rate limit)
→ Check ost_twilio_sms_optout (opt-out list)
→ Send SMS via Twilio API
→ Record in ost_ticket_sms_alert (UNIQUE on ticket_id)
→ Increment daily counter
→ Twilio fires status_callback webhook
→ Delivery status stored in ost_twilio_delivery_status

Deduplication

Each ticket can only trigger one SMS alert, enforced by a UNIQUE constraint:

-- ost_ticket_sms_alert
CREATE TABLE ost_ticket_sms_alert (
id INT AUTO_INCREMENT PRIMARY KEY,
ticket_id INT NOT NULL,
staff_id INT NOT NULL,
phone_number VARCHAR(20),
message_sid VARCHAR(64),
sent_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY unique_ticket (ticket_id)
);

If a ticket's urgency is re-evaluated and set to CRITICAL again, no duplicate SMS is sent.


Rate Limiting

A daily counter prevents excessive SMS sending:

-- ost_twilio_daily_counter
CREATE TABLE ost_twilio_daily_counter (
id INT AUTO_INCREMENT PRIMARY KEY,
date DATE NOT NULL,
count INT DEFAULT 0,
UNIQUE KEY unique_date (date)
);

The daily limit is configurable in admin settings. When the limit is reached, SMS alerts are queued but not sent until the next day.

Counter Reset

The cron-twilio-cleanup.php cron (midnight daily) resets counters and generates a failure report for any undelivered messages.


Opt-Out Management

Staff can opt out of SMS alerts:

-- ost_twilio_sms_optout
CREATE TABLE ost_twilio_sms_optout (
id INT AUTO_INCREMENT PRIMARY KEY,
phone_number VARCHAR(20) NOT NULL,
staff_id INT,
opted_out_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY unique_phone (phone_number)
);

Opt-outs are managed via Admin → Twilio → Opt-Outs (scp/twilio-optouts.php).


Delivery Status Webhooks

Twilio sends delivery status updates to a webhook endpoint:

MethodEndpointDescription
POST/scp/ajax.php/twilio/status_callbackReceives delivery status from Twilio

Status events are stored in ost_twilio_delivery_status:

StatusMeaning
queuedMessage accepted by Twilio
sentMessage sent to carrier
deliveredMessage confirmed delivered
failedDelivery failed
undeliveredCould not be delivered

Configuration

Configured via Admin → Settings → Twilio SMS:

SettingPurpose
Account SIDTwilio account identifier
Auth TokenTwilio authentication token
From NumberTwilio phone number (sender)
Daily LimitMaximum SMS per day
Test ModeWhen enabled, logs SMS but doesn't send
Status Callback URLWebhook URL for delivery status

Message Format

🚨 CRITICAL TICKET #108749
Subject: Checkout page 500 error
Client: Acme Corp
Urgency: CRITICAL (95%)
Est. Hours: 4.5

View: https://tickets.rhinogroup.com/scp/tickets.php?number=108749

Troubleshooting

IssueSolution
SMS not sendingCheck daily counter hasn't hit limit; verify Test Mode is off
Duplicate SMSShould be impossible (UNIQUE constraint); check for race condition
"Undelivered" statusCheck recipient number is valid; review Twilio error codes
Opt-out not respectedVerify number format matches (include country code)
Webhook not receivingVerify callback URL is accessible from internet; check Apache config

Cron: Cleanup (cron-twilio-cleanup.php)

Runs at midnight daily:

  1. Resets daily SMS counter for the new day
  2. Checks for any failed or undelivered messages from prior day
  3. Generates failure report email to admins
  4. Cleans up delivery status records older than 30 days

Key Files

FilePurpose
include/class.twilio-sms.phpTwilio API client, SMS sending, dedup, rate limiting
cron-twilio-cleanup.phpDaily cleanup cron (counter reset, failure report)
scp/twilio-optouts.phpAdmin UI for managing SMS opt-outs
deploy/deploy-sms-tracking.sqlMigration: creates all Twilio tables