「LINE Bot からの返答をよりリッチに」- Flex Messageを試してみた

インサイトウォッチ

こんにちは、中村です。
先月になってしまいますが、 LINE の Messaging API にアップデートがありました!

【LINE】「Messaging API」の新しいメッセージタイプとして、 画像やボタンなどを自由にレイアウトが可能な「Flex Message」を公開

Flex Message は、 HTML 近い感覚でメッセージレイアウトできます。 これによりメッセージの UI/UX を改善し、よりよりユーザーコミュニケーションを可能にします。

Flex Message はiOS版およびAndroid版のLINE 6.7.0以降で対応しています。

今回は LINE Bot の一部を Flex Message にします。
JSONデータの生成は、LINE が用意している Flex Message Simulatorを使用してみます。
Bot 用の Lambda や API Gateway については、こちらを参照してください。

Flex Message を使ってみる

今回の LINE Bot は、商品の購入ができる機能を持っています。
LINE Bot との対話ストーリーはこのような形です。

商品の表示と決済用 QR コード表示に、 Flex Message を使用します。
本来は想定される言葉で反応するようにすべきですが、今回は対話ストーリーに記載しているワードのみにします。

それでは、 Flex Message Simulator を使って作成していきます。
+マークをクリックし、モーダルから Menu タイプを選択します。

プレビューで確認しながら、エディタで修正していきます。

送信するJSONデータのcontentsプロパティに貼り付けます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
{
    "type": "flex",
    "altText": "#",
    "contents": {
        "type": "bubble",
        "hero": {
            "type": "image",
            "size": "full",
            "aspectRatio": "20:13",
            "aspectMode": "cover",
            "action": {
                "type": "uri",
                "uri": "https://classmethod.jp/"
            }
        },
        "body": {
            "type": "box",
            "layout": "vertical",
            "spacing": "md",
            "action": {
                "type": "uri",
                "uri": "https://classmethod.jp/"
            },
            "contents": [
            {
                "type": "text",
                "text": "Hamburger",
                "size": "xl",
                "weight": "bold"
            },
            {
                "type": "box",
                "layout": "vertical",
                "spacing": "sm",
                "contents": [
                {
                    "type": "box",
                    "layout": "baseline",
                    "contents": [
                    {
                        "type": "icon",
                        "url": "https://scdn.line-apps.com/n/channel_devcenter/img/fx/restaurant_regular_32.png"
                    },
                    {
                        "type": "text",
                        "text": "$10.5",
                        "weight": "bold",
                        "margin": "sm",
                        "flex": 0
                    },
                    {
                        "type": "text",
                        "text": "400kcl",
                        "size": "sm",
                        "align": "end",
                        "color": "#aaaaaa"
                    }
                    ]
                }
                ]
            },
            {
                "type": "text",
                "text": "Sauce, Onions, Pickles, Lettuce & Cheese",
                "wrap": true,
                "color": "#aaaaaa",
                "size": "xxs"
            }
            ]
        },
        "footer": {
            "type": "box",
            "layout": "vertical",
            "contents": [
            {
                "type": "spacer",
                "size": "xxl"
            },
            {
                "type": "button",
                "style": "primary",
                "color": "#905c44",
                "action": {
                    "type": "message",
                    "label": "Order",
                    "text": "CM01_001"
                }
            }
            ]
        }
    }
}

次に、メニューを選択した時に、注文メニューと受け取りQRコードを表示させます。
先ほどと同じ要領で、 Ticket タイプを作成していきます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
{
    "type": "flex",
    "altText": "#",
    "contents": {
        "type": "bubble",
        "hero": {
            "type": "image",
            "size": "full",
            "aspectRatio": "20:13",
            "aspectMode": "cover",
            "action": {
                "type": "uri",
                "label": "#",
                "uri": "https://classmethod.jp/"
            }
        },
        "body": {
            "type": "box",
            "layout": "vertical",
            "spacing": "md",
            "contents": [
            {
                "type": "text",
                "text": "Hamburger",
                "wrap": true,
                "weight": "bold",
                "gravity": "center",
                "size": "xl"
            },
            {
                "type": "box",
                "layout": "vertical",
                "margin": "xxl",
                "contents": [
                {
                    "type": "spacer",
                    "size": "lg"
                },
                {
                    "type": "image",
                    "aspectMode": "cover",
                    "size": "xl"
                },
                {
                    "type": "text",
                    "text": "You can pick up your order by using this code instead of a ticket.",
                    "color": "#aaaaaa",
                    "wrap": true,
                    "margin": "xxl",
                    "size": "xs"
                }
                ]
            }
            ]
        }
    }
}

これで、対話フローに必要なもののうち Flex Message に関わる部分が完了しました。
最後に全体のつなぎの部分を実装していきます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
var channelAccessToken = 'XXXXXXXXXXX';
var response = { statusCode: 200 };
const line = require('@line/bot-sdk');
const client = new line.Client({channelAccessToken: channelAccessToken});
 
exports.handler = async (event) => {
    console.log(JSON.stringify(event));
    let body = JSON.parse(event.body);
    if (body.events[0].message.text == 'メニューを教えて') {
        var message = {
            "type": "flex",
            "altText": "#",
            "contents": {
              "type": "bubble",
              "hero": {
                "type": "image",
                "url": "https://s3-ap-northeast-1.amazonaws.com/xxxxxxx/hamburger.jpg",
                "size": "full",
                "aspectRatio": "20:13",
                "aspectMode": "cover",
                "action": {
                  "type": "uri",
                  "uri": "https://classmethod.jp/"
                }
              },
              "body": {
                "type": "box",
                "layout": "vertical",
                "spacing": "md",
                "action": {
                  "type": "uri",
                  "uri": "https://classmethod.jp/"
                },
                "contents": [
                  {
                    "type": "text",
                    "text": "Hamburger",
                    "size": "xl",
                    "weight": "bold"
                  },
                  {
                    "type": "box",
                    "layout": "vertical",
                    "spacing": "sm",
                    "contents": [
                      {
                        "type": "box",
                        "layout": "baseline",
                        "contents": [
                          {
                            "type": "icon",
                            "url": "https://scdn.line-apps.com/n/channel_devcenter/img/fx/restaurant_regular_32.png"
                          },
                          {
                            "type": "text",
                            "text": "$10.5",
                            "weight": "bold",
                            "margin": "sm",
                            "flex": 0
                          },
                          {
                            "type": "text",
                            "text": "400kcl",
                            "size": "sm",
                            "align": "end",
                            "color": "#aaaaaa"
                          }
                        ]
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "text": "Sauce, Onions, Pickles, Lettuce & Cheese",
                    "wrap": true,
                    "color": "#aaaaaa",
                    "size": "xxs"
                  }
                ]
              },
              "footer": {
                "type": "box",
                "layout": "vertical",
                "contents": [
                  {
                    "type": "spacer",
                    "size": "xxl"
                  },
                  {
                    "type": "button",
                    "style": "primary",
                    "color": "#905c44",
                    "action": {
                      "type": "message",
                      "label": "Order",
                      "text": "CM01_001"
                    }
                  }
                ]
              }
            }
        }
      } else if (body.events[0].message.text == 'CM01_001') { // hamburger
        var message = {
          "type": "flex",
          "altText": "#",
          "contents": {
              "type": "bubble",
              "hero": {
                  "type": "image",
                  "url": "https://s3-ap-northeast-1.amazonaws.com/xxxxxxx/hamburger.jpg",
                  "size": "full",
                  "aspectRatio": "20:13",
                  "aspectMode": "cover",
                  "action": {
                      "type": "uri",
                      "label": "#",
                      "uri": "https://classmethod.jp/"
                  }
              },
              "body": {
                  "type": "box",
                  "layout": "vertical",
                  "spacing": "md",
                  "contents": [
                  {
                      "type": "text",
                      "text": "Hamburger",
                      "wrap": true,
                      "weight": "bold",
                      "gravity": "center",
                      "size": "xl"
                  },
                  {
                      "type": "box",
                      "layout": "vertical",
                      "margin": "xxl",
                      "contents": [
                      {
                          "type": "spacer",
                          "size": "lg"
                      },
                      {
                          "type": "image",
                          "url": "https://scdn.line-apps.com/n/channel_devcenter/img/fx/linecorp_code_withborder.png",
                          "aspectMode": "cover",
                          "size": "xl"
                      },
                      {
                          "type": "text",
                          "text": "You can pick up your order by using this code instead of a ticket.",
                          "color": "#aaaaaa",
                          "wrap": true,
                          "margin": "xxl",
                          "size": "xs"
                      }
                      ]
                  }
                  ]
              }
          }
      };
    } else {
        var message = {
            'type': 'text',
            'text': 'こんにちは。\n\nメニューを知りたい場合は、「メニューを教えて」と送信してください。'
        };
    }
    await client.replyMessage(body.events[0].replyToken, message);
    return response;
};

テスト

実際に対話フロー通りにできているかテストしてみます。

まとめ

いかがでしたでしょうか。
より自由になったメッセージで企業とユーザーのコミュニケーションの幅が広がっていくでしょう。
今後 Flex Message オブジェクトの細かい部分を解説していきます。

新メンバーズ