Twilioを使って、ブラウザで電話を受け取れるようにする


やること

Twilioのライブラリを利用して、電話の着信機能を作成します。
Twilioへの登録と、電話番号の取得が必要です。
以下がTwilio側とブラウザ側の処理の流れです。

Twilio側の流れ

  1. Twilioが通話を受け取る
  2. Twilioが自動応答のシナリオ(TwiML)を返すAPIを呼び出す
  3. TwilioがTwiMLを読み取って、クライアント(ブラウザの着信者)を呼び出す

ブラウザ側の流れ

  1. twilio-clientライブラリを使って、着信時の挙動を設定する
  2. クライアントのトークンを作成するAPIを呼び出す
  3. トークンを使って、着信を受け取れるようにする

APIのコードをかく

今回はnode.js + typescript + expressで書きます。前もってtwilioパッケージをインストールしときましょう
npm i twilio

以下の2つのAPIを作ります

  • TwiMLを返すAPI
  • クライアントのトークンを作って返すAPI
import {jwt, twiml} from 'twilio';
import express = require('express');
import {json} from 'express';

const app = express();
app.use(json());

/**
 * TwiMLを返すAPI
 */
app.route('/incoming').post((req, res) => {
  const voice = new twiml.VoiceResponse(); // ここに設定していく
  voice.say('hello'); // 音声を再生
  voice.say({voice: 'Polly.Mizuki', language: 'ja-JP'}, '日本語でおk'); // 日本語で再生(voiceなどは設定可能)
  voice.pause({length: 1}); // 1秒待つ

  // クライアント名を指定して電話をかける
  voice
    .dial({callerId: req.body.From || '', ringTone: 'jp'}) // オプション
    .client('[クライアント名]');

  const response = voice.toString(); // TwiML(XML)を作成

  res.type('text/xml');
  res.send(response); // レスポンスを返す
});

/**
 * クライアントのトークンを作って返すAPI
 */
app.route('/token').get((_, res) => {
  // capabilityに能力を足していく
  const capability = new jwt.ClientCapability({
    accountSid: 'TwilioアカウントのSID',
    authToken: 'Twilioアカウントのトークン',
    ttl: 600, // トークンの有効期限。最大24H(86400)らしい
  });
  capability.addScope(
    new jwt.ClientCapability.IncomingClientScope('[クライアント名]')
  );

  // 今は使わないが、外にかけるときに使う
  // capability.addScope(
  //   new jwt.ClientCapability.OutgoingClientScope({
  //     applicationSid: "TwilioAppのSID",
  //   })
  // );

  const token = capability.toJwt(); // これを返す
  res.send({ok: true, token: token});
});

app.listen(3000); // 3000番ポートでリッスン

簡単に試す場合は、このコードをts-nodeなどで実行しましょう
http://localhost:3000/tokenにGETリクエストを送ると、tokenが帰ってくると思います

TwilioコンソールでAPIを登録する

↓コンソールはこれです
https://jp.twilio.com/console/

電話番号 / 番号の管理 / アクティブな電話番号 /の「A CALL COMES IN」にTwiMLを返すAPIを指定します。

クライアント側のコードをかく

js(typescript)で書きます。JSフレームワークは好きなの選択。

前もってtwilio-clientをインストールしときましょう
(間違ってnpm i twilioをしないように気をつけてください。こっちはサーバ向けです)

デバイスのセットアップ方法を、ざっくり書きます。

import { Device, Connection } from "twilio-client";

const device = new Device(); // ここに処理をのっける

device.on("incoming", (connection: Connection) => {
  const onAccept = () => {
    connection.accept(); // 受け取る
  };
  const onReject = () => {
    connection.reject(); // 拒否る
  };

  openIncomingCallModal(onAccept, onReject); // Viewの部分はお任せ
});

その後、前に作った「クライアントのトークンを作って返すAPI」を呼び出して、トークンを取得します(コード略)。
トークンを受け取ったら、それを使ってデバイスをセットアップ。

device.setup(jwt);

これでOK

ちなみに、こちらから通話を切るときはdisconnectAll()を呼びます。

device.disconnectAll();

まだ機能が少ないので、ドキュメントをみて、諸々の機能を足していくといいかもしれません。