はじめに
色々なページを参考に、テキストをオウム返しするLINEbotを作成しました。
次のステップとして、公式ドキュメントを参考にボタンテンプレートを返そうと思いましたがイメージが掴めなかったので、とりあえず作るかの精神で色々試した結果うまくいったので、参考になればと思い記事にしました。
完成イメージ
下の画像のような感じで、にゃーんと言うとボタンテンプレートが送られてくるようにします。
また、画像上の「URIアクションのLABEL」部分をタップすると、指定のURLを開くようにします。
ちなみにその前のにゃーんの連打は、失敗したやつです。悪しからず。
前提条件
すでにMessaging APIを利用して、オウム返しができる状態から解説を始めます。
0から始める場合は下記記事などを参考にしてください。
LINE Messaging API を使ってLINEにメッセージ送信/メッセージ返信する
PythonでLine botを作ってみた
Python初心者がたったの3日間でチャットボットを作った【0日目】
FlaskでLINE botを実装し,herokuにdeployするまで
line-bot-sdk-python(こちらのコードを元にオウム返し版を作成しました)
私はPython3+Flask+Herokuで作りました。
追加コード
準備として、from linebot.models import()
の中にTemplateSendMessage,ButtonsTemplate,URIAction
を追加してください。
from linebot.models import (
MessageEvent, TextMessage, TextSendMessage,
TemplateSendMessage,ButtonsTemplate,URIAction #こ↑こ↓が追加分
)
今回は分かりやすくするため、関数として定義します。
下記コードを@app.route("/")
の上あたりに記載します。
(記事の最後にコード全文がありますので、どこかよく分からない場合は参考にしてください)
def make_button_template():
message_template = TemplateSendMessage(
alt_text="にゃーん",
template=ButtonsTemplate(
text="どこに表示されるかな?",
title="タイトルですよ",
image_size="cover",
thumbnail_image_url="https://任意の画像URL.jpg",
actions=[
URIAction(
uri="https://任意のページURL",
label="URIアクションのLABEL"
)
]
)
)
return message_template
各パラメーターの詳しい解説は、下記を参照してください。
ボタンテンプレート
次に、@handler.add(MessageEvent, message=(TextMessage))
を下記のように変更します。
@handler.add(MessageEvent, message=(TextMessage))
def handle_image_message(event):
messages = make_button_template()
line_bot_api.reply_message(
event.reply_token,
messages
)
簡単な解説
def make_button_template():
にて、テンプレートメッセージ(今回はボタンテンプレート)を作成します。
そしてaction
のところでURIActionを使用して、表示したいURLとタップする箇所のラベル文字を指定します。
あとはline_bot_api.reply_message
の部分で、作成したテンプレートメッセージを送信してもらいます。
完成!
にゃーんとメッセージを送信すると、下記のようにボタンテンプレートが返ってきます。
(今回はオウム返しの延長として作っているので、テキストならなんでも返ってきますが)
↓「URIアクションのLABEL」部分をタップすると
指定したURLに飛びます。
今回はテスト用に私の写真ブログの画像とURLを使用しました。
応用
例えばこのコードを基に、title
やthumbnail_image_url
なんかをベタ書きではなく、ブログやニュースサイトなんかをスクレイピングしてランダムに送信するとか、送信したメッセージによって取ってくる記事のジャンル(野球、サッカーみたいな感じ)を指定したりとかすると、発想次第では面白いLINEbotができそうですね。
LINEbotを作るのに参考にした中では、下記のbotが個人的に面白かったです。
[筋トレ] LINE Notifyからマッチョの画像が送られてくる
毎朝大相撲力士の画像を送ってくれるLINE BOTを作った
困ったところ(2020.04.22追記)
チャネルアクセストークンがない
1年ぶりくらいに触ったらチャネルアクセストークンがなくて焦りましたが、
「Messaging API設定」タブの一番下にあります。
古い記事だと更新されていないので、チャネル基本設定を穴があくほど見がちですが、場所を移動しただけでした。
メッセージが返ってこない
試してみて欲しいこととしては、
- 「Webhook設定」-「検証」をクリックする
「成功」または「Webhookが無効なHTTPステータスコードを返しました(期待されるステータスコードは200です)」が出れば、ひとまずMessaging APIの設定は問題ないと思われます。
ダメな場合は、
- チャネルアクセストークンを再発行する
- Herokuの環境設定でアクセストークンを再設定する
- Herokuを再起動する
heroku restart
これで解決したことがありました。
「メッセージありがとうございます!」+おうむ返しが返ってくる
- 「Messaging API設定」タブ-「あいさつメッセージ」の編集をクリックする
- 「応答設定」-「詳細設定」-「応答メッセージ」をオフにする
ところで「応答メッセージ」の編集と「あいさつメッセージ」の編集が結局同じページに行くのは何故なんだぜ?
#おわりに
近々これを応用したLINEbotを作成する予定です。お楽しみに。
分かりづらい所や誤りがあればコメントください。
#コード全体
サンプルコードを開く
from flask import Flask, request, abort
from linebot import (
LineBotApi, WebhookHandler
)
from linebot.exceptions import (
InvalidSignatureError
)
from linebot.models import (
MessageEvent, TextMessage, TextSendMessage,
TemplateSendMessage,ButtonsTemplate,URIAction
)
import os
app = Flask(__name__)
#環境変数取得
YOUR_CHANNEL_ACCESS_TOKEN = os.environ["YOUR_CHANNEL_ACCESS_TOKEN"]
YOUR_CHANNEL_SECRET = os.environ["YOUR_CHANNEL_SECRET"]
line_bot_api = LineBotApi(YOUR_CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(YOUR_CHANNEL_SECRET)
def make_button_template():
message_template = TemplateSendMessage(
alt_text="にゃーん",
template=ButtonsTemplate(
text="どこに表示されるかな?",
title="タイトルですよ",
image_size="cover",
thumbnail_image_url="https://example.com/gazou.jpg",
actions=[
URIAction(
uri="https://example.com",
label="URIアクションのLABEL"
)
]
)
)
return message_template
@app.route("/")
def hello_world():
return "hello world!"
@app.route("/callback", methods=['POST'])
def callback():
# get X-Line-Signature header value
signature = request.headers['X-Line-Signature']
# get request body as text
body = request.get_data(as_text=True)
app.logger.info("Request body: " + body)
# handle webhook body
try:
handler.handle(body, signature)
except InvalidSignatureError:
abort(400)
return 'OK'
@handler.add(MessageEvent, message=(TextMessage))
def handle_image_message(event):
messages = make_button_template()
line_bot_api.reply_message(
event.reply_token,
messages
)
if __name__ == "__main__":
# app.run()
port = int(os.getenv("PORT",5000))
app.run(host="0.0.0.0", port=port)