[LINE] 最新の Flex Message を試してみた

# Flex Message

Flex Message の機能が新規追加されたので、色々試してみることにした。
下記に「curlのサンプル」と「トークルームで表示される画像」を添付しておくので参考にして欲しい。

詳しい概要説明は、LINE公式のリファレンス参照
https://developers.line.me/ja/reference/messaging-api/

# PushMessage の messageObject の構成

* 全体構成を簡単にまとめておく。

# バブルコンテナの構成

```
- to
- message = messageObject (テンプレートメッセージ (カルーセルで使用) or Flex Message など..)
              - type (flex)
              - altText (代替テキスト)
              - contents = Flex Messageのコンテナオブジェクト (バブルコンテナ)
                              - type = bubble
                              - header = ボックスコンポーネント
                              - hero = 画像コンポーネント
                              - body = ボックスコンポーネント
                              - footer = ボックスコンポーネント
                              - direction = テキストの書字方向および水平ボックス内のコンポーネントの並び順
                              - styles = バブルスタイルオブジェクト
                                            - header = ブロックスタイル
                                            - hero = ブロックスタイル
                                            - body = ブロックスタイル
                                            - footer = ブロックスタイル
                                                        - backgroundColor
                                                        - separator 
                                                        - separatorColor
```

# バブルコンテナのSAMPLE

百聞は一見に如かずという事で、まずサンプル (バブルコンテナとカルーセルコンテナ) をお見せする。
コンテナの構成する要素の説明については、後ほど説明していきます。

```
curl -X POST -H 'Content-Type:application/json' -H 'Authorization: Bearer {トークン}' -d '
{
    "messages": [
        {  
        "type": "flex",
        "altText": "this is a flex message",
        "contents": {
          "type": "bubble",
          "header": {
            "type": "box",
            "layout": "vertical",
            "contents": [
              {
                "type": "text",
                "text": "Header text"
              }
            ]
          },
          "hero": {
            "type": "image",
            "url": "https://www.sample.jpg"
          },
          "body": {
            "type": "box",
            "layout": "vertical",
            "contents": [
              {
                "type": "text",
                "text": "hello"
              },
              {
                "type": "text",
                "text": "world"
              }
            ]
          },
          "footer": {
            "type": "box",
            "layout": "vertical",
            "contents": [
              {
                "type": "text",
                "text": "Footer text"
              }
            ]
          },
          "styles": {
             "header": {
               "backgroundColor": "#00ffff"
             },
             "hero": {
               "separator": true,
               "separatorColor": "#000000"
             },
             "footer": {
               "backgroundColor": "#00ffff",
               "separator": true,
               "separatorColor": "#000000"
             }
           }
        }
      }
    ],
    "to": "LINE UserID"
}' \https://api.line.me/v2/bot/message/push
```

<img width="749" alt="スクリーンショット 2018-07-11 午後1.20.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/102862/afa398b3-667a-4950-5a1b-309461ebfb4f.png">

# カルーセルコンテナの構成
* type = carousel になっている
* バブル数は、最大10個までとなっている
* バブルコンテナにボディブロックがある場合は、そのバブルコンテナがカルーセルで最大の高さを持つバブルコンテナと同じ高さになるように、ボディブロックが伸長します。 (※リファレンス引用)

 ```
- to
- message = メッセージオブジェクト (テンプレートメッセージ or Flex Message etc..)
              - type (flex)
              - altText (代替テキスト)
              - contents = Flex Messageのコンテナオブジェクト (カルーセル)
                              - type = carousel
                              - contents = [バブルコンテナ1, バブルコンテナ2, バブルコンテナ3] // 最大バブル数：10
```

# カルーセルコンテナのSAMPLE

```
curl -X POST -H 'Content-Type:application/json' -H 'Authorization: Bearer {トークン}' -d '{
    "messages": [
        {  
        "type": "flex",
        "altText": "this is a flex message",
        "contents": {
          "type": "carousel",
          "contents": [
          {
            "type": "bubble",
            "header": {
              "type": "box",
              "layout": "vertical",
              "contents": [
                {
                  "type": "text",
                  "text": "Header text"
                }
              ]
            },
            "hero": {
              "type": "image",
              "url": "https://example.com/flex/images/image.jpg"
            },
            "body": {
              "type": "box",
              "layout": "vertical",
              "contents": [
                {
                  "type": "text",
                  "text": "hello"
                },
                {
                  "type": "text",
                  "text": "world"
                }
              ]
            },
            "footer": {
              "type": "box",
              "layout": "vertical",
              "contents": [
                {
                  "type": "text",
                  "text": "Footer text"
                }
              ]
            },
            "styles": {
               "header": {
                 "backgroundColor": "#00ffff"
               },
               "hero": {
                 "separator": true,
                 "separatorColor": "#000000"
               },
               "footer": {
                 "backgroundColor": "#00ffff",
                 "separator": true,
                 "separatorColor": "#000000"
               }
             }
          },
            {
              "type": "bubble",
              "body": {
                "type": "box",
                "layout": "vertical",
                "contents": [
                  {
                    "type": "text",
                    "text": "Second bubble"
                  }
                ]
              }
            }
          ]
        }
      }
    ],
    "to": "LINE UserID"
}' \https://api.line.me/v2/bot/message/push

```

<img width="749" alt="スクリーンショット 2018-07-11 午後1.21.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/102862/46584414-7891-bbf8-3cf9-5b96c6ebbe90.png">

# バブルコンテナ を構成する要素の説明

```
バブルコンテナ = 
      - type = bubble
      - direction = テキストの書字方向および水平ボックス内のコンポーネントの並び順
      - header = ボックスコンポーネント
      - hero = 画像コンポーネント
      - body = ボックスコンポーネント
      - footer = ボックスコンポーネント
      - styles = バブルスタイルオブジェクト
```

## directionについて
* 指定可能な値
 * 1.  ltr
 * 2.  rtl

#### direction = ltr

* left to right に配置する

```
curl -X POST -H 'Content-Type:application/json' -H 'Authorization: Bearer {トークン}' -d '
{
    "messages": [
        {  
        "type": "flex",
        "altText": "this is a flex message",
        "contents": {
          "type": "bubble",
          "direction": "ltr",
          "hero": {
                    "type": "image",
                    "url": "https://www.sample.jpg",
                    "size": "full"
                  },
          "body": {
            "type": "box",
            "layout": "vertical",
            "contents": [
              {
                "type": "text",
                "text": "hello"
              },
              {
                "type": "text",
                "text": "world"
              }
            ]
          }
        }
      }
    ],
    "to": "LINE UserID"
}' \https://api.line.me/v2/bot/message/push
```

<img width="533" alt="スクリーンショット 2018-07-11 午後1.26.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/102862/62778be0-992f-e826-119a-ce8e5b41bb7a.png">

#### direction = rtl

* right to left に配置する

```
curl -X POST -H 'Content-Type:application/json' -H 'Authorization: Bearer {トークン}' -d '
{
    "messages": [
        {  
        "type": "flex",
        "altText": "this is a flex message",
        "contents": {
          "type": "bubble",
          "direction": "ltr",
          "hero": {
                    "type": "image",
                    "url": "https://www.sample.jpg",
                    "size": "full"
                  },
          "body": {
            "type": "box",
            "layout": "vertical",
            "contents": [
              {
                "type": "text",
                "text": "hello"
              },
              {
                "type": "text",
                "text": "world"
              }
            ]
          }
        }
      }
    ],
    "to": "LINE UserID"
}' \https://api.line.me/v2/bot/message/push
```

<img width="533" alt="スクリーンショット 2018-07-11 午後1.23.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/102862/f503f6ad-3e46-e198-d9ec-cb4f2a07b4c3.png">

## コンポーネントについて
バブルコンテナを構成するオブジェクト(要素) のこと

## コンポーネントの種類

1.  ボックス
* ボタン
* フィラー
* アイコン
* 画像
* セパレータ
* スペーサー
* テキスト
 
## ボックスコンポーネントとは
子要素のレイアウトを定義するコンポーネントです。ボックスにボックスを含めることもできます。

```
ボックスコンポーネント = 
  - type =  box (固定)
  - layout =  vertical / horizon / baseline
  - contents = [コンポーネント1, コンポーネント2]
  - mergin
  - spacing
  - flex
```

## layout の種類
1.  horizontal (水平配置)
*  vertical (垂直配置)
* baseline (水平配置)

## layout の仕様
* horizontal / vertical の場合：ボックス、ボタン、フィラー、画像、セパレータ、およびテキストコンポーネント
* baselineの場合：フィラー、アイコン、およびテキストコンポーネント


#  vertical

```
curl -X POST -H 'Content-Type:application/json' -H 'Authorization: Bearer {トークン}' -d '
{
    "messages": [
        {  
        "type": "flex",
        "altText": "this is a flex message",
        "contents": {
          "type": "bubble",
          "direction": "rtl",
          "hero": {
                    "type": "image",
                    "url": "https://www.sample.jpg",
                    "size": "full"
                  },
          "body": {
            "type": "box",
            "layout": "vertical",
            "contents": [
              {
                "type": "text",
                "text": "hello"
              },
              {
                "type": "text",
                "text": "world"
              }
            ]
          }
        }
      }
    ],
    "to": "LINE UserID"
}' \https://api.line.me/v2/bot/message/push
```

<img width="533" alt="スクリーンショット 2018-07-11 午後1.26.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/102862/89508775-9bc1-dbcc-3730-27e141bb8867.png">

#  horizon

```
curl -X POST -H 'Content-Type:application/json' -H 'Authorization: Bearer {トークン}' -d '
{
    "messages": [
        {
        "type": "flex",
        "altText": "this is a flex message",
        "contents": {
          "type": "bubble",
          "direction": "ltr",
          "hero": {
                    "type": "image",
                    "url": "https://www.sample.jpg",
                    "size": "full"
                  },
          "body": {
            "type": "box",
            "layout": "horizontal",
            "contents": [
              {
                "type": "text",
                "text": "hello"
              },
              {
                "type": "text",
                "text": "world"
              }
            ]
          }
        }
      }
    ],
    "to": "LINE UserID"
}' \https://api.line.me/v2/bot/message/push

```

<img width="535" alt="スクリーンショット 2018-07-11 午後1.26.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/102862/f18d1c8f-70d5-f1e2-6b17-5d8629fa39d0.png">


## ボタンコンポーネントとは

ボタンを描画するコンポーネントです。ユーザーがタップすると、指定したアクションが実行されます。

```
ボタンコンポーネント = 
  - type =  button (固定)
  - action =  アクションオブジェクト (uri / postback / message/ 日時選択)
  - color 
  - height
  - mergin
```

### SAMPLE

```
curl -X POST -H 'Content-Type:application/json' -H 'Authorization: Bearer {トークン}' -d '
{
    "messages": [
        {  
        "type": "flex",
        "altText": "this is a flex message",
        "contents": {
          "type": "bubble",
          "direction": "ltr",
          "hero": {
                    "type": "image",
                    "url": "https://rs-j.adtdp.com/line-dev/10/carousel_image/pixta_29373431_M.jpg",
                    "size": "full"
                  },
          "body": {
            "type": "box",
            "layout": "vertical",
            "contents": [
              {
                "type": "text",
                "text": "hello"
              },
              {
                "type": "text",
                "text": "world"
              },
              {
              "type": "button",
              "action": {
                "type": "uri",
                "label": "Tap me",
                "uri": "https://example.com"
              },
              "style": "primary",
              "color": "#0000ff"
            }
            ]
          }
        }
      }
    ],
    "to": "LINE UserID"
}' \https://api.line.me/v2/bot/message/push
```

<img width="529" alt="スクリーンショット 2018-07-11 午後1.27.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/102862/ce39d91f-4e86-e7dd-ea61-d80a6dc6cc45.png">

## アイコンコンポーネントとは

アイコンを描画するコンポーネントです。

```
アイコンコンポーネント = 
  - type =  icon (固定)
  - url =  画像url (最大画像サイズ：240×240px)
  - size 
  - mergin
```

```
curl -X POST -H 'Content-Type:application/json' -H 'Authorization: Bearer {トークン}' -d '
{
    "messages": [
        {  
        "type": "flex",
        "altText": "this is a flex message",
        "contents": {
          "type": "bubble",
          "body": {
            "type": "box",
            "layout": "baseline",
            "contents": [
            {
              "type": "icon",
              "url": "https://sample.jpg",
              "size": "lg"
            },
            {
              "type": "icon",
              "url": "https://sample.jpg",
              "size": "lg"
            }
            ]
          }
        }
      }
    ],
    "to": "LINE UserID"
}' \https://api.line.me/v2/bot/message/push
```

<img width="532" alt="スクリーンショット 2018-07-11 午後1.27.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/102862/ec53598b-3922-4293-44a2-2a46120b0c26.png">

## セパレータコンポーネントとは

親ボックス内のコンポーネントの間に境界線を描画するコンポーネントです。

```
セパレータコンポーネント = 
  - type =  separator (固定)
  - margin
  - color
```

## SAMPLE

```
curl -X POST -H 'Content-Type:application/json' -H 'Authorization: Bearer {トークン}' -d '{
    "messages": [
        {  
        "type": "flex",
        "altText": "this is a flex message",
        "contents": {
          "type": "carousel",
          "contents": [
          {
            "type": "bubble",
            "header": {
              "type": "box",
              "layout": "vertical",
              "contents": [
                {
                  "type": "text",
                  "text": "Header text"
                }
              ]
            },
            "hero": {
              "type": "image",
              "url": "https://example.com/flex/images/image.jpg"
            },
            "body": {
              "type": "box",
              "layout": "vertical",
              "contents": [
                {
                  "type": "text",
                  "text": "hello"
                },
                {
                  "type": "separator",
                  "color": "#000000"
                },
                {
                  "type": "text",
                  "text": "world"
                }
              ]
            },
            "footer": {
              "type": "box",
              "layout": "vertical",
              "contents": [
                {
                  "type": "text",
                  "text": "Footer text"
                }
              ]
            },
            "styles": {
               "header": {
                 "backgroundColor": "#00ffff"
               },
               "hero": {
                 "separator": true,
                 "separatorColor": "#000000"
               },
               "footer": {
                 "backgroundColor": "#00ffff",
                 "separator": true,
                 "separatorColor": "#000000"
               }
             }
          },
            {
              "type": "bubble",
              "body": {
                "type": "box",
                "layout": "vertical",
                "contents": [
                  {
                    "type": "text",
                    "text": "Second bubble"
                  }
                ]
              }
            }
          ]
        }
      }
    ],
    "to": "LINE UserID"
}' \https://api.line.me/v2/bot/message/push
```

<img width="532" alt="スクリーンショット 2018-07-11 午後1.28.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/102862/c4a27c13-a1b3-b0ce-cdec-02aed01b04e7.png">


## スペーサーコンポーネントとは

ボックス内の先頭または末尾に固定サイズのスペースを配置する不可視のコンポーネントです

```
スペーサーコンポーネント = 
  - type =  spacer (固定)
  - size = xs / sm / md / lg / xx / xxl
```

# SAMPLE

```
curl -X POST -H 'Content-Type:application/json' -H 'Authorization: Bearer {トークン' -d '{
    "messages": [
        {  
        "type": "flex",
        "altText": "this is a flex message",
        "contents": {
          "type": "carousel",
          "contents": [
          {
            "type": "bubble",
            "header": {
              "type": "box",
              "layout": "vertical",
              "contents": [
                {
                  "type": "text",
                  "text": "Header text"
                }
              ]
            },
            "hero": {
              "type": "image",
              "url": "https://example.com/flex/images/image.jpg"
            },
            "body": {
              "type": "box",
              "layout": "vertical",
              "contents": [
                {
                  "type": "text",
                  "text": "hello"
                },
                {
                  "type": "separator",
                  "color": "#000000"
                },
                {
                  "type": "text",
                  "text": "world"
                },
                {
                  "type": "spacer",
                  "size": "xxl"
                }
              ]
            },
            "footer": {
              "type": "box",
              "layout": "vertical",
              "contents": [
                {
                  "type": "text",
                  "text": "Footer text"
                }
              ]
            },
            "styles": {
               "header": {
                 "backgroundColor": "#00ffff"
               },
               "hero": {
                 "separator": true,
                 "separatorColor": "#000000"
               },
               "footer": {
                 "backgroundColor": "#00ffff",
                 "separator": true,
                 "separatorColor": "#000000"
               }
             }
          },
            {
              "type": "bubble",
              "body": {
                "type": "box",
                "layout": "vertical",
                "contents": [
                  {
                    "type": "text",
                    "text": "Second bubble"
                  }
                ]
              }
            }
          ]
        }
      }
    ],
    "to": "LINE UserID"
}' \https://api.line.me/v2/bot/message/push
```

### スペーサー無

<img width="531" alt="スクリーンショット 2018-07-11 午後1.28.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/102862/87aae55d-6a1f-3a14-1f07-ec00fb43c530.png">

### スペーサー有

<img width="529" alt="スクリーンショット 2018-07-11 午後1.29.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/102862/f8afd906-0c28-28c0-09bd-00e0ea49dc20.png">

# 注意事項

*  multi castで Flex Messageは送信できません。