Guides & Tutorials5 min read
Ruby SDK Tutorial for MMS
Pictures speak a thousand words... so why not send one? Follow our tutorial to send and receive your first MMS in just 30 minutes.

MMS, or multimedia messaging lets you send gifs, photos, audio, and videos, or texts longer than 160 characters to enhance communication with end users.
Some useful MMS use cases across various industries include:
- Customer Service: Businesses are leveraging MMS to streamline the customer service experience. Sharing product images or delivering instructions via audio saves time on back and forth chatter.
- Ticketing: MMS allows businesses to send QR codes to customers for a digital ticketing experience.
Lucky for you, we’ve updated our MMS quickstart developer docs in Ruby SDK so that you can get up and running, send and receive your first MMS on the Telnyx platform in just 30 minutes -- are you ready?
First, let’s start with an outline of the content we will be covering in this post.
- Introduction
- Setup
a. Install packages
b. Setting environment variables
c. .env file*
d. App.rb*
e. Setup Sinatra Server - Receiving Webhooks
f. Basic Routing and Functions - Media Download and Upload Functions
g. Inbound message handling
h. Outbound message handling
i. Final app.rb - Usage
1. Introduction
This tutorial will walk you through the set up and process of building an application in Ruby that can receive an inbound MMS on the Telnyx platform. Inbound messages include an attachment link in the webhook, and the application will be able to:
- Download the remote attachment locally
- Uploads the same attachment to AWS3 (or any other media storage location that you choose to save the media)
- Sends the attachment back to the number that originally sent the message
Before you get started, make sure you’re familiar with these technologies:
- Completed or familiar with the Receiving SMS & MMS Quickstart
- A working Messaging Profile on our portal, with a SMS and MMS enabled phone number
- Ruby & Gem installed
- Familiarity with Sinatra
- Ability to receive webhooks with something like ngrok
- AWS account set up with proper profiles and groups with IAM for S3 -- more information in the Quickstart Previously created S3 with public permissions available
If those prerequisites are good to go, let’s go ahead and get started!
2.Setup
Install packages
First, install packages via Gem/Bundler. This will create a GemFile file with the packages needed to run the application.
1 2 3 4 5 6 7
gem install telnyx gem install sinatra gem install dotenv gem install ostruct gem install json gem install aws-sdk gem install down
Setting environment variables
The following environment variables need to be set:
Variable | Description |
---|---|
TELNYX_API_KEY | Your Telnyx API Key |
TELNYX_PUBLIC_KEY | Your Telnyx Public Key |
TELNYX_APP_PORT | Defaults to 8000 The port the app will be served |
AWS_PROFILE | Your AWS profile as set in ~/.aws |
AWS_REGION | The region of your S3 bucket |
TELNYX_MMS_S3_BUCKET | The name of the bucket to upload the media attachments |
.env file
We’ll be using the dotenv package to manage variables. Make a copy of the file below, add your credentials, and save as .env in your root directory.
1 2 3 4 5 6
TELNYX_API_KEY= TELNYX_PUBLIC_KEY= TENYX_APP_PORT=8000 AWS_PROFILE= AWS_REGION= TELNYX_MMS_S3_BUCKET=
App.rb
We’ll be using a single app.rb to build the MMS application.
1
touch app.rb
Setup Sinatra Server
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
require 'sinatra' require 'telnyx' require 'dotenv/load' require 'json' require 'ostruct' require 'aws-sdk-s3' require 'down' if __FILE__ == $0 TELNYX_API_KEY=ENV.fetch("TELNYX_API_KEY") TELNYX_APP_PORT=ENV.fetch("TELNYX_APP_PORT") AWS_REGION = ENV.fetch("AWS_REGION") TELNYX_MMS_S3_BUCKET = ENV.fetch("TELNYX_MMS_S3_BUCKET") Telnyx.api_key = TELNYX_API_KEY set :port, TELNYX_APP_PORT end get '/' do "Hello World" end
3. Receiving Webhooks
Now, it’s time to set up an endpoint to receive webhooks for inbound messages and outbound message delivery receipts (DLR).
Basic Routing and Functions
Here’s a basic overview of the application:
- Verify webhook & create TelnyxEvent
- Extract information from the webhook
- Iterate over any media and download/re-upload to S3 for each attachment
- Send the message back to the phone number from which it came
- Acknowledge the status update (DLR) of the outbound message
Media Download and Upload Functions
The following functions are for managing attachments:
- Download_file saves the content from a URL to disk
- Upload_file uploads the file passed to AWS S3 (and makes object public)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
def upload_file(file_path) s3 = Aws::S3::Resource.new(region: AWS_REGION) name = File.basename(file_path) obj = s3.bucket(TELNYX_MMS_S3_BUCKET).object(name) obj.upload_file(file_path, acl: 'public-read') obj.public_url end def download_file(uri) temp_file = Down.download(uri) path = "./#{temp_file.original_filename}" FileUtils.mv(temp_file.path, path) path end
Inbound Message Handling
Now that the functions for managing the media are in place, you’re ready to receive your first MMS:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
def deserialize_json(json) object = JSON.parse(json, object_class: OpenStruct) object end post '/messaging/inbound' do webhook = deserialize_json(request.body.read) dlr_uri = URI::HTTP.build(host: request.host, path: '/messaging/outbound') to_number = webhook.data.payload.to[0].phone_number from_number = webhook.data.payload.from.phone_number media = webhook.data.payload.media file_paths = [] media_urls = [] if media.any? media.each do |item| file_path = download_file(item.url) file_paths.push(file_path) media_url = upload_file(file_path) media_urls.push(media_url) end end begin telnyx_response = Telnyx::Message.create( from: to_number, to: from_number, text: "Hello, world!", media_urls: media_urls, use_profile_webhooks: false, webhook_url: dlr_uri.to_s ) puts "Sent message with id: #{telnyx_response.id}" rescue Exception => ex puts ex end end
Outbound Message Handling
As we defined our webhook_url path to be /messaging/outbound we'll need to create a function that accepts a POST request to that path within messaging.js.
1 2 3 4
post '/messaging/outbound' do webhook = deserialize_json(request.body.read) puts "Received message DLR with ID: #{webhook.data.payload.id}" end
Final app.rb
Now, let’s put it all together!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
require 'sinatra' require 'telnyx' require 'dotenv/load' require 'json' require 'ostruct' require 'aws-sdk-s3' require 'down' if __FILE__ == $0 TELNYX_API_KEY=ENV.fetch("TELNYX_API_KEY") TELNYX_APP_PORT=ENV.fetch("TELNYX_APP_PORT") AWS_REGION = ENV.fetch("AWS_REGION") TELNYX_MMS_S3_BUCKET = ENV.fetch("TELNYX_MMS_S3_BUCKET") Telnyx.api_key = TELNYX_API_KEY set :port, TELNYX_APP_PORT end get '/' do "Hello World" end def deserialize_json(json) object = JSON.parse(json, object_class: OpenStruct) object end def upload_file(file_path) s3 = Aws::S3::Resource.new(region: AWS_REGION) name = File.basename(file_path) obj = s3.bucket(TELNYX_MMS_S3_BUCKET).object(name) obj.upload_file(file_path, acl: 'public-read') obj.public_url end def download_file(uri) temp_file = Down.download(uri) path = "./#{temp_file.original_filename}" FileUtils.mv(temp_file.path, path) path end post '/messaging/inbound' do webhook = deserialize_json(request.body.read) dlr_uri = URI::HTTP.build(host: request.host, path: '/messaging/outbound') to_number = webhook.data.payload.to[0].phone_number from_number = webhook.data.payload.from.phone_number media = webhook.data.payload.media file_paths = [] media_urls = [] if media.any? media.each do |item| file_path = download_file(item.url) file_paths.push(file_path) media_url = upload_file(file_path) media_urls.push(media_url) end end begin telnyx_response = Telnyx::Message.create( from: to_number, to: from_number, text: "Hello, world!", media_urls: media_urls, use_profile_webhooks: false, webhook_url: dlr_uri.to_s ) puts "Sent message with id: #{telnyx_response.id}" rescue Exception => ex puts ex end end post '/messaging/outbound' do webhook = deserialize_json(request.body.read) puts "Received message DLR with ID: #{webhook.data.payload.id}" end
Usage
Start the server ruby app.rb. The final step is to make your application accessible from the internet -- right now, we have a local web server that’s not typically accessible from the public internet.
To work around this, we’ll use a tunneling service which comes with client software that runs on your computer and opens an outgoing permanent connection to a public server. Then, they assign a public URL on that server to your account.
The specific tunneling tool that we’ll use is ngrok; after setting up ngrok setup on your computer, you can add the public URL to your Inbound Setting in the Mission Control Portal. To do this, click the edit symbol ✎ and paste the forwarding address from ngrok into the 'Send a Webhook to this URL' field, and add messaging/inbound to the end of the URL. You can also add an alternate address in the “Failover URL” section, or leave it blank for now.
Congratulations! Your application is ready to use -- you should be able to text a MMS to your phone number and get that same picture back!
Share on Social