Twilio Flex で保留中の音楽を変更する

:::note alert
2023年5月1日を持ちまして、株式会社KDDIウェブコミュニケーションズのTwilioリセール事業が終了したため、本記事に記載されている内容は正確ではないことを予めご了承ください。
:::

# はじめに

みなさん、こんにちは。
KDDIウェブコミュニケーションズ、Twilioエバンジェリストの高橋です。

今回は、Twilio Flex で着信時の保留音を変更する方法についてご紹介します。

## 着信時の保留音とは

Twilio Flex では、着信時に TaskRouter にコールが渡り、エージェントがコールを取るまでの間に保留音を流すことができます。
デフォルトで設定されている音はあまりイケてないので、オリジナルの音楽や音声に変えたいですよね。

もちろん、変更は可能です。

![スクリーンショット 2022-09-22 8.39.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/f840a721-eb98-6c63-5760-fca928cdda1c.png)

もし、着信呼を Studio Flow に割り当てている場合（ほとんどのケースはそうなっているはず）、TaskRouter に渡す`Enqueue Call`ウィジェットの`HOLD MUSIC TWIML URL`に、流したい音声もしくは音楽を再生する TwiML を返すURLを指定すればOKです。

ここでポイントは、音声ファイルのURLを直接指定するのではなく、音声ファイルを再生する TwiML を返却させないと行けない点です。
なので、[TwiMLBins](https://console.twilio.com/us1/develop/twiml-bins/twiml-bins?frameUrl=%2Fconsole%2Ftwiml-bins%3Fx-target-region%3Dus1)などを使って、以下のような TwiML を返すようにして、その Twiml Bins のURLを指定するようにしましょう。

```xml:Playの例
<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Play loop="0">https://api.twilio.com/cowbell.mp3</Play>
</Response>
```

:::note info
loop="0"を忘れると、音楽は１回再生されて無音になります。
:::

と、ここまでであれば、わざわざ記事を書くほどでもないわけです。

## 保留の途中で音楽を変更したい

先日、こんな要望をいただきました。
「音楽にガイダンスを載せて再生したい。ただし、ガイダンスは初回のみ。」

普通に考えると、「初回だけガイダンスを載せた長い音源を作ってそれを流せばいいじゃん」なんですけど、長い音源とはいえいずれは終わるはずですし、無駄に長い音源をつかうことでそれを再生するときにオーバーヘッドがかかります。

:::note info
`HOLD MUSIC TWIML URL`に指定したTwimlは、再生が終了すると再度呼び出されるようになっているので、再びガイダンスが流れてしまいます。
:::

## 解決方法

そもそも保留音は、なぜ何度も再生されるようになっているのでしょうか？
実は、Twimlを呼び出す際に以下のパラメータを渡してくれるようになっているのです。

- QueuePosition: 現在のキューの位置（1〜）
- QueueSid: キューのSid
- QueueTime: キューに入っている時間（秒）
- AveQueueTime: キューの平均待ち時間（秒）
- CurrentQueueSize: キューに入っている通話の数

これらのパラメータを判定することで、たとえば「現在、あなたの順番は○番目になります。お繋ぎするには、おおよそ○分程度かかります。」といった文言を流すことができます。
なので、今回のケースでは`QueueTime`を判定して、一定時間より短い場合だけガイダンス付きの音源、それ以降はガイダンスなしの音源を流せば良さそうです。

で、それを実現するためには、TwimlBins では難しいため、Functions を作ってみました。

```javascript:Functionで音源を切り替える
/**
 * 保留音を再生する（初回のみガイダンスあり）
 */
exports.handler = async function (context, event, callback) {
  const { DOMAIN_NAME } = context;
  const { QueueTime } = event;
  console.log(`🐞 play-music-guid started. ${DOMAIN_NAME} ${QueueTime}`);
  let twiml = new Twilio.twiml.VoiceResponse();

  twiml.play(
    `https://${DOMAIN_NAME}/holdmusic_${
      QueueTime < 1 ? 'guide' : 'no_guide'
    }.mp3`,
  );
  return callback(null, twiml);
};
```

音源ファイルは以下の2種類を用意し、Functionsと同じAssets内に格納しておきます。

- holdmusic_guide.mp3 ガイダンスあり
- holdmusin_no_guide.mp3 ガイダンスなし

また、初回に呼ばれた時は`QueueTime`が`0`になるため、`< 1`で初回かどうかを判定しています。
あとは、Studio Flow の`HOLD MUSIC TWIML URL`に、この Functions のURLを指定すればOKです。

# オペレーターが保留をしたときの音楽を変更したい場合

着信時の保留ではなく、オペレーターが応答後に保留操作をした場合の対応はどうすればいいでしょうか。

こちらについては、Flex プラグインを作成して対応が可能です。
具体的には、以下のコードを`init`関数の中で定義するとよいでしょう。

```javascript
  flex.Actions.replaceAction('HoldCall', (payload, original) => {
    return new Promise((resolve) => {
      original({
        ...payload,
        holdMusicUrl: `https://${FLEX_APP_FUNCTION_DOMAIN}/play-music-no-guide`,
        holdMusicMethod: 'POST',
      });
      resolve();
    });
  });
```

このコードは、予め Flex で定義されている`HoldCall`アクションを上書きし、音源ファイルを指定したものに変更するものです。

:::note info
`FLEX_APP_FUNCTION_DOMAIN`はご自分の環境に合わせて設定してください。
先ほど説明したものと同じく、音源を再生する TwiML を返すようにします。
:::

# まとめ

今回は Twilio Flex で説明をしましたが、この仕組みはそもそも Twilio Voice の Enqueue で実現されているため、Flex以外でも利用ができます。

https://jp.twilio.com/docs/voice/twiml/enqueue

ぜひお試しあれ。

---
### Twilio（トゥイリオ）とは

https://cloudapi.kddi-web.com
Twilio は音声通話、メッセージング（SMS /チャット）、ビデオなどの 様々なコミュニケーション手段をアプリケーションやビジネスへ容易に組み込むことのできるクラウド API サービスです。初期費用不要な従量課金制で、各種開発言語に対応しているため、多くのハッカソンイベントやスタートアップなどにも、ご利用いただいております。

Twilioに関するご相談などがございましたら、ぜひ毎週水曜日の午後に開催しております相談会をご利用ください。
[Twilio相談会（毎週水曜日）](https://cloudapi.kddi-web.com/contact/consultation?hsLang=ja-jp)

自己紹介|　
:--|:--
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/b51a8b88-abd5-ce5e-195a-de3564ba2ae6.png" height='200' width='150'/>|高橋克己（Katsumi Takahashi） 自称「<font color='red'>赤い芸人</font>」<br />グローバル・インターネット・ジャパン株式会社　代表取締役<br />株式会社KDDIウェブコミュニケーションズ　Twilio事業部エバンジェリスト<br /><br />2001年より大手通信事業者の法人サービスの教育に携わり、企業における電話のしくみや重要性を研究。2016年よりTwilio事業部にジョインし、Twilioを使ったスマートコミュニケーションの普及活動を精力的に行っている。<br />2015 Hall of Doers<br />2019 Twilio Champions