Amazon Connect コンタクトフローモジュールでフローのメンテナンスおよび可読性を向上させる

2022.07.13

はじめに

Amazon Connectのコンタクトフローモジュールを使うと共通の機能として切り出すことができて、フローのメンテナンスおよび可読性があがります。今回はコンタクトフローモジュールを活用したコンタクトフローの作成方法についてご紹介します。

コンタクトフローモジュールとは

コンタクトフローモジュールとは、2021年にリリースされた機能でコンタクトフローの一部の処理をモジュール化し、コンタクトフロー内で呼び出すことで利用することができます。

コンタクトフローモジュールの制約事項は、以下の通りです。

  • モジュールを利用できるフロータイプはコンタクトフロー(インバウンド)でのみ利用できる
  • 呼び出し元のコンタクトフローで定義した一部の属性は上書きできない(外部、Lex、Customer Profiles,Widsom、キューメトリクス、保存済みのお客様の入力)
  • モジュールからモジュールの呼び出しはできない

モジュール化前のコンタクトフロー

モジュール化する前のコンタクトフローは以下の通りです。

記録と分析の動作を設定ブロック音声の設定ブロックログ記録動作の設定ブロック作業キューの設定ブロックや各タイプのフローは、どのコンタクトフローでも利用されるブロックです。また、営業時間を判定する処理も同様にどのコンタクトフローでも利用頻度が高いと考えます。このコンタクトフローををアップデートしていきます。

コンタクトフローの初期化用モジュール

共通化できるブロックを一つのモジュール集約させすぎないようメンテナンスおよび可読性を意識して分離しましょう。まずはコンタクトフローの初期化用モジュールとして - 記録と分析の動作を設定ブロック - 音声の設定ブロック - ログ記録動作の設定ブロック 上記ブロックをまとめたモジュール(モジュール名はinit)を作成します
コンタクトフローのモジュールタブを開いて「フローモジュールの作成」をクリックします。

ブロックを配置します。各ブロックは有効無効、言語や音声を選択するブロック固有の値でそれぞれ設定します。モジュール名に名前を入力したら公開しましょう。

作成したモジュール(サンプル)はこちらです。

{
    "start": "d9004588-71c4-46f2-88f4-feba5f9a1cfc",
    "version": "1",
    "blocks": [
        {
            "id": "d9004588-71c4-46f2-88f4-feba5f9a1cfc",
            "branches": [
                {
                    "condition": "Success",
                    "transition": "29eeade3-1697-426b-ab9c-33ac7792795f"
                }
            ],
            "parameters": [
                {
                    "name": "RecordingBehaviorOption",
                    "value": "Enable"
                },
                {
                    "name": "RecordingParticipantOption",
                    "value": "Both"
                }
            ],
            "metadata": {
                "position": {
                    "x": 163,
                    "y": 20
                }
            },
            "type": "SetRecordingBehavior"
        },
        {
            "id": "29eeade3-1697-426b-ab9c-33ac7792795f",
            "branches": [
                {
                    "condition": "Success",
                    "transition": "14faeeb3-b7a3-4558-8a01-30ff612393cc"
                }
            ],
            "parameters": [
                {
                    "name": "GlobalEngine",
                    "value": "Neural"
                },
                {
                    "name": "GlobalVoice",
                    "value": "Takumi"
                },
                {
                    "name": "SpeakingStyle",
                    "value": "None"
                }
            ],
            "metadata": {
                "position": {
                    "x": 400,
                    "y": 21
                },
                "overrideConsoleVoice": true,
                "defaultVoice": "None"
            },
            "type": "SetVoice"
        },
        {
            "id": "14faeeb3-b7a3-4558-8a01-30ff612393cc",
            "branches": [
                {
                    "condition": "Success",
                    "transition": "3d18949f-38ff-4e2d-95eb-8745d722318a"
                }
            ],
            "parameters": [
                {
                    "name": "LoggingBehavior",
                    "value": "Enable"
                }
            ],
            "metadata": {
                "position": {
                    "x": 641,
                    "y": 23
                }
            },
            "type": "SetLoggingBehavior"
        },
        {
            "id": "3d18949f-38ff-4e2d-95eb-8745d722318a",
            "branches": [],
            "parameters": [],
            "metadata": {
                "position": {
                    "x": 882,
                    "y": 23
                }
            },
            "type": "ReturnFromFlowModule"
        }
    ],
    "metadata": {
        "entryPointPosition": {
            "x": 20,
            "y": 20
        },
        "snapToGrid": false,
        "name": "init",
        "status": "published",
        "hash": "78c4b14ba2d54068d52bd87b91883f928a455efd45bf54ae583506b5effcf82b"
    },
    "settings": {
        "inputParameters": [],
        "outputParameters": [],
        "branches": [
            {
                "displayName": "Success",
                "referenceName": "Success",
                "description": ""
            },
            {
                "displayName": "Error",
                "referenceName": "Error",
                "description": ""
            }
        ]
    }
}

作業キューおよび各タイプのフロー設定用モジュール

続いて、作業キューと各タイプのフロー設定用モジュールを作成します。

  • 作業キューの設定ブロック
  • 保留フローの設定ブロック
  • 顧客保留フローの設定ブロック
  • ウィスパーフローの設定ブロック

上記ブロックを配置したモジュール(モジュール名はqueue_flows)を作成します。

コンタクトフローのモジュールタブを開いて「フローモジュールの作成」をクリックします。

各ブロックは作業キューやフローを指定することがありますが、呼び出し元のコンタクトフローの用途によって設定が異なることがほとんどです。動的に設定できるように属性を使用するを設定します。
作業キューを例として、タイプをユーザー定義、属性をqueueArnとします。

他のブロックも同様にタイプをユーザー定義、属性を設定(unique)します。

モジュール名に名前を入力したら公開しましょう。
作成したモジュール(サンプル)はこちらです。

{
    "start": "bb381663-f0b0-43e2-b535-e7984c176327",
    "version": "1",
    "blocks": [
        {
            "id": "af35357c-03ca-4365-af1a-dc0f8e225bfe",
            "branches": [
                {
                    "condition": "Error",
                    "transition": "80c382f6-558f-4245-ac4f-0c395020d6f1"
                },
                {
                    "condition": "Success",
                    "transition": "77b50bb6-6052-4c96-ad45-5eb51a35a3c0"
                }
            ],
            "parameters": [
                {
                    "name": "Type",
                    "value": "CustomerHold"
                },
                {
                    "name": "ContactFlowId",
                    "value": "customerHold",
                    "namespace": "User Defined"
                }
            ],
            "metadata": {
                "position": {
                    "x": 657,
                    "y": 21.875
                },
                "contactFlow": "customerHold",
                "customerOrAgent": true,
                "useDynamic": true
            },
            "type": "SetEventHook"
        },
        {
            "id": "77b50bb6-6052-4c96-ad45-5eb51a35a3c0",
            "branches": [
                {
                    "condition": "Error",
                    "transition": "80c382f6-558f-4245-ac4f-0c395020d6f1"
                },
                {
                    "condition": "Success",
                    "transition": "964c55f1-fe95-4da4-ad35-98d3b4aedb93"
                }
            ],
            "parameters": [
                {
                    "name": "Type",
                    "value": "CustomerQueue"
                },
                {
                    "name": "ContactFlowId",
                    "value": "customerQueueFlow",
                    "namespace": "User Defined"
                }
            ],
            "metadata": {
                "position": {
                    "x": 897,
                    "y": 22.875
                },
                "contactFlow": "customerQueueFlow",
                "customerOrAgent": true,
                "useDynamic": true
            },
            "type": "SetEventHook"
        },
        {
            "id": "964c55f1-fe95-4da4-ad35-98d3b4aedb93",
            "branches": [
                {
                    "condition": "Error",
                    "transition": "80c382f6-558f-4245-ac4f-0c395020d6f1"
                },
                {
                    "condition": "Success",
                    "transition": "a95af587-b94b-4a17-8d43-0334eae7cf07"
                }
            ],
            "parameters": [
                {
                    "name": "Type",
                    "value": "AgentWhisper"
                },
                {
                    "name": "ContactFlowId",
                    "value": "agentWhisperFlow",
                    "namespace": "User Defined"
                }
            ],
            "metadata": {
                "position": {
                    "x": 1137,
                    "y": 23.875
                },
                "contactFlow": "agentWhisperFlow",
                "customerOrAgent": false,
                "useDynamic": true
            },
            "type": "SetEventHook"
        },
        {
            "id": "a95af587-b94b-4a17-8d43-0334eae7cf07",
            "branches": [
                {
                    "condition": "Error",
                    "transition": "80c382f6-558f-4245-ac4f-0c395020d6f1"
                },
                {
                    "condition": "Success",
                    "transition": "f0158832-4e83-4a45-9a1c-e846f4312a79"
                }
            ],
            "parameters": [
                {
                    "name": "Type",
                    "value": "CustomerWhisper"
                },
                {
                    "name": "ContactFlowId",
                    "value": "customerWhisperFlow",
                    "namespace": "User Defined"
                }
            ],
            "metadata": {
                "position": {
                    "x": 1378,
                    "y": 22
                },
                "contactFlow": "customerWhisperFlow",
                "customerOrAgent": true,
                "useDynamic": true
            },
            "type": "SetEventHook"
        },
        {
            "id": "f0158832-4e83-4a45-9a1c-e846f4312a79",
            "branches": [],
            "parameters": [],
            "metadata": {
                "position": {
                    "x": 1618,
                    "y": 21.875
                }
            },
            "type": "ReturnFromFlowModule"
        },
        {
            "id": "79b903fb-e57b-419b-b635-e343517dc6e8",
            "branches": [
                {
                    "condition": "Error",
                    "transition": "80c382f6-558f-4245-ac4f-0c395020d6f1"
                },
                {
                    "condition": "Success",
                    "transition": "af35357c-03ca-4365-af1a-dc0f8e225bfe"
                }
            ],
            "parameters": [
                {
                    "name": "Type",
                    "value": "AgentHold"
                },
                {
                    "name": "ContactFlowId",
                    "value": "agentHold",
                    "namespace": "User Defined"
                }
            ],
            "metadata": {
                "position": {
                    "x": 415,
                    "y": 20.875
                },
                "contactFlow": "agentHold",
                "customerOrAgent": false,
                "useDynamic": true
            },
            "type": "SetEventHook"
        },
        {
            "id": "80c382f6-558f-4245-ac4f-0c395020d6f1",
            "branches": [],
            "parameters": [],
            "metadata": {
                "position": {
                    "x": 1618,
                    "y": 200.875
                }
            },
            "type": "Disconnect"
        },
        {
            "id": "bb381663-f0b0-43e2-b535-e7984c176327",
            "branches": [
                {
                    "condition": "Error",
                    "transition": "80c382f6-558f-4245-ac4f-0c395020d6f1"
                },
                {
                    "condition": "Success",
                    "transition": "79b903fb-e57b-419b-b635-e343517dc6e8"
                }
            ],
            "parameters": [
                {
                    "name": "Queue",
                    "value": "queueArn",
                    "namespace": "User Defined"
                }
            ],
            "metadata": {
                "position": {
                    "x": 162,
                    "y": 22.875
                },
                "useDynamic": true,
                "queue": "queueArn"
            },
            "type": "SetQueue"
        }
    ],
    "metadata": {
        "entryPointPosition": {
            "x": 15,
            "y": 20
        },
        "snapToGrid": false,
        "name": "queue_flows",
        "status": "published",
        "hash": "6dc8b35e8a6fc88e9324f7bad093c99334524e40bbb6331f047fa6ac1ef7fcb0"
    },
    "settings": {
        "inputParameters": [],
        "outputParameters": [],
        "branches": [
            {
                "displayName": "Success",
                "referenceName": "Success",
                "description": ""
            },
            {
                "displayName": "Error",
                "referenceName": "Error",
                "description": ""
            }
        ]
    }
}

営業時間の判定用モジュール

最後に作成するのは、営業時間を判定するモジュールです。毎日の営業時間はオペレーション時間で判定し、休業日はAWS Systems Change Calenderで判定します。

コンタクトフローのモジュールタブを開いて「フローモジュールの作成」をクリックします。

オペレーション時間の設定ブロックのパラメータは設定不要です。作業キューおよび各タイプのフロー設定用モジュールの前に営業時間の判定モジュール前に配置します。休業日を判定は、Lambda関数を呼び出すのでLambda関数を呼び出すブロックを配置します。AWS Systems Change Managerの戻り値はOPEN or CLOSEDなので後続にコンタクト属性の確認ブロックでLambda関数の戻り値をチェックします。なお、呼び出し元のコンタクトフローによっては、休業日判定が不要の場合もあるのでLambda関数を呼び出すブロックの前にコンタクト属性を確認するブロックを配置して分岐させます。
呼び出し元のコンタクトフローに戻る前に営業時間かどうか判定するコンタクト属性を設定するブロックを2つ配置します。1つは営業時間内(OPEN)、もう1つは営業時間外(CLOSED)を設定するブロックです。

モジュール名に名前を入力したら公開しましょう。
作成したモジュール(サンプル)はこちらです。

{
    "start": "4eb099de-f0c0-4b6e-b5ad-ef707e79a36f",
    "version": "1",
    "blocks": [
        {
            "id": "6f14976a-fe93-4366-a9b5-25cca6413e17",
            "branches": [],
            "parameters": [],
            "metadata": {
                "position": {
                    "x": 1628,
                    "y": 244
                }
            },
            "type": "Disconnect"
        },
        {
            "id": "be4163ac-86d6-424f-834b-7232fa6cd71b",
            "branches": [
                {
                    "condition": "Error",
                    "transition": "6f14976a-fe93-4366-a9b5-25cca6413e17"
                },
                {
                    "condition": "Success",
                    "transition": "7b65b802-75a8-4f79-94c0-79dc990808fe"
                }
            ],
            "parameters": [
                {
                    "name": "Attribute",
                    "value": "OPEN",
                    "key": "STATE"
                }
            ],
            "metadata": {
                "position": {
                    "x": 1607,
                    "y": 23
                },
                "dynamicParams": []
            },
            "type": "SetAttributes"
        },
        {
            "id": "d7ee9626-954b-4104-8e23-1e615b9dd644",
            "branches": [],
            "parameters": [],
            "metadata": {
                "position": {
                    "x": 524,
                    "y": 283
                }
            },
            "type": "Disconnect"
        },
        {
            "id": "7b65b802-75a8-4f79-94c0-79dc990808fe",
            "branches": [],
            "parameters": [],
            "metadata": {
                "position": {
                    "x": 1865,
                    "y": 23.125
                }
            },
            "type": "ReturnFromFlowModule"
        },
        {
            "id": "b63d201e-964b-4535-b617-3e59eb5af2de",
            "branches": [],
            "parameters": [],
            "metadata": {
                "position": {
                    "x": 1870,
                    "y": 700.125
                }
            },
            "type": "Disconnect"
        },
        {
            "id": "acf0194b-8868-42dd-8fc3-32971559d935",
            "branches": [
                {
                    "condition": "Evaluate",
                    "transition": "be4163ac-86d6-424f-834b-7232fa6cd71b",
                    "conditionType": "Equals",
                    "conditionValue": "OPEN"
                },
                {
                    "condition": "Evaluate",
                    "transition": "a15f8f3f-40c3-463b-8b72-88e9926f7157",
                    "conditionType": "Equals",
                    "conditionValue": "CLOSED"
                },
                {
                    "condition": "NoMatch",
                    "transition": "666b6894-7127-432b-9f98-a027d254be10"
                }
            ],
            "parameters": [
                {
                    "name": "Attribute",
                    "value": "CalState"
                },
                {
                    "name": "Namespace",
                    "value": "External"
                }
            ],
            "metadata": {
                "position": {
                    "x": 1344,
                    "y": 21.125
                },
                "conditionMetadata": [
                    {
                        "operator": {
                            "name": "等しい",
                            "value": "Equals",
                            "shortDisplay": "="
                        },
                        "value": "OPEN",
                        "id": "1a949c82-bb7a-49ca-ae78-dde2c4a24af1"
                    },
                    {
                        "operator": {
                            "name": "等しい",
                            "value": "Equals",
                            "shortDisplay": "="
                        },
                        "value": "CLOSED",
                        "id": "c923ece7-ea14-49f4-bda0-411c8192558c"
                    }
                ]
            },
            "type": "CheckAttribute"
        },
        {
            "id": "a15f8f3f-40c3-463b-8b72-88e9926f7157",
            "branches": [
                {
                    "condition": "Error",
                    "transition": "b63d201e-964b-4535-b617-3e59eb5af2de"
                },
                {
                    "condition": "Success",
                    "transition": "7b65b802-75a8-4f79-94c0-79dc990808fe"
                }
            ],
            "parameters": [
                {
                    "name": "Attribute",
                    "value": "CLOSED",
                    "key": "STATE"
                }
            ],
            "metadata": {
                "position": {
                    "x": 1606,
                    "y": 545.125
                },
                "dynamicParams": []
            },
            "type": "SetAttributes"
        },
        {
            "id": "9780b058-4f56-4648-8a90-1f2d093c04de",
            "branches": [
                {
                    "condition": "Error",
                    "transition": "666b6894-7127-432b-9f98-a027d254be10"
                },
                {
                    "condition": "Success",
                    "transition": "acf0194b-8868-42dd-8fc3-32971559d935"
                }
            ],
            "parameters": [
                {
                    "name": "FunctionArn",
                    "value": "arn:aws:lambda:ap-northeast-1:123456789012:function:flow_is_holiday"
                },
                {
                    "name": "TimeLimit",
                    "value": "5"
                }
            ],
            "metadata": {
                "position": {
                    "x": 1083,
                    "y": 23.125
                },
                "dynamicMetadata": {},
                "useDynamic": false
            },
            "type": "InvokeExternalResource",
            "target": "Lambda"
        },
        {
            "id": "666b6894-7127-432b-9f98-a027d254be10",
            "branches": [],
            "parameters": [],
            "metadata": {
                "position": {
                    "x": 1345,
                    "y": 286.125
                }
            },
            "type": "Disconnect"
        },
        {
            "id": "4eb099de-f0c0-4b6e-b5ad-ef707e79a36f",
            "branches": [
                {
                    "condition": "True",
                    "transition": "17e6df1b-c648-48b8-a517-123ea9113fa0"
                },
                {
                    "condition": "False",
                    "transition": "a15f8f3f-40c3-463b-8b72-88e9926f7157"
                },
                {
                    "condition": "Error",
                    "transition": "d7ee9626-954b-4104-8e23-1e615b9dd644"
                }
            ],
            "parameters": [],
            "metadata": {
                "position": {
                    "x": 523,
                    "y": 23
                }
            },
            "type": "CheckHoursOfOperation"
        },
        {
            "id": "17e6df1b-c648-48b8-a517-123ea9113fa0",
            "branches": [
                {
                    "condition": "Evaluate",
                    "transition": "9780b058-4f56-4648-8a90-1f2d093c04de",
                    "conditionType": "Equals",
                    "conditionValue": "On"
                },
                {
                    "condition": "NoMatch",
                    "transition": "be4163ac-86d6-424f-834b-7232fa6cd71b"
                }
            ],
            "parameters": [
                {
                    "name": "Attribute",
                    "value": "HOLIDAY"
                },
                {
                    "name": "Namespace",
                    "value": "User Defined"
                }
            ],
            "metadata": {
                "position": {
                    "x": 805,
                    "y": 22.125
                },
                "conditionMetadata": [
                    {
                        "operator": {
                            "name": "等しい",
                            "value": "Equals",
                            "shortDisplay": "="
                        },
                        "value": "On",
                        "id": "49f27ae2-9ba3-4cd0-8ece-c2133c4d10cf"
                    }
                ]
            },
            "type": "CheckAttribute"
        }
    ],
    "metadata": {
        "entryPointPosition": {
            "x": 15,
            "y": 20
        },
        "snapToGrid": false,
        "name": "open_closed",
        "status": "published",
        "hash": "05d07bd6b7a3994171243a292dcab9ee842ab98c5ba94f3d760b27d6760b7ff0"
    },
    "settings": {
        "inputParameters": [],
        "outputParameters": [],
        "branches": [
            {
                "displayName": "Success",
                "referenceName": "Success",
                "description": ""
            },
            {
                "displayName": "Error",
                "referenceName": "Error",
                "description": ""
            }
        ]
    }
}

モジュールは以上です。

モジュール化したコンタクトフロー

モジュールを組み込んだコールフローに変更します。以下、全体像です。

まずはじめに呼び出しモジュールブロックでコンタクトフローの初期化用モジュールを設定します。次が重要で作業キューおよび各タイプのフロー設定用モジュールと営業時間の判定用モジュールで配置したブロックのユーザー定義の属性値を設定するためにコンタクト属性を設定するブロックを配置しします。

設定する属性値は、キューおよび各フローのARNです。属性を使わない場合は、コネクトインスタンス内にあるリソース名を選択することになりますが、実体としては各リソースのARNが参照されています。なので属性値にはARNを設定することで動的にリソースが参照されます。最後のHOLIDAYは、営業時間の判定用モジュールで休業日判定する為の属性です。Onに設定されていればLambda関数を呼び出すブロックが処理されます。
後続に呼び出しモジュールブロックを2つ配置します。営業時間の判定用モジュールは、作業キューの設定ブロックで設定されたオペレーション時間を参照するので作業キューおよび各タイプのフロー設定用モジュール→営業時間の判定用モジュールの順番です。

次にコンタクト属性を確認するブロックを配置し、営業時間の判定用モジュールで設定した営業時間内(OPEN) or 営業時間外(CLOSED)で分岐できるように設定します。OPENはキューの転送ブロック、CLOSEDは切断ブロックにつなげて完成です。
作成したコンタクトフロー(サンプル)はこちらです。

{
    "modules": [
        {
            "id": "28597900-a55e-4324-8404-09a5d1082810",
            "type": "InvokeFlowModule",
            "branches": [
                {
                    "condition": "NoMatch",
                    "transition": "7d36660b-7741-4335-b52b-ebff2d0c3cc5"
                },
                {
                    "condition": "Error",
                    "transition": "086cf604-30ff-45ef-9fcf-53f76beb4542"
                }
            ],
            "parameters": [
                {
                    "name": "FlowModuleId",
                    "value": "9645cc5f-b537-4a63-8031-991cc3305778",
                    "resourceName": "init",
                    "namespace": null
                }
            ],
            "metadata": {
                "position": {
                    "x": 157,
                    "y": 23.875
                },
                "useDynamic": false,
                "contactFlowModuleName": "init"
            }
        },
        {
            "id": "7d36660b-7741-4335-b52b-ebff2d0c3cc5",
            "type": "SetAttributes",
            "branches": [
                {
                    "condition": "Success",
                    "transition": "56d77b9d-ceaa-49e6-9268-24e642171b37"
                },
                {
                    "condition": "Error",
                    "transition": "086cf604-30ff-45ef-9fcf-53f76beb4542"
                }
            ],
            "parameters": [
                {
                    "name": "Attribute",
                    "value": "arn:aws:connect:ap-northeast-1:123456789012:instance/3ff2093d-af96-43fd-b038-3c07cdd7609c/queue/eefbe764-2ded-45b3-963a-2a066ab1ec76",
                    "key": "queueArn",
                    "namespace": null
                },
                {
                    "name": "Attribute",
                    "value": "arn:aws:connect:ap-northeast-1:123456789012:instance/3ff2093d-af96-43fd-b038-3c07cdd7609c/contact-flow/154dab33-7bd2-4015-8b85-1244cafa6411",
                    "key": "agentHold",
                    "namespace": null
                },
                {
                    "name": "Attribute",
                    "value": "arn:aws:connect:ap-northeast-1:123456789012:instance/3ff2093d-af96-43fd-b038-3c07cdd7609c/contact-flow/08ddef36-098d-44c4-97d0-796607780faa",
                    "key": "customerHold",
                    "namespace": null
                },
                {
                    "name": "Attribute",
                    "value": "arn:aws:connect:ap-northeast-1:123456789012:instance/3ff2093d-af96-43fd-b038-3c07cdd7609c/contact-flow/eb520c19-e795-402e-b039-19cef5927d63",
                    "key": "customerQueueFlow",
                    "namespace": null
                },
                {
                    "name": "Attribute",
                    "value": "arn:aws:connect:ap-northeast-1:123456789012:instance/3ff2093d-af96-43fd-b038-3c07cdd7609c/contact-flow/1fd07644-1e2a-416b-8377-71c953f420c3",
                    "key": "agentWhisperFlow",
                    "namespace": null
                },
                {
                    "name": "Attribute",
                    "value": "arn:aws:connect:ap-northeast-1:123456789012:instance/3ff2093d-af96-43fd-b038-3c07cdd7609c/contact-flow/552ae155-3963-4f1a-8a80-d0069fc718bf",
                    "key": "customerWhisperFlow",
                    "namespace": null
                },
                {
                    "name": "Attribute",
                    "value": "On",
                    "key": "HOLIDAY",
                    "namespace": null
                }
            ],
            "metadata": {
                "position": {
                    "x": 402,
                    "y": 21
                },
                "dynamicParams": []
            }
        },
        {
            "id": "56d77b9d-ceaa-49e6-9268-24e642171b37",
            "type": "InvokeFlowModule",
            "branches": [
                {
                    "condition": "NoMatch",
                    "transition": "afd840a1-aa61-4a83-b0a7-e19cc2b478e0"
                },
                {
                    "condition": "Error",
                    "transition": "086cf604-30ff-45ef-9fcf-53f76beb4542"
                }
            ],
            "parameters": [
                {
                    "name": "FlowModuleId",
                    "value": "65607f9a-3a00-48e9-8b30-b4e0176ff34e",
                    "resourceName": "queue_flows",
                    "namespace": null
                }
            ],
            "metadata": {
                "position": {
                    "x": 643,
                    "y": 22
                },
                "useDynamic": false,
                "contactFlowModuleName": "queue_flows"
            }
        },
        {
            "id": "afd840a1-aa61-4a83-b0a7-e19cc2b478e0",
            "type": "InvokeFlowModule",
            "branches": [
                {
                    "condition": "NoMatch",
                    "transition": "f5d244f7-911c-4fa6-8b73-53109f4ca280"
                },
                {
                    "condition": "Error",
                    "transition": "086cf604-30ff-45ef-9fcf-53f76beb4542"
                }
            ],
            "parameters": [
                {
                    "name": "FlowModuleId",
                    "value": "9a3881c1-911b-4a53-9ed6-35bbbaec9582",
                    "resourceName": "open_or_closed",
                    "namespace": null
                }
            ],
            "metadata": {
                "position": {
                    "x": 881,
                    "y": 23
                },
                "useDynamic": false,
                "contactFlowModuleName": "open_or_closed"
            }
        },
        {
            "id": "086cf604-30ff-45ef-9fcf-53f76beb4542",
            "type": "Disconnect",
            "branches": [],
            "parameters": [],
            "metadata": {
                "position": {
                    "x": 1122,
                    "y": 281
                }
            }
        },
        {
            "id": "f5d244f7-911c-4fa6-8b73-53109f4ca280",
            "type": "CheckAttribute",
            "branches": [
                {
                    "condition": "Evaluate",
                    "conditionType": "Equals",
                    "conditionValue": "OPEN",
                    "transition": "faa603db-c678-4d6a-a7ce-cc5630a40583"
                },
                {
                    "condition": "Evaluate",
                    "conditionType": "Equals",
                    "conditionValue": "CLOSED",
                    "transition": "a8d3bbc2-ec12-4ef2-b662-3b93eca27926"
                },
                {
                    "condition": "NoMatch",
                    "transition": "a8d3bbc2-ec12-4ef2-b662-3b93eca27926"
                }
            ],
            "parameters": [
                {
                    "name": "Attribute",
                    "value": "STATE"
                },
                {
                    "name": "Namespace",
                    "value": "User Defined"
                }
            ],
            "metadata": {
                "position": {
                    "x": 1120,
                    "y": 23
                },
                "conditionMetadata": [
                    {
                        "operator": {
                            "name": "等しい",
                            "value": "Equals",
                            "shortDisplay": "="
                        },
                        "value": "OPEN",
                        "id": "4715280f-4eb4-4b3c-b5cb-7e63ceefbc16"
                    },
                    {
                        "operator": {
                            "name": "等しい",
                            "value": "Equals",
                            "shortDisplay": "="
                        },
                        "value": "CLOSED",
                        "id": "5736350d-e8f7-410e-91e0-ee57ddd390c3"
                    }
                ]
            }
        },
        {
            "id": "2202cc85-c410-4f45-8bfc-871f48ddc0e7",
            "type": "Transfer",
            "branches": [
                {
                    "condition": "AtCapacity",
                    "transition": "dd7ebdc3-dda0-4c21-b36a-823025f7180d"
                },
                {
                    "condition": "Error",
                    "transition": "dd7ebdc3-dda0-4c21-b36a-823025f7180d"
                }
            ],
            "parameters": [],
            "metadata": {
                "position": {
                    "x": 1604,
                    "y": 20
                },
                "useDynamic": false,
                "queue": null
            },
            "target": "Queue"
        },
        {
            "id": "a8d3bbc2-ec12-4ef2-b662-3b93eca27926",
            "type": "PlayPrompt",
            "branches": [
                {
                    "condition": "Success",
                    "transition": "dd7ebdc3-dda0-4c21-b36a-823025f7180d"
                },
                {
                    "condition": "Error",
                    "transition": "dd7ebdc3-dda0-4c21-b36a-823025f7180d"
                }
            ],
            "parameters": [
                {
                    "name": "Text",
                    "value": "只今、営業していません。営業時間内におかけ直しくださいますようおねがいします。",
                    "namespace": null
                },
                {
                    "name": "TextToSpeechType",
                    "value": "text"
                }
            ],
            "metadata": {
                "position": {
                    "x": 1602,
                    "y": 288
                },
                "useDynamic": false
            }
        },
        {
            "id": "faa603db-c678-4d6a-a7ce-cc5630a40583",
            "type": "PlayPrompt",
            "branches": [
                {
                    "condition": "Success",
                    "transition": "2202cc85-c410-4f45-8bfc-871f48ddc0e7"
                },
                {
                    "condition": "Error",
                    "transition": "dd7ebdc3-dda0-4c21-b36a-823025f7180d"
                }
            ],
            "parameters": [
                {
                    "name": "Text",
                    "value": "オペレータにお繋ぎします。",
                    "namespace": null
                },
                {
                    "name": "TextToSpeechType",
                    "value": "text"
                }
            ],
            "metadata": {
                "position": {
                    "x": 1361,
                    "y": 23
                },
                "useDynamic": false
            }
        },
        {
            "id": "dd7ebdc3-dda0-4c21-b36a-823025f7180d",
            "type": "Disconnect",
            "branches": [],
            "parameters": [],
            "metadata": {
                "position": {
                    "x": 2017,
                    "y": 241
                }
            }
        }
    ],
    "version": "1",
    "start": "28597900-a55e-4324-8404-09a5d1082810",
    "metadata": {
        "entryPointPosition": {
            "x": 15,
            "y": 20
        },
        "snapToGrid": false,
        "name": "nakahara_module_test",
        "description": null,
        "type": "contactFlow",
        "status": "published",
        "hash": "07e8543025606ed1308c840feb4657b67c975688e1a234e973c262bbf4ae7fcf"
    },
    "type": "contactFlow"
}

さいごに

モジュール化前のコンタクトフローと比べるとブロック数が減って可読性が向上し、モジュールも機能毎に分離している為、メンテナンスもしやすくなりました。
多くのコンタクトフローを運用されている場合は、ぜひともモジュール化を意識したコンタクトフローを設計または既存のコンタクトフローのアップデートをオススメします。