【Amazon Connect】在宅コールセンター向けにCCP（発着信画面）をカスタマイズする

ここ最近は在宅コールセンターの気運が高まっていますが、
Amazon Connectを利用すれば１日で最低限のシステムを構築することが可能です。
[前回の記事](https://qiita.com/duplicate1984/items/e97c6acdd8d7932a7ee1)でAmazon Connectの構築から、コマンドラインからのアウトバウンドまでやってみましたが、コールセンターとして主に必要なのはインバウンドに対応したGUIです。
今回はこのCPPに簡易的にログインボタンの配置と、着信時にサブウインドウを開いて「着信しています」みたいな通知する機能を追加してみたいと思います。

イメージ画像↓
![tempsnip3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503026/da211a9a-836e-3bd3-83a2-e995d9470634.png)



#CPPとは
Amazon Connectには[CPP（Contact Control Panel）](https://docs.aws.amazon.com/ja_jp/connect/latest/adminguide/agent-user-guide.html)という受話・発信・転送などの機能を持ったGUIの機能がデフォルトであります。↓
![tempsnip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503026/0650a5e6-6ce5-787c-1e90-b4ffc284cd1f.png)

現在Amazon Connectのインスタンスから起動できるのはVer.2で、以下のアドレスから直接アクセスすることも可能です。
**https://インスタンスの名前.awsapps.com/connect/ccp-v2/**
ただVer.1も使用することは可能です。↓
**https://インスタンスの名前.awsapps.com/connect/ccp#/**

コールセンターを構築する際に、一般的なエージェント（オペレータ）にはインスタンスのコンソールにアクセスする権限は与えないこともあると思うので、その場合は上記のアドレスを公開してCPPにアクセスしてもらうことになると思います。

Ver.2ではチャット機能などが追加されていたりしますが、
エージェントに余計な操作をさせたくないときなどはVer.1で十分かもしれません。


#CPPカスタマイズに必要なもの
CPPのカスタマイズの手順としては以下のようになります。

1. Amazon Connect Streamsの準備
2. WebページへのCPPの埋め込み
3. html/jsなどによるカスタマイズ
4. httpsによるホスティング
5. アプリケーション統合

###1. Amazon Connect Streamsの準備
Amazon Connect Streamsとは自前のWebアプリにCPPを統合するためのAPIです。
Githubに公開されているソースを、readmeにある通りmakeすることでjsライブラリとして利用します。

githubリポジトリ
https://github.com/amazon-connect/amazon-connect-streams
APIの詳細
https://github.com/amazon-connect/amazon-connect-streams/blob/master/Documentation.md

###2. WebページへのCPPの埋め込み
jsでconnect.core.initCPP()によりCPPの初期化を行い、それをhtmlに埋め込んでいます。
CPPの初期化時には自動でエージェントのログイン画面が別タブで開きます。
※html/js初心者です。なんか間違ってたらスミマセン。

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>Demo CCP</title>
</head>
<body>
    <div id="containerDiv" style="width: 100%; height: 465px; min-height: 400px;"></div>
</body>
</html>

<script src="amazon-connect-1.4.js"></script>
<script type="text/javascript">

// CCP初期化
connect.core.initCCP(containerDiv, {
    ccpUrl: "https://インスタンスの名前.awsapps.com/connect/ccp#/",
    loginPopup: true,
    loginPopupAutoClose: true,
    region: "ap-northeast-1",
    softphone: {              
        disableRingtone: false, 
        ringtoneUrl: null,
        allowFramedSoftphone: true
    }
});

</script>
```


###3. html/jsなどによるカスタマイズ
冒頭に書いた通り、今回のカスタマイズではログインボタンの配置と、着信時にサブウインドウを開いて通知する機能を追加します。

######ログインボタン
ログインボタンについては特に工夫もせず、以下のようにリンク貼るだけにしました。
自作したWebページのCPPでログアウトをした場合、CPPを使用できなくなってしまうため、画面のリロードが必要になります。
CPPとは別部品でログイン機能を用意しておくことでこれを回避します。

```
<a href="https://インスタンスの名前.awsapps.com/connect/ccp#/" target="_blank">ログインはこちら</a>
```

######着信通知
着信時にサブウインドウを開く機能ですが、これにはエージェントが着信していることを判定しなければなりません。
Contact APIのcontact.getActiveInitialConnection()を利用し、コネクションの存在を確認することで着信判定をします。
※contact.onIncoming()で着信イベントの取得できますが、コネクションの存在確認≒発着信だと思っているので、
　getType()で着信であることが分かったらそれを着信イベントとします。

CPPは着信時に画面の色が変わったり、音を鳴らしてくれるので、この機能いる？という感じではありますが、
ブラウザを背面にしている時などは気づかない可能性も無きにしも非ずなので無駄ではない、はずです。

```
// Contact APIをサブスクライブ
connect.contact(function(contact) {

    // sub_window
    var winObj;

    // 着信（コネクションの存在を確認）
    if (contact.getActiveInitialConnection() && contact.getActiveInitialConnection().getEndpoint()) {
        let conn = contact.getActiveInitialConnection();
        if (conn.getType() == "inbound") {
            // sub_windowをopen
            var option ='left=50,top=50,width=550,height=200,menubar=no,toolbar=no,location=no,status=no,resizable=no,scrollbars=no';
	        winObj = window.open('sub_window.html', 'PopupWindow', option);
        }
    }
});
```


######最終ソース
最終的なソースは以下のようになります。
contact.onConnected(), contact.onEnded()で通話の開始と終了のイベントを取得し、
開いていたサブウインドウを閉じる処理を追加しています。

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>Demo CCP</title>
</head>
<body>
    <div id="containerDiv" style="width: 100%; height: 465px; min-height: 400px;"></div>
</body>
</html>

<script src="amazon-connect-1.4.js"></script>
<script type="text/javascript">

// CCP初期化
connect.core.initCCP(containerDiv, {
    ccpUrl: "https://インスタンスの名前.awsapps.com/connect/ccp#/",
    loginPopup: true,
    loginPopupAutoClose: true,
    region: "ap-northeast-1",
    softphone: {              
        disableRingtone: false, 
        ringtoneUrl: null,
        allowFramedSoftphone: true
    }
});

// Contact APIをサブスクライブ
connect.contact(function(contact) {

    // sub_window
    var winObj;

    // 着信（コネクションの存在を確認）
    if (contact.getActiveInitialConnection() && contact.getActiveInitialConnection().getEndpoint()) {
        let conn = contact.getActiveInitialConnection();
        if (conn.getType() == "inbound") {
            // sub_windowをopen
            var option ='left=50,top=50,width=550,height=200,menubar=no,toolbar=no,location=no,status=no,resizable=no,scrollbars=no';
	        winObj = window.open('sub_window.html', 'PopupWindow', option);
        }
    }

    // コンタクトが確立
    contact.onConnected(function() {
        // 通話が開始されたらsub_windowをとじる
        if( (winObj) && (!winObj.closed) ){
            winObj.close();
        }
        winObj = null;
        let voiceConnections = contact.getConnections();
    });

    // コンタクトが終了
    contact.onEnded(function() {
        // 通話が切断された際もsub_windowがあればとじる
        if( (winObj) && (!winObj.closed) ){
            winObj.close();
        }
        winObj = null;
        let voiceConnections = contact.getConnections();
    });
});
</script>
```


#httpsによるホスティング
さて、ここまでCPPのカスタマイズをやってきましたが、
そもそもAmazon Connect StreamsはhttpsによってホスティングされたWebアプリでないと使用できません。
今回のお試しカスタマイズは、S3のバケットにhtmlを配置して、Cloudfront経由で公開することにしました。
この辺りの詳細は記事の目的から外れるので割愛します。


#アプリケーション統合
最後にAmazon Connectのインスタンス設定からアプリケーション統合を行います。
「オリジンの追加」から、公開したWebページのURLを入力して登録します。
あとはURLにアクセスして正常に表示できれば完了です。

#まとめ
というわけでAmazon Connect CPPのカスタマイズを試してみました。
S3 + Cloudfrontでサイト公開の部分を割愛したので、次あたりにBASIC認証などと合わせて書ければいいなと思ってます。