Created
May 3, 2012 20:59
-
-
Save t2-support-gists/2589422 to your computer and use it in GitHub Desktop.
MMS Ruby app1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
AT&T API Samples - MMS app 1 | |
------------------------------ | |
This file describes how to set up, configure and run the ruby versions of the AT&T HTML5 Program sample applications. | |
It covers all steps required to register the application on DevConnect and, based on the generated API keys and secrets, | |
create and run one's own full-fledged sample applications. | |
1. Configuration | |
2. Installation | |
3. Parameters | |
4. Running the application | |
1. Configuration | |
Configuration consists of a few steps necessary to get an application registered on DevConnect with the proper services and | |
endpoints, depending on the type of client-side application (autonomous/non-autonomous). | |
To register an application, go to https://devconnect-api.att.com/ and login with your valid username and password. | |
Next, choose "My Apps" from the bar at the top of the page and click the "Setup a New Application" button. | |
Fill in the form, in particular all fields marked as "required". | |
Be careful while filling in the "OAuth Redirect URL" field. It should contain the URL that the oAuth provider will redirect | |
users to when he/she successfully authenticates and authorizes your application. | |
NOTE: You MUST select MMS in the list of services under field 'Services' in order to use this sample application code. | |
Having your application registered, you will get back an important pair of data: an API key and Secret key. They are | |
necessary to get your applications working with the AT&T HTML5 APIs. See 'Adjusting parameters' below to learn how to use | |
these keys. | |
Initially your newly registered application is restricted to the "Sandbox" environment only. To move it to production, | |
you may promote it by clicking the "Promote to production" button. Notice that you will get a different API key and secret, | |
so these values in your application should be adjusted accordingly. | |
Depending on the kind of authentication used, an application may be based on either the Autonomous Client or the Web-Server | |
Client OAuth flow (see https://devconnect-api.att.com/docs/oauth20/autonomous-client-application-oauth-flow or | |
https://devconnect-api.att.com/docs/oauth20/web-server-client-application-oauth-flow respectively). | |
2. Installation | |
** Requirements | |
To run the examples you need ruby 1.8+ and a few gems that the applications are heavily based on: | |
- sinatra (http://www.sinatrarb.com/) | |
used to construct a simple web application and manage URLs within. | |
- sinatra-contrib | |
additional set of useful helpers, including ones used to read settings from external files. | |
- also make sure you have rest-client and json gems installed | |
To install these gems open up a terminal window and invoke: | |
gem install sinatra sinatra-contrib rest-client json | |
Having them installed, you are almost ready to run the sample applications. | |
** Setting up on a different port number | |
In case multiple applications need to be run at the same time, you need to consider using different | |
port numbers. | |
By default sinatra uses port number 4567 and only one running application may use this port. In case | |
you want to run one more sinatra-based application, you need to change its port number, eg. to 4568. This way you | |
may have each application running on a unique port. | |
3. Parameters | |
Each application contains a config.yml file. It holds configurable parameters | |
described in an easy to read YAML format which you are free to adjust to your needs. Following are short descriptions | |
of parameters used by this application: | |
1) FQDN : https://api.att.com | |
2) port : port number that application binds to (default: 4567) | |
3) phone_number : destination phone number | |
4) api_key : set the value as per your registered appliaction 'API key' field value | |
5) secret_key : set the value as per your registered appliaction 'Secret key' field value | |
6) registration_id : short-code | |
7) tokens_file : file containing authorization and refresh tokens | |
Note: If your application is promoted from Sandbox environment to Production environment and you decide to use | |
production application settings, you must update parameters 1-2 as per production application details. | |
4. Running the application | |
To run the application, open up a terminal window and type: | |
ruby ./mms.rb | |
or | |
./mms.rb | |
Your application becomes available in a web browser, so you may visit: http://localhost:4567/ to see it working. | |
You may interrupt the application at any time by pressing ctrl-C. | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Tries to parse supplied address using one of known formats. Returns false on failure. | |
def parse_address(address) | |
address.strip! | |
if (address.match('^\d{10}$')) | |
elsif (m = address.match('^1(\d{10})$')) | |
address = m[1].to_s | |
elsif (m = address.match('^\+1(\d{10})$')) | |
address = m[1].to_s | |
elsif (m = address.match('^tel:(\d{10})$')) | |
address = m[1].to_s | |
elsif (address.match('^\d{3}-\d{3}-\d{4}$')) | |
address.gsub! '-', '' | |
else | |
return false | |
end | |
address | |
end | |
# Makes sure that valid access_token is stored in the session. Retrieves new tokens if needed. | |
def obtain_tokens(fqdn, client_id, client_secret, scope, tokens_file) | |
read_tokens(tokens_file) | |
if @access_token and @access_token_expires > Time.now | |
return | |
elsif @refresh_token and @refresh_token_expires > Time.now | |
response = RestClient.post "#{fqdn}/oauth/token", :grant_type => 'refresh_token', :client_id => client_id, :client_secret => client_secret, :refresh_token => @refresh_token | |
else | |
response = RestClient.post "#{fqdn}/oauth/token", :grant_type => 'client_credentials', :client_id => client_id, :client_secret => client_secret, :scope => scope | |
end | |
from_json = JSON.parse(response.to_str) | |
@access_token = from_json['access_token'] | |
@refresh_token = from_json['refresh_token'] | |
@access_token_expires = Time.now + (from_json['expires_in'].to_i)/1000 | |
@refresh_token_expires = Time.now + (60*60*24) | |
write_tokens(tokens_file) | |
end | |
def write_tokens(tokens_file) | |
File.open(tokens_file, 'w+') { |f| f.puts @access_token, @access_token_expires, @refresh_token, @refresh_token_expires } | |
end | |
def read_tokens(tokens_file) | |
@access_token, access_expiration, @refresh_token, refresh_expiration = File.foreach(tokens_file).first(4).map! &:strip! | |
@access_token_expires = Time.parse access_expiration | |
@refresh_token_expires = Time.parse refresh_expiration | |
rescue | |
return | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
port: 4567 | |
phone_number: 425-802-8620 | |
api_key: | |
secret_key: | |
registration_id: 22627096 | |
tokens_file: tokens | |
FQDN: https://api.att.com |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/ruby | |
require 'rubygems' | |
require 'json' | |
require 'rest_client' | |
require 'sinatra' | |
require 'sinatra/config_file' | |
require 'base64' | |
require File.join(File.dirname(__FILE__), 'common.rb') | |
enable :sessions | |
config_file 'config.yml' | |
set :port, settings.port | |
SCOPE = 'SMS,MMS' | |
# setup filter fired before reaching our urls | |
# this is to ensure we are o-authenticated before actual action (like sendMms) | |
# autonomous version | |
['/sendMms', '/getMmsDeliveryStatus'].each do |path| | |
before path do | |
obtain_tokens(settings.FQDN, settings.api_key, settings.secret_key, SCOPE, settings.tokens_file) | |
end | |
end | |
get '/' do | |
erb :mms | |
end | |
post '/sendMms' do | |
session[:mms1_address] = params[:address] | |
session[:mms1_subject] = params[:subject] | |
send_mms | |
end | |
get '/getMmsDeliveryStatus' do | |
session[:mms_id] = params[:mmsId] | |
get_mms_delivery_status | |
end | |
# use this URL to clear token file | |
get '/clear' do | |
File.delete settings.tokens_file if File.exists? settings.tokens_file | |
redirect '/' | |
end | |
def send_mms | |
if @address_valid = parse_address(session[:mms1_address]) | |
address = 'tel:' + session[:mms1_address].gsub("-","") | |
att_idx = 0 | |
@split = "----=_Part_0_#{((rand*10000000) + 10000000).to_i}.#{((Time.new.to_f) * 1000).to_i}" | |
@contents = [] | |
result = "Content-Type: application/json" | |
result += "\nContent-ID: <startpart>" | |
result += "\nContent-Disposition: form-data; name=\"root-fields\"" | |
result += "\n\n" | |
result += '{ "Address" : "' + "#{address}" + '", "Subject" : "' + "#{params[:subject]}" + '", "Priority": "High" }' | |
result += "\n" | |
@contents << result | |
[ params[:f1], params[:f2], params[:f3] ].each do |param| | |
if param | |
temp = param[:tempfile] | |
file = File.open(temp.path, "rb") | |
result = "Content-Type: #{param[:type]}" | |
content_id = "<attachment#{att_idx}>" | |
result += "\nContent-ID: #{content_id}" | |
result += "\nContent-Transfer-Encoding: base64 " | |
result += "\nContent-Disposition: attachment; name=\"\"; filename=\"\"" | |
attachment = Base64.encode64(file.read) | |
result += "\n\n#{attachment}" | |
result += "\n" | |
@contents << result | |
file.close | |
att_idx += 1 | |
end | |
end | |
mimeContent = "--#{@split}\n" + @contents.join("--#{@split}\n") + "--#{@split}--\n" | |
response = RestClient.post "#{settings.FQDN}/rest/mms/2/messaging/outbox?access_token=#{@access_token}", "#{mimeContent}", :Accept => 'application/json', :Content_Type => 'multipart/form-data; type="application/json"; start=""; boundary="' + @split + '"' | |
@mms_id = session[:mms_id] = JSON.parse(response)['Id'] | |
end | |
rescue => e | |
@send_error = e.response | |
ensure | |
return erb :mms | |
end | |
def get_mms_delivery_status | |
response = RestClient.get "#{settings.FQDN}/rest/mms/2/messaging/outbox/#{session[:mms_id]}?access_token=#{@access_token}" | |
delivery_info_list = JSON.parse(response).fetch 'DeliveryInfoList' | |
delivery_info = delivery_info_list['DeliveryInfo'].first | |
@delivery_status = delivery_info['DeliveryStatus'] | |
@delivery_URL = delivery_info_list['ResourceURL'] | |
rescue => e | |
@delivery_error = e.response | |
ensure | |
return erb :mms | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment