Twilioで電話をしたらその電話へSMSメッセージを送るサンプルアプリを作っていこうと思います。
サーバーサイドはHerokuで作ろう。言語はrubyです。フレームワークはsinatraで。(Ruby on Railsがまだ覚えられてない。。)
実行環境
- ruby 2.1.3p242
- OSX Yosemite 10.10.5
- sinatra 1.4.6
目次
- Herokuでアプリを作る
- Twilioで電話番号を購入&設定
- 2の電話番号に電話してSMSのメッセージがくるのを確認
Herokuでアプリを作る
初期設定
どこでもいいので、作業ディレクトリを作ってgit,Gemfileを作ります
# フォルダ作成&移動
mkdir sample-app && cd sample-app
# Gitリポジトリにする
git init
# Gemfile の生成
bundle init
Gemのインストール
vim Gemfile
Gemfileを編集します。
# A sample Gemfile
source "https://rubygems.org"
# gem "rails"
gem 'sinatra'
gem 'sinatra-contrib', '~> 1.4.2'
# twilio
gem 'twilio-ruby', '~> 3.12'
# Unicorn
gem 'unicorn'
gem 'faraday'
group :development, :test do
# Foreman
gem 'foreman'
end
group :production do
end
Gemfileが終わったらインストールします。
bundle install --path vendor/bundle --without production
###アプリの作成
今回はsinatraでアプリケーションを作っていきます
アプリケーションの本体となるmain.rb
を作ります。
vim main.rb
main.rbでとりあえず、動くHerokuアプリを作ります。
require 'sinatra'
require 'sinatra/base'
class MainApp < Sinatra::Base
get '/' do
'Hello, World!'
end
end
MainApp
というクラスにgetでHello,worldを出すだけです。
次にHerokuの実行環境に必要なconfig.ru と unicorn.rb と Procfileを作ります。
config.ruを作ります。
vim config.ru
require './main.rb'
run MainApp.new
unicorn.rbを作ります。
mkdir config && vim config/unicorn.rb
worker_processes Integer(ENV["WEB_CONCURRENCY"] || 3)
timeout 15
preload_app true
before_fork do |server, worker|
Signal.trap 'TERM' do
puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
Process.kill 'QUIT', Process.pid
end
defined?(ActiveRecord::Base) and
ActiveRecord::Base.connection.disconnect!
end
after_fork do |server, worker|
Signal.trap 'TERM' do
puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to send QUIT'
end
defined?(ActiveRecord::Base) and
ActiveRecord::Base.establish_connection
end
Procfileを作ります。
vim Procfile
web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb
アプリを起動してみます。GemfileにForemanを入れているので起動してみます。
foreman start
http://0.0.0.0:5000
にアクセスしてHello, World!
が表示されていたらとりあえず成功です。
Herokuアプリの作成
Herokuのアプリも作ってしまいましょう
heroku create TWILIO_APP_NAME
git add .
git commit -m 'first commit.'
git push heroku master
うまく成功すれば、http://TWILIO_APP_NAME.herokuapp.com
でもHello, World!
が表示されるはずです。
Twilioアプリを作る
ここまでは、準備段階。いよいよ、電話をしたらSMSメッセージが送られるTwilioサンプルを作っていきます。
main.rb
を編集します。
require 'sinatra'
require 'sinatra/base'
require 'twilio-ruby'
require 'rubygems'
require 'net/http'
require 'uri'
require 'faraday'
class MainApp < Sinatra::Base
before do
@rootPath = 'https://TWILIO_APP_NAME.herokuapp.com'
end
end
必要なライブラリーをrequireで指定して、 beforeでインスタンス変数@rootPath
を作成しました。Herokuのパスを他でも使えるようにしています。
###電話着信の処理
post '/call' do
content_type "text/xml"
#かかってきた電話番号
fromNumber = params[:From]
Twilio::TwiML::Response.new do |r|
r.Say "Twilioのエスエムエスサンプルです。この後強制的にあなたのエスエムエスにメッセージを送ります。ごめんね", language: 'ja-JP', voice: 'alice', loop: '3'
r.Pause
r.Redirect "#{@rootPath}/postsms/#{fromNumber}" , method: 'post'
end.text
end
誰かからTwilioの電話番号へ電話がかかってきた時のTwilioの応答処理を実装していきます。
post '/call' do
でhttps://TWILIO_APP_NAME.herokuapp.com/callにpostでリクエスト来た時に応答するようにします。
これはあとで、Twilioの電話番号にも指定するので覚えておきます。
content_type "text/xml"
デバックがしやすいようにcontent_typeをxmlにします。
#かかってきた電話番号
fromNumber = params[:From]
かかってきた電話番号はパラメーターでFrom
の中に入っています。
他に取得できるパラメーターは以下で確認できます。
さて、Twilioの自動音声を実装します。
Twilio::TwiML::Response.new do |r|
r.Say "Twilioのエスエムエスサンプルです。この後強制的にあなたのエスエムエスにメッセージを送ります。ごめんね", language: 'ja-JP', voice: 'alice', loop: '3'
r.Pause
r.Redirect "#{@rootPath}/postsms/#{fromNumber}" , method: 'post'
end.text
r.Say
でTwilioの自動音声させる文章や、言語、声の種類、ループ回数を指定しています。
r.Pause
でちょっと待機させて、r.Redirect
でSMSを処理するリクエストを投げる処理へ移動させます。
(/callのこの部分で、SMSをポストすることもできたんですが、それだと電話中にSMSが送られてしまいました。なので、r.Redirectでリダイレクトさせて、ほかのURLでSMSのポストをすることにしました。)
###電話を終了させる
post '/postsms/:fromNumber' do
content_type "text/xml"
#かかってきた電話番号
fromNumber = params[:fromNumber]
Twilio::TwiML::Response.new do |r|
conn = Faraday.new(:url => @rootPath) do |faraday|
faraday.request :url_encoded # form-encode POST params
faraday.response :logger # log requests to STDOUT
faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
end
conn.post "/sendsms/#{fromNumber}"
#hangupで終了させないとだめ
r.Hangup
end.text
end
SMSの処理です。この処理に来た時点ではまだTwilioとの電話は継続しています。SMSへのpostリクエストを送ってから、電話を終了させます。
Twilioの処理としては、r.Hangup
電話を終了させているだけです。
Twilio::TwiML::Response.new do |r|
#hangupで終了させないとだめ
r.Hangup
end.text
電話を終了させる前に、rubyのHTTP クライアントライブラリ Faraday でpostリクエストを投げます。
Faradayの詳しい説明はこちら
conn = Faraday.new(:url => @rootPath) do |faraday|
faraday.request :url_encoded # form-encode POST params
faraday.response :logger # log requests to STDOUT
faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
end
conn.post "/sendsms/#{fromNumber}"
###SMS送信
SMSを送信する処理です。
post '/sendsms/:postPhoneNumber' do
content_type "text/xml"
postPhoneNumber = params[:postPhoneNumber]
if postPhoneNumber != nil
#先頭の0を国際番号+81に入れ替える
postPhoneNumber = postPhoneNumber.gsub(/\A0/, "+81")
#アカウント
account_sid = "ACxxxxxxxxxxxxxxxxxxxxxx"
auth_token = "yyyyyyyyyyyyyyyyyyyyyy"
client = Twilio::REST::Client.new account_sid, auth_token
# Your Twilio number
from = "+1xxxxxxxxxx"
client.account.messages.create(
:from => from,
:to => postPhoneNumber,
:body => "smsメッセージをtwilioで送りました・ω・"
)
end
end
SMS送信する処理は以下です。
#アカウント
account_sid = "ACxxxxxxxxxxxxxxxxxxxxxx"
auth_token = "yyyyyyyyyyyyyyyyyyyyyy"
client = Twilio::REST::Client.new account_sid, auth_token
# Your Twilio number
from = "+1xxxxxxxxxx"
client.account.messages.create(
:from => from,
:to => postPhoneNumber,
:body => "smsメッセージをtwilioで送りました・ω・"
)
アカウントのaccount_sid
とauth_token
は自分のTwilioのアカウントを指定します。
ここにTwilioにログインして
プログラマブルVOICE > はじめよう > APIクレデンシャルを表示する
で確認ができます。
# Your Twilio number
from = "+1xxxxxxxxxx"
ここはあとで電話番号を買うのでその番号を指定します。
コードは以上です。
Herokuにデプロイする
ここまで作ったらHerokuにデプロイしましょう
git add .
git commit -m 'twilio sms app commit.'
git push heroku master
Twilioで電話番号を購入&設定
Twilioで電話を買います。
SMS送信できる電話番号はアメリカの番号です。
なのでアメリカの番号を買いましょう
Twilioログイン後、プログラマブルVOICE > 電話番号 に移動します。
https://jp.twilio.com/user/account/voice/phone-numbers
Buy a Numberボタンを押します。
国をアメリカに指定して検索
購入が終わったら
プログラマブルVOICE > 電話番号 に戻り、電話番号に紐づくURLを登録します。HerokuアプリのURLになります。
今回はアクセスが/callにアプリで作っているので
http://TWILIO_APP_NAME.herokuapp.com/callのURLを指定します。
main.rbの電話番号を買った電話番号に更新しましょう
# Your Twilio number
from = "+1xxxxxxxxxx"
そしてHerokuにデプロイします。
git add .
git commit -m 'add phone number.'
git push heroku master
2の電話番号に電話してSMSのメッセージがくるのを確認
ここまでくれば購入した電話番号に電話をすればSMSが来るはずです。
が、国際電話になるので、ちょっと戸惑いました。。
私のキャリアがSoftbankのiPhoneを使っているのですが、国際電話には
010 > 国番号 > 相手先電話番号
または
-
国番号 > 相手先電話番号
をしないと電話がかけられないみたいです。
http://www.softbank.jp/mobile/service/global/outgoing/call/support/setting-method/iphone/
アメリカの国番号は1です。
なので仮にTwilioで+1 123-456-7890という電話番号を購入したのなら
キーパッドで010 1 1234567890と入力すれば電話がかけられるようになります。
上手く行けば電話が終わったあとにSMSにメッセージが来るはずです!
#最後に
TwilioでHerokuのアプリを作って電話購入までをまとめました。
国際電話のかけかたとか、プログラムではないところでつまづいたので、参考になれば幸いです。
参考
- http://dev.classmethod.jp/server-side/ruby-on-rails/sinatra-postgresql-unicorn-on-heroku/
- https://gist.github.com/mitukiii/2775321
- http://qiita.com/srockstyle/items/111d25f44ef2cc51d9ac
- http://dev.classmethod.jp/server-side/twilio/twilio-sms/
- https://jp.twilio.com/docs/quickstart/ruby/sms/sending-via-rest