*

AppEngineでTwilioを試してみた(応用編)

公開日: : 最終更新日:2015/04/17 投稿者: GAE, GCP

AppEngineでTwilioを試してみた(基本編)
AppEngineでTwilioを試してみた(応用編)

はじめに

前回は基本編ということで、twilioの簡単な説明とプログラム(電話をかけると言葉を出力する)の説明をおこないました。今回はtwilioの応用編ということで、SMSメッセージの送信から通話記録の保存までを取り上げます。

-前回の記事(基本編)はコチラです。
http://www.apps-gcp.com/twilio-basic/
※開発環境に関しても前回の記事を参考にしてください。

SMSメッセージを送信してみる

指定のサーバからSMSメッセージを送信する方法について説明します。この仕組みを利用すればGoogleが提供するような2段階認証を簡易に実装することが可能となります。それでは実際にプログラムからSMSメッセージを送信するための手順について説明します。

(1)認証キーの準備
SMSメッセージを送信するためには以下2つの認証キーが必要となります。これらのキーはtwilioのアカウントページの「Account Settings」から取得可能です。

・ACOUNT_SID
・AUTH_TOKEN

(2)電話番号の購入
SMSを利用する場合、SMSに対応した電話番号を購入します。ただし、日本リージョンで購入できる電話番号がSMSに対応していないため、SMSを利用するためにはアメリカの電話番号を購入する必要があります。米国番号は月額税込み150円(一つにつき)となります。購入にはクレジット番号の登録も必要となります。

※1 最初にtwilioから発行される番号もSMSには対応していません。
※2 料金については以下をご参考ください。

http://twilio.kddi-web.com/price/

image01

画像1.電話番号の購入

(3)SMSメッセージを送信するサーブレットの作成
アカウント画面から取得したACCOUNT_SIDとAUTH_TOKENを以下のようにプログラム内に記載します。(2)で購入した電話番号は送信先の”FROM”に設定してください。

-SmsServlet

public class SmsServlet extends HttpServlet {
	/* Find your sid and token at twilio.com/user/account */
    public static final String ACCOUNT_SID = "**************************";
    public static final String AUTH_TOKEN = "**************************";

    //Handle an incoming HTTP Request
    public void doGet(HttpServletRequest request, HttpServletResponse response)
    		throws IOException {
    	//Create a Twilio REST client
        TwilioRestClient client = new TwilioRestClient(ACCOUNT_SID, AUTH_TOKEN);

        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("Body", "ようこそ!吉積情報株式会社です!"));
        params.add(new BasicNameValuePair("To", "+81**********"));
        params.add(new BasicNameValuePair("From", "+15104038862"));

        MessageFactory messageFactory = client.getAccount().getMessageFactory();
        try {
			Message message = messageFactory.create(params);
			response.getWriter().println("sid=>" + message.getSid());
		} catch (TwilioRestException e) {
			// TODO Auto-generated catch block
			response.getWriter().println("" + e.getMessage());
		}
    }
}

図1. SMS送信サーブレット

-web.xml

...
<servlet>
	<servlet-name>Sms</servlet-name>
	<servlet-class>test.SmsServlet</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>Sms</servlet-name>
	<url-pattern>/sms</url-pattern>
</servlet-mapping>
...

図2. SMS送信サーブレットのURL定義

(4)デプロイ
作成したプログラムをEclipseからデプロイします。

(5)実行してみる
作成したサーブレットのURLにアクセスし、以下のSMSメッセージを受信できればプログラムの実行は成功となります。

※受信をおこなう電話番号は(2)のサーブレットで記載した送信先番号(To)となります。

image00

画像2. SMSメッセージ

 

音声メッセージを保存してみる

電話の通話内容を保存する方法について説明します。ただし、通話内容の保存先はtwilioのサーバとなります。ユーザ側で取得できるのは音声データの保存先のURLとなります。本章では、音声の録音から音声データ共有ページの作成までをおこないます。

・保存料金について
音声録音は10,000分までは無料となり、それを超過した場合は1分につき0.1円がかかります。

※詳細は以下のURLを参考にしてください。
http://twilio.kddi-web.com/price/

(1)録音用twiMLを出力するサーブレットの作成
録音twiMLを出力するサーブレットを作成します。録音をおこなうためには<Record>タグを利用します。タグ属性の説明とサーブレットサンプルは以下の通りです。

・action
録音データを取得するサーブレットのURLを指定します。

・method
GETまたはPOSTを指定します。

・maxLength
録音時間(秒数)を指定します。

・finishOnKey
録音を終了する電話キーを指定します。

public class RecordTwimlServlet extends HttpServlet {
	public void doGet(HttpServletRequest req, HttpServletResponse resp)
  		throws IOException {
		// Create a TwiML response and add our friendly message.
		TwiMLResponse twiml = new TwiMLResponse();
		// 音声メッセージの作成
		Say say = new Say("ろくおんがおわったらしゃーぷをおしてください。");
		say.setLanguage("ja-jp");
		// 録音
		Record record = new Record();
		record.setAction("http://twilio-sample.appspot.com/record"); //録音データの取得先
		record.setMethod("POST");
		record.setMaxLength(30); //30秒の録音
		record.setFinishOnKey("#");
		// エラーの場合
		Say errorSay = new Say("エラーが発生しました。");
		try {
			twiml.append(say);
			twiml.append(record);
			twiml.append(errorSay);
		} catch (TwiMLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		resp.setContentType("text/xml;charset=UTF-8");
		resp.getWriter().println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
		resp.getWriter().print(twiml.toXML());
	}
}

図3. 録音用twiMLを出力するサーブレット

(2)録音情報を保存するサーブレットの作成
データの保存にはGoogleAppEngineのデータストア(Low Level API)を利用します。サンプルサーブレットは以下の通りです。

public class RecordServlet extends HttpServlet {
	public void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {
		// 音声保存先URL
		String recordingUrl = req.getParameter("RecordingUrl");
		// 音声ファイルの保存秒数
		String recordingDuration = req.getParameter("RecordingDuration");
		// データストアに音声情報の保存
		DatastoreService service = DatastoreServiceFactory.getDatastoreService();
		Entity entity = new Entity("Record");
		entity.setProperty("recordingUrl", recordingUrl);
		entity.setProperty("recordingDuration", recordingDuration);
		entity.setProperty("registerDate", new Date());
		service.put(entity);
		// 録音データの保存を知らせるtwiMLの出力
		TwiMLResponse twiml = new TwiMLResponse();
		Say say = new Say("ろくおんがかんりょうしました。");
		say.setLanguage("ja-jp");
		try {
			twiml.append(say);
		} catch (TwiMLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		resp.setContentType("text/xml;charset=UTF-8");
		resp.getWriter().println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
		resp.getWriter().print(twiml.toXML());
	}
}

図4. 録音情報を保存するサーブレット

(3)録音情報の一覧を表示するサーブレットの作成
データストアから録音データの一覧を取得し画面に表示します。サンプルサーブレットは以下の通りです。

public class RecordListServlet extends HttpServlet {
	public void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {
		// 録音データ一覧の出力
		DatastoreService service = DatastoreServiceFactory.getDatastoreService();

		Query q = new Query("Record");
		q.addSort("registerDate", SortDirection.DESCENDING);
		PreparedQuery pq = service.prepare(q);
		List<Entity> list = pq.asList(FetchOptions.Builder.withOffset(0));
		StringBuffer sb = new StringBuffer();
		sb.append("<table style=\"border:1px solid #000;width:800px;\">");
		sb.append("<tr><td>音声URL</td><td>再生時間</td><td>登録時間</td></tr>");
		for(Entity entity:list) {
			sb.append("<tr><td><a href=\"");
			sb.append(entity.getProperty("recordingUrl"));
			sb.append("\">再生する</a></td><td>");
			sb.append(entity.getProperty("recordingDuration"));
			sb.append("秒</td><td>");
			sb.append(entity.getProperty("registerDate"));
			sb.append("</td></tr>");
		}
		sb.append("</table>");
		resp.setContentType("text/html;charset=UTF-8");
		resp.getWriter().print(sb.toString());
	}
}

図5. 録音情報

(4)3つのサーブレットをweb.xmlに定義
(1)〜(3)で作成したサーブレットをweb.xmlに定義します。

...
	<servlet>
		<servlet-name>RecordList</servlet-name>
		<servlet-class>sample.RecordListServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>RecordList</servlet-name>
		<url-pattern>/recordList</url-pattern>
	</servlet-mapping>

	<servlet>
		<servlet-name>Record</servlet-name>
		<servlet-class>sample.RecordServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>Record</servlet-name>
		<url-pattern>/record</url-pattern>
	</servlet-mapping>

	<servlet>
		<servlet-name>RecordTwiml</servlet-name>
		<servlet-class>sample.RecordTwimlServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>RecordTwiml</servlet-name>
		<url-pattern>/recordTwiml</url-pattern>
	</servlet-mapping>
...

(5)デプロイ
作成したプログラムをEclipseからデプロイします。web.xmlで設定したサーブレットURLにアクセスし、以下のtwiMLが出力されることを確認します。

image02

画像3. 録音twiML

(6)RequestURLの登録
twilioのアカウントページにログインし、対象の電話番号に対してRequestURLを登録します。

※本サンプルでは「SMSメッセージを送信してみる」の章で購入した電話番号を利用します。

image03

画像4. 録音twiMLの登録

(7)実際に電話をかけて録音してみる
実際に録音twiMLが登録された番号(以下の電話番号)に対して電話をかけてみます。通話が始まると「録音が終わったら#(シャープ)を押してください。」というメッセージが流れるので、メッセージが流れ終わったら何かメッセージを録音してみます(録音の終了は#ボタン)。

010-1-510-403-8862

※こちらの電話番号はしばらく公開しておきますので、興味がある方は録音してみてください。ただし、一定期間後に削除する可能性がありますので、そのときはご了承ください。

(8)録音データの一覧を確認
録音した音声の一覧は以下のURLから確認することができます。録音データを再生する場合は「再生」するリンクをクリックしてください(画像4参照)。

http://twilio-sample.appspot.com/recordList

image04

画像4. 音声ファイル一覧

まとめ

今回取り上げたサンプルプログラムはtwilio APIライブラリを利用して作成しました。実際に作ってみれば実感できると思いますが、このライブラリを利用すれば非常に簡易に電話やSMSを利用したサービスを作成することができます。今回はJAVAを取り上げましたが、ライブラリはその他にもPython、PHP、C#、Ruby等の言語にも対応しているので、幅広い開発者が手をつけやすいAPIであると言えると思います。twilioは一般のクラウドサービスと同様にクレジットカードがあれば誰でも簡単にすぐにでも始めることができます。ぜひ今回のtwilioの記事をキッカケに新規サービスや既存のシステムに組み込んでみては如何でしょうか。

apps-gcpではtwilio以外にもさまざまなサードパーティのホットなAPIを取り上げていく予定ですので、今後もapps-gcpのチェックを宜しくお願いします!!

AppEngineでTwilioを試してみた(基本編)
AppEngineでTwilioを試してみた(応用編)

この記事を書いた人

tomorier
tomorier
普段はGCP専門のエンジニアをやっています。
最近は個人的な活動としてGOとswiftでアプリ作ってます。

関連記事

2015/06/17 GCE vs AWS ベンチマーク

2015/06/17 GCE vs AWS ベンチマーク 本シリーズでは定期的にGCEとEC2のベ

記事を読む

GAE負荷テスト その1「Hello World!」

2011年11月にGAEのプレビューが終わり、早数ヶ月経ちました。 これからGAEでの開発に乗り出

記事を読む

GAE負荷テスト その2「無料で何PVまで表示できるのか試してみた」

その1のアップからだいぶ日が経ってしまい、いつの間にか年すら変わっていましたね。。。 " GA

記事を読む

GAE/JからBigQueryへのStream Insert

今回はGAE/JからBigQueryへのStream Insertを試してみます。 BigQuer

記事を読む

Google ロードバランサーのチートレベル性能検証:リージョンまたぎ編(デモあり)

6月に発表され、現在Limited PreviewされているGCPのL7ロードバランサの機能を紹介し

記事を読む

2015/02/12 GCE vs AWS ベンチマーク

2015/02/12 GCE vs AWS ベンチマーク 本シリーズでは定期的にGCEとEC2のベ

記事を読む

GAEのスケーリング 後編 <最適化の実践>

この記事では、こちらの公式ドキュメントをもとに、GAEのスケーリングの仕組みと最適化のやり方について

記事を読む

Search API詳細解説 Part5「Search API 詳細 反映速度編」

Search API詳細解説シリーズ タイトル Part1Search API 概要説明

記事を読む

Search API詳細解説 Part3「Search APIの使い方 検索編」

Search API詳細解説シリーズ タイトル Part1Search API 概要説明

記事を読む

新しいRPCフレームワーク、gRPCをGoで試してみる。

  みなさん、今年の2月末にGoogleが発表したgRPCをご存知でしょうか?gRP

記事を読む

PAGE TOP ↑