Amazon ConnectでLambdaを使ってユーザ認証


##Amazon Connectの概要
Amazon Connect は、多機能(IVRや着電管理、ケース追跡など)なコールセンターをセルフサービスで簡単に構築できる画期的なサービスです。

Lambdaとの組み合わせで、担当者に電話を飛ばすだけではなく、ユーザ認証やその後の処理も柔軟に組み込めます。
今回はAmazon Connect + Lambdaでユーザの電話番号と入力されたパスワードで認証する処理を作ってみます。

##処理の流れ
1. コールセンタに電話をかけられたら、パスワード入力の音声を流す
2. かけてきた電話番号と入力されたパスワードを取得
3. Lambdaで認証処理(DynamoDBにユーザ情報を事前に格納)を実行
4. 認証が成功したら次のフローへ、失敗したらメッセージを流し終了

といった簡単な処理フローです。

##コールセンタ作成
Amazon Connectのセットアップと設定は以下を参考
[Amazon Connect でコールセンターを作成する](https://qiita.com/kooohei/items/fec4e677cdfc3d2b35aa)

##問い合わせフロー作成
Sample Lambda integrationの問い合わせフローをベースとします。
![image1.png](https://qiita-image-store.s3.amazonaws.com/0/191079/93140a62-594e-a710-4ea9-d8c3604beda6.png)

主に利用するAmazon Connectの機能は以下の通り

| 利用機能| 説明 |
|:----------------|:------------|
|Play prompt               |音声を再生する|
|Store Customer Input      |ユーザの番号入力を受け取り、保存する|
|Invoke AWS Lambda function|Lambda関数を実行する|
|Check contact attributes  |情報を元に処理を分岐させる|

####顧客入力（パスワード）を取得
Store Customer Input機能を使って、パスワード入力を促す音声（テキスト読み上げ）を設定、Prompt設定で、Custom入力の最大桁数（Maximum Digits）と入力インターバルの秒数を設定します。
![image2.png](https://qiita-image-store.s3.amazonaws.com/0/191079/b3c375db-ee25-7680-b0e1-c007ac0dcd51.png)

ここで入力されるパスワードは、Contact Attributeに保存され、
次の機能で呼び出すことが可能です。

####AWS Lambda関数を呼び出す
Store Customer Input機能の次に、Invoke AWS Lambda function機能を使って、認証処理を実現します。
![image3.png](https://qiita-image-store.s3.amazonaws.com/0/191079/92562c1e-1e35-f1f6-15d7-8df0412976c8.png)
Invoke AWS Lambda functionからLambda(poc-lambda-helloというLambda関するを作っておく)を呼び出すには、
ARNを使って指定する必要があります。
arn:aws:lambda:ap-northeast-1:xxxxxxxxxxxx:function:poc-lambda-hello
![image4.png](https://qiita-image-store.s3.amazonaws.com/0/191079/15e249bf-abc2-4f71-fd40-64bfe16e2bed.png)

Store Customer Input機能で保存しているパスワードは「StoredCustomerInput」というAttributeに格納されているので、Send Attributeで指定すると、Lambda関数のevent引数に入れて渡してくれます。

```python
from DynamoDB import dynamoCustomerTbl
import logging

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):

    logger.info('got event:{}'.format(event))

    # かけてくる電話番号を取得
    customernumber =  event["Details"]["Parameters"]["CustomerNumber"]
    # プッシュされたパスワードを取得
    password = event['Details']['Parameters']['StoredCustomerInput']

    # 電話番号とパスコードの組み合わせが存在するか
    customerData = dynamoCustomerTbl(dynamoCustomerTbl, customernumber, password)
    isAuthOK = bool(customerData['Items'])

    if isAuthOK:
        return {"State": "Successed"}
    else:
        return {"State": "Failured"}
```

####AWS Lambda関数を呼び出す権限の付与
Lambdaを呼び出すには、Triggerを設定する必要があります。よくあるのは、API Gateway、S3、DynamoDB等、上記のコンソール画面キャプチャの左側に設定できるTriggerがリストアップされています。
ただ、よく見たら、Amazon ConnectというTriggerはいないです。
[Amazon Connectを使って電話からEC2を再起動する](https://dev.classmethod.jp/cloud/aws/reboot-ec2-by-amazon-connect/)の記事を参考し、
AWS ConnectからLambdaを呼び出すために、リソースポリシーの設定も必要そうです。
その設定方法もこのページに記載されています。
[Using AWS Lambda Functions with Amazon Connect](https://docs.aws.amazon.com/ja_jp/connect/latest/adminguide/connect-lambda-functions.html)

要するに、AWS CLIコマンドでAdd Permissionする必要があります。

```shell
aws lambda add-permission --function-name function:poc-lambda-hello --statement-id 1 \
--principal connect.amazonaws.com  --action lambda:InvokeFunction --source-account xxxxxxxxxxxx \
--source-arn arn:aws:connect:us-east-1:xxxxxxxxxxxx:instance/def1a4fc-ac9d-11e6-b582-06a0be38cccf \
--profile lambda-dev
```

| 設定項目 | 設定値（例） | 説明 |
|:----------------|:------------|:------------|
|function-name    |function:poc-lambda-hello|Add Permissionする対象Lambda関数名|
|source-account   |123456789011|Lambda関数のオーナーAWSアカウントID|
|source-arn       |arn:aws:connect:us-east-1:xxxxxxxxxxxx:instance/def1a4fc-ac9d-11e6-b582-06a0be38cccf|Amazon ConnectのARN、コールセンタのOverview画面で確認可能|

####認証結果による分岐処理
Check contact attributes機能を使って、認証結果に従い分岐させます。

```python
    if isAuthOK:
        return {"State": "Successed"}
    else:
        return {"State": "Failured"}
```

Lambda関数の返り値(State)をCheck contact attributes機能で取得できます。
User Defined属性で同じ属性名（State）を入力すれば、
"equal to", "greater than", "less than" "starts with", "ends with", "contains"等の条件で値をマッチさせることが可能です。

![image5.png](https://qiita-image-store.s3.amazonaws.com/0/191079/e0f55d6f-c821-ed84-f9c0-9d8c1569eb04.png)

SuccessedかFailuredにより、次に流す音声Promptをつなぎます。

##最後に電話をかけて確認
00812341234