12
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Twilioで電話したらSMSを送るアプリをHerokuで作る

Last updated at Posted at 2015-12-20

Twilioで電話をしたらその電話へSMSメッセージを送るサンプルアプリを作っていこうと思います。
サーバーサイドはHerokuで作ろう。言語はrubyです。フレームワークはsinatraで。(Ruby on Railsがまだ覚えられてない。。)

実行環境

  • ruby 2.1.3p242
  • OSX Yosemite 10.10.5
  • sinatra 1.4.6

目次

  1. Herokuでアプリを作る
  2. Twilioで電話番号を購入&設定
  3. 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アプリを作ります。

main.rb
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
config.ru
require './main.rb'
run MainApp.new

unicorn.rbを作ります。

mkdir config && vim config/unicorn.rb
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を編集します。

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のパスを他でも使えるようにしています。

###電話着信の処理

main.rb
	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' dohttps://TWILIO_APP_NAME.herokuapp.com/callにpostでリクエスト来た時に応答するようにします。
これはあとで、Twilioの電話番号にも指定するので覚えておきます。

content_type "text/xml"
デバックがしやすいようにcontent_typeをxmlにします。

		#かかってきた電話番号
        fromNumber = params[:From]

かかってきた電話番号はパラメーターでFromの中に入っています。
他に取得できるパラメーターは以下で確認できます。

TwiMLTMメッセージ : Twilioのリクエスト

さて、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のポストをすることにしました。)

###電話を終了させる

main.rb
   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の詳しい説明はこちら

main.rb
				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を送信する処理です。

main.rb

	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送信する処理は以下です。

main.rb
			#アカウント
			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クレデンシャルを表示する
で確認ができます。

スクリーンショット 2015-12-20 12.40.53.png

main.rb
# 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ボタンを押します。

国をアメリカに指定して検索

スクリーンショット 2015-12-20 12.46.36.png

好きな電話番号を選んで購入します。
スクリーンショット 2015-12-20 12.46.57.png

購入が終わったら
プログラマブルVOICE > 電話番号 に戻り、電話番号に紐づくURLを登録します。HerokuアプリのURLになります。

スクリーンショット 2015-12-20 12.54.03.png

今回はアクセスが/callにアプリで作っているので
http://TWILIO_APP_NAME.herokuapp.com/callのURLを指定します。

main.rbの電話番号を買った電話番号に更新しましょう

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 > 国番号 > 相手先電話番号
または

アメリカの国番号は1です。

なので仮にTwilioで+1 123-456-7890という電話番号を購入したのなら

キーパッドで010 1 1234567890と入力すれば電話がかけられるようになります。

上手く行けば電話が終わったあとにSMSにメッセージが来るはずです!

IMG_3710.PNG

#最後に
TwilioでHerokuのアプリを作って電話購入までをまとめました。
国際電話のかけかたとか、プログラムではないところでつまづいたので、参考になれば幸いです。

参考

12
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?