PHPでLINE Flex Messageを作ってみる

LINEで写真や画像を使ってかっこよく送信ボタンがあるメッセージを送りたい！ 
ということでFlex Messageをphpで作成してみました。  
## Flex Messageとは
LINEのMessaging API機能を使うとLINE公式アカウントと対話するユーザーに対してメッセージを送ることができます。  
Flex Messageという種類のメッセージを使うと、自由なレイアウトでメッセージを作成することができます。
使わないとただのテキストメッセージになっちゃいます。

## Flex Messageの作り方
  - デザイン作成
    まずシュミレーターを使ってメッセージのデザインを決めます。 
    LINEが用意しているシュミレーターを使うとデザインを簡単に作成することができます。
    ありがたい！
    
  Flex Message Simulator 
  https://account.line.biz/login?scope=line&redirectUri=https%3A%2F%2Fdevelopers.line.biz%2Fflex-simulator%2F
  ![flexMessageSimulator.6fa91ae3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685449/ac09ca12-b6de-2bb3-d007-657a879280d4.png)

  - 要素の種類  
      Flex Messageはコンテナ、ブロック（ヘッダー、ヒーロー、ボディ、フッター）、コンポーネントの3層のデータから構成されます。それぞれ細かく設定することができます。  
![overviewSample.772a618f.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685449/bcee899b-0fd9-fba8-3bd1-5b650b23e6d6.png)


## 準備するもの
LINE公式のPHP版のSDKをインストールしておく 
https://github.com/line/line-bot-sdk-php


## 活用例
- FlexMessageを作成して送信する関数

```
    public function sendGroupCvMessage(array $data) : LINEBot\Response
    {
        $flexMessageParams = $this->getFlexMessageParams($data);
        $flexMessage = $this->makeFlexMessage($data, $flexMessageParams);
        $flexMessageBuilder = new FlexMessageBuilder('反響が来ました！', $flexMessage);
        $response = $this->bot->pushMessage($data['groupId'], $flexMessageBuilder);

        return $response;
    }
```  
  
- 各パーツの呼び出し元関数

```
   public function makeFlexMessage(array $data, array $flexMessageParams) : BubbleContainerBuilder
    {
        $headerComponentBuilder = $this->buildHeader();
        $imageComponentBuilder = $this->buildImage($flexMessageParams);
        $bodyComponentBuilder = $this->buildTotitateInfoMessage($data['inquiryId'], $flexMessageParams);
        $footerSpacerComponentBuilder = $this->buildFooter();
        $footerButtonComponentBuilder = $this->buildSendButton($data['inquiryId'], $flexMessageParams);
        $containerBuilder = $this->buildContainer($imageComponentBuilder, $bodyComponentBuilder, $footerSpacerComponentBuilder, $footerButtonComponentBuilder);

        return $containerBuilder;
    }
```

- ヘッダー作成関数

```
    public function buildHeader()
    {
        $headerComponentBuilder = new TextComponentBuilder('タイトル');

        return $headerComponentBuilder;
    }
```   
- 画像作成関数

```
    public function buildImage(array $flexMessageParams)
    {
        $image = config('custom.imageUrl') . $flexMessageParams['image'];
        $imageComponentBuilder = new ImageComponentBuilder($image);
        $imageComponentBuilder->setSize('full');
        $imageComponentBuilder->setAspectRatio('5:1');

        return $imageComponentBuilder;
    }
```
- メッセージ作成関数

```
    public function buildTotitateInfoMessage(int $inquiryId, array $flexMessageParams)
    {
        $body = new TextComponentBuilder($flexMessageParams['title']);
        $body->setWrap(true);
        $body->setSize('sm');
        $body->setWeight('bold');
        $results[] = $body;

        return $results;
    }
```     
- ボタン要素作成関数

```
    public function buildSendButton(int $inquiryId, array $flexMessageParams)
    {
        $footerButtonComponentBuilder = new ButtonComponentBuilder(
            new UriTemplateActionBuilder(
                '案件詳細を見る',
                config('custom.baseUrl') . '/index/detail/' . $inquiryId . '/?openExternalBrowser=1'
            ),
            2,
            ComponentMargin::XS,
            ComponentButtonHeight::MD,
            ComponentButtonStyle::PRIMARY,
            $flexMessageParams['buttonColor'],
            ComponentGravity::TOP
        );

        return $footerButtonComponentBuilder;
    }
``` 
- フッター作成関数

```
    public function buildFooter()
    {
        $footerSpacerComponentBuilder = new SpacerComponentBuilder('md');

        return $footerSpacerComponentBuilder;
    }

    public function buildContainer(ImageComponentBuilder $imageComponentBuilder, array $bodyComponentBuilder, SpacerComponentBuilder $footerSpacerComponentBuilder, ButtonComponentBuilder $footerButtonComponentBuilder)
    {
        $containerBuilder = new BubbleContainerBuilder(
            ContainerDirection::LTR,
            null,
            $imageComponentBuilder,
            new BoxComponentBuilder(ComponentLayout::VERTICAL, $bodyComponentBuilder),
            new BoxComponentBuilder(ComponentLayout::VERTICAL, [$footerSpacerComponentBuilder, $footerButtonComponentBuilder]),
            BubbleStylesBuilder::builder()->setBody(new BlockStyleBuilder(null, false, '#000000'))
        );

        return $containerBuilder;
    }
 ```

## 作ってみた感想

 Flex Messageは自由に細かくカスタマイズできるので、設計したままのメッセージを作成できます。
 最初コンポーネントの概念がいまいちわからなくて手こずりましたが、シュミレーターで確認しながら作成すると、かなりハードルが下がります。
一回仕組みが分かってしまうといろいろ活用したくなりました。 作成してて楽しかったのでよかったよかった。