Bot Framework Composer でボット開発 : その 4 応答の作成

[前回](https://qiita.com/kenakamu/items/11bae087ca93f5a6d997#%E3%81%BE%E3%81%A8%E3%82%81)の記事ではユーザー入力の理解について見ていきました。この記事ではボット側の応答について見ていきます。

# 応答の種類

ボットからユーザーに送れるメッセージの種類は情報の伝達とインプットの要求になります。インプットの要求については[前回記事のインプットへの対応](https://qiita.com/kenakamu/items/11bae087ca93f5a6d997#%E3%82%A4%E3%83%B3%E3%83%97%E3%83%83%E3%83%88%E3%81%B8%E3%81%AE%E5%AF%BE%E5%BF%9C)を参照してください。

情報の伝達方法は大きく分けると、テキストとカードになります。Bot Framework Compose は [Language Generation](https://github.com/Microsoft/BotBuilder-Samples/tree/master/experimental/language-generation) 機能を利用して、柔軟に応答メッセージを作成することができます。この記事では基本となるいくつかのメッセージについて見ていきます。

# テキストメッセージ

最もシンプルな形式であるテキストメッセージも、Language Generation の機能で柔軟に作成できます。

## ランダム回答

まずはランダム回答から見ていきましょう。

1\.「New Dialog」をクリックして「Hello」ダイアログを作成。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/0381f0dd-cee5-b265-f36f-233fc15736dc.png)

2\.「BeginDialog」トリガーを選択し、「Send a response」アクションを追加。「Language Generation」の項目で複数の回答候補を追加。

```shell
- おはようございます
- こんにちは
- こんばんわ
- おやすみなさい
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/a40eb3f8-70d3-fdab-d9ac-bd431a933334.png)

3\. メインダイアログでトリガーを追加。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/ddd865db-a2bd-0f9c-22e2-e3357b9d6bbc.png)

4\. ダイアログの開始アクションで Hello ダイアログを呼び出す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/c640d942-ae69-6852-8f15-96de6e3630c5.png)

5\. ボットを再起動してエミュレーターで検証。用意した回答がランダムに返ることを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/6891b724-1b44-8324-ec79-5455f46c15e0.png)

6\. ボットからの返信は「Bot Response」メニューからも確認が可能。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/b54a7797-f628-c13c-7975-9aaad3793aab.png)

## メモリオブジェクトの利用

ボットは user/conversation/dialog/turn などのメモリオブジェクトを持っているため、動的に回答を作成することができます。動的な箇所は **${user.name}** のように **${}** で囲って表現します。

1\. Hello ダイアログの BeginDialog トリガーを開き、内容を以下のように変更。

```shell
- ${user.name}さん、おはようございます
- ${user.name}さん、こんにちは
- ${user.name}さん、こんばんわ
- ${user.name}さん、おやすみなさい
```

2\. ボットを再起動してエミュレーターで検証。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/262c9c0e-d8cc-ef3a-8da2-6782a7b8a3c1.png)

## 複数行テキスト

文章を ``` で括ることで複数行にもできます。

1\. Hello ダイアログの BeginDialog トリガーを開き、内容を以下のように変更。

```shell
- ```${user.name}さん、おはようございます。
猫にも挨拶しましたか？```
- ```${user.name}さん、こんにちは。
猫の様子はどうですか？```
- ```${user.name}さん、こんばんわ。
猫がおなかを空かしてますよ```
- ${user.name}さん、おやすみなさい
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/c323f7c8-2c40-842f-0126-a4f8e7e6b464.png)

2\. ボットを再起動してエミュレーターで検証。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/e8a1560b-c29d-b9b1-d386-26ad5958c15a.png)

## 分岐

フローの中で分岐を行う事もできますが、応答の切り替えであれば、Language Generation で分岐処理を行う方がシンプルに記述できます。

1\. Hello ダイアログの BeginDialog トリガーを開き、内容を以下のように変更。

- [utcNow](https://github.com/microsoft/BotBuilder-Samples/blob/master/experimental/common-expression-language/prebuilt-functions.md#utcNow): 現在の UTC 時刻取得
- [convertFromUTC](https://github.com/microsoft/BotBuilder-Samples/blob/master/experimental/common-expression-language/prebuilt-functions.md#convertFromUTC): タイムゾーンを指定して変換
- [getTimeOfDay](https://github.com/microsoft/BotBuilder-Samples/blob/master/experimental/common-expression-language/prebuilt-functions.md#getTimeOfDay): 指定した時間の時間帯を取得

```shell
- IF: ${getTimeOfDay(convertFromUTC(utcNow(), 'Tokyo Standard Time'))== 'morning'}
    - ${user.name}さん、おはようございます。
- ELSEIF: ${getTimeOfDay(convertFromUTC(utcNow(), 'Tokyo Standard Time')) == 'noon'}
    - ${user.name}さん、こんにちは。
- ELSEIF: ${getTimeOfDay(convertFromUTC(utcNow(), 'Tokyo Standard Time')) == 'evening'}
    - ${user.name}さん、こんばんわ。
- ELSE:
    - ${user.name}さん、おやすみなさい
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/c323f7c8-2c40-842f-0126-a4f8e7e6b464.png)

2\. ボットを再起動してエミュレーターで検証。
※検証した時間が 1:02 AM のため morning の分岐になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/3e3199b9-6a16-2cf2-b709-c1867b81d1c7.png)

尚、SWITCH でも同様の記述が可能。

```shell
-SWITCH: ${getTimeOfDay(convertFromUTC(utcNow(), 'Tokyo Standard Time'))}
-CASE: ${'morning'}
  - ${user.name}さん、おはようございます。
-CASE: ${'noon'}
  - ${user.name}さん、こんにちは。
-CASE: ${'evening'}
  - ${user.name}さん、こんばんわ。
-DEFAULT:
  - ${user.name}さん、おやすみなさい
```

# カードメッセージ

カードは種類が多岐に渡ります。

- ヒーローカード
- サムネイルカード
- サインインカード
- アニメーションカード
- ビデオカード
- オーディオカード
- アダプティブカード

今回はヒーローカードを試してみます。各カードの詳細は [How to send cards](https://docs.microsoft.com/en-us/composer/how-to-send-cards) を参照してください。

## ヒーローカード

ヒーローカードは複数の要素を持っているため、事前に LG Composition と呼ばれる関数を定義して、それを呼び出します。

1\.「Bot Response」メニューから「All」を選択し、「Edit mode」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/9cc53f3c-960c-e6ba-60aa-14e2adab3116.png)

2\. 以下を追加。

- # で始まる名前は関数名
- [] の範囲がカードテンプレート
- HeroCard テンプレートで cardActionTemplate を呼び出して imBack ボタンを作成

```shell
# HeroCard
[HeroCard
    title = BotFramework ヒーローカード
    subtitle = Microsoft Bot Framework
    text = Composer で簡単にボット開発
    image = https://sec.ch9.ms/ch9/7ff5/e07cfef0-aa3b-40bb-9baa-7c9ef8ff7ff5/buildreactionbotframework_960.jpg
    buttons = ${cardActionTemplate('imBack', '他のカードも見る', '他のカードも見る')}
]

# cardActionTemplate(type, title, value)
[CardAction
    Type = ${if(type == null, 'imBack', type)}
    Title = ${title}
    Value = ${value}
    Text = ${title}
]
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/d7045636-faf6-31ee-2eb7-69701a6cc7f7.png)

3\. Hello ダイアログの BeginDialog トリガーにメッセージアクションを追加。上記追加した HeroCard を呼び出し。

```shell
- ${HeroCard()}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/0b6ac3f5-59e3-b4d8-0b71-df9a1ce47846.png)

4\. ボットを再起動してエミュレーターで検証。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/7542e87b-f8fb-7ae4-fca3-536bbb5964c6.png)

# まとめ

今回は Language Generation の機能を使った応答の作成を見ていきました。同じ構文が様々なところで利用可能であるため、是非他のカードも試してください。次回は割り込み処理について見ていきます。

[次の記事へ](https://qiita.com/kenakamu/items/26570ca0866923a184c0)
[目次へ戻る](https://qiita.com/kenakamu/items/6dc043cfc1f199032883#bot-framework-composer)