KEMBAR78
Mobilizing Your Rails Application - LA Ruby Conference 2009 | PPT
Mobilize  Your Rails Application Brendan Lim e-mail:  [email_address]   twitter:  @brendanlim
 
Why care about  mobile There’s an estimated 2.9 billion mobile users Over 255 million mobile users in the U.S.  In developing nations, a mobile phone is sometimes their only way to connect to the Internet
Some  mobile  stats (in billions of course)
So, how do we take advantage of this?
Make your application accessible by the majority of   web enabled   mobile  devices devices devices
Keep your users engaged through  SMS ,  MMS   and  E-Mail E-Mail
Many  Mobile  Devices Can Access the Real Web From Flickr User Carlos Magaña
One Web Making the same information and services available to all users regardless of the device used Making the same information and services available to all users regardless of the device used
Max resolution? JavaScript? Flash? Connection speed? Processor speed? Problems with  one web
Mobile Fu  Plugin Can detect if a user is on a mobile device Ability to add custom styling based on the device’s user agent Gives you some tools to make the concept of  one web  easier to achieve
How does one master  mobile  fu?
Not   Like This ...
Maybe   Like This ...
class ApplicationController < ActionController::Base  has_mobile_fu end end
demo. presentlyapp.com iPhone Safari
respond_to  do | format | format.html format.mobile end views/ layouts application.html.erb application.mobile.erb sessions new.html.erb new.mobile.erb
<%= mobile_xhtml_doctype %> <html> <head> ... </head> <body> ... </body> </html> </html> ../layouts/ application.mobile.erb http://mobiforge.com/designing/story/comparison-xhtml-mobile-profile-and-xhtml-basic
<?xml version=&quot;1.0&quot; charset=&quot;UTF-8&quot; ?> <!DOCTYPE html PUBLIC &quot;-//WAPFORUM//DTD XHTML Mobile 1.0//EN&quot; &quot; http://www.wapforum.org/DTD/xhtml-mobile10.dtd &quot;> <html> <head> ... </head> <body> ... </body> </html> </html> ../layouts/ application.mobile.erb http://mobiforge.com/designing/story/comparison-xhtml-mobile-profile-and-xhtml-basic
Is the user using a specific device? is_device?( ‘blackberry’ ) Is the user using a mobile device? is_mobile_device? Is the request format currently :mobile ? in_mobile_view?
iPhone   foo_ mobilewebkit .css  <%= stylesheet_link_tag 'foo' %> Android   foo_ mobilewebkit .css  BlackBerry   foo_ blackberry .css  Win Mobile   foo_ mobileexplorer .css  etc...
 
What about leveraging other  mobile   technologies ?
SMS Short Message Service Short Message Service
Keep Users Informed with  SMS Text messages are read by about 94% of their recipients. Supported by almost all mobile phones out there Good for quick notifications Generally limited to 160 characters Relatively easy to leverage
What tools can we use to send  SMS  messages from our Rails application?
Clickatell  Gem Paid solution Uses Clickatell’s API Currently $0.043 per text message sent within the U.S. No need to know the recipient’s carrier
api  =  Clickatell::API.authenticate(' your_api_id ',  ' your_username ', ' your_password ') api.send_message(' 5558675309 ', ' Hello from clickatell ') require 'clickatell'
SMS Fu  Plugin Doesn’t cost the sender anything Leverages ActionMailer to send a  text message You need to know the recipient’s carrier Not as many supported carriers as Clickatell
Wait, it’s free? So how does it work?
Number:  555-867-5309 5558675309 @ vtext.com Carrier:  Verizon
deliver_sms(‘ 5558675309 ’,‘ verizon ’, ‘ hello! ’) class AwesomeController < ApplicationController  has_sms_fu end end
Some  SMS  Fu Carriers Alltell, Ameritech, AT&T, Bell South Mobility, BlueSkyFrog, Boost Mobile, Cellular South, Kajeet, Metro PCS, Powertel, PSC Wireless, Qwest, Southern Link, Spring, Rodgers, Suncom, T-Mobile, Virgin Mobile, Verizon Wireless ,  E-Plus, O2, Orange,  Telconica, Vodafone ...
What if I want to add a new carrier called  Ruby Mobile ?
carriers: ... ruby_mobile:  name: Ruby Mobile  value: @txt.rubymobile.com  Add the following to   .../config/sms_fu.yml deliver_sms(‘ 5558675309 ’,’ ruby_mobile ’, ‘ hello! ’)
Remind Your Users That They May Get Charged from flickr user ‘bowbrick’
MMS Multimedia Message Service Multimedia Message Service
MMS Can send photo, video, audio or other attachments Most commonly used for photos Attachment size limitation generally dependent on device Multipart MIME
The Problem with Receiving  MMS Crap Crap Crap Cat
Well, how can I receive  SMS  or  MMS  from my Rails app ?
Short Codes Special numbers that are, you guessed it, short, that can be used to receive SMS or MMS messages from mobile phones. Special numbers that are, you guessed it, short, that can be used to receive SMS or MMS messages from mobile phones.
 
Short Codes Also referred to as short numbers MMS support added in this year Crazy Expensive Monthly fees up to $1000/mo Setup fees close to $5000 Many companies share short codes
Receiving  SMS  or  MMS  as an e-mail is another solution and its free and relatively simple
MMS2R  Gem Removes carrier advertising Eliminates carrier default text Decodes and extracts intended files from the multipart MIME e-mail Most major carriers are supported
Retrieve only the intended attachment mms.default_media Retrieve all media files from the MMS mms.media Retrieve only the intended message mms.body Create a new MMS2R object from a TMail object mms =   MMS2R::Media.new(email)
require ‘ mms2r ’ class   MailReceiver  <  ActionMailer::Base def   receive (email) begin # load the TMail object into an MMS2R::Media object mms =  MMS2R::Media .new(email) # grab a user on record by the e-mail it was sent from user =  User .find_by_email(mms.from) # store the body of the mms into a new BlogPost blog_post =  BlogPost .create(: body  => mms.body, : user  => user,  : title  => mms.subject) # grab the attachment from the mms message media = mms.default_media # store the attachment from mms into a BlogPhoto BlogPhoto .create(: uploaded_data  => media, : blog_post  => blog_post) if media.content_type.include?(‘ image ’) ensure # cleans up temporary files used for text and attachments mms.purge end end end
require ‘ mms2r ’ class   MailReceiver  <  ActionMailer::Base def   receive (email) begin # load the TMail object into an MMS2R::Media object mms =  MMS2R::Media . new (email) # grab a user on record by the e-mail it was sent from user =  User .find_by_email(mms.from) # store the body of the mms into a new BlogPost blog_post =  BlogPost .create(: body  => mms.body, : user  => user,  : title  => mms.subject) # grab the attachment from the mms message media = mms.default_media # store the attachment from mms into a BlogPhoto BlogPhoto .create(: uploaded_data  => media, : blog_post  => blog_post) if media.content_type.include?(‘ image ’) ensure # cleans up temporary files used for text and attachments mms.purge end end end
require ‘ mms2r ’ class   MailReceiver  <  ActionMailer::Base def   receive (email) begin # load the TMail object into an MMS2R::Media object mms =  MMS2R::Media .new(email) # grab a user on record by the e-mail it was sent from user =  User .find_by_email( mms.from ) # store the body of the mms into a new BlogPost blog_post =  BlogPost .create(: body  => mms.body, : user  => user,  : title  => mms.subject) # grab the attachment from the mms message media = mms.default_media # store the attachment from mms into a BlogPhoto BlogPhoto .create(: uploaded_data  => media, : blog_post  => blog_post) if media.content_type.include?(‘ image ’) ensure # cleans up temporary files used for text and attachments mms.purge end end end
require ‘ mms2r ’ class   MailReceiver  <  ActionMailer::Base def   receive (email) begin # load the TMail object into an MMS2R::Media object mms =  MMS2R::Media .new(email) # grab a user on record by the e-mail it was sent from user =  User .find_by_email(mms.from) # store the body of the mms into a new BlogPost blog_post =  BlogPost .create(: body  =>  mms.body ,  : user  => user, : title  =>  mms.subject ) # grab the attachment from the mms message media = mms.default_media # store the attachment from mms into a BlogPhoto BlogPhoto .create(: uploaded_data  => media, : blog_post  => blog_post) if media.content_type.include?(‘ image ’) ensure # cleans up temporary files used for text and attachments mms.purge end end end
require ‘ mms2r ’ class   MailReceiver  <  ActionMailer::Base def   receive (email) begin # load the TMail object into an MMS2R::Media object mms =  MMS2R::Media .new(email) # grab a user on record by the e-mail it was sent from user =  User .find_by_email(mms.from) # store the body of the mms into a new BlogPost blog_post =  BlogPost .create(: body  => mms.body, : user  => user,  : title  => mms.subject) # grab the attachment from the mms message media = mms. default_media # store the attachment from mms into a BlogPhoto BlogPhoto .create(: uploaded_data  => media, : blog_post  => blog_post) if media.content_type.include?(‘ image ’) ensure # cleans up temporary files used for text and attachments mms.purge end end end
require ‘ mms2r ’ class   MailReceiver  <  ActionMailer::Base def   receive (email) begin # load the TMail object into an MMS2R::Media object mms =  MMS2R::Media .new(email) # grab a user on record by the e-mail it was sent from user =  User .find_by_email(mms.from) # store the body of the mms into a new BlogPost blog_post =  BlogPost .create(: body  => mms.body, : user  => user,  : title  => mms.subject) # grab the attachment from the mms message media = mms.default_media # store the attachment from mms into a BlogPhoto BlogPhoto .create(: uploaded_data  =>  media , : blog_post  => blog_post) if  media . content_type .include?(‘ image ’) ensure # cleans up temporary files used for text and attachments mms.purge end end end
require ‘ mms2r ’ class   MailReceiver  <  ActionMailer::Base def   receive (email) begin # load the TMail object into an MMS2R::Media object mms =  MMS2R::Media .new(email) # grab a user on record by the e-mail it was sent from user =  User .find_by_email(mms.from) # store the body of the mms into a new BlogPost blog_post =  BlogPost .create(: body  => mms.body, : user  => user,  : title  => mms.subject) # grab the attachment from the mms message media = mms.default_media # store the attachment from mms into a BlogPhoto BlogPhoto .create(: uploaded_data  => media, : blog_post  => blog_post) if media.content_type.include?(‘ image ’) ensure # cleans up temporary files used for text and attachments mms. purge end end end
Adding new templates for carriers is easy --- ignore:    image / gif:     -  top.gif    -  bottom.gif    -  middle_img.gif    text / html:      -   /< html > \s +< head > \s +< meta http - equiv = \&quot;Content-Type \&quot; content=\&quot;text\/html; charset=iso-8859-1\&quot;>\s+<title>MMS Email<\/title>/im transform:     text / plain:     -   -   / Note:\s{1,2}. *? \s + message:\s{1,2}(. + )$ / m      -  &quot;\1&quot; conf/mms.myhelio.com.yml
Mobilizing  your Rails app is simple and easy
Mobile Fu http://github.com/brendanlim/mobile-fu/ Clickatell http://clickatell.rubyforge.org/ SMS Fu http://github.com/brendanlim/sms-fu/ MMS2R http://github.com/monde/mms2r/
Questions!

Mobilizing Your Rails Application - LA Ruby Conference 2009

  • 1.
    Mobilize YourRails Application Brendan Lim e-mail: [email_address] twitter: @brendanlim
  • 2.
  • 3.
    Why care about mobile There’s an estimated 2.9 billion mobile users Over 255 million mobile users in the U.S. In developing nations, a mobile phone is sometimes their only way to connect to the Internet
  • 4.
    Some mobile stats (in billions of course)
  • 5.
    So, how dowe take advantage of this?
  • 6.
    Make your applicationaccessible by the majority of web enabled mobile devices devices devices
  • 7.
    Keep your usersengaged through SMS , MMS and E-Mail E-Mail
  • 8.
    Many Mobile Devices Can Access the Real Web From Flickr User Carlos Magaña
  • 9.
    One Web Makingthe same information and services available to all users regardless of the device used Making the same information and services available to all users regardless of the device used
  • 10.
    Max resolution? JavaScript?Flash? Connection speed? Processor speed? Problems with one web
  • 11.
    Mobile Fu Plugin Can detect if a user is on a mobile device Ability to add custom styling based on the device’s user agent Gives you some tools to make the concept of one web easier to achieve
  • 12.
    How does onemaster mobile fu?
  • 13.
    Not Like This ...
  • 14.
    Maybe Like This ...
  • 15.
    class ApplicationController <ActionController::Base has_mobile_fu end end
  • 16.
  • 17.
    respond_to do| format | format.html format.mobile end views/ layouts application.html.erb application.mobile.erb sessions new.html.erb new.mobile.erb
  • 18.
    <%= mobile_xhtml_doctype %><html> <head> ... </head> <body> ... </body> </html> </html> ../layouts/ application.mobile.erb http://mobiforge.com/designing/story/comparison-xhtml-mobile-profile-and-xhtml-basic
  • 19.
    <?xml version=&quot;1.0&quot; charset=&quot;UTF-8&quot;?> <!DOCTYPE html PUBLIC &quot;-//WAPFORUM//DTD XHTML Mobile 1.0//EN&quot; &quot; http://www.wapforum.org/DTD/xhtml-mobile10.dtd &quot;> <html> <head> ... </head> <body> ... </body> </html> </html> ../layouts/ application.mobile.erb http://mobiforge.com/designing/story/comparison-xhtml-mobile-profile-and-xhtml-basic
  • 20.
    Is the userusing a specific device? is_device?( ‘blackberry’ ) Is the user using a mobile device? is_mobile_device? Is the request format currently :mobile ? in_mobile_view?
  • 21.
    iPhone foo_ mobilewebkit .css <%= stylesheet_link_tag 'foo' %> Android foo_ mobilewebkit .css BlackBerry foo_ blackberry .css Win Mobile foo_ mobileexplorer .css etc...
  • 22.
  • 23.
    What about leveragingother mobile technologies ?
  • 24.
    SMS Short MessageService Short Message Service
  • 25.
    Keep Users Informedwith SMS Text messages are read by about 94% of their recipients. Supported by almost all mobile phones out there Good for quick notifications Generally limited to 160 characters Relatively easy to leverage
  • 26.
    What tools canwe use to send SMS messages from our Rails application?
  • 27.
    Clickatell GemPaid solution Uses Clickatell’s API Currently $0.043 per text message sent within the U.S. No need to know the recipient’s carrier
  • 28.
    api = Clickatell::API.authenticate(' your_api_id ', ' your_username ', ' your_password ') api.send_message(' 5558675309 ', ' Hello from clickatell ') require 'clickatell'
  • 29.
    SMS Fu Plugin Doesn’t cost the sender anything Leverages ActionMailer to send a text message You need to know the recipient’s carrier Not as many supported carriers as Clickatell
  • 30.
    Wait, it’s free?So how does it work?
  • 31.
    Number: 555-867-53095558675309 @ vtext.com Carrier: Verizon
  • 32.
    deliver_sms(‘ 5558675309 ’,‘verizon ’, ‘ hello! ’) class AwesomeController < ApplicationController has_sms_fu end end
  • 33.
    Some SMS Fu Carriers Alltell, Ameritech, AT&T, Bell South Mobility, BlueSkyFrog, Boost Mobile, Cellular South, Kajeet, Metro PCS, Powertel, PSC Wireless, Qwest, Southern Link, Spring, Rodgers, Suncom, T-Mobile, Virgin Mobile, Verizon Wireless , E-Plus, O2, Orange, Telconica, Vodafone ...
  • 34.
    What if Iwant to add a new carrier called Ruby Mobile ?
  • 35.
    carriers: ... ruby_mobile: name: Ruby Mobile value: @txt.rubymobile.com Add the following to .../config/sms_fu.yml deliver_sms(‘ 5558675309 ’,’ ruby_mobile ’, ‘ hello! ’)
  • 36.
    Remind Your UsersThat They May Get Charged from flickr user ‘bowbrick’
  • 37.
    MMS Multimedia MessageService Multimedia Message Service
  • 38.
    MMS Can sendphoto, video, audio or other attachments Most commonly used for photos Attachment size limitation generally dependent on device Multipart MIME
  • 39.
    The Problem withReceiving MMS Crap Crap Crap Cat
  • 40.
    Well, how canI receive SMS or MMS from my Rails app ?
  • 41.
    Short Codes Specialnumbers that are, you guessed it, short, that can be used to receive SMS or MMS messages from mobile phones. Special numbers that are, you guessed it, short, that can be used to receive SMS or MMS messages from mobile phones.
  • 42.
  • 43.
    Short Codes Alsoreferred to as short numbers MMS support added in this year Crazy Expensive Monthly fees up to $1000/mo Setup fees close to $5000 Many companies share short codes
  • 44.
    Receiving SMS or MMS as an e-mail is another solution and its free and relatively simple
  • 45.
    MMS2R GemRemoves carrier advertising Eliminates carrier default text Decodes and extracts intended files from the multipart MIME e-mail Most major carriers are supported
  • 46.
    Retrieve only theintended attachment mms.default_media Retrieve all media files from the MMS mms.media Retrieve only the intended message mms.body Create a new MMS2R object from a TMail object mms = MMS2R::Media.new(email)
  • 47.
    require ‘ mms2r’ class MailReceiver < ActionMailer::Base def receive (email) begin # load the TMail object into an MMS2R::Media object mms = MMS2R::Media .new(email) # grab a user on record by the e-mail it was sent from user = User .find_by_email(mms.from) # store the body of the mms into a new BlogPost blog_post = BlogPost .create(: body => mms.body, : user => user, : title => mms.subject) # grab the attachment from the mms message media = mms.default_media # store the attachment from mms into a BlogPhoto BlogPhoto .create(: uploaded_data => media, : blog_post => blog_post) if media.content_type.include?(‘ image ’) ensure # cleans up temporary files used for text and attachments mms.purge end end end
  • 48.
    require ‘ mms2r’ class MailReceiver < ActionMailer::Base def receive (email) begin # load the TMail object into an MMS2R::Media object mms = MMS2R::Media . new (email) # grab a user on record by the e-mail it was sent from user = User .find_by_email(mms.from) # store the body of the mms into a new BlogPost blog_post = BlogPost .create(: body => mms.body, : user => user, : title => mms.subject) # grab the attachment from the mms message media = mms.default_media # store the attachment from mms into a BlogPhoto BlogPhoto .create(: uploaded_data => media, : blog_post => blog_post) if media.content_type.include?(‘ image ’) ensure # cleans up temporary files used for text and attachments mms.purge end end end
  • 49.
    require ‘ mms2r’ class MailReceiver < ActionMailer::Base def receive (email) begin # load the TMail object into an MMS2R::Media object mms = MMS2R::Media .new(email) # grab a user on record by the e-mail it was sent from user = User .find_by_email( mms.from ) # store the body of the mms into a new BlogPost blog_post = BlogPost .create(: body => mms.body, : user => user, : title => mms.subject) # grab the attachment from the mms message media = mms.default_media # store the attachment from mms into a BlogPhoto BlogPhoto .create(: uploaded_data => media, : blog_post => blog_post) if media.content_type.include?(‘ image ’) ensure # cleans up temporary files used for text and attachments mms.purge end end end
  • 50.
    require ‘ mms2r’ class MailReceiver < ActionMailer::Base def receive (email) begin # load the TMail object into an MMS2R::Media object mms = MMS2R::Media .new(email) # grab a user on record by the e-mail it was sent from user = User .find_by_email(mms.from) # store the body of the mms into a new BlogPost blog_post = BlogPost .create(: body => mms.body , : user => user, : title => mms.subject ) # grab the attachment from the mms message media = mms.default_media # store the attachment from mms into a BlogPhoto BlogPhoto .create(: uploaded_data => media, : blog_post => blog_post) if media.content_type.include?(‘ image ’) ensure # cleans up temporary files used for text and attachments mms.purge end end end
  • 51.
    require ‘ mms2r’ class MailReceiver < ActionMailer::Base def receive (email) begin # load the TMail object into an MMS2R::Media object mms = MMS2R::Media .new(email) # grab a user on record by the e-mail it was sent from user = User .find_by_email(mms.from) # store the body of the mms into a new BlogPost blog_post = BlogPost .create(: body => mms.body, : user => user, : title => mms.subject) # grab the attachment from the mms message media = mms. default_media # store the attachment from mms into a BlogPhoto BlogPhoto .create(: uploaded_data => media, : blog_post => blog_post) if media.content_type.include?(‘ image ’) ensure # cleans up temporary files used for text and attachments mms.purge end end end
  • 52.
    require ‘ mms2r’ class MailReceiver < ActionMailer::Base def receive (email) begin # load the TMail object into an MMS2R::Media object mms = MMS2R::Media .new(email) # grab a user on record by the e-mail it was sent from user = User .find_by_email(mms.from) # store the body of the mms into a new BlogPost blog_post = BlogPost .create(: body => mms.body, : user => user, : title => mms.subject) # grab the attachment from the mms message media = mms.default_media # store the attachment from mms into a BlogPhoto BlogPhoto .create(: uploaded_data => media , : blog_post => blog_post) if media . content_type .include?(‘ image ’) ensure # cleans up temporary files used for text and attachments mms.purge end end end
  • 53.
    require ‘ mms2r’ class MailReceiver < ActionMailer::Base def receive (email) begin # load the TMail object into an MMS2R::Media object mms = MMS2R::Media .new(email) # grab a user on record by the e-mail it was sent from user = User .find_by_email(mms.from) # store the body of the mms into a new BlogPost blog_post = BlogPost .create(: body => mms.body, : user => user, : title => mms.subject) # grab the attachment from the mms message media = mms.default_media # store the attachment from mms into a BlogPhoto BlogPhoto .create(: uploaded_data => media, : blog_post => blog_post) if media.content_type.include?(‘ image ’) ensure # cleans up temporary files used for text and attachments mms. purge end end end
  • 54.
    Adding new templatesfor carriers is easy --- ignore:    image / gif:    - top.gif    - bottom.gif    - middle_img.gif    text / html:     - /< html > \s +< head > \s +< meta http - equiv = \&quot;Content-Type \&quot; content=\&quot;text\/html; charset=iso-8859-1\&quot;>\s+<title>MMS Email<\/title>/im transform:    text / plain:    - - / Note:\s{1,2}. *? \s + message:\s{1,2}(. + )$ / m      - &quot;\1&quot; conf/mms.myhelio.com.yml
  • 55.
    Mobilizing yourRails app is simple and easy
  • 56.
    Mobile Fu http://github.com/brendanlim/mobile-fu/Clickatell http://clickatell.rubyforge.org/ SMS Fu http://github.com/brendanlim/sms-fu/ MMS2R http://github.com/monde/mms2r/
  • 57.