Textris
Implement texter classes for sending SMS messages in similar way to how e-mails are sent with ActionMailer-based mailers. Take advantage of e-mail proxying and enhanced phone number parsing, among others.
Install / Use
/learn @visualitypl/TextrisREADME
textris
Simple gem for implementing texter classes which allow sending SMS messages in similar way to how e-mails are implemented and sent with ActionMailer-based mailers.
Unlike similar gems, textris has some unique features:
- e-mail proxy allowing to inspect messages using Mailinator or similar service
- phone number E164 validation and normalization with the phony gem
- built-in support for the Twilio and Nexmo APIs with twilio-ruby and nexmo gems
- multiple, per-environment configurable and chainable delivery methods
- extensible with any number of custom delivery methods (also chainable)
- background and scheduled texting for Rails 4.2+ thanks to integration with ActiveJob
- scheduled texting for Rails 4.1 and older thanks to integration with the sidekiq gem
- support for testing using self-explanatory
Textris::Base.deliveries - simple, extensible, fully tested code written from the ground up instead of copying ActionMailer
See the blog entry for the whole story and a practical usage example.
Installation
Add to Gemfile:
gem 'textris'
Then run:
bundle install
Usage
Place texter classes in app/texters (e.g. app/texters/user_texter.rb):
class UserTexter < Textris::Base
default :from => "Our Team <+48 666-777-888>"
def welcome(user)
@user = user
text :to => @user.phone
end
end
Place relevant view templates in app/views/<texter_name>/<action_name>.text.* (e.g. app/views/user_texter/welcome.text.erb):
Welcome to our system, <%= @user.name %>!
Invoke them from application logic:
class User < ActiveRecord::Base
after_create do
UserTexter.welcome(self).deliver
end
end
MMS
Media messages are supported if you are using the Twilio, Log or Mail adapter. Twilio currently supports sending MMS in the US and Canada.
Media messages aren't part of a template, but must be specified as an array of URLs when sending the message, like:
class UserMediaTexter < Textris::Base
default :from => "Our Team <+48 666-777-888>"
def welcome(user)
@user = user
text(
:to => @user.phone,
:media_urls => ["http://example.com/hilarious.gif"]
)
end
end
Background and scheduled
ActiveJob integration
As of version 0.4, textris supports native Rails 4.2+ way of background job handling, the ActiveJob. You can delay delivery of your texters the same way as with ActionMailer mailers, like:
UserTexter.welcome(user).deliver_later
UserTexter.welcome(user).deliver_later(:wait => 1.hour)
UserTexter.welcome(user).deliver_later(:wait_until => 1.day.from_now)
UserTexter.welcome(user).deliver_later(:queue => :custom_queue)
UserTexter.welcome(user).deliver_now
You can safely pass ActiveRecord records as delayed action arguments. ActiveJob uses GlobalID to serialize them for scheduled delivery.
By default, textris queue will be used by the Textris::Delay::ActiveJob::Job job.
Direct Sidekiq integration
As of Rails 4.2, ActiveJob is the recommended way for background job handling and it does support Sidekiq as its backend, so please see chapter above if you're using Rails 4.2 or above. Otherwise, keep on reading to use textris with Sidekiq regardless of your Rails version.
Thanks to Sidekiq integration, you can send text messages in the background to speed things up, retry in case of failures or just to do it at specific time. To do so, use one of three delay methods:
UserTexter.delay.welcome(user)
UserTexter.delay_for(1.hour).welcome(user)
UserTexter.delay_until(1.day.from_now).welcome(user)
Remember not to call deliver after the action invocation when using delay. It will be called by the Textris::Delay::Sidekiq::Worker worker.
You can safely pass ActiveRecord records and arrays as delayed action arguments. textris will store their
ids and find them upon scheduled delivery.
Keep in mind that textris does not install sidekiq for you. If you don't have it yet, install Redis on your machine and add the sidekiq gem to Gemfile:
gem 'sidekiq'
Then run:
bundle install
bundle exec sidekiq
Testing
Access all messages that were sent with the :test delivery:
Textris::Base.deliveries
You may want to clear the delivery queue before each test:
before(:each) do
Textris::Base.deliveries.clear
end
Keep in mind that messages targeting multiple phone numbers, like:
text :to => ['48111222333', '48222333444']
will yield multiple message deliveries, each for specific phone number.
Configuration
You can change default settings by placing them in any of environment files, like development.rb or test.rb, or setting them globally in application.rb.
Choosing and chaining delivery methods
Below you'll find sample settings for any of supported delivery methods along with short description of each:
# Send messages via the Twilio REST API
config.textris_delivery_method = :twilio
# Send messages via the Nexmo API
config.textris_delivery_method = :nexmo
# Don't send anything, log messages into Rails logger
config.textris_delivery_method = :log
# Don't send anything, access your messages via Textris::Base.deliveries
config.textris_delivery_method = :test
# Send e-mails instead of SMSes in order to inspect their content
config.textris_delivery_method = :mail
# Chain multiple delivery methods (e.g. to have e-mail and log backups of messages)
config.textris_delivery_method = [:twilio, :mail, :log]
Unless otherwise configured, default delivery methods will be: log in
developmentenvironment, test intestenvironment and mail inproductionenvironment. All these come with reasonable defaults and will work with no further configuration.
Twilio
textris connects with the Twilio API using twilio-ruby gem. It does not, however, install the gem for you. If you don't have it yet, add the twilio-ruby gem to Gemfile:
gem 'twilio-ruby'
Then, pre-configure the twilio-ruby settings by creating the config/initializers/twilio.rb file:
Twilio.configure do |config|
config.account_sid = 'some_sid'
config.auth_token = 'some_auth_token'
end
To use Twilio's Copilot use twilio_messaging_service_sid in place of from when sending a text or setting defaults.
Nexmo
In order to use Nexmo with textris, you need to include the nexmo gem in your Gemfile:
gem 'nexmo', '~> 4'
The Nexmo gem uses the environment variables NEXMO_API_KEY and NEXMO_API_SECRET to authenticate with the API.
Therefore the safest way to provide authentication credentials is to set these variables in your application environment.
Log
textris logger has similar logging behavior to ActionMailer. It will log single line to info log with production in mind and then a couple details to debug log. You can change the log level for the whole output:
config.textris_log_level = :info
Custom delivery methods
Currently, textris comes with several delivery methods built-in, but you can easily implement your own. Place desired delivery class in app/deliveries/<name>_delivery.rb (e.g. app/deliveries/my_provider_delivery.rb):
class MyProviderDelivery < Textris::Delivery::Base
# Implement sending message to single phone number
def deliver(phone)
send_sms(:phone => phone, :text => message.content)
end
# ...or implement sending message to multiple phone numbers at once
def deliver_to_all
send_multiple_sms(:phone_array => message.to, :text => message.content)
end
end
Only one of methods above must be implemented for the delivery class to work. In case of multiple phone numbers and no implementation of deliver_to_all, the deliver method will be invoked multiple times.
You can place your custom deliveries in
app/textersorapp/modelsinstead ofapp/deliveriesif you don't want to clutter the app directory too much.
After implementing your own deliveries, you can activate them by setting app configuration:
# Use your new delivery
config.textris_delivery_method = :my_provider
# Chain your new delivery with others, including stock ones
config.textris_delivery_method = [:my_provider, :twilio, :mail]
Configuring the mail delivery
textris comes with reasonable defaults for the mail delivery method. It will send messag
Related Skills
node-connect
344.4kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
99.2kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
344.4kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
344.4kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
