[Amazon Connect] 電話番号とPINコードで認証してSMSメッセージを送信する
1 はじめに
Amazon Connect(以下、Connect)を使用したシステムで、ユーザーの電話番号と、ユーザーが入力したPINコードの確認をする仕組みを作ってみました。
作成したイメージは、以下のようなものです。
- あるサービスでは、会員のスマフォの電話番号は、予め登録されている
- 会員は、何らかの形でPINコードを取得する
- コールセンターに登録済のスマフォから電話して、PINコードを入力するとお得情報にアクセスできるメールが送られてくる
構成は以下のようなものです。
動作している様子です。
2 共通のLambda関数
Connectの問い合わせフローで処理できない機能は、Lambda関数で処理します。
今回の要件では、次の2つの機能が必要です。
- 電話の発信元番号が、会員登録されているかどうか
- 入力されたPINコードの有効性を確認して、SMSを送信する
この2つの機能を1つのLambda関数で実装し、パラメータ(cmd)で処理を分けるようにしました。
パラメータ | 処理 |
---|---|
getMemberId | 会員番号の照会 |
sendSms | PINコードの照会とSMS送信 |
Lambdaのメイン関数で、機能によって分岐している様子です。
exports.handler = async (event) => { console.log(JSON.stringify(event)); const params = event.Details.Parameters; // Lambdaへの入力パラメータ const phone = event.Details.ContactData.CustomerEndpoint.Address; // 発信元の電話番号 if (params.cmd == 'getMemberId') { // 電話番号の照会 return await getMemberId(phone); } else if (params.cmd == 'sendSms') { // PINコードの照会とSMS送信 const pinCode = params.pinCode; return await sendSms(pinCode, phone); } throw new Error("command not found."); };
3 会員番号の照会(電話番号の照会)
ConnecのコンタクトフローからLambdaを呼び出すと、そのパラメータに発信元の電話番号が入っています。
{ "Details": { "ContactData": { "Attributes": { }, "Channel": "VOICE", "ContactId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "CustomerEndpoint": { "Address": "+819011112222", "Type": "TELEPHONE_NUMBER" }, "InitialContactId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "InitiationMethod": "INBOUND", "InstanceARN": "arn:aws:connect:ap-southeast-2:xxxxxxxxxxxx:instance/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "MediaStreams": null, "PreviousContactId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "Queue": null, "SystemEndpoint": { "Address": "+818001235990", "Type": "TELEPHONE_NUMBER" } }, "Parameters": { } }, "Name": "ContactFlowEvent" }
そこで、着信時に、直ちにLambdaを起動し、その発信者番号をの会員DBで照会しています。
Lambdaは、発信元の電話番号が会員登録されている場合、会員番号が取得できます。問い合わせフローでは、この戻り値から、会員でない場合、「ご利用の電話は、会員登録されていません」とアナウンスしてフローを切断しています。
(1) Lambdaへのパラメータ
Key | Value |
---|---|
cmd | getMemberId |
(2) Lambdaからのの戻り値
Key | Value |
---|---|
memberId | 1234 ※ 会員以外の場合は -1 |
会員情報が格納されているDB(campaign_member_table)は、以下の様になっています。電話番号がキーになっていて、会員番号が格納されています。
発信元の電話番号から会員情報を検索しているLambdaのコードは、以下のとおりです。
const AWS = require('aws-sdk'); const dynamo = new AWS.DynamoDB.DocumentClient({region: 'ap-southeast-2'}); async function getMemberId(phone){ if (phone) { var param = { TableName : 'campaign_member_table', Key:{ phone: phone } }; const data = await dynamo.get(param).promise(); if(data.Item){ return { memberId: data.Item.id }; } } return { memberId: -1 }; }
4 PINコードの照会とSMS送信
問い合わせフローの中では、顧客入力の保存ブロックを使用して、PINコードの入力を取得しています。
Lambdaへのパラメータは、ユーザーの入力したPINコードだけで、発信元電話番号は、先程と同じくシステム属性から取得するためパラメータ等の設定は必要ありません。
(1) Lambdaへのパラメータ
Key | Value |
---|---|
cmd | sendSms |
pinCode | 123456 |
(2) Lambdaからの戻り値
Key | Value |
---|---|
result | Success(失敗の時Failed) |
特典URLが保存されているDB(campaign_benefits_table)には、PINコードをキーとしてURLが格納されています。
処理しているコードは、以下のとおりです。PINコードが有効な場合(URLが取得できる場合)、発信元の電話番号にSMSを送信しています。
```js const AWS = require('aws-sdk'); const dynamo = new AWS.DynamoDB.DocumentClient({region: 'ap-southeast-2'}); const sns = new AWS.SNS();
async function sendSms(pinCode, phone){ if (pinCode && phone) { // PINコードでURLを取得する var param = { TableName : 'campaign_benefits_table', Key:{ pinCode: pinCode } }; const data = await dynamo.get(param).promise(); if(data.Item){ const campaignUrl = data.Item.campaignUrl;
//SMS送信 const params = { Message: `キャンペーンページ ', PhoneNumber: phone }; await sns.publish(params).promise(); return { result: "Success" }; } } return { result: "Fail" }; } ```
5 問い合わせフロー
正常系で通過するブロックは下記のとおりです。
- 音声の設定
- AWS Lambda関数を呼び出す(cmd=getMemberId)
- 問い合わせ属性を確認する(memberId != -1)
- 顧客の入力を保存する(ピンコードを入力して下さい)
- AWS Lambda関数を呼び出す(cmd=sendSms)
- 問い合わせ属性を確認する(result == Seccess)
- プロンプトの再生(メールをご確認下さい)
これぐらいのフローなら1つのファイルで充分かも知れません。
6 最後に
今回は、発信者電話番号とPINコードを確認して処理するConnectの問い合わせフローを作成してみました。これぐらいの要件を非常に簡単に実装できるConnectは、使えるようにしておくと結構重宝するかも知れません。