This repository contains a Flask application (run under Gunicorn) for handling Twilio API interactions and sending messages to a RabbitMQ exchange for consumption by other services.
- Receiving SMS: The app receives inbound SMS from Twilio, validates authenticity, and forwards message data to RabbitMQ.
- Sending SMS: The app also exposes protected endpoints to queue outgoing SMS messages. These are consumed by an internal consumer that fires off the SMS through Twilio.
- Validates incoming webhooks using Twilio's request signature.
- Publishes inbound messages to RabbitMQ exchange with a structured routing key.
- Offers endpoints for sending, banning, or unbanning phone numbers via GET requests.
- Uses Redis to track acknowledgments for inbound messages (e.g. to verify that the message was consumed).
-
app.py:- Sets up a Flask application with multiple routes (
/sms,/send,/ban,/unban, etc.). - Handles inbound SMS with
@validate_twilio_request. - Publishes inbound messages to RabbitMQ on the
source.twilio.sms.incomingrouting key. - Launches a consumer thread that listens for
source.twilio.sms.outgoingmessages, which are then sent via the Twilio API. - Acknowledgments flow back through a
/acknowledgeendpoint.
- Sets up a Flask application with multiple routes (
-
config.py:- Holds environment variables and constants (Twilio credentials, RabbitMQ info, etc.).
-
utils/:- Utility modules for logging and Redis connectivity.
- Twilio will retry or fall back to a secondary handler if this app doesn't return a 200 status.
- The
/acknowledgeendpoint needs multiple Flask/Gunicorn workers or processes. Otherwise, the main process might block while waiting for the acknowledgment. - Inbound message requests are validated through the Twilio signature in
validate_twilio_request(). - Outbound message sending uses a background consumer that reads from the RabbitMQ queue, calls Twilio, and logs the result.
-
Install dependencies:
pip install -r requirements.txt
-
Set environment variables
-
Ensure your RabbitMQ and Redis server is online
-
Launch with Docker (using
make)
Configure your Twilio phone number's webhook to point at /sms. For example: https://yourdomain.com/sms
When Twilio sends an inbound SMS:
- The app verifies Twilio's signature.
- It publishes the message into RabbitMQ with routing key source.
twilio.sms.incoming. - It waits briefly for a downstream acknowledgment on
/acknowledge. - Responds with TwiML (or returns an error if acknowledgment isn't received in time, to let Twilio know to use its fallback).
There are two main ways to send a text from this app:
- Direct RabbitMQ (publish your own message to
source.twilio.sms.outgoing). - Via the
/sendendpoint in your browser (GET request).-
Example:
GET https://yourdomain.com/send?password=secret123&recipient_number=%2B12025550123&body=Hello+WBOR
-
Must pass the correct password defined in the
.env. -
Must supply recipient_number in E.164 format (e.g.
+12025550123). -
Must supply body text within 1600 characters.
-

