【ワークショップ2日目】Amazon Chime SDK PSTNでコールバックを行う
📅 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を解釈します。
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サービスから送信されるという点がポイントです。
試してみる
今回も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(機械学習)を利用した音声ノイズを除去する機能です。