Twilioでの通話を指定時間で切断してみました

技術ネタ

こんばんわ、hisayukiです!

最近は自社サービス(紹介してないんですが)を改修し続けてるのですが、その中で利用しているTwilioの指定時間で切断する機能について書きます❗

スポンサーリンク

やりたかったこと

今のサービスでは、ポイントを先行購入して通話を提供しています。
そのため、通話時間が所持ポイントを上回る場合になった場合に自動で切断するようにして欲しいと要望がありました。

例えば、

1000pt所持で、通話に100pt/分の消費をする場合、通話開始から10分後に自動切断

というような感じで、問答無用に切ってしまう。

ポイントの減算処理は通話終了時の通話時間から利用ポイントを割り出します。
分単位なので秒についてはすべて切り上げ計算。
そのため、先程の例では1秒でも過ぎたら11分となるので1100ptとなり所持ポイントがマイナスになります。

これを作り込むの辛い・・・・

時間にまつわる処理って出来る限り避けたいんですよね、テストし辛いしバグの温情になりやすいし。
ポイント減算に使う通話時間とかもTwilioが持ってくれてるので、開始から終了までの時間計算しないでTwilioのAPIから引っ張ってるだけ。

時間計算とかもしてるならタイムアウトとか自動切断とかも出来るんじゃないかなぁ・・・
Twilioでいい感じに指定できないかなぁって調べてたら・・・

あったw

timeLimit

The timeLimit attribute sets the maximum duration of the <Dial> in seconds.


For example, by setting a time limit of 120 seconds, <Dial> will automatically hang up on the called party two minutes into the phone call.


The default time limit on calls is four hours – this is also the maximum length of a call.

https://jp.twilio.com/docs/voice/twiml/dial#timelimit

というわけでやってみましたヽ(=´▽`=)ノ

実装

実装自体はそんなに難しくなかったです。
今のサービス内でTwilioが行っているのはDialによる転送電話なのでTwiMLはこんな感じ。

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Dial callerId="【Twilioの電話番号】">
        <Number>【転送先電話番号】</Number>
    </Dial>
</Response>

このTwiMLに以下のようにtimeLimitを追記するだけ!

timeLimitに渡す時間は秒単位になります。

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Dial callerId="【Twilioの電話番号】" timeLimit="【指定時間(秒)】">
        <Number>【転送先電話番号】</Number>
    </Dial>
</Response>

Kotlinで実装するとこんな感じで、Dial.Builderに.timeLimitを追加するだけですね。

class TwilioVoiceResponseFactory {
    companion object {
        fun createDial(twilioPhoneNumber: String, trancePhoneNumber: String, callTimeLimit: Int): TwilioVoiceResponse {
            return DialResponse.create(
                Dial.Builder()
                    .callerId(twilioPhoneNumber)
                    .number(Number.Builder(trancePhoneNumber).build())
                    .timeLimit(callTimeLimit)
                    .build()
                )
        }
    }
}

結果

結果TwiMLで240秒で指定したら、子通話は4分ピッタリで切れています❗
転送通話なので親通話は転送前、子通話が転送後なので子通話の時間が実際の通話時間になります。

ちなみに親通話の通話時間は4分10秒、この時間には子通話の時間も含まれているので転送前コールが10秒、その後転送先で4分って見方です。

一つ課題点としては、この子通話の4分には転送先へのコール時間も含まれている
つまり、

コール時間 + 実際に通話している時間 = timeLimitでの指定時間

となりますので、コール時間が長いとその分通話時間は削られます。

まとめ

timeLimit設定では秒単位で正確なので、通話時間を正確に切断したいときには有効です❗

ただ、ユースケースがSayを使った自動音声とか通話時間を正確にしないと行けない場合など、そんなに無いかもしれないですが(;´∀`)

今回計算で使う通話時間は子通話の時間をAPIで取得しているので、無事にやりたいことも出来ました❗
ただ、実際に通話している時間を抜き出すところまでは今できていないので今後の課題かなと。

今回この件でTwiMLのことをいろいろ調べてみたら、DialやNumberなどのAttributesがめちゃ優秀❗
TwiMLでもWebhookの設定できたり、録音できたりと、手動設定ではなくコードで設定とかもできそうなのでいい感じだなぁと思いました(*´▽`*)

特にステータス変更時のWebhookはコンソールからだとcompletedのみにしかキックしないですが、TwiMLからだとキックさせたいステータスを指定できます。
指定出来るURLは1つですが、API側で渡されたステータスごとに処理を分けることが出来ます❗

また一つ、新しい知見が得られました❗

コメント