Professional Documents
Culture Documents
SERVER IS DOWN
SPARKS ARE UP
Popular Applications to Send SMS
Standard Email
yournumber@gatewayaddr Example:2065551234@txt.att.net
Find your provider gateway
Instant Message
AOL (US only)
Skype (small fee)
Other
Teleflip RIP
remindblast.com - Send SMS reminders to be awesome or do laundry
Facebook SMS app
Cell providers web page (ex. http://www.t-mobile.com)
Overview: One Way Messaging
Mobile Terminated (MT) or Outbound
Black Box of
Your application &
gateway &
other
Mobile
Terminated
(MT)
Overview: Two Way Messaging
Mobile Originated (MO) or Inbound
Black Box of
Your application &
MT
gateway &
other
MO
ROCK
Simplest approach: SMS as email
Pros and Cons of sending SMS through email
The Good
• Free to application (end-user with phone might pay)
• Easy to integrate. Only email setup required.
• Excellent for use with known numbers
• Emergency Messages with plugins like Exception Notification
Pros and Cons of sending SMS through email
The Tricky
• User carrier must be known
• additional user input
• storage considerations
• No delivery confirmation
• Supported by most US but not all cell phone carriers
• No two way messaging
Giant Black Box Explained:
SMSCs, SMS Gateways,
Service Providers
Before exploring the other available
SMS options, lets look at how
SMS works
SMS Centers (SMSC)
GSM
Modem
(Cell Phone)
AT Commands
Super
App
GSM Modem APIs and Applications
• Kannel in C (open source) supports an API
• RubyGSM - Written by Unicef for RapidSMS to inexpensively send
text messages
GSM Modem LoDown
Advantages
Cheap
Can use almost anywhere
Two way messaging support
Disadvantages
Difficult to setup
Slow
Doesn’t scale (only 6 to 10 messages per second)
Must connect modem to a server
Talk directly to all SMS Centers
Awesome
App
Mission Impossible: Coding for each SMSC
Large number of SMS Centers
Each use different and proprietary communication protocols
SMS Gateway
Rockstar
App
SMS Gateways
Free Open Source Gateways
Kannel - written in C supports many SMSCs and also acts as a WAP
gateway
Must setup/configure on a server yourself
Pay the middleman!
• Charge for sending messages
• ~ 5 cents per message
• Bulk discounts
• Provide convenient APIs
• Most provide two way
messaging
• Can help obtain short code
SMS Gateway: Sending Outbound (MT)
Typical approach for Outbound messages is simple:
• Create an account
• Buy credits (or messages)
• Start sending messages through the API
Ruby Outbound (MT) message with HTTPS
/^OPT(\s*[-_]?\s*)OUT|STOP|END|QUIT|
UNSUBSCRIBE|EXIT|HALT|
FUCK(\s*[-_]?\s*)OFF|REMOVE|CANCEL)/i
Two way messaging: Pull
Setup a cron task to pull new messages every few seconds.
Two way messaging: Push
Provide a callback URL that service provider invokes for each new
message
Do I need a short code?
PhoneNumber
Number
WhiteList?
PhoneCarrier
DoNotSend?
Name
Email gateway
Outbound Status: Produce and Consume
• Web action creates an Outbound record with status
NOT_PROCESSED
• Cron task processes messages with status NOT_PROCESSED and
marks them SUCCESS or FAIL
SUCCESS
NOT_PROCESSED PROCESSING
FAILED
Bulk Message Delivery
• Use batch API call to send multiple phone numbers the same msg
• For huge deliveries, use SMPP to maintain an open connection
• Set delivery date and send to provider in advance
• Lock multiple records with your database (MySQL FOR UPDATE)
• Use Multiple servers
Bulk Message Delivery Tips
• Reduce contention for competing servers storing data
• Assign a group of records (ID mod X srvrs) to each server
• (non dedicated servers) put tasks on staggered timers (ex. every
2 min) that execute for a shorter duration(ex. 45 seconds)
• Identify fatal errors and stop the task
• Fatal, stop task: Ex. No response from service provider
• Single message error: Mark failed and continue processing
• Cron to Recover messages in 'PROCESSING' state with updated_at
field > duration of consumer task (ex. 10 min)
• Delivery status background task to request delivery information
• Set priority on messages
Sanitize Phone Numbers
PhoneNumber.create!(:number => '(206)-555-1212 ')
PhoneNumber.find_by_number('12065551212') == nil