Back to Blog
Integration Guides

How to Send SMS with Twilio and Ruby on Rails: Step-by-Step Tutorial

Add Twilio SMS to your Rails app using the Twilio Ruby gem with Active Job for async sending and proper webhook controller setup.

DA
Danial A
Senior Twilio Consultant, Telphi Consulting
June 22, 2026
7 min read
Twilio
Integration
SDK
Mobile
How to Send SMS with Twilio and Ruby on Rails: Step-by-Step Tutorial

Twilio SMS and Ruby on Rails integrate through the Twilio Ruby gem added to the Gemfile, with credentials stored in Rails encrypted credentials or environment variables, service objects for dispatch logic, Active Job for asynchronous sending, and dedicated controllers for inbound SMS webhooks that return TwiML responses using the twilio-ruby TwiML builder. This integration is used by Rails teams building SaaS applications, marketplaces, or e-commerce platforms that need SMS for order alerts, OTP codes, appointment reminders, or user notifications, and who want to leverage Rails conventions including service objects, callbacks, and background jobs to integrate Twilio without polluting models or controllers with third-party API calls. The Twilio client is initialized in a service object, messages are dispatched from Active Job workers queued via Sidekiq or Solid Queue, and Twilio's status callbacks update message records through a webhook controller.

What You Need Before You Start

Add gem 'twilio-ruby', '~> 7.0' to your Gemfile and run bundle install. Store Twilio credentials in Rails encrypted credentials by running rails credentials:edit, which opens the credentials file in your editor, and adding a twilio section with account_sid, auth_token, and from_number keys. Access them in code as Rails.application.credentials.twilio[:account_sid]. Alternatively, use environment variables read with ENV.fetch('TWILIO_ACCOUNT_SID') which raises KeyError with a descriptive message if the variable is missing, providing fast failure for misconfiguration. Add an Active Job backend by installing Sidekiq or Solid Queue according to their documentation, configuring config.active_job.queue_adapter = :sidekiq or :solid_queue in config/application.rb, and ensuring the job processing server is running alongside Rails.

Step-by-Step Integration Guide

Create a TwilioService at app/services/twilio_service.rb that initializes the Twilio client in an initialize method with @client = Twilio::REST::Client.new(Rails.application.credentials.twilio[:account_sid], Rails.application.credentials.twilio[:auth_token]) and defines a send_sms(to:, body:) method that calls @client.messages.create(from: Rails.application.credentials.twilio[:from_number], to: to, body: body) wrapped in a begin/rescue catching Twilio::REST::RestError, logging the error with Rails.logger.error, and re-raising. Create an Active Job at app/jobs/send_sms_job.rb with rails generate job send_sms, inject TwilioService.new.send_sms(to: @to, body: @body) in the perform method, and dispatch from controllers with SendSmsJob.perform_later(to: phone, body: message). For inbound SMS webhooks, generate a controller with rails generate controller Twilio sms_webhook, define the sms_webhook action that constructs a Twilio::TwiML::MessagingResponse, calls twiml.message 'Reply text', renders xml: twiml.to_s, and protect_from_forgery with: :null_session in the controller. Add a route for POST /twilio/sms_webhook in routes.rb and set the URL in your Twilio Console phone number's messaging webhook configuration.

Common Issues and How to Fix Them

Rails encrypted credentials raise ActiveSupport::MessageEncryptor::InvalidMessage when the RAILS_MASTER_KEY environment variable is not set in the production environment, causing the Twilio credentials read to fail and the SendSmsJob to raise an exception. Set the RAILS_MASTER_KEY from config/master.key in your deployment environment's secrets configuration and verify with rails credentials:show in a production console. The Twilio::REST::Client initialization in a job fails when Rails.application.credentials.twilio returns nil because the credentials file has a different structure, such as a typo in the key name. Add a configuration initializer at config/initializers/twilio.rb that validates the presence of all three Twilio credentials using raise 'Missing Twilio credentials' if Rails.application.credentials.twilio.blank? so misconfiguration is caught at application boot. The inbound webhook controller returns HTTP 422 when called by Twilio because Rails CSRF protection raises an exception for POST requests without a valid CSRF token. Add protect_from_forgery with: :null_session to the Twilio controller class, not just the action, and implement Twilio signature validation using Twilio::Security::RequestValidator.new(auth_token).validate(url, params, signature) as a before_action to replace CSRF with Twilio's own request authentication.

How to Get More from This Integration

Build Rails Action Mailer-style abstractions for SMS by creating a TwilioMailer base class with class methods for each notification type such as order_confirmed(order) and appointment_reminder(appointment) that each return a TwilioMessage value object with the to number and body, and a deliver_later class method that enqueues a SendSmsJob, enabling notification dispatch with TwilioMailer.order_confirmed(@order).deliver_later syntax that mirrors Rails mailer conventions. Add delivery status tracking with Active Record by creating an SmsMessage model with rails generate model SmsMessage sid:string to:string body:string status:string, saving the model after each TwilioService.send_sms call with SmsMessage.create(sid: result.sid, to: to, body: body, status: 'queued'), and updating status in the webhook controller by calling SmsMessage.find_by(sid: params[:MessageSid])&.update(status: params[:MessageStatus]). Implement Twilio Verify for Rails user phone verification by adding a PhoneVerification concern to the User model with verify_phone and check_verification instance methods that call TwilioService methods backed by the Twilio Verify API, and mounting a PhoneVerificationsController with routes for send and check actions in your Rails routes.

Conclusion

Ruby on Rails and Twilio together provide a convention-driven SMS integration using service objects, Active Job, and Rails credentials that keeps dispatch logic clean and testable across your application. Reach out to Telphi Consulting to implement and optimize the Twilio SMS integration in your Rails application.

Share this article:
0 views

Ready to Transform Your Business Communications?

Get a free consultation with our VoIP experts and discover how we can help you save costs, improve efficiency, and scale your business.

Comments (0)

Join the discussion and share your thoughts (AI-moderated for quality)

Protected by AI moderation

Be the first to comment

No comments yet. Share your thoughts below.