実践的なFlexMessageの使用方法

## はじめに
[前回の記事](https://qiita.com/course_k/items/a5b5392f21e7e8869f83)でFlexMessageの基本について触れましたが、あまりにも簡素な形式だったので、より実践的な使用方法について考えます。

## 予約システムと連動
例えば、お店の予約管理システムと連動させ、予約状況をリッチな情報とともに表示させることができます。

以下の例では、ユーザーが「予約確認」と入力すると、ユーザー情報に紐づく予約情報をFlexMessageで送信しています。
<img width='80%' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251137/0f708991-775a-b017-0fa3-4a7b860f6f17.png'>

お店の画像を一緒に表示させたり、予約キャンセルボタンを設けたり、お店の地図へのURLを添付したりしています。

このユーザーからの「予約確認」のメッセージは、リッチメニューで実装するとより便利になりそうです。

実際のソースを少し紹介します。

## 実装方法
### ヘッダーの設定
```typescript
    const header = {
      type: "box",
      layout: "vertical",
      backgroundColor: status.color,
      contents: [
        {
          type: "text",
          text: status.text,
          color: "#FFFFFF",
          weight: "bold",
          size: "xl",
          align: "center",
        },
      ],
    };
```
ヘッダー部分はテキストベースの設定にしています。
後ほど紹介しますが、予約ステータスによってテキスト内容と背景色を変更できるようにしています。
現在は予約が確定状態なので「予約確定」というステータスと、緑色の背景色となるような設定になっています。
テキストのスタイルは自由に設定できるので、柔軟な表示が可能です。

### ヒーローの設定
4つあるFlexMessageのブロックのうち、ヒーローは唯一ボックス以外をトップレベルに指定できるブロックです。
よって、通常は画像、または動画を使ったインパクトがあるコンテンツを設定します。

```typescript
    const hero = {
      type: "image",
      url: reservationData.shopImage,
      size: "full",
      aspectRatio: "20:13",
      aspectMode: "cover",
    };
```

例ではお店の画像を設定しています。
アスペクト比やはみ出た場合の表示方法を設定することで、適切な画像表示が可能になります。

### ボディの設定
メインの内容を設定します。

```typescript
    const body = {
      type: "box",
      layout: "vertical",
      spacing: "md",
      contents: [
        this.createInfoRow("予約日時", reservationData.dateTime),
        this.createInfoRow("店舗", reservationData.shopName),
        this.createInfoRow("人数", `${reservationData.numberOfPeople}名`),
        this.createInfoRow("予約番号", reservationData.reservationId),
      ],
    };
    if (reservationData.qrCodeUrl) {
      (body.contents as any[]).push({
        type: "image",
        url: reservationData.qrCodeUrl,
        size: "sm",
        aspectRatio: "1:1",
        margin: "md",
      });
    }
```

例では共通化した処理を使ってメインコンテンツの内容を設定しています。
また、動的にQRコードの画像データを設定しています。

テキストや画像データは組み合わせて使うことができるので、いろいろな表示が可能になります。

### フッターの設定
```typescript
    const footer = {
      type: "box",
      layout: "vertical",
      spacing: "sm",
      contents: [
        {
          type: "button",
          action: {
            type: "postback",
            label: "予約をキャンセル",
            data: `action=cancel&reservationId=${reservationData.reservationId}`,
          },
          style: "secondary",
          color: "#E74C3C",
        },
        {
          type: "button",
          action: {
            type: "uri",
            label: "お店の地図を見る",
            uri: reservationData.mapUrl,
          },
        },
      ],
    };
```
FlexMessageの柔軟性には様々な魅力がありますが、中でも個人的には一番と言っても過言ではないのがボタン機能を追加できることです。

ボタンの機能にも様々あり、今回の例のようにポストバックイベントの発生や、リンク機能、またメッセージの送信やカメラ起動、リッチメニュー切り替えなど、様々な機能を設定できます。

これにより、更に動的でユーザー体験を向上させるメッセージを送信することができるようになります。

### ソース全文
今回はガチガチに機能を作り込んだので（生成AIの力も借りて）、ソース全文は記事に載せきることができませんでした。
以下のリポジトリにて全文を公開しているので、もしよければ参考にしてみてください。

https://github.com/course-k/flex-booking-example

## まとめ
今回はFlex Messageの実践的な使用方法として予約機能との連動を紹介しました。
他にはステップ入力方式のアンケートフォーム、ニュースや記事の配信、商品情報の詳細表示や購入フローの設定など、様々な活用方法が考えられます。

自由度が高いだけに使い方に困ってしまいますが、究極的にはわざわざLIFFなどでページを作らずとも、簡易的な操作であればFlexMessage上で完結させることも可能です。

ページ遷移を挟まず、メッセージのやり取りで操作が可能なので、うまく使えばかなり効果を発揮してくれそうですね。