ZappaとTwilioでサーバレスな録音システムを作る

2016.11.18

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

平田です。

最近巷で流行りのServerlessですが、本記事ではServerless Frameworkとtwilioを使って、録音システムを構築してみました。

twilioの録音機能について

Twilioとは、電話やSMSとwebサービスを繋げるクラウドサービスです。twilioが提供するクラウドAPIを利用することで、簡単に電話やSMSを利用したサービスを実現することができます。

Twilioの詳細については、弊社ブログで既にいくつか記事がまとまっています。詳細はそちらに譲るとして、今回はTwilioの機能の一つである録音機能に注目してみます。

Twilioでは、TwiMLと呼ばれるHTML-likeなマークアップ言語を使って、電話やSMSを受信した際の挙動を記述することができます。

例えば、以下の様なtwiMLをweb上に公開し、Twilioで電話着信時のトリガとして指定すると、電話が着信したのちに、録音が開始されます。

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Record timeout="10"/>
</Response>

録音した内容はTwilioサービスに管理されており、後から音声を確認することができます。

この様に、Twilioでは一般的なwebシステムの枠組みをそのまま流用して電話応答システムなどを簡単に作れる仕組みとなっています。

Zappa

ZappaはPythonベースのServerless Frameworkの一種です。近いものにchaliceがありますが、chaliceがFlaskクローンのchaliceフレームワークに限定されているのに対し、ZappaはWSGIに対応するフレームワークであれば、限定せずに利用できるという特徴があります。FlaskをそのままZappaで利用することも可能です。

今回はZappaを用いて、TwiMLを返す簡易なwebシステムを構築し、Twilioの録音機能を試してみました。

作ってみた

Zappaのインストール手順やプロジェクトの作成方法についてはREADMEを参考にしました。

プロジェクト作成後は、twilio-sdkを利用して、以下のコードを作成し、デプロイしています。

# coding=utf-8

from flask import Flask, request, redirect
import twilio.twiml

app = Flask(__name__)

@app.route("/home", methods=['GET', 'POST'])
def home():
    resp = twilio.twiml.Response()
    resp.say(u"こんにちは", language="ja-JP")

    with resp.gather(numDigits=1, action="recording", method="POST") as g:
        g.say(u"録音する場合は1を, キャンセルする場合は2を押してください", language="ja-JP")

    return str(resp)

@app.route("/recording", methods=['GET', 'POST'])
def recording():
    digit_pressed = request.values.get('Digits', None)
    if digit_pressed == "1":
        resp = twilio.twiml.Response()
        resp.say(u"はっしんおんのあとに、録音が開始されます。終了する場合は、シャープを押してください", language="ja-JP")

        resp.record(maxLength="30", action="playback", finishOnKey="#")

        return str(resp)

    elif digit_pressed == "2":
        resp = twilio.twiml.Response()
        resp.say(u"さようなら", language="ja-JP")
        return str(resp)

    else:
        return redirect("home")

@app.route("/playback", methods=['GET', 'POST'])
def playback():
    recording_url = request.values.get("RecordingUrl", None)

    resp = twilio.twiml.Response()
    resp.say(u"録音した内容を再生します", language="ja-JP")
    resp.play(recording_url)
    resp.say(u"さようなら", language="ja-JP")

    return str(resp)

if __name__ == "__main__":
    app.run(debug=True)

試しにブラウザからURLを叩いてみると、以下の様にTwiMLが帰ってくることがわかります。

twilio_1

無事TwiMLが公開されたので、次はTwilioの電話番号に発信した際のwebhookとしてURLを設定してみます。webhookの設定はTwilioのwebコンソールから設定できます。

twilio_2

対応する電話番号に電話をかけてみると、音声ガイダンスに従い、録音が開始されます。録音された結果は、webコンソールからも確認できます。

twilio_3

まとめ

Serverless Frameworkを用いることで、Twilioの検証が簡単にできました。

Serverの設定などの煩雑な作業をスキップして、すぐにwebにコンテンツを公開できるのは検証の際にはとても楽でいいですね。

参考