SMS Integration with SignalWire

This document explains the SMS notification system for Quarry Rentals using SignalWire.

Overview

The SMS integration sends automated text message notifications to customers for:

Configuration

Environment Variables

The following environment variables are configured in .env and .kamal/secrets:

SIGNALWIRE_PROJECT_ID=f44e91f7-e99f-4d00-938b-32abd1f56440
SIGNALWIRE_SPACE_URL=quarryllc.signalwire.com
SIGNALWIRE_TOKEN=PT6cb78671dcc14ad5992fb218c8012fcfa9663c7cf5130502
SIGNALWIRE_FROM_NUMBER=+14157611123

Components

1. SmsService (app/services/sms_service.rb)

Core service for sending SMS messages via SignalWire API.

Methods:

Example:

sms_service = SmsService.new
result = sms_service.send_delivery_reminder(order)
# => { success: true, message_sid: "...", status: "queued", ... }

2. Background Jobs

SendDeliveryReminderSmsJob

Sends delivery reminder SMS for a specific order.

SendDeliveryReminderSmsJob.perform_later(order.id)

SendPickupReminderSmsJob

Sends pickup reminder SMS for a specific order.

SendPickupReminderSmsJob.perform_later(order.id)

SendOrderStatusSmsJob

Sends status update SMS when order status changes.

SendOrderStatusSmsJob.perform_later(order.id, "confirmed")

SendSmsRemindersJob

Daily job that queues reminders for tomorrow's deliveries and pickups.

SendSmsRemindersJob.perform_now

3. Order Model Integration

The Order model automatically sends status update SMS when the status changes:

after_update :send_status_update_sms, if: :saved_change_to_status?

4. SMS Tracking Fields

Orders table includes fields to track SMS notifications:

5. Webhook Controller

Handles incoming SMS messages from SignalWire.

Endpoint: POST /webhooks/sms

The webhook:

  1. Receives incoming SMS from customers
  2. Finds the associated order by phone number
  3. Logs the message
  4. Sends auto-reply to customer
  5. Notifies admin via email (if configured)

Usage

Automatic Notifications

Order Status Updates

SMS notifications are sent automatically when order status changes to:

Daily Reminders

Set up a cron job to run daily at 5 PM:

# Using cron
0 17 * * * cd /path/to/app && bin/rails sms:send_reminders

# Or using whenever gem
every 1.day, at: '5:00 pm' do
  rake "sms:send_reminders"
end

Manual SMS Sending

# Send delivery reminder for a specific order
sms_service = SmsService.new
result = sms_service.send_delivery_reminder(order)

# Send custom SMS
result = sms_service.send_sms(
  to: "+15551234567",
  body: "Your custom message here"
)

Testing SMS Integration

Test SMS Service in Console

# Rails console
order = Order.last
sms_service = SmsService.new

# Test delivery reminder
result = sms_service.send_delivery_reminder(order)
puts result.inspect

# Test pickup reminder
result = sms_service.send_pickup_reminder(order)
puts result.inspect

# Test status update
result = sms_service.send_order_status_update(order, "confirmed")
puts result.inspect

Test Background Jobs

# Test individual job
SendDeliveryReminderSmsJob.perform_now(order.id)

# Test daily reminders job
SendSmsRemindersJob.perform_now

Test Rake Task

bin/rails sms:send_reminders

SignalWire Setup

Configure Phone Number

  1. Log into SignalWire dashboard: https://quarryllc.signalwire.com
  2. Go to Phone Numbers
  3. Select your phone number (+1 (415) 761-1123)
  4. Under "Messaging", configure:

Test Phone Number

Send a test SMS to +1 (415) 761-1123 to verify webhook is working.

Message Templates

Delivery Reminder

Quarry Rentals: Your [product] delivery is scheduled for [date].
We'll call 30 min before arrival. Questions? Reply to this message or call us.

Pickup Reminder

Quarry Rentals: Your [product] pickup is scheduled for [date].
Please ensure the container is accessible. Questions? Reply to this message.

Status Updates

Monitoring

Check SMS Logs

# Find orders with sent delivery reminders
Order.where.not(delivery_reminder_sent_at: nil)

# Find orders with sent pickup reminders
Order.where.not(pickup_reminder_sent_at: nil)

# Check Rails logs
tail -f log/production.log | grep "SMS"

SignalWire Dashboard

Monitor SMS delivery, costs, and responses at: https://quarryllc.signalwire.com/logs

Error Handling

The SmsService includes error handling for:

All errors are logged to Rails logger and return a hash with success: false and error message.

Security Notes

  1. Webhook Security: The webhook endpoint skips CSRF token verification and authentication
  2. Phone Number Privacy: Customer phone numbers are never exposed in logs (only last 4 digits)
  3. Rate Limiting: Consider implementing rate limiting for webhook endpoint
  4. Credentials: Store SignalWire credentials securely (already in .env and .kamal/secrets)

Troubleshooting

SMS Not Sending

  1. Check environment variables are loaded:

    ENV['SIGNALWIRE_PROJECT_ID']
    ENV['SIGNALWIRE_TOKEN']
    ENV['SIGNALWIRE_SPACE_URL']
    
  2. Verify customer has valid phone number:

    order.contact&.phone.present?
    
  3. Check SignalWire logs for delivery status

Webhook Not Working

  1. Verify webhook URL in SignalWire dashboard
  2. Check webhook endpoint is accessible: curl -X POST https://admin.quarryrents.com/webhooks/sms
  3. Review Rails logs for incoming requests

Background Jobs Not Running

  1. Ensure Solid Queue is running:

    bin/rails solid_queue:start
    
  2. Check job queue:

    SolidQueue::Job.all
    

Future Enhancements