Hello, Twilio! たった4行のコードで電話機能を実装するクラウド電話APIに触れてみよう
2016年3月17日 木曜日 | LEXUES
こんにちは!あげなかずと@新入社員です!
この度沖縄からTwilio UGを立ち上げるに当たり、ハンズオン資料を書きました。
今回は
Heroku + Sinatra + twilio-ruby を使って、Twilioの基本的な機能、
・電話を着信する
・音声を再生
・プッシュによる分岐
・通話を録音する
・電話をかける
を行いたいと思います。
なお、このドキュメントはTwilio公式サイトの「Ruby REST クイックスタート チュートリアル」を参考にしておりますm(__)m
また、ソースコードは rice-american/twilio-ruby-tutorial に push しております。ご参照下さいm(__)m
事前確認
このハンズオンでは、Twilioのアカウントが必要です。もし取得していない場合は、下記ブログなどを参考に、取得してください。
・新規登録ですぐ使える-クラウド電話-sms-api-twilioの新規登録
・Twilio(トゥイリオ)を触ってみた
また、このハンズオンではRuby, Herokuを使用します。もしインストールされていない場合は、下記URLからダウンロードし、インストールしてください。
・Ruby公式ドキュメント
・HerokuToolbelt
1. Heroku上にアプリケーションを作成する
1.1. 任意の場所にディレクトリを作成し、移動します。
1 2 |
$ mkdir ~/trial/twilio/ruby-tutorial $ cd ~/trial/twilio/ruby-tutorial |
※注: Windowsのコマンドプロンプトの場合、mkdirコマンドは一度に複数階層作成できないため、1つずつ作成する必要があります。
1.2. heroku login
を実行
先ほど作成したディレクトリに移動し、heroku login
を実行しましょう。
1 2 3 4 5 6 7 8 9 10 |
% heroku login heroku-cli: Installing Toolbelt v4... done For more information on Toolbelt v4: https://github.com/heroku/heroku-cli heroku-cli: Adding dependencies... done heroku-cli: Installing core plugins... done Enter your Heroku credentials. Email: [設定したメールアドレスを入力] Password (typing will be hidden): [設定したパスワードを入力] Logged in as [設定したメールアドレスが表示されます] |
これでコマンドラインからherokuへログインできました。
1.3. gitリポジトリの用意
git init
を実行し、Gitリポジトリを作成します。
1 2 3 |
% git init Initialized empty Git repository in /Users/k.agena/trial/twilio/ruby-tutorial/.git/ |
続いて.gitignore
ファイルを生成します。
1 2 3 4 |
(master)% vim .gitignore ## Environment normalization: /.bundle /vendor/bundle |
次にgit commit -am "add .gitignore"
を実行します。
1 2 |
(master)% git add .gitignore (master)% git commit -m "add .gitignore" |
※注: git add時に改行コードについて警告が出た場合は、下記のように対処してください。
warning: LF will be replaced by CRLF in {ファイル名}.
対処方法:git config --global core.autoCRLF false
を実行
1.5. heroku create
を実行
heroku create
を実行します。この時、heroku create {アプリケーション名前}
とすることで、アプリに任意の名前をつけられます。
なお、アプリケーションの名前は過去に誰にも付けられていないものでなければなりません。
今回はtwilio-ruby-agena
というアプリ名をつけます。
1 2 3 |
(master)% heroku create twilio-ruby-agena Creating twilio-ruby-agena... done, stack is cedar-14 https://twilio-ruby-agena.herokuapp.com/ | https://git.heroku.com/twilio-ruby-agena.git |
2. Sinatra アプリ作成
2.1 ライブラリ(sinatra, twilio-ruby)をインストール
必要なライブラリをインストールするのに、bundleを使用します。
(bundle がインストールされていない方は gem install bundle
でbundleをインストールしてください。)
最初にGemfileを生成します。
1 |
(master)% bundle init |
生成されたGemfileを下記のように編集します。
1 2 3 4 5 6 |
# A sample Gemfile source "https://rubygems.org" gem "sinatra" gem "twilio-ruby" gem "rack" |
続いてbundle install --path=vendor/bundle
を実行し、ライブラリをインストールします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
(master)% bundle install --path=vendor/bundle Fetching gem metadata from https://rubygems.org/............ Fetching version metadata from https://rubygems.org/.. Installing builder 3.2.2 Installing jwt 1.5.3 Installing multi_json 1.11.2 Installing rack 1.6.4 Installing tilt 2.0.2 Using bundler 1.11.2 Installing twilio-ruby 4.11.1 Installing rack-protection 1.5.3 Installing sinatra 1.4.7 Bundle complete! 3 Gemfile dependencies, 9 gems now installed. Bundled gems are installed into ./vendor/bundle. |
ここで、一度git commitを行いましょう。
1 2 |
(master)% git add . (master)% git commit -m "ライブラリをインストール" |
3. 電話をかけて、音声を再生してみよう
3.1 Twilioにおけるプログラミング
前提知識として、Twilioを使用するプログラミングは、Twimlを動的に生成することを目的とします。
Twimlとは、マークアップ言語で書かれた「通話や SMS を受信した時の動作を Twilio に指示するための、命令のセット」です。
Twilioは、ユーザからTwilio電話番号に対して着信すると、そのTwilio電話番号に紐付けられたTwimlのURLへアクセスします。
そして、そのTwimlに書かれた命令(音声を再生する、音声を録音するなど)を実行します。
そのため、Twimlはインターネット上からアクセスできるサーバにアップロードし、アクセスが出来るようにしてておく必要があります。
今回ははherokuを使用することで、サーバを用意することなく、Twimlを使用できる場所にアップロードでき、sinatraを使うことで、
アクセスに対してレスポンスできます。
3.2 Hello, Twilio!
Twilioプログラミングの第一歩として、音声を読み上げるプログラムを作成しましょう。
twiml-quickstart.rb
というファイルに下記を記入してください。
1 2 3 4 5 6 7 8 9 |
require 'rubygems' require 'sinatra' require 'twilio-ruby' get '/hello-twilio' do Twilio::TwiML::Response.new do |r| r.Say 'Hello Twilio!' end.text end |
3.3 プログラムの解説
<6行目>
1 |
r.Say 'Hello Twilio!' |
動詞にはデフォルトで英語(en)が設定されているため、そのままでは日本語を再生できません。
日本語を再生する場合は、下記のように、languageオプションに’ja-jp’を指定します。
1 |
r.Say 'ハロー! トゥイリオ!', :language => 'ja-jp' |
より詳細な仕様は https://jp.twilio.com/docs/api/twiml/say をご参照下さい。
3.4 ローカルでsinatraを起動してみよう
今回、herokuでsinatraを起動するため、先ほどgem install
したライブラリ、rackを使用します。
rackを起動させるため、config.ru(設定ファイル)に下記のように記入します。
1 2 |
require './twiml-quickstart' run Sinatra::Application |
キチンと動くか、 bundle exec rackup config.ru
を実行して確認しましょう。
1 2 3 4 |
(master)% bundle exec rackup config.ru [2016-03-06 14:59:52] INFO WEBrick 1.3.1 [2016-03-06 14:59:52] INFO ruby 2.3.0 (2015-12-25) [x86_64-darwin15] [2016-03-06 14:59:52] INFO WEBrick::HTTPServer#start: pid=77677 port=9292 #=> listenしているポート番号 |
listenしているポート番号は9292と表示されているため、http://localhost:9292/hello-twilio
にWebブラウザからアクセスします。
成功していればHello Twilio!が表示されていると思います。
次に、ソースコードを表示してみましょう。下記のようなTwiMLが生成されていると思います。
1 2 3 4 |
<?xml version="1.0" encoding="UTF-8"?\> <Response> <Say>Hello Twilio!</Say> </Response> |
このTwimlは、アクセスされると”Hello Twilio!”と返答します。
3.5. herokuへデプロイする
起動していたサーバを<ctrl-c>を押して終了し、ここまでの修正をgit commit
し、herokuへデプロイしましょう。
1 2 3 |
(master)% git add . (master)% git commit -m "hello twilio! を再生する機能作成" (master)% git push heroku master |
※注: Windowsの場合、pushに失敗することが有ります。その際は、下記のコマンドを実行してください。
1 2 3 4 |
(master)% git config --global user.name "{あなたの名前}" (master)% git config --global user.email "{あなたのメールアドレス}" (master)% git remote add heroku git@heroku.com:{先ほど作成したHerokuアプリ名}.git (master)% heroku keys:add |
ブラウザから https://{作成したherokuアプリ名}.herokuapp.com/hello-twilio
へアクセスしてみましょう。
ローカルと同様、のTwiMLが生成されていれば成功です!
3.6.「Herllo Twilio!」を聞きに行く
TwiMLを設置できたので、早速メッセージを聞きましょう!
まずは下記URLからTwilio電話番号を取得します。
Twilio User – Account Phone Numbers Getting Started
https://jp.twilio.com/user/account/phone-numbers/getting-started
画面上の「最初のTwilio電話番号を取得」を押して、「Choose this Number」を選択します。
続いて、下記URLから取得したTwilio電話番号にVoiceURLを登録します。
これによって、この電話番号へ発信すると、VoiceURLの指し示すTwiMLを読み込みに行きます。
下記リンクから、先ほど取得したTwilio電話番号のリンクをクリックします。(図1)
Twilio User – Account Phone Numbers Incoming
https://jp.twilio.com/user/account/phone-numbers/incoming
すると、Twilio電話番号の設定画面へ遷移するので、画面中腹にある「Request URL」にhttps://{作成したherokuアプリ名}.herokuapp.com/hello-twilio
を記入しましょう。この時、メソッドをHTTP POSTからHTTP GETへ変更しておきます。(図2)
変更したら、画面下部の「保存」ボタンを押します。
設定したら、実際にTwilio電話番号へ電話をかけてみましょう!
英語で「このメッセージはアカウントをアップグレードをすると流れなくなります。何かダイヤルキーを押してください」という旨のメッセージがなれるので、何かしらのキーを押した後、「Hello, Twilio!」と音声が聞こえたら成功です!
4. プッシュによる分岐 & 通話を録音してみよう
4.1 実装
続いて、プッシュによる分岐・通話の録音機能を実装しましょう。
先ほど作成したtwiml-quickstart.rbを下記のように編集します。
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 |
require 'rubygems' require 'sinatra' require 'twilio-ruby' # # 最初にアクセスされる # get '/hello-twilio' do Twilio::TwiML::Response.new do |r| r.Gather :numDigits => '1', :action => '/hello-twilio/handle-gather', :method => 'get' do |g| g.Say 'こんにちは!', :language => 'ja-jp' g.Say '音声を録音する場合は1, ', :language => 'ja-jp' g.Say 'なにもしない場合は2を押してください...', :language => 'ja-jp' end end.text end # # 押されたボタンを判断する # get '/hello-twilio/handle-gather' do pushed_key = params['Digits'] # 1, 2以外のボタンが押された場合はもう一度メッセージを入力させる redirect '/hello-twilio' unless ['1', '2'].include? pushed_key if pushed_key == '1' response = Twilio::TwiML::Response.new do |r| r.Say 'ピー!と言う発信音の後にテキトーに喋ってください。 何かキーを押すと録音を終了します。', :language => 'ja-jp' r.Record :maxLength => '30', :action => '/hello-twilio/handle-record', :method => 'get' end elsif pushed_key == '2' response = Twilio::TwiML::Response.new do |r| r.Say 'サヨナラ!', :language => 'ja-jp' end end response.text end # # 録音したメッセージを再生する # get '/hello-twilio/handle-record' do Twilio::TwiML::Response.new do |r| r.Say '録音したメッセージを再生します!', :language => 'ja-jp' r.Play params['RecordingUrl'] r.Say 'サヨナラ!', :language => 'ja-jp' end.text end |
4.2 プログラムの解説
<10行目>
1 |
r.Gather :numDigits => '1', :action => '/hello-twilio/handle-gather', :method => 'get' do |g| |
動詞は、ユーザからの入力受付を行います。numDigits => '1’
は “1以上の整数”を意味しており、:action => '/hello-twilio/handle-gather
は”ユーザからの入力値を/hello-twilio/handle-gatherのTwiMLへ渡す”、:method => 'get'
は、actionに指定したURLに対して”GETリクエストを送信する”ことを意味しています。
より詳細な仕様はhttps://jp.twilio.com/docs/api/twiml/gatherをご参照ください。
<29行目>
1 |
r.Record :maxLength => '30', :action => '/hello-twilio/handle-record', :method => 'get' |
動詞は、ユーザの音声を録音します。:maxLength => '30'
と指定することで、「最大30秒」録音できることを意味しています。maxLengthの最大値は3600秒(1時間)です。録音した音声へアクセスするためのURLは、Rubyの場合params[‘RecordingUrl’]でアクセスできます。
より詳細な仕様は https://jp.twilio.com/docs/api/twiml/record をご参照下さい。
<45行目>
1 |
r.Play params['RecordingUrl'] |
動詞では、指定されたURLの音声を再生します。params[‘RecordingURL’]を指定することで、ユーザが録音した音声が再生できます。
より詳細な仕様は https://jp.twilio.com/docs/api/twiml/playをご参照下さい。
4.3 録音してみよう
先ほどのプログラムを保存し、git commit
を行ったのち、git push heroku master
を行いましょう。
1 2 3 |
(master)% git add . (master)% git commit -m "録音機能を追加" (master)% git push heroku master |
『3.4.「Herllo Twilio!」を聞きに行く』で取得したTwilio電話番号に発信してみましょう。
うまく、録音した自分の音声を聞くことが出来たでしょうか?
5. 発信してみよう
URLを叩いたら、自分の携帯電話に発信し、紐付けられたURLのTwimlを再生する機能を作りましょう!
先ほど編集したtwiml-quickstart.rbを下記のように編集します。
5.1 実装
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 |
require 'rubygems' require 'sinatra' require 'twilio-ruby' # # メッセージを再生する # post '/hello-twilio' do Twilio::TwiML::Response.new do |r| r.Gather :numDigits => '1', :action => '/hello-twilio/handle-gather', :method => 'get' do |g| ######################## # 中略 ######################## # # 電話をかける # get '/hello-twilio/make-call' do account_sid = ENV['TWILIO_ACCOUNT_SID'] auth_token = ENV['TWILIO_AUTH_TOKEN'] @client = Twilio::REST::Client.new account_sid, auth_token @call = @client.account.calls.create( :from => ENV['TWILIO_PHONE_NUMBER'], :to => ENV['MY_PHONE_NUMBER'], :url => 'https://twilio-ruby-agena.herokuapp.com/hello-twilio' ) end |
5.2 プログラムの解説
電話の発信にはTwilio クライアントを使用します。
Twilioクライアントを使用するには、ユーザの使用しているアカウントを特定するため、2つのクレデンシャル「Account SID」と「Auth Token」 が必要です。
(※これらのキーの取得方法については後述します)
Rubyでは、下記のように書くことでTwilioクライアントオブジェクトを生成できます。
1 2 3 |
account_sid = ENV['TWILIO_ACCOUNT_SID'] auth_token = ENV['TWILIO_AUTH_TOKEN'] @client = Twilio::REST::Client.new account_sid, auth_token |
ここで、ENV['TWILIO_ACCOUNT_SID']
, ENV['TWILIO_AUTH_TOKEN']
という表記が出てきました。
これにより、それぞれ環境変数 “TWILIO_ACCOUNT_SID”, TWILIO_AUTH_TOKENが展開されます。
こうしているのは、プログラム上に直接クレデンシャルを記入した場合、Githubなどに公開した際にクレデンシャルを使われてしまう危険性があるためです。
続いて、下記のコードを解説します。
1 2 3 4 5 |
@call = @client.account.calls.create( :from => ENV['TWILIO_PHONE_NUMBER'], :to => ENV['MY_PHONE_NUMBER'], :url => 'https://twilio-ruby-agena.herokuapp.com/hello-twilio' ) |
ここでは、作成したclientオブジェクトに対してオプションを設定しています。:from
には発信元の電話番号、ここでは、Twilio電話番号、:to
には発信先の電話番号。ここでは、アカウント登録時に認証した電話番号を入れます。
発信先電話番号の表記は、たとえば「090-1234-5678」という電話番号の場合、「+819012345678」と入力しましょう。
:url
には、発信先で電話を受け取られた時に遷移するURLです。今回は、前章「4. プッシュによる分岐 & 通話を録音してみよう」で作成したルート、hello-twilio
へ飛ばします。
また、一つ重要なポイントとして、下記のように、hello-twilioルートのメソッドがGETメソッドからPOSメソッドに変更されています。
1 2 3 |
post '/hello-twilio' do Twilio::TwiML::Response.new do |r| r.Gather :numDigits => '1', :action => '/hello-twilio/handle-gather', :method => 'get' do |g| |
これは、クライアントが:url
のパラメタに遷移するときにPOSTメソッドでアクセスするためです。GETメソッドのままだと404エラーとなってしまいます。
解説は以上です。続いてHerokuへデプロイしてみましょう!
5.3 「Account SID」と「Auth Token」を取得
Twilioクライアントを使用するのに必要な「Account SID」と「Auth Token」は、Twilioの自分のアカウントページから新しく生成する必要があります。まず、図3のように、アカウントページの「APIキー」をクリックします。
遷移先で「APIキーを作成する」を押した後の画面(図4)で、
フレンドリーネーム(Twilio電話番号から先頭の+を除いたもの)を入力し、「Create API Key」を押します。
次に、一度だけ表示される「Auth Token」を控えておいてください。
これで、「Account SID」と「Auth Token」が取得できました!
5.3 Herokuへデプロイ
Herokuへデプロイを行う前に、Heroku上に、プログラムで使用している環境変数を定義します。
下記のコマンドに適宜パラメタを入力し、実行してください。
1 2 3 4 5 |
$ mkdir ~/trial/twilio/ruby-tutorial $ heroku config:add TWILIO_ACCOUNT_SID='{あなたのsid}' $ heroku config:add TWILIO_AUTH_TOKEN='{あなたのauth token}' $ heroku config:add TWILIO_PHONE_NUMBER='{あなたのTwilio電話番号}' $ heroku config:add MY_PHONE_NUMBER='{あなたの電話番号(アカウント登録時に認証したもの)}' |
先ほどのプログラムを保存し、git commit
を行ったのち、git push heroku master
を行いましょう。
1 2 3 |
(master)% git add . (master)% git commit -m "発信機能の追加" (master)% git push heroku master |
それでは、ブラウザから https://{作成したherokuアプリ名}.herokuapp.com/hello-twilio/make-call
へアクセスしてみましょう。
自分の携帯に電話がかかり、例の音声が聴こえれば成功です!
さいごに
みなさま、ハンズオンお疲れ様でした!
今回のイベントを通して、「Twilioを使ってこんな新しいサービスが作れるのではないか」、「Twilioと今自分がやっている仕事のあの部分は、Twilioを使えば効率化出来るのではないか」、など、Twilioでだいぶ夢が広がっただろうと思います。
沖縄UGでは、今後もそんな素敵API、Twilioを沖縄で広めるべく、活動していこうと思っております。
今回参加してくださった皆様も、機会があれば、またお会いしましょう!
以上!あげなかずと@新入社員でした。m(__)m