こんにちは!岩間です。
Amazon Connect Advent Calendar 2025 20日目の記事です。
今回は、Amazon Connectのチャットウィジェットでチャットから通話に切り替える際に、チャット履歴を引き継ぐ方法を試してみました。
目次
課題
Amazon Connectのチャットウィジェットでは、チャットから通話へシームレスに切り替えることができます。


ただ、デフォルトだとオペレーターは直前までのチャット内容がわからず、チャットと通話で別々のcontactIdが振り出されるので紐付けもできません。
いろいろ調べてみましたが、標準機能では解決できなさそうでした。
解決策:セッショントークンで紐付ける
そこで考えたのが、ブラウザのセッションごとにトークンを発行し、チャットと通話を紐付ける方法です。
流れとしては、
1. チャットウィジェットを組み込んだWEBサイト側でユニークなトークンを生成
2. チャット開始時にコンタクト属性としてトークンを設定
3. 通話に切り替わった際、トークンをキーにContact Lens APIでチャットのcontactIdを取得
4. Contact LensのURLを生成し、オペレーターに連携
といった感じです。
前提条件
- チャットウィジェットを組み込んだWEBサイト(通話機能を有効化)
- HTTPSが必須(HTTPだと通話機能が動作しませんでした)
- 今回はデモ用のため、ウィジェットのセキュリティは無効にしています
実装手順
1. トークン生成とコンタクト属性の設定
チャットウィジェットのスニペットコードに、トークン生成処理を追加します。
|
1 2 3 4 5 6 7 8 9 10 |
// ユニークなトークンを生成 function generateUniqueToken() { return 'token_' + Math.random().toString(36).substr(2, 9) + '_' + Date.now(); } // コンタクト属性にトークンを設定 const uniqueToken = generateUniqueToken(); amazon_connect('contactAttributes', { 'sessionToken': uniqueToken, }); |
なぜcontactIdではなくトークンを使うのか?
「contactIdで紐付ければいいのでは?」とも思ったのですが問題がありました。
例えば以下のようなコードを書いてみたところ、
|
1 2 3 4 5 6 7 8 9 10 |
// ContactIdを取得 amazon_connect('contactMetadataHandler', function(contactMetadata) { console.log('contactId:', contactMetadata.chatContactId); savedContactId = contactMetadata.chatContactId; }) // ContactIdをコンタクト属性として設定 amazon_connect('contactAttributes', { chatContactId: savedContactId }); |
- contactIdはチャット開始時に作成される
- コンタクト属性の保存はチャット開始前に設定する必要がある(チャット開始後に設定できない)
つまり、contactIdを取得できる頃にはコンタクト属性を設定できない、ということがわかりました。
セッショントークンならページロード時に生成できますし、チャットと通話でcontactIdが違っても同じトークンで紐付けできます。
2. 検索可能属性の設定
Contact Lens APIでトークンを検索できるように、事前に設定が必要です。
1. Amazon Connectコンソール → 分析ツール → コンタクトの検索ページに移動
2. 「フィルターを追加してください」から「カスタム問い合わせ属性」を選択
3. 設定アイコンをクリック

4. キー:HostedWidget-sessionTokenを追加し保存
※チャットウィジェット経由で設定したコンタクト属性名には、HostedWidget-というプレフィックスがつきます

参考:カスタムコンタクト属性またはコンタクトセグメント属性を使用して Amazon Connect でコンタクトを検索する
3. 通話フローの作成
通話に切り替わった際のフローを編集します。チャットウィジェット追加時に「ウェブ通話コンタクトフロー」で設定したフローです。

以下の画像はフローの中身です。

やってることとしては、
- Lambda関数を呼び出してトークンからContact Lens URLを取得
- コンタクト属性に保存(今回はSalesforceに渡すため)
- キューへ転送してオペレーターに接続
という感じです。
4. Lambda関数の実装(CDK)
今回はCDKでLambdaをデプロイしてみました。
Lambda定義
typescript
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
import * as cdk from "aws-cdk-lib"; import { Runtime } from "aws-cdk-lib/aws-lambda"; import { NodejsFunction } from "aws-cdk-lib/aws-lambda-nodejs"; import { PolicyStatement, Effect } from "aws-cdk-lib/aws-iam"; // Contact Lens URL取得用Lambda関数 const getContactLensUrlFunction = new NodejsFunction( this, "getContactLensUrlFunction", { functionName: "getContactLensUrlFunction", runtime: Runtime.NODEJS_22_X, entry: "lambda/get-contactlens-url.ts", handler: "handler", timeout: cdk.Duration.seconds(30), initialPolicy: [ new PolicyStatement({ effect: Effect.ALLOW, actions: [ "connect:SearchContacts", "connect:DescribeContact", "connect:GetContactAttributes", "connect:ListContactReferences", ], resources: [ `arn:aws:connect:${this.region}:${this.account}:instance/${props?.CONNECT_INSTANCE_ID}`, `arn:aws:connect:${this.region}:${this.account}:instance/${props?.CONNECT_INSTANCE_ID}/*`, ], }), ], environment: { CONNECT_INSTANCE_ID: props?.CONNECT_INSTANCE_ID || "", CONNECT_INSTANCE_ALIAS: props?.CONNECT_INSTANCE_ALIAS || "", }, } ); |
Lambdaコード
トークンをキーにコンタクトを検索し、Contact LensのURLを返すLambda関数を作成します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
import { ConnectClient, SearchContactsCommand, } from "@aws-sdk/client-connect"; const client = new ConnectClient({ region: "ap-northeast-1" }); const { CONNECT_INSTANCE_ID, CONNECT_INSTANCE_ALIAS } = process.env; export const handler = async (event) => { const sessionToken = event.Details?.ContactData?.Attributes?.["HostedWidget-sessionToken"]; if (!sessionToken) { return { error: "sessionToken is required" }; } // 過去24時間のコンタクトを検索 const now = new Date(); const yesterday = new Date(now.getTime() - 24 * 60 * 60 * 1000); const response = await client.send(new SearchContactsCommand({ InstanceId: CONNECT_INSTANCE_ID, TimeRange: { Type: "INITIATION_TIMESTAMP", StartTime: yesterday, EndTime: now, }, SearchableContactAttributes: { Criteria: [{ Key: "HostedWidget-sessionToken", Values: [sessionToken], }], MatchType: "MATCH_ALL", }, MaxResults: 1, })); if (!response.Contacts || response.Contacts.length === 0) { return { error: "Contact not found" }; } const contactId = response.Contacts[0].Id; const contactLensUrl = `https://${CONNECT_INSTANCE_ALIAS}.my.connect.aws/contact-trace-records/details/${contactId}`; return { contactLensUrl }; }; |
オペレーターへの連携
取得したContact LensのURLは、様々な方法でオペレーターに連携できます。
- Salesforce:CTI Adapterのスクリーンポップでカスタム項目に設定
- CCP:Streams APIでカスタムUIに表示
- その他CRM:コンタクト属性経由で連携
今回はSalesforceのケースオブジェクトにURLを設定し、オペレーターがワンクリックでチャット履歴を確認できるようにしました。
動作確認
オペレータ着信時の画面

Contact LensのURLをクリックすると、直前までのチャット履歴が確認できます。

トークンでコンタクトの検索を行えば、関連性のあるチャットや通話が検索可能です。

まとめ
チャットから通話への切り替え時にチャット履歴を引き継ぐ方法をご紹介しました。
- セッショントークンでチャットと通話を紐付ける
- Contact Lens APIでトークンからcontactIdを取得
- Contact LensのURLをオペレーターに連携
今回はSalesforceへの連携を例にしましたが、他のCRMやカスタムCCPでも応用できます。
もっと良い方法があるかもしれませんが、参考になれば幸いです!
- Amazon Connectでチャット→通話の切り替え時にオペレーターに直前のチャット履歴を見せたい - 2025-12-20
- 社内でフルAI開発バトルやってみた結果、全員違うTodoアプリができた話 - 2025-12-18
- Amazon Q in Connectセルフサービスで多言語対応チャットボットを作ってみた - 2025-12-14
- 【Kiro・Playwright】社内でフルAI開発バトルを企画した話〜ルール説明編〜 - 2025-12-01
- ロングネイル女子エンジニア、筋トレとピラティスで最強になった話 - 2025-08-26
【採用情報】一緒に働く仲間を募集しています




