every Tech Blog

株式会社エブリーのTech Blogです。

トモニテ相談室におけるTwilioを用いた電話の仕組み

お久しぶりです,トモニテ開発部でSoftware Engineer(SE)をしている鈴木です.
every Tech Blog Advent Calendar 2023 の18日目を担当する事になりましたので,鈴木が関わっているトモニテの新規事業についてお話させていただきます.

はじめに

トモニテ相談室のロゴ

トモニテは2023年11月30日に家族・家庭や恋愛に対する悩みをプロのカウンセラーと相談出来る新サービス トモニテ相談室 をローンチしました!
有り難いことに,新卒2年目にも関わらずトモニテ相談室のローンチメンバーの1人に選任していただき,webサイトとそれに必要なAPI全般,及びサービスの基盤である相談の仕組みを任せていただきました.
開発当初,通話形式での相談を提供することだけが決まっており,通話に関する技術に対して弊社に知見があまり無かったことやコスト面,そしてリリースまでの工数感を踏まえ,相談基盤にはTwilioを利用する運びになりました.
トモニテ相談室にはどのような開発要件があり,その要件を満たすためにTwilioのどの機能をどのように利用したのかを紹介していこうと思います.

Twilioとは?

Twilioは,人間が機械を通して行うコミュニーケーションに対してアクセス出来る様々なAPI群を提供しているサービスです.
多種多様なコミュニーケーションに対して対応しており,電話やSMSはもちろんのこと,Eメールやビデオ配信,そしてそれらを用いた認証等にも対応しております.
Twilioを利用することで電話によるお問い合わせ対応の一部を自動化出来たり,電話/SMS認証やメール認証の仕組みを一任することが出来ます.
公式ドキュメントを眺めるとTwilioで実現出来る事とその豊富さが実感出来ると思いますので,是非一読いただきたいです.

満たすべき要件

トモニテ相談室の相談基盤が満たすべき主要な要件として以下が挙げられます.

  • カウンセラー様固有の連絡先情報無しで相談が可能
  • 通話の状態遷移をトリガーにアクションが出来る
  • 通話内容を録音可能

カウンセラー様固有の連絡先情報無しで相談が可能

カウンセラー様固有の連絡先情報(電話番号など)を用いて相談可能にしてしまうと,トモニテ相談室が関与しないところでカウンセラー様にご迷惑をおかけしてしまう可能性があり,カウンセラー様に不利益を与えてしまいます.
このような可能性を排除するため,カウンセラー様固有の連絡先情報無しでカウンセラー様と相談可能にする必要がありました.

通話の状態遷移をトリガーにアクションが出来る

トモニテ相談室ではユーザー様が相談したいカウンセラー様を選ぶようになっているため,カウンセラー様が現在どのような状態なのかをユーザー様にお知らせすることが重要になります.
具体的には,カウンセラー様は退席中なのか,相談受付中なのか,それとも他のユーザー様と現在通話中なのかをお知らせすることで,ユーザー様が相談したいカウンセラー様を選ぶ際の判断の一助になると考えています.
また,トモニテ相談室は通話した時間でユーザー様に課金するため,ユーザー様とカウンセラー様の間で通話が正常に開始されたのかどうか,開始された場合にはいつ開始されたのかといった情報が必要になります.
これらを実現するためには通話の状態遷移をトリガーにアクションが出来る事が必須でした.

通話内容を録音可能

トモニテ相談室では,「相談」が持つべきプライベートな性質を考慮し,相談中はユーザー様とカウンセラー様の2人だけが接続された状態になり,トモニテ相談室は関与しないようになっております.
このようにすることでユーザー様は安心して悩みを打ち明けることが出来ると考えております.一方で,プライベート故にカウンセラー様に対してより良いカウンセリングをするためのフィードバックをする事や,相談中に何らかのトラブルが発生した際の対応が難しくなってしまいます.
これらの課題を解決するため,必要に応じて相談後に関与することが出来る録音機能が必要でした.

要件を満たすために利用したTwilioの機能

上記要件は,TwilioのVoice Webhooksを利用しTwilioに指示を出すことで大部分を満たす事が出来ます(一部録音データを外部のストレージに保存するための設定などが別途必要となります).

Voice Webhooksとは

Voice Webhooksとは,特定の電話番号(今回はトモニテ相談室の電話番号)に対して電話があったことをトリガーに指定されたAPIにリクエストを送る機能のことです.
Voice Webhooksを利用する開発者は,TwiMLというXMLベースのマークアップ方式で記述されたレスポンスを返すAPIを用意し,事前にエンドポイントを設定しておく必要があります.

TwiML

TwiMLはXMLに対して独自のタグを追加したものです.
独自タグはVerb(動詞)とNoun(名詞)から構成されており,これらを組み合わせることでTwilioに対して多種多様な処理を指示します.
例えば,以下のTwiMLは動詞Sayと動詞Dial及びそれに付随する名詞Numberから構成されており,Twilioに対して次のことを指示しています.

  1. 日本語で「お電話ありがとうございます」と読み上げる
  2. 受けた電話を+810123456789の電話番号に繋ぎ直す

このTwiMLを利用するだけでカウンセラー様の連絡先情報を公開すること無くユーザー様とカウンセラー様を接続することが出来ます.
また,Dial動詞はrecordプロパティを指定出来,このプロパティを指定することでTwilioに録音の指示が出来ます(保存先の指定には別途設定が必要になります).
更に,Number名詞はstatusCallbackプロパティを持っており,このプロパティを利用することで通話の状態遷移が発生した際に指定のエンドポイントにリクエストを送ることが出来ます.
つまり,以下のシンプルなTwiML(を一部拡張したもの)を動的に生成し返すAPIを用意するだけで,トモニテ相談室における要件の全てを満たすことが出来るのです!

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Say language="ja-JP">お電話ありがとうございます</Say>
    <Dial>
        <Number>+810123456789</Number>
    </Dial>
</Response>

なお,トモニテ相談室ではカウンセラー様が相談中にユーザー様の事前アンケートの内容を確認したり,メモを取る際などの利便性を考慮し,実際にはNumber名詞ではなくClient名詞によるブラウザフォンを採用しています.両者の間には電話かブラウザフォンか以外に大きな違いはないため,ここではNumberを用いて説明いたしました.

トモニテ相談室の電話の仕組み

カウンセラー様の行動

カウンセラー様が相談可能な時にはカウンセラー様専用のwebにログインしていただき,待機開始処理をしていただいています.
待機が開始された際にAPIサーバーがトークンを発行し,そのトークンを利用してTwilioとWebSocketを利用した双方向通信を開始し,ブラウザフォンを有効にしています.

カウンセラー様の行動

ユーザー様の行動

ユーザー様には相談受付中のカウンセラー様から相談したいカウンセラー様を予約していただいています.
予約が成功したらAPIサーバーからトモニテ相談室の電話番号が返され,カウンセラー様の連絡先情報は返されません.

ユーザー様の行動

電話の流れ

ユーザー様からの発信をトリガーにTwilioからAPIサーバーへリクエストが届き,カウンセラー様のトークンと紐付けられた情報をもとにTwiMLを生成してレスポンスを返します.
TwilioはTwiMLの内容を元にリダイレクト先のブラウザフォンを特定し,リダイレクトします.
通話の状態が遷移する度にTwilioはTwiMLで指定されたエンドポイント(今回はトモニテ相談室のAPIサーバー)へリクエストを送ります.
また,通話が終了した段階で弊社のS3バケットに確定した録音データが保存されます.

電話の流れ

全体像

上記を踏まえ,トモニテ相談室における電話の仕組みの全体像は以下の図のようになります.
Twilioを利用することで,シンプルな構成にも関わらず満たしたい要件全てを満たすことが出来ています.

全体像

まとめ

トモニテの新規事業サービス「トモニテ相談室」における電話の仕組みを紹介させていただきました.
トモニテ相談室の電話の仕組みの多くはTwilioというサービスのVoice Webhooksを利用することで実現されており,Voice WebhookではTwiMLというマークアップ言語を用いてTwilioに対して様々な指示をすることが出来ます.
TwiMLで実現出来ることは非常に多岐に渡るため,TwiMLをカスタマイズすることで満たしたい要件のほとんどを満たすことが出来ました.
この記事が類似の要件に対してどのようにアプローチすべきか検討されている開発者の方々のお役に立てたら大変嬉しいです.
ここまでお読みいただきありがとうございました!