Skip to content

【ワークショップ2日目】Amazon Chime SDK PSTNでコールバックを行う

promotion image
  • Amazon Chime SDK

📅 2022-03-27

Amazon Chime SDK PSTN Audioを触ってみるの2日目です。
Amazon Chime SDK PSTN Audio Workshopを実際にやってみるシリーズとなります。

今回は、「Amazon Chime SDKでコールバック」をやっていきます。

前回の記事はこちら

今回のワークショップでの期待する動作

今回やるレッスンはこちら

アプリケーションが通話に応答し、Amazon Pollyでメッセージを再生して切断、その後コールバック発信、メッセージを再生を行います。

アプリケーションの動き

前回のレッスンにコールバック処理を追加したものになります。また、今回も前回同様、着信時にアナウンス再生を行いますが、音声ファイルを再生するのではなくAmazon PollyのText to Speechを使用します。

speakActionでAmazon Pollyを使う

Amazon PollyはPSTN Audioサービスにネイティブに統合されています。
Amazon PollyはspeakAction.Parameters.TextにセットされたSSMLを解釈します。

Pollyでサポートされているタグのリスト

function newCall(event: any) {
  const from = event.CallDetails.Participants[0].From;
  speakAction.Parameters.Text = "<speak>Hello!  I will call you back!  Goodbye!</speak>";
  return [pauseAction, speakAction, hangupAction];
}

speakActionオブジェクトの中身は下記です。

const speakAction = {
  Type: "Speak",
  Parameters: {
    Engine: "neural", // 必須 standard or neural
    LanguageCode: "en-US", // オプション
    Text: "", // 必須 テキストかSSMLをセット
    TextType: "ssml", // オプション。デフォルトはtext
    VoiceId: "Matthew" // 必須
  }
}

コールバック

回線が切断されると、PSTN AudioサービスはHANGUPイベントでLambdaを実行します。あとはイベントがマッチしたときの処理を記載するだけです。

 case 'HANGUP':
      console.log('HANGUP');
      if (event.CallDetails.Participants[0].Direction == 'Inbound') {
        actions = await makeDial(event);
      } else {
        console.log("Second hangup, task completed");
      }
      break;

HANGUPイベントで必ずコールバックするようにしてしまうと、通話を終了する度にコールバックが発生するため、無限に電話をかけ続けることになります。 なので、着信通話のときだけコールバックを行うようにeventオブジェクトから通話の方向を取得します。

発信はPSTN Audioサービスへのレスポンスによって行っているわけではなく、AWS SDKのChimeクライアントを使用してAPI実行という形で行います。

API呼び出しは非同期で実行されるため、awaitとtry catchを利用しましょう。

function makeDial(event: any) {
  console.log(event);
  var params = {
    FromPhoneNumber: event.CallDetails.Participants[0].To,
    SipMediaApplicationId: event.CallDetails.SipMediaApplicationId,
    ToPhoneNumber: event.CallDetails.Participants[0].From,
    SipHeaders: {},
  };
  console.info('params: ' + JSON.stringify(params));  // just for debugging
  const command = new CreateSipMediaApplicationCallCommand(params);
  try {
    const response = await chimeClient.send(command);
  } catch (err) {
    console.log(err);
    return err;
  }
}

発信APIが実行されると、PSTN Audioサービスから発信が行われ、NEW_OUTBOUND_CALL、RINGING、CALL_ANSWEREDといったイベントでLambdaが実行されます。このレッスンではNEW_OUTBOUND_CALL、RINGINGでは何も処理行わず、CALL_ANSWEREDでPollyでのアナウンス再生を行います。

function callAnswered(event: any) {
  const from = event.CallDetails.Participants[0].From;
  speakAction.Parameters.Text = "<speak>Hello!  I am just calling you back!  Goodbye!</speak>";
  return [pauseAction, speakAction, pauseAction, hangupAction];
}

アナウンス再生後、再びHANGUPイベントが呼び出されますが、今回は通話がOutboundであるためアプリケーションはコールバックを行わずに終了します。

シーケンス図

⑤でNEW_OUTBOUND_CALLがLambdaからのアクションレスポンスではなく、API実行を経由してPSTN Audioサービスから送信されるという点がポイントです。

chime-sdk-callback-sequence

試してみる

今回もyarnコマンドでデプロイしますが、その前にPollyのメッセージを日本語に変えてみましょう。

/* 変更前 */
function newCall(event: any) {
  const from = event.CallDetails.Participants[0].From;
  speakAction.Parameters.Text = "<speak>Hello!  I will call you back!  Goodbye!</speak>";
  return [pauseAction, speakAction, hangupAction];
}

function callAnswered(event: any) {
  const from = event.CallDetails.Participants[0].From;
  speakAction.Parameters.Text = "<speak>Hello!  I am just calling you back!  Goodbye!</speak>";
  return [pauseAction, speakAction, pauseAction, hangupAction];
}

const speakAction = {
  Type: "Speak",
  Parameters: {
    Engine: "neural", // Required. Either standard or neural
    LanguageCode: "en-US", // Optional
    Text: "", // Required
    TextType: "ssml", // Optional. Defaults to text
    VoiceId: "Matthew" // Required
  }
}

/* 変更後 */
function newCall(event: any) {
  const from = event.CallDetails.Participants[0].From;
  speakAction.Parameters.Text = "<speak>こんにちは!  このあとすぐにコールバックするよ!</speak>"; // 文章を変更
  return [pauseAction, speakAction, hangupAction];
}

function callAnswered(event: any) {
  const from = event.CallDetails.Participants[0].From;
  speakAction.Parameters.Text = "<speak>こんにちは!  コールバック通話だよ!  さようなら!</speak>"; // 文章を変更
  return [pauseAction, speakAction, pauseAction, hangupAction];
}

const speakAction = {
  Type: "Speak",
  Parameters: {
    Engine: "neural", // Required. Either standard or neural
    LanguageCode: "ja-JP", // 言語コードをja-JPに変更
    Text: "", // Required
    TextType: "ssml", // Optional. Defaults to text
    VoiceId: "Takumi" // 話者をTakumiに変更
  }
}

コードを修正できたのでデプロイします。

$ yarn deploy
$ yarn swap

通話切断後、10秒ほどでコールバック通話が着信しました。アナウンスもばっちり日本語化できています。

動作した際の音声です。Amazon Connectだとコールバック通話を録音することができないので携帯で発信、録音をしました。

今回わかったこと

Amazon Chime SDKで、コールバック発信を実装することができました。また、発信通話、着信通話においてAmazon Pollyでアナウンス再生をすることができました。

  • Lambda呼び出しイベントのCallDetailsに通話のメタデータが入っている
  • HANGUPイベントで発信APIを実行することでコールバックが可能
  • Lambda内でspeakActionを使用することでPollyを呼び出すことができる

通話イベントごとにLambda内で処理を変えるという点は前回もやったので慣れていましたね。

次回予告

次回3日目は要素が多くなります。

  • DTMF(数値入力)の取得
  • 通話転送とIVR
  • Amazon Voice Focusの有効化

Amazon Voice FocusはML(機械学習)を利用した音声ノイズを除去する機能です。

参考文献

← PrevNext →
  • produced by GeekFeed
  • produced by GeekFeed