Championsの西口です。前回は、クラウドコンタクトセンターをスモールスタートする際にあたり必要なモノについて記載しました。今回はクラウドコンタクトセンターをスモールスタートするときのコード例についてご紹介していきます。この記事の技術構成について私が得意な技術だけでまとめました。Client(JavaScript)ChromeブラウザCentOSサーバ今回、PHPインストールとCentOSセットアップについては触れませんが、なるべく最新バージョンでWebサーバを使用する状態にしてください。SDKの準備https://jp.twilio.com/docs/libraries/phpこのドキュメントを参照にインストールをしてください。composerさえあれば、すぐに利用可能な状態にできると思います。不明な場合は、KDDIウェブコミュニケーションズ社にこちらからお問い合わせください。Clientはブラウザで動作するライブラリです。そのため、電話機としての操作をするためのインターフェイスは作る必要がありますが、架電や受電などの通話部分に関することは、このライブラリを利用するだけでとても簡単に完成します。CDNが用意されているため、CDNを利用すると、自動でClientのバージョンアップが行われます。Clientバージョンアップに伴う不具合も少なからず起きているため、ブラウザ側の自動テストなどが用意できていない場合、突然不具合が発生する場合もあるためご注意ください。開発時点の最新バージョンをダウンロードし、それをテストした後、利用することを個人的にはおすすめしています。架電については、下記のドキュメントとGithubリポジトリが参考になります。Clientクイックスタートドキュメント(PHP):https://github.com/TwilioDevEd/client-quickstart-phpクイックスタートには特に記載ありませんが、様々なユーザに利用してもらうにあたり、電話番号の入力チェックを実装してください。入力チェックを実装する理由として、架電にあたり数字以外も利用するためです。Client同士の通話する際、Identityを用いた架電を行います。Clientと通話するために利用します。下記要件を満たす入力チェックをJavaScriptの正規表現で実装しておき、実際にサーバに架電リクエストを行う前にチェックします。アルファベットから始まるクライアント名のフォーマット電話番号は正式には「+国番号」から始まる番号形式ですが、スモールスタートでは利用可能な国は日本限定とし、上記のような正規表現を利用します。Identityのドキュメント:https://jp.twilio.com/docs/voice/client/tutorials/calls-between-devicesIdentityは同じアカウント内での通話を行ういわゆる内線をする際や、通話ログから誰がどこと通話したかなどの分析で利用します。そのため、一意で特定のユーザと紐づけできるようにしておいてください。受電については、前回の記事で書いた通り、特定のIdentityの人達のClientを同時に鳴らすことにします。同時に鳴らせる人数は10人までです。複数のClientを同時に鳴らすには、「ClientというTwiml」を使用します。PHPで下記のように書くことで、複数Clientを同時に指定し、電話を鳴らすことができます。Webhookに設定します。詳しくは下記のドキュメントを参照してください。https://jp.twilio.com/docs/voice/tutorials/how-to-respond-to-incoming-phone-calls-php#buy-and-configure-a-phone-numberこのコードは簡易的な仕様のため、受電者のaliceとbobを変えたり、増やしたりするにはコードの修正が必要ですし、aliceとbobが受電可能かどうか、そもそも存在するのかどうかの確認もしていません。プロダクトで使用するには心もとないですが、期間限定のスモールスタートで使用してもらう分には問題ありませんでした。Client側は下記ドキュメントも参考になります。https://www.twilio.com/docs/voice/client/tutorials/incoming-calls#accepting-an-incoming-callただし、ドキュメントのコードだと、受電したら即座に通話が始まってしまうため、「電話を取るボタン」を用意する必要があります。Notificationを使って、受電していることの通知と通知クリックで通話が始まるように修正しました。};});これだけだと、どこの番号からどこの番号へ受電したのか不明のため、下記ドキュメントを参照に、customParametersを利用するのが良さそうです。https://support.twilio.com/hc/en-us/articles/115011213347-Passing-Custom-Information-via-Requests-to-TwilioParameterにfromとtoの番号をもたせて、customParametersから取得した情報をNotificationに渡すことでどこからどこへの受電なのか表示が可能です。一般的な電話機同様、実装が可能です。保留にあたり、サーバ側でQueueと呼ばれる、通話を待機させる場所に通話を入れることで実現ができます。ドキュメントの下記コードが参考になります。https://jp.twilio.com/docs/voice/twiml/enqueue?code-sample=code-simple-enqueue-1&code-language=PHP&code-sdk-version=5.xまた、このEnqueueの呼び出しにあたり、通話相手の通話を更新する必要があります。詳しくは下記ドキュメントを参考にしてください。https://cloudapi.kddi-web.com/dev/679/ドキュメントの通りだと、すべての保留はsampleというQueueに入ってしまうため、取次時に困ることになります。いうのもQueueに入っている通話は、最初に入った通話から順次取り出されて通話するため、指定した通話を取り次ぐためにはQueueの状態を見ながら指定の通話が次に取り出されるタイミングまで待つ必要があるからです。この仕様だと、とても使いづらいかと思います。そこでQueueの名前はTwilioが自動で割り振りするCallSidを使用するのをおすすめします。下記のようなコードになります。$response;Clientでは、上記のURLに対して、通話中のCallSidを付与して、呼び出すようにしましょう。通話中のCallSidは'Twilio.DeviceのactiveConnection()'を呼び出し、Connectionオブジェクトを取得します。Connectionオブジェクトにparametersというプロパティがあり、その中でCallSidを保持しています。説明すると長いですが、コードだと下記のようになります。一意な名前を持つQueueが作成できます。ここで取得したcall_sidは次の取次でも利用します。取次Twilioにおいて「取次」とは、指定のQueueに対して、電話をかけることに該当します。そのため、コードとしてはシンプルで架電とほぼ同じ実装です。$response;取次の難しいところは、上で指定したCallSidの受け渡しが難しいことです。Syncというリアルタイムデータベースを用いて、同じアカウント内のClientはすべて保留一覧が同期された状態で見れるようにしています。ユーザにとって、CallSidは意味のわからない文字列なのでこれは見せず、通話相手の電話番号と保留した人の情報が見れるようになっています。コードは公開していないのですが、システム構成図自体は下記スライドに乗せています。このスライドの29ページ目からが参考になると思います。https://www.slideshare.net/ssuser4d37c8/twilio-104443847ただし、Syncは実装やテストが大変なので、ひとまずは保留したらユーザのブラウザなどにログを残し、手動でCallSidをチャットツールなどで受け渡すなどの方法でも大丈夫だと考えています。こちらは締切との兼ね合いになるため、どれくらい保留取次が発生するかなどの要件をすり合わせた上で、どの実装方法を選択するかエンジニアの腕の見せ所になります。DTMFトーン宅配便などの再配達で、「再配達の依頼は1を、配達状況の確認は2を、それ以外は3を押してください」というようなアナウンスを聞いて、用件に合わせて指定された番号を押したことがあると思います。この番号ボタンを押した際に発生する音が「DTMFトーン」です。DTMFトーンの実装をしておかないと、「架電したのにトーンを送る方法がなくて通話ができなかった」ということが起こりえます。実装自体は簡単なので、必ず実装しておくようにしてください。このドキュメントにあるsendDigitsを使用するだけです。https://jp.twilio.com/docs/voice/client/javascript/connection#sendDigits保留でも使用したactiveConnectionからConnectionオブジェクトを参照し、押された数字を引数に呼び出すだけです。かんたんなコード例ですが、下記がそのまま使用できると思います。}};まとめ今回はドキュメントをベースに実際にスモールスタートでコンタクトセンターを運用した際に使ったコードを抜粋しつつ、起きた問題を改修したサンプルコードを挙げました。サーバとクライアントの連携が必須で、覚えることもたくさんありますが、サンプルコードを参考に、ぜひスモールスタートなコンタクトセンターを実現してみてください。次回は本格的なコールセンター移行にあたり考慮が必要な仕様や要件の洗い出しについてまとめますので乞うご期待ください。西口瑛一:前職でTwilioを用いた国内最大規模のコンタクトセンターを1から開発。Championsに選ばれる。