Power Apps でチャットライクなエクスペリエンスを実装する


# はじめに

これまで、Power Apps をフロントエンドにして、Azure OpenAI の ChatGPT と連携をするアプリについて、いくつかの記事で紹介してきました。

https://qiita.com/Takashi_Masumori/items/8a07fb6d1869967ce1f9

https://qiita.com/Takashi_Masumori/items/e9739e545bfc0c7c2c81

これまで紹介してきた通り、フロントエンドをローコードにすることで、カスタマイズ含め、短期間でアプリを作成可能というメリットがありますが、Power Apps でチャットライクなエクスペリエンスを実現する方法について少なからず悩まれるケースもあると思います。

例えば、以下のアプリでは、チャットのやり取りの表示部分はギャラリー、文字の入力はテキストインプットを利用していますが、ただ単にこれらの部品を利用するだけだと、例として、以下のような問題が出てきます。

* ギャラリーにデータ (チャット履歴) が上から下に表示され、基本的に下のやり取り (最新のチャット履歴) を見るためにはスクロールバーを下に動かす必要がある

* ギャラリー内のラベルの高さが固定のため、ChatGPT からの返答の文字数が多い場合、その返答を見るためにスクロールバーを沢山動かす必要がある


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/619f9051-120a-35f2-013d-684ee971a998.png)

そのため、今回は、これらの部品をベースに、出来る限りチャットライクなエクスペリエンスを実現するアプローチについて、以下の観点で紹介します。

* 入力文字数が増えた際に自動でテキストインプットの幅を広げる

* 文字入力後、Shift+Enter を押下した際に ChatGPT に依頼する

* 文字数に合わせて個々のギャラリーのアイテムの高さを調整する

* チャットの履歴が長くなった際、最新履歴が一番下に表示されるようにする


# 入力文字数が増えた際に自動でテキストインプットの幅を広げる

もしかしたらいくつかアプローチあるのかもしれませんが、私のアプリの場合、テキストインプットコントロールの`[Height]`プロパティに以下のような処理を入れています。テキストインプットの幅的に、一旦 50 文字程度入れたら高さを広げるようにしていますが、こちらは必要に応じて変えてもいいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/294aaa3c-c63b-a960-210a-9d72225ad0c1.png)

```
If(
    (IsBlank(txtChatMessage.Text) Or Len(txtChatMessage.Text) < 50),40,
    Len(txtChatMessage.Text) / 50 * 40
)

```

一応、以下のようにたくさん文字を入れると、高さが広がります。ChatGPT に対して結構長文で相談することもあると思うので、動的に高さを調整出来た方がチャットライクな気がします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/ec5b5611-2035-1950-a823-d74a8e3941b4.png)

# 文字入力後、Shift+Enter を押下した際に ChatGPT に依頼する

もちろん、こちらのボタンを押下した際に入力した文字をベースに ChatGPT に依頼するようにしていていますが、Shift+Enter を押下したした際にも ChatGPT に依頼できるようにしたいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/8186e529-7eb7-e3a6-d364-000dcff7199a.png)

まず、色々調べましたが、テキストインプットコントロールでは、Shift+Enter を押した際にデータを送信するようなプロパティはありません。

そのため、こちらの Creator kit を利用します。

https://learn.microsoft.com/en-us/power-platform/guidance/creator-kit/overview

インストール方法はいくつかあるのですが、例えば、ダウンロードしたソリューションをインポートすることで利用可能です。

https://learn.microsoft.com/en-us/power-platform/guidance/creator-kit/setup

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/aee7f8a8-8fc0-dc09-ca44-811a710cf255.png)


:::note warn
インポートする環境で以下の設定をオンにしておきます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/76a489f7-fc7d-68a6-927f-6d8149c40fe3.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/fb894554-5880-0ccf-bc11-e2a722ef3b82.png)
:::

今回は、以下のコントロールを使います。

https://learn.microsoft.com/ja-jp/power-platform/guidance/creator-kit/keyboardshortcuts

こちらの箇所からコードを選び、KeyboardShortcuts を選びます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/00c507ce-50e9-d5ae-5c37-6b8969d293ef.png)

こちらからコンポーネントを追加できるようになります。アプリ上のどこかに適当に配置し、非表示にしておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/91b0596f-5bef-264f-eafc-d8b176bb7663.png)

`[KeyConfig]`プロパティに以下のような値を入れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/091dae88-c076-3f2f-d6ce-1682fbfe40a0.png)

```
"[""shift + enter""]"
```

次に、`[OnChange]`プロパティに以下のような処理を入れます。今回は、データ送信をするアイコンの `[OnSelect]`を実行するようにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/7405747c-dc34-8c67-0a3a-5a491285089c.png)

```
If(
    Self.OnKey = "shift enter",
    Select(icnSend)
);
```

これにより、Shift+Enter を押下した際にもデータが送信され結果が表示されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/36b49313-35b0-769c-b4f7-92b6d210f125.png)

# 文字数に合わせて個々のギャラリーのアイテムの高さを調整する

こちらは以前にも別記事で書きましたが、こちらの記事に載せる方が良いと思うので再掲します。

https://qiita.com/Takashi_Masumori/items/12095390a633b8789522#power-apps-%E3%81%A7%E3%83%81%E3%83%A3%E3%83%83%E3%83%88%E3%82%A8%E3%82%AF%E3%82%B9%E3%83%9A%E3%83%AA%E3%82%A8%E3%83%B3%E3%82%B9%E3%82%92%E5%AE%9F%E8%A3%85%E3%81%99%E3%82%8B-%E3%82%AE%E3%83%A3%E3%83%A9%E3%83%AA%E3%83%BC%E9%83%A8%E5%88%86

まず、チャットライクなエクスペリエンスにするためには、以下のようにギャラリー内のアイテムについて、文字数に合わせて高さを動的に調整する必要があります。固定かされている場合、文字数が多いと沢山スクロールしないといけなくなり、エクスペリエンスが悪くなると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/6aef31c3-3976-6fe1-bab3-99e4310f0509.png)

こちらの実現方法について、まず、ギャラリーの種類として、以下を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/76088a0b-e413-bd09-92d0-006667a9ac7a.png)

ギャラリー内のラベルの`[Text]`プロパティを設定します。今回は、ChatGPT とのやり取りが入るようにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/f738a44e-9a60-c2c7-7f2e-337edaf751de.png)

ギャラリー内のラベルについて、以下のように、高さの自動調整をオンにします。これにより、文字の量に応じてギャラリー内のラベルの高さが自動調整され、チャットライクな感じになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/cedcb8d2-dcf5-e8c3-9e51-6f7274921a9a.png)

# チャットの履歴が長くなった際、最新履歴が一番下に表示されるようにする

こちらも以前にも別記事で書きましたが、こちらの記事に載せる方が良いと思うので再掲します。

チャットのようなエクスペリエンスにするために、以下のようにチャットのやり取りが続いた際、一番最新のやり取り (ギャラリーで言うと一番下) が選択されるようにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/d04558cc-8d09-a5b4-7173-8692c2653652.png)

こちらは、送信ボタンの以下の処理により実現しております。こちらを実施しない場合、チャットが長くなった場合、一番したのやり取りが隠れてしまい、わざわざ下にスクロールしないといけなくなり、チャットのエクスペリエンスが低下すると思います。

```
Select(
    galChat,
    CountRows(galChat.AllItems)
);
```
# その他

ChatGPT と連携するようなアプリを作成する場合、例えば、以下のようにプログラムのコードの回答をもらった際、Web の ChatGPT のようにコード部分を分けて表示したいといった要望も少なからずあると思います。こちらについては、以下の記事でアプローチを紹介しております。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/fe72e1cc-df34-eaa0-3b13-5026d76a3247.png)

https://qiita.com/Takashi_Masumori/items/e9739e545bfc0c7c2c81


# まとめ

今回は、Power Apps で出来る限りチャットライクなエクスペリエンスを実現するアプローチについて紹介しました。例えば、ChatGPT と連携するようなアプリのフロントエンドを Power Apps にして、出来る限りサクッと作りたいものの、エクスペリエンスは出来るだけ落としたくないといったニーズはあると思うので、少しでも参考になれば幸いです。