18
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

Organization

LINE BotでFlex Messageを使ってみる(Python編)

目的

LINE Botではただのテキストメッセージだけではなく、Flex Messageというリッチなコンテンツをレスポンスとして返せるようになっています。
image.png
こんな感じのやつです。

Pythonでこれを実現している記事が少なかったので自分なりのメモがてら書いてみます。

やったこと

LINE BOTを用意する

こちらは今度別記事で書こうと思います。
登録後、発行される「ACCESS_TOKEN」をメモしておきましょう。コード内で使います。

Pythonコードを用意する

まずは、モジュールをインストールします。

pip install line-bot-sdk

これでとりあえずインストールは完了です。

次に、コードを解説していきます。

コード序盤部分(importなど事前準備)

push.py
#linebotapiのインポート
from linebot import LineBotApi
from linebot.models import TextSendMessage,  FlexSendMessage

#LineBotApiインスタンスの生成
#これ以降、line_bot_apiオブジェクト内のメソッドを呼び出すことで、メッセージの送信が可能になります
line_bot_api = LineBotApi('LINE Developersページで発行されたACCESS_TOKEN')

Flex Messageの準備

Botが返すFlex MessageはJSON形式で記述するのですが、あまりにも複雑で自力で書くのはおすすめしません。公式にLine Bot Designerというデスクトップアプリケーションが用意されているので、これを利用するのが楽です。

アプリケーションをインストール後、起動するとログインを求められるので、ここは自分のLINEアカウントでログインしてください。
その後、こんな画面が出ますので「プロジェクトを作成」ボタンをクリックします。
image.png
「プロジェクトの設定」ウィンドウが開きますが、適当で構いません。

するとこんな画面が開きますが、この画面では様々なメッセージやリッチメニュー、Flex MessageをGUI上で生成することができます。(なにげにエミュレータもついててすごい・・・)
image.png

さて、今回のターゲットは「Flex Message」なので、左側の3つのアイコンのうち真ん中のアイコンをクリックします。
image.png

試しに、バブルメッセージを作ってみます。
「バブルメッセージ」の横の+ボタンをクリックすると、こんな感じになります。
image.png

適当にテンプレートを選んでみます。今回はレストランにしてみました。
勝手に、このようにJSONが生成されるのでこれをコピーしておきます。これがプレビュー部分に表示されているFlex Messageを実現するためのJSONになります。
image.png

コード中盤部分

適当な変数を作り、先程コピーしておいたJSONコードを代入します。
ここで注意点です。真偽値の部分が「true」と書かれており、JavaScript等であればそのままで良いのでしょうけど、Pythonでは真偽値は「True/False」と大文字で始まるため、そこだけ書き換える必要があります。
エディタの置換機能などを使って書き換えてしまうと良いでしょう。

push.py
payload = {
  "type": "flex",
  "altText": "Flex Message",
  "contents": {
    "type": "bubble",
    "hero": {
      "type": "image",
      "url": "https://scdn.line-apps.com/n/channel_devcenter/img/fx/01_1_cafe.png",
      "size": "full",
      "aspectRatio": "20:13",
      "aspectMode": "cover",
      "action": {
        "type": "uri",
        "label": "Line",
        "uri": "https://linecorp.com/"
      }
    },
    "body": {
      "type": "box",
      "layout": "vertical",
      "contents": [
        {
          "type": "text",
          "text": "Brown Cafe",
          "size": "xl",
          "weight": "bold"
        },
        {
          "type": "box",
          "layout": "baseline",
          "margin": "md",
          "contents": [
            {
              "type": "icon",
              "url": "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png",
              "size": "sm"
            },
            {
              "type": "icon",
              "url": "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png",
              "size": "sm"
            },
            {
              "type": "icon",
              "url": "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png",
              "size": "sm"
            },
            {
              "type": "icon",
              "url": "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png",
              "size": "sm"
            },
            {
              "type": "icon",
              "url": "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gray_star_28.png",
              "size": "sm"
            },
            {
              "type": "text",
              "text": "4.0",
              "flex": 0,
              "margin": "md",
              "size": "sm",
              "color": "#999999"
            }
          ]
        },
        {
          "type": "box",
          "layout": "vertical",
          "spacing": "sm",
          "margin": "lg",
          "contents": [
            {
              "type": "box",
              "layout": "baseline",
              "spacing": "sm",
              "contents": [
                {
                  "type": "text",
                  "text": "Place",
                  "flex": 1,
                  "size": "sm",
                  "color": "#AAAAAA"
                },
                {
                  "type": "text",
                  "text": "Miraina Tower, 4-1-6 Shinjuku, Tokyo",
                  "flex": 5,
                  "size": "sm",
                  "color": "#666666",
                  "wrap": True
                }
              ]
            },
            {
              "type": "box",
              "layout": "baseline",
              "spacing": "sm",
              "contents": [
                {
                  "type": "text",
                  "text": "Time",
                  "flex": 1,
                  "size": "sm",
                  "color": "#AAAAAA"
                },
                {
                  "type": "text",
                  "text": "10:00 - 23:00",
                  "flex": 5,
                  "size": "sm",
                  "color": "#666666",
                  "wrap": True
                }
              ]
            }
          ]
        }
      ]
    },
    "footer": {
      "type": "box",
      "layout": "vertical",
      "flex": 0,
      "spacing": "sm",
      "contents": [
        {
          "type": "button",
          "action": {
            "type": "uri",
            "label": "CALL",
            "uri": "https://linecorp.com"
          },
          "height": "sm",
          "style": "link"
        },
        {
          "type": "button",
          "action": {
            "type": "uri",
            "label": "WEBSITE",
            "uri": "https://linecorp.com"
          },
          "height": "sm",
          "style": "link"
        },
        {
          "type": "spacer",
          "size": "sm"
        }
      ]
    }
  }
}

これでJSONコードが出来上がりました。

コード終盤部分(メッセージの送信)

今回は、pushでメッセージを送ってみました。
line_bot_api.push_message()メソッドを使っていますが、メッセージへの応答にするためには
line_bot_api.reply_message()メソッドを使えばOKです。
reply_message()の引数は、REPLY_TOKEN(LINE Developersで発行可能)とメッセージオブジェクト(下のコードだとcontainer_obj変数)になります。

push.py
#new_from_json_dictメソッドはJSONデータをFlexMessage等各種オブジェクトに変換してくれるメソッドです
#FlexSendMessage.new_from_json_dict(対象のJSONデータ)とすることで、
#FlexSendMessage型に変換されます
container_obj = FlexSendMessage.new_from_json_dict(payload)

#最後に、push_messageメソッドを使ってPUSH送信する
line_bot_api.push_message('送りたい相手のUserID', messages=container_obj)

まとめ

というわけで、下記コードが完成品になります。

push.py
from linebot import LineBotApi
from linebot.models import TextSendMessage,  FlexSendMessage

line_bot_api = LineBotApi('発行されたCHANNEL_ACCESS_TOKEN')

payload = {
  "type": "flex",
  "altText": "Flex Message",
  "contents": {
    "type": "bubble",
    "hero": {
      "type": "image",
      "url": "https://scdn.line-apps.com/n/channel_devcenter/img/fx/01_1_cafe.png",
      "size": "full",
      "aspectRatio": "20:13",
      "aspectMode": "cover",
      "action": {
        "type": "uri",
        "label": "Line",
        "uri": "https://linecorp.com/"
      }
    },
    "body": {
      "type": "box",
      "layout": "vertical",
      "contents": [
        {
          "type": "text",
          "text": "Brown Cafe",
          "size": "xl",
          "weight": "bold"
        },
        {
          "type": "box",
          "layout": "baseline",
          "margin": "md",
          "contents": [
            {
              "type": "icon",
              "url": "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png",
              "size": "sm"
            },
            {
              "type": "icon",
              "url": "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png",
              "size": "sm"
            },
            {
              "type": "icon",
              "url": "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png",
              "size": "sm"
            },
            {
              "type": "icon",
              "url": "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png",
              "size": "sm"
            },
            {
              "type": "icon",
              "url": "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gray_star_28.png",
              "size": "sm"
            },
            {
              "type": "text",
              "text": "4.0",
              "flex": 0,
              "margin": "md",
              "size": "sm",
              "color": "#999999"
            }
          ]
        },
        {
          "type": "box",
          "layout": "vertical",
          "spacing": "sm",
          "margin": "lg",
          "contents": [
            {
              "type": "box",
              "layout": "baseline",
              "spacing": "sm",
              "contents": [
                {
                  "type": "text",
                  "text": "Place",
                  "flex": 1,
                  "size": "sm",
                  "color": "#AAAAAA"
                },
                {
                  "type": "text",
                  "text": "Miraina Tower, 4-1-6 Shinjuku, Tokyo",
                  "flex": 5,
                  "size": "sm",
                  "color": "#666666",
                  "wrap": True
                }
              ]
            },
            {
              "type": "box",
              "layout": "baseline",
              "spacing": "sm",
              "contents": [
                {
                  "type": "text",
                  "text": "Time",
                  "flex": 1,
                  "size": "sm",
                  "color": "#AAAAAA"
                },
                {
                  "type": "text",
                  "text": "10:00 - 23:00",
                  "flex": 5,
                  "size": "sm",
                  "color": "#666666",
                  "wrap": True
                }
              ]
            }
          ]
        }
      ]
    },
    "footer": {
      "type": "box",
      "layout": "vertical",
      "flex": 0,
      "spacing": "sm",
      "contents": [
        {
          "type": "button",
          "action": {
            "type": "uri",
            "label": "CALL",
            "uri": "https://linecorp.com"
          },
          "height": "sm",
          "style": "link"
        },
        {
          "type": "button",
          "action": {
            "type": "uri",
            "label": "WEBSITE",
            "uri": "https://linecorp.com"
          },
          "height": "sm",
          "style": "link"
        },
        {
          "type": "spacer",
          "size": "sm"
        }
      ]
    }
  }
}

container_obj = FlexSendMessage.new_from_json_dict(payload)

line_bot_api.push_message('送りたい相手のUserID', messages=container_obj)

上記コードを実行したところ、無事送られてきたのが確認できました。
image.png

というわけで以上です。
何か不明点あればコメント頂けると嬉しいです!

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
18
Help us understand the problem. What are the problem?