はじめに
2026年1月のアップデートで、Amazon Connectのコンタクトフローにおいて配列のループ処理が可能になりました。
従来、Lambda関数から配列を含むJSONを返しても、コンタクトフロー側では配列の要素を個別に参照できず、フラット化用Lambdaや件数分の固定的な分岐で対応する必要がありました。本記事では、このアップデートで配列に対して具体的に何ができるようになったのかを、実際にコンタクトフローを構築しながら検証します。
本記事の情報は2026年4月時点のものです。
最新情報については公式ドキュメントをご確認ください。
この記事でわかること
- 配列を含むJSONをLambda関数から返し、ループブロックで要素を1件ずつ処理する方法
- 配列のインデックス直接参照の可否
- 従来のフラット化+固定分岐と比べてどう改善されるか
前提条件
- Amazon Connectインスタンスの初期設定(受架電可能な状態)が完了していること
- AWS Lambdaの基本的な知識があること
先に結論
配列を含むネストされたJSONをLambda関数から返した場合に、コンタクトフローで何ができて何ができないかをまとめます。
⭕ できること
- ループの現在のインデックスを取得する
- ループブロック内で配列の各要素のプロパティを参照する
❌ できないこと
- 外部属性に含まれる配列の要素の参照(
$.Externalでの参照)
配列の要素にアクセスするにはループブロックの利用が必須です。ループブロックを活用すれば、従来必要だったフラット化用Lambdaや件数分の固定的な分岐が不要になり、フロー設計が大幅にシンプルになります。
1. 何が変わったのか
Before: 配列を含むJSONをコンタクトフローで扱えなかった
2023年3月のアップデートで、Lambda関数ブロックの「レスポンスの検証(Response validation)」にJSONオプションが追加され、ネストされたオブジェクトの参照は可能になりました(クラスメソッドさんの検証記事参照)。
しかし、配列の要素にアクセスする手段がないという制約が残っており、配列を含むJSONをコンタクトフローで実用的に扱うことはできませんでした。
何が問題か
例として、旅行代理店のコールセンターで以下のシナリオを考えてみます。
シナリオ: ホテルの空き日時を音声で案内し、予約を受け付ける
- お客様が電話をかけてくる
- 希望するホテルの空き日時をシステムに問い合わせる
- 直近の空き日時を3件取得する
- 取得した空き日時を1件ずつ音声で案内し、お客様に都合の良い日を選んでもらう
上記3.の処理において、外部APIが以下のようなネストされたJSONを返すとします。
{
"hotelName": "リゾートホテル沖縄",
"availableTimes": [
{ "date": "2026-05-01", "checkInStartTime": "15:00"},
{ "date": "2026-05-02", "checkInStartTime": "15:00"},
{ "date": "2026-05-03", "checkInStartTime": "15:00"}
]
}
このような配列を含むJSONが返された場合、コンタクトフロー側では配列の要素にインデックスでアクセスできない(availableTimes[0].date のような参照ができない) ため、そのままでは活用できませんでした。
そこで、従来は以下のような回避策が取られていました。
従来の方法: フラット化 + 件数分の分岐作成
従来、このようなネストされたJSONを含む配列データをコンタクトフローで扱うには、以下の2ステップが必要でした。
ステップ1: フラット化用Lambdaでネスト構造を解体する
コンタクトフローで参照可能な形式にするため、フラット化用のLambda関数を挟んでJSONオブジェクトのネスト構造を解体する方法が考えられます。以下はその一例です。
-
外部システムより空室日時データを取得
{ "hotelName": "リゾートホテル沖縄", "availableTimes": [ { "date": "2026-05-01", "checkInStartTime": "15:00"}, { "date": "2026-05-02", "checkInStartTime": "15:00"}, { "date": "2026-05-03", "checkInStartTime": "15:00"} ] } -
フラット化用のLambdaで、1.のJSONをフラットなキーバリューペアに変換
{ "hotelName": "リゾートホテル沖縄", "available1_date": "2026-05-01", "available1_checkInTime": "15:00", "available2_date": "2026-05-02", "available2_checkInTime": "15:00", "available3_date": "2026-05-03", "available3_checkInTime": "15:00" } -
2.のJSONのキーを使用して値を参照
// 例:1つ目の空き日時を取得(外部属性項目) $.External.available1_date -> "2026-05-01"
ステップ2: 取得件数分の分岐を作成する
フラット化によって個別のキーで参照できるようになりましたが、シナリオの4番目のステップ「空き日時を1件ずつ案内し、お客様に都合の良い日を選んでもらう」を実現するには、件数分の分岐を作る必要がありました(下図「フロー構成イメージ」の赤枠参照)。
フロー構成イメージ(従来)
今回は3件の例ですが、候補数が5件・10件と増えればその分だけ赤枠のブロックセットが増え、フローはさらに複雑になります。
また、3件分作っているため、実際に取得できた空き日時が2件しかない場合は3件目の参照先が空になり、逆に5件ある場合は4件目・5件目を案内できません。件数の変動に対応するには、件数ごとの分岐をさらに追加する必要があり、フロー設計の負担が大きくなります。
従来の方法の問題点
| 問題 | 説明 |
|---|---|
| フラット化用Lambdaが必要 | ネストされたJSONをフラットなキーバリューに変換するLambdaを別途用意・管理する必要がある |
| キー名の固定が必要 |
available1_xxx、available2_xxx のように件数分のキーを事前に定義する必要がある |
| フローが冗長になる | 候補数分だけ「プロンプト再生 → 入力取得 → 分岐」のセットを繰り返す必要がある |
| 候補数の変動に対応できない | 3件固定で作ると、2件しかない場合や5件ある場合に対応できない |
| メンテナンスコストが高い | 案内文言を変更する場合、全ての分岐ブロックを個別に修正する必要がある |
After: ループブロックで配列の要素を1件ずつ処理できるように
2026年1月のアップデートにより、ループブロックに配列を渡して要素を1件ずつ処理できるようになりました。
本アップデートにより、先ほどの「空き日時を案内する」ユースケースも、ループブロックを使えば以下のようにシンプルになります。
フロー構成イメージ(配列対応)
従来は候補数分だけ赤枠のブロックセット(「候補日確認 → 候補保存」)を繰り返し作成する必要がありましたが、ループブロックを使えばこの部分が1セットで済みます。候補が何件あっても同じループ内のブロックが繰り返し実行されるため、フローの構造を変更する必要がありません。
2. 実際に試してみた
2.1 検証環境
本記事で使用する環境は以下のとおりです。
- AWS リージョン:東京(
ap-northeast-1)
今回はアップデート内容(配列のループ処理)の検証に焦点を当てているため、Amazon Lexボットの統合やエージェントへの転送といった応用的な構成は含めていません。最小限のフロー構成で、ループブロックの動作を確認しています。
2.2 検証内容
以下の5項目について、コンタクトフローの「プロンプトの再生」ブロックで値が取得できるかを確認します。
| # | 検証項目 | 参照パス | 確認したいこと |
|---|---|---|---|
| 1 | ループインデックス | $.Loop.loopTest.Index |
現在のループインデックスを取得できるか |
| 2 | ループ要素(date) | $.Loop.loopTest.Element.date |
ループ内で要素のプロパティを参照できるか |
| 3 | ループ要素(checkInTime) | $.Loop.loopTest.Element.checkInTime |
ループ内で別のプロパティを参照できるか |
| 4 | 外部属性のインデックス指定 | $.External.availableTimes[0].date |
ループを使わずにLambda戻り値の配列要素をインデックスで取得できるか |
| 5 | 外部属性のドット記法 | $.External.availableTimes.date |
ループを使わずにLambda戻り値の配列プロパティをドット記法で取得できるか |
2.3 Lambda関数の作成
検証用に、配列を含むJSONを返すLambda関数を作成します。ホテルの空き日時情報を想定しています。
- 関数名:
任意の文字列 - ランタイム:
Node.js 24.x - アーキテクチャ:
x86_64 - 実行ロール:
デフォルトロール - ソースコード
export const handler = async (event) => {
return {
hotelName: "リゾートホテル沖縄",
availableTimes: [
{ date: "2026-05-01", checkInTime: "10:00" },
{ date: "2026-05-02", checkInTime: "10:00" },
{ date: "2026-05-03", checkInTime: "10:00" },
],
totalAvailable: 3,
status: 200,
};
};
上記Lambda関数を対象のAmazon Connectインスタンスへ追加します。
2.4 コンタクトフローの作成
検証用のコンタクトフローを作成します。
全体像は以下の通りです。
計6つのブロックで構成されていますが、重要な①「AWS Lambda関数」ブロックと②「ループ」ブロック、③「プロンプトの再生」ブロックの設定です。
① 「AWS Lambda関数」ブロック
- アクションを選択:
Lambda を呼び出す - 関数のARN:
作成したLambda関数 - 実行モード:
同期モード - タイムアウト:
3秒(デフォルト) - レスポンスの検証:
JSON
② 「ループ」ブロック
- アクションを選択:
ループ用の配列を設定 - ループ用の配列(動的に設定):
- 名前空間:
外部 - キー:
availableTimes - ループ名を設定(手動で設定):
loopTest
- 名前空間:
③「プロンプトの再生」ブロック
- テキスト読み上げまたはチャットテキスト:
手動で設定 - 次として解釈:
テキスト - 読み上げるテキスト:
検証1 ループインデックス: $.Loop.loopTest.Index
検証2 ループ要素 date: $.Loop.loopTest.Element.date
検証3 ループ要素 checkInTime: $.Loop.loopTest.Element.checkInTime
検証4 外部属性のインデックス指定 date: $.External.availableTimes[0].date
検証5 外部属性のドット記法: $.External.availableTimes.date
3. 動作確認
ループブロックが配列の各要素を正しく参照できるか、また配列のインデックス直接参照やドット記法での参照が可能かをテストしました。5項目の参照パスを「プロンプトの再生」ブロックに設定し、配列要素3件分のループ(計3回)で出力されるシステムメッセージの内容を確認しています。
動作確認結果
| # | 検証項目 | 参照パス | 期待する動作 | ループ1回目(Index: 0) | ループ2回目(Index: 1) | ループ3回目(Index: 2) |
|---|---|---|---|---|---|---|
| 1 | ループインデックス | $.Loop.loopTest.Index |
現在のループインデックスが返る |
0 ⭕ |
1 ⭕ |
2 ⭕ |
| 2 | ループ要素(date) | $.Loop.loopTest.Element.date |
ループ中の要素の日付が返る |
2026-05-01 ⭕ |
2026-05-02 ⭕ |
2026-05-03 ⭕ |
| 3 | ループ要素(checkInTime) | $.Loop.loopTest.Element.checkInTime |
ループ中の要素の時間が返る |
10:00 ⭕ |
10:00 ⭕ |
10:00 ⭕ |
| 4 | 外部属性のインデックス指定 | $.External.availableTimes[0].date |
配列の先頭要素の日付が返る |
[0].date(文字列がそのまま返る)❌ |
[0].date(文字列がそのまま返る)❌ |
[0].date(文字列がそのまま返る)❌ |
| 5 | 外部属性のドット記法 | $.External.availableTimes.date |
配列のプロパティが返る | (空)❌ | (空)❌ | (空)❌ |
テストの結果、ループブロック内の $.Loop.<LoopName>.Element.<プロパティ名> と $.Loop.<LoopName>.Index は全てのループ回で正しい値を返しました。一方、インデックス直接参照([0])は JSONPath として解釈されず文字列がそのまま返され、ドット記法での参照は値が返りませんでした。
チャット表示例
4. まとめ
本記事では、配列を含むネストされたJSONに対して、Amazon Connectコンタクトフローのループブロックでどこまで参照できるかを実際にフローを構築して検証しました。
ループブロックを活用すれば、配列の各要素を1件ずつ処理でき、従来必要だったフラット化用Lambdaや件数分の固定的な分岐が不要になります。一方、インデックス直接参照([0])はサポートされていないため、特定の要素だけ取得したい場合はLambda関数側で個別のキーとして返すか、「コンタクト属性の確認」ブロックで条件に合う要素を取り出すといった工夫が必要です。
予約候補の案内や注文履歴の読み上げなど、可変長のリストデータを扱うユースケースで特に効果を発揮するアップデートだと感じました。
5. 参考
- Amazon Connect now provides the capability to store nested JSON object and looping arrays(What's New / 2026年1月2日)
- Amazon Connect launches expanded JSON attribute support in flows(What's New / 2023年3月30日)
- Amazon Connectの「Lambda関数を呼び出す」でパラメーターとレスポンスにJSONが使えるようになったので検証してみた(DevelopersIO)
- コンタクト属性一覧とJSONPathリファレンス
- Lambda関数へのアクセス許可
- ループブロック
- Lambda関数の戻り値をコンタクト属性として保存する










