【Salesforce】CTI Flowのブロックについて

# 概要

SalesforceのCTI Flowで使用するCTI Blockについて記載しています。
案件で使用したCTI Blockを中心に記載しており、全てのCTI Blockを含んだ内容ではありません。
CTI Blockを検索や使用する上で少しでもお役に立てればと思い、本記事を投稿いたしました。

# 前提

CTI Flowを使用するためには、`SalesforceにAmazon Connect CTI Adapter for Salesforce`をインストールし、初期セットアップを行う必要がある。
本記事では、インストールや初期セットアップについては記載しない。

## 注意点

CTI Blockを使用する際に、下記の画像の箇所でブロックを検索することがあると思います。
検索の入力フォーム（名前による検索）に**和名**で入力してもヒットしません。
**英名**で検索しないとブロックの検索を行うことができません。

![スクリーンショット 2025-03-12 18.15.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766655/b19f3cab-68ed-4539-9cb4-15a39f8a72eb.png)

:::note info
※2025年3月時点での内容になります。
:::


# CTI Blocks（一部）

| ブロック名(和名) | ブロック名(英名) | 出来ること | 詳細な内容 |
| --- | --- | --- | --- |
| コンタクトのプロパティを取得 | Get Contact Properties | Amazon Connectのコンタクトフローの情報を取得できる | 1 |
| コンタクトの属性を取得 | Get Contact Attribute | Amazon Connectの「コンタクト属性の設定」ブロックで、設定した値を取得できる | 2 |
| レコードの保存（または作成） | Save (or Create) a Record | ・Salesforce内に存在するレコードを最新の状態に保存(更新)する際に使用する<br>・レコードの作成も可能 | 3 |
| Salesforce レコードの取得 | Retrieve Salesforce Record | Salesforce内のレコードを取得することができる | 4 |
| 値の抽出 | Extract Value | ・主に「レコードの取得」ブロックと組み合わせて、特定の項目の値を抜き出すことができる<br>・各機能ブロックの戻り値から値を取得できる | 5 |
| 検索とスクリーンポップ | Search And Screenpop | 指定したオブジェクトから特定の文字列を検索し、検索結果が一致したレコードをポップアップする<br>（※ 検索対象は　Salesforceのソフトフォンレイアウトに設定したオブジェクトに依存する） | 6 |
| スクリーンポップの検索 | Screenpop Search | Salesforceのソフトフォンレイアウトに関わらず、指定した検索キーでSalesforceのオブジェクトを検索し、ポップアップさせる（すべてのオブジェクトが対象） | 7 |
| スクリーンポップの新しいレコード | Screenpop New Record | 指定したオブジェクトの新規レコードを作成し、ポップアップする | 8 |
| スクリーンポップのオブジェクト | Screenpop Object | ・特定のSalesforce レコードをポップアップさせる<br>・「レコードの保存（または作成）」ブロックの戻り値を本ブロックの引数に設定することで、レコードを明示的にポップアップさせることができる | 9 |
| If-else | If-else | 条件分岐を行う際に使用 | 10 |
| コンソールにログを記録する | Log to Console | 開発者コンソールにログを出力する | 11 |
| 結合文字列 | Join Strings | ・電話番号を「国際電話番号形式」から「090・080などの国内電話番号形式」に変更する場合<br>・文字列を結合する場合 | 12 |

## ブロックの詳細
### 1. コンタクトのプロパティを取得
Amazon Connectのコンタクトフローに含まれる全てのコンタクト属性情報をCTI Flow内に取得する。
本ブロックには設定はない。
CTI Flowの先頭に配置することで、後続のブロックのインプット情報としてコンタクト属性情報が使用可能。

**戻り値(取得可能なプロパティの一覧)**
| 戻り値名 | 内容 |
| --- | --- |
| channel | 「音声」または「チャット」 |
| formattedPhoneNumberE164 | 発信者の電話番号（E164形式） |
| formattedPhoneNumber | 発信者の電話番号 |
| queueTimestamp | キューのタイムスタンプ |
| queueId | キュー ID |
| phone | 発信者の電話番号 |
| isInbound | 着信通話かどうか |
| status | 「着信中」または「進行中」 |
| country | 発信者の国 |
| attributes | コンタクトフロー内で定義した属性値 |
| callType | 「インバウンド」または「アウトバウンド」 |
| type | 「音声」または「チャット」 |
| contactId | コンタクト ID |
| queueName | キュー名 |
| isConnected | 接続されているかどうか |

### 2. コンタクトの属性を取得
Amazon Connectのコンタクトフロー内で設定した特定のコンタクト属性情報をCTI Flow内に取得する。
設定値として、attributeNameにAmazon Connectの「コンタクト属性を設定する」ブロックで設定したキーを入力する。

**設定内容**
- attributeName
    - コンタクト属性を設定するブロックで設定したキー

**戻り値**
| 戻り値名 | 内容 |
| --- | --- |
| value | コンタクト属性の値またはデフォルト値 |

### 3. レコードの保存（または作成）
Salesforceのレコードを新規作成または保存(更新)する。
entityTypeは標準オブジェクト以外のカスタムオブジェクトにも対応している。
作成するレコードの各項目の初期値を設定できる。
戻り値で本ブロックで作成または保存(更新)されたレコードIDが取得できる。

**設定内容**
- recordId
    - 新規作成：null
    - 保存(更新)：レコードID（手動で直接指定 or Salesforce レコードを取得ブロックを使用）
        - Salesforce レコードを取得ブロックを使用した例：$.actions.uid-XX.results.record.Id
            - XX：Salesforce レコードを取得ブロックのブロック番号
            - record：Salesforce レコードを取得ブロックの戻り値
            - Id：recordの結果に含まれるId
- entityType
    - オブジェクトのAPI名
        - 例：Case、Account、Custom__c
- fieldValues（オプション）
    - Enter key：項目のAPI名
    - Enter value：$.actions.uid-XX.results.YY
        - XX：CTIブロックのブロック番号
        - YY：XXで指定したブロックの戻り値

**戻り値**
| 戻り値名 | 内容 |
| --- | --- |
| Id | オブジェクトのID |

### 4. Salesforce レコードの取得
IDを指定してSalesforceの特定のレコードを取得する。
特定の項目値を取得するには、本ブロックと後述の「値の抽出」ブロックを使用する。

**設定内容**
- fields
    - 取得に含める項目のカンマ区切り文字列
        - 例：Id,Name,custom__c
- type
    - オブジェクトのAPI名
        - 例：Case、Account、Custom__c
- id
    - 取得するレコードのID

**戻り値**
| 戻り値名 | 内容 |
| --- | --- |
| record | 取得オペレーションの結果。この値はオブジェクトである必要がある |

### 5. 値の抽出
前述の「Salesforce レコードの取得」ブロックと使用して、取得したレコードの特定の項目値を取得する。
「コンタクトのプロパティを取得」ブロックなどの各機能ブロックの戻り値から特定の値を取得する。

**設定内容**
- targetField
    - 特定の値を取得したい元(各機能ブロック)を指定
        - 例：「コンタクトのプロパティを取得」ブロックのstatus
- keyPath
    - targetFieldで指定した元(各機能ブロック)のどこの値を取得したいかを指定
        - 例：status内にあるtimestamp
- 例の階層構造の一部（「コンタクトのプロパティを取得」ブロック）
```jsx
"results":{
    "contactId":"xxxxxxx-xxxxxxx-xxxxx",
    "type":"voice",
    "status":{
        "type":"connecting",
        "timestamp":"2025-02-01T11:40:45.696Z"},
```

**戻り値**
| 戻り値名 | 内容 |
| --- | --- |
| value | targetField から keyPath を抽出した結果 |

### 6. 検索とスクリーンポップ
ソフトフォンのレイアウトで指定されたオブジェクトから特定の文字列を検索する
検索結果が返され、画面は一致するレコードをポップする
「Screenpop Search」では使用できない

**設定内容**
- searchParams
    - 検索する文字列
        - 例：Id,Name,custom__c
- queryParams（オプション）
    - URL に渡すクエリパラメータを指定
- defaultFieldValues（オプション）
    - 検索結果がないときに新しいエンティティにポップするようにソフトフォンを設定する場合 (受信通話の場合)、この引数を使用してスクリーンポップのデフォルト項目を指定
- deferred（オプション）
    - 画面ポップが検索の直後に実行されるか、後で実行されるかを指定
    - スクリーンポップが後で実行される場合は、JSON オブジェクトが返される
- callType
    - 通話のタイプ (受信、発信、内部、null など) を指定
    - ソフトフォンのレイアウトの設定に基づき、通話のタイプによって一致を検索するオブジェクトが決まる

**戻り値**
| 戻り値名 | 内容 |
| --- | --- |
| Id | レコード ID（ExactMatch が true の場合にのみ使用できる） |
| Name | レコード名（ExactMatch が true の場合にのみ使用できる） |
| RecordType | レコードタイプ（ExactMatch が true の場合にのみ使用できる） |
| ExactMatch | 単一の一致があったことを示す |
| recordCount | レスポンスのレコード数。複数の一致があった場合にのみ使用できる |

### 7. スクリーンポップの検索
検索入力に基づいて検索結果をスクリーンポップする
「Search And Screenpop」では使用できない

**設定内容**
- searchString
    - スクリーンポップで結果を入力するために使用する検索入力

**戻り値**
| 戻り値名 | 内容 |
| --- | --- |
| なし | - |

### 8. スクリーンポップの新しいレコード
指定されたデフォルトの項目値を持つ指定されたタイプの新しいレコードにスクリーンポップする

**設定内容**
- entityName
    - エンティティの名前
        - 例：Account
- defaultFieldValues（オプション）
    - 新しい(作成する)レコードで使用するデフォルト値
    - Enter key：項目のAPI名
    - Enter value：$.actions.uid-XX.results.YY
        - XX：CTIブロックのブロック番号
        - YY：XXで指定したブロックの戻り値

**戻り値**
| 戻り値名 | 内容 |
| --- | --- |
| なし | - |

### 9. スクリーンポップのオブジェクト
オブジェクトからの情報を含むスクリーンポップを開く

**設定内容**
- recordId
    - スクリーンポップするするレコードのID
- noPopOnEmpty（オプション）
    - True の場合、レコード ID が空のときにスクリーンポップは表示されず、失敗したパスに戻る
    - False の場合、スクリーンポップが表示される

**戻り値**
| 戻り値名 | 内容 |
| --- | --- |
| なし | - |

### 10. If-else
取得または保存する項目の値に応じて、フローを分岐させる

**設定内容**
- operandA（オプション）
    - 比較する値
- comparator（オプション）
    - 比較に使用するオペレーション
```
・ ===（等しい）
・ !==（等しくない）
・ >（AはBより大きい）
・ >=（AはB以上）
・ <（AはBより小さい）
・ <=（AはB以下）
```
- operandB（オプション）
    - 比較する値
- evaluateAs（オプション）
    - 比較前に入力をキャストする
    - Javascript 型

**戻り値**
| 戻り値名 | 内容 |
| --- | --- |
| なし | - |

### 11. コンソールにログを記録する
CTI Flowの実行結果をログに記録する

**設定内容**
- level（オプション）
    - 使用するログレベル
    - 「info」、「warn」、「error」、または「debug」のいずれか
- message
    - 出力するログメッセージ

**戻り値**
| 戻り値名 | 内容 |
| --- | --- |
| なし | - |

### 12. 結合文字列
2 つの値を文字列に連結する
例：電話番号を国際電話番号形式の`+81`ではなく、`090`などの国内電話番号形式で登録したい場合に使用

**設定内容**
- value1
    - 最初の値
        - 例：0
- value2
    - 2番目の値
        - 例：コンタクトのプロパティを取得ブロックの「**formattedPhoneNumberE164**」を指定
            - +8180-xxxx-xxxx

**戻り値**
| 戻り値名 | 内容 |
| --- | --- |
| string | 2 つの値を結合した結果 |

# 関連サイト

- [Amazon Connect CTI Adapter for Salesforce](https://appexchangejp.salesforce.com/appxListingDetail?listingId=a0N3A00000EJdCcUAL)
- [Amazon Connect Salesforce CTI アダプタ_セットアップおよびインストールガイド](https://amazon-connect.github.io/amazon-connect-salesforce-cti/docs/lightning/appendices/appendix-f-cti-flow-blocks/01-cti-flow-blocks)

# まとめ

名称が似ているCTI Blockがあるため、どのブロックならやりたいことを実現できるのかを調査するのが大変でした。
現状は、案件で使用した**CTI Block**についてのみ記載しておりますが、新規のCTI Blockを使用したら今後も本記事に追加していく予定です。
次回の記事では、実際にどのCTI Blockを使用してどのような顧客の要望を実現したのかを記載していきたいと思っております。

# 次回記事

CTI Blockを使用したレコードの自動作成/更新についての記事