LINE botのカルーセル形式のレスポンスが返せない(Python+Lambda+API Gateway)
Q&A
Closed
解決したいこと
- 料理レシピをカルーセル形式のレスポンスで返すLINE Botを実装しています。
- その前にオウム返しのbotを作成し、問題なくテキスト形式でのレスポンスはできました。
- 「line-bot-sdk」の公式GitHubに記載のあるカルーセル形式で実装をしていますが、レスポンスが返りません。
- 解決方法を教えて下さい。
問題のコード
コメントアウトしている箇所が、実装してレスポンスが返らない部分です。
lambda_function.py
# -----------------line-bot-sdkで使用するライブラリのインポート-----------------
from asyncio.log import logger
from flask import Flask, request, abort
from linebot import (LineBotApi, WebhookHandler)
from linebot.models import (MessageEvent, TextMessage, TextSendMessage, CarouselColumn, CarouselTemplate, LocationMessage, TemplateSendMessage, URITemplateAction, FlexSendMessage)
from linebot.exceptions import (InvalidSignatureError, LineBotApiError)
# -----------------環境変数を参照するためのライブラリのインポート-----------------
import os
import urllib.request
import json
import logging
import sys
import requests
from bs4 import BeautifulSoup
# -----------------フレームワークにFlaskを使用-----------------
app = Flask(__name__)
logger = logging.getLogger()
logger.setLevel(logging.ERROR)
CHANNEL_ACCESS_TOKEN = os.getenv('LINE_CHANNEL_ACCESS_TOKEN', None)
LINE_CHANNEL_SECRET = os.getenv('LINE_CHANNEL_SECRET', None)
if LINE_CHANNEL_SECRET is None:
logger.error('Specify LINE_CHANNEL_SECRET as environment variable.')
sys.exit(1)
if CHANNEL_ACCESS_TOKEN is None:
logger.error('Specify LINE_CHANNEL_ACCESS_TOKEN as environment variable.')
sys.exit(1)
line_bot_api = LineBotApi(CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(LINE_CHANNEL_SECRET)
def lambda_handler(event, context):
if "x-line-signature" in event["headers"]:
signature = event["headers"]["x-line-signature"]
elif "X-Line-Signature" in event["headers"]:
signature = event["headers"]["X-Line-Signature"]
body = event["body"]
ok_json = {"isBase64Encoded": False,
"statusCode": 200,
"headers": {},
"body": ""}
error_json = {"isBase64Encoded": False,
"statusCode": 500,
"headers": {},
"body": "Error"}
@handler.add(MessageEvent, message=TextMessage)
def message(line_event):
# # LINEから入力されたテキスト
text = line_event.message.text
# # 料理リスト
# menu = []
# # クラシルで検索
# url = 'https://www.kurashiru.com/search?query=' + text
# # 検索結果取得
# r = requests.get(url)
# soup = BeautifulSoup(r.text, 'html.parser')
# # レシピタイトル
# title = soup.find_all(class_="DlyLink title")
# # レシピ画像
# image = soup.find_all(class_="DlyImg-img")
# # レシピ内容
# description = soup.find_all(class_="video-list-introduction")
# # 5つのレシピを料理リストに追加
# i = 0
# for each in title[:]:
# titleUrl = title[i].get('href')
# result_menu = {
# "thumbnail_image_url" : image[i].get('src'),
# "title" : title[i].get_text(),
# "text" : description[i].get_text().strip('¥n'),
# "actions" : {
# "type" : "uri",
# "label" : "料理を見る",
# "uri" : "https://www.kurashiru.com" + titleUrl
# }
# }
# menu.append(result_menu)
# i += 1
# # カルーセルに渡す形に変換
# columns = [
# CarouselColumn(
# thumbnail_image_url = column["thumbnail_image_url"],
# title = column["title"],
# text = column["text"],
# actions = [
# URITemplateAction(
# label = column["actions"]["label"],
# uri = column["actions"]["uri"],
# )
# ]
# )
# for column in menu
# ]
# # メッセージ作成
# messages = TemplateSendMessage(
# alt_text="オススメのメニューを紹介します。",
# template=CarouselTemplate(columns=columns),
# )
# line_bot_api.reply_message(event.reply_token, TemplateSendMessage(messages=messages))
try:
handler.handle(body, signature)
except LineBotApiError as e:
logger.error("Got exception from LINE Messaging API: %s\n" % e.message)
for m in e.error.details:
logger.error(" %s: %s" % (m.property, m.message))
return error_json
except InvalidSignatureError:
return error_json
return ok_json
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
「memu」の中身
type(menu)
>>list
[{'actions': {'label': '料理を見る',
'type': 'uri',
'uri': 'https://www.kurashiru.com/recipes/edf70dec-925c-468d-ae4e-4495c3adea71'},
'text': '\n 可愛い!簡単!美味しい!バラのアップルパイの紹介です。たくさ...\n ',
'thumbnail_image_url': 'https://video.kurashiru.com/production/videos/edf70dec-925c-468d-ae4e-4495c3adea71/compressed_thumbnail_square_normal.jpg?1639367889',
'title': '\n 可愛い!材料5つでバラのアップルパイ\n '},
# ---中略---
{'actions': {'label': '料理を見る',
'type': 'uri',
'uri': 'https://www.kurashiru.com/recipes/4c7c5209-5581-4275-baa5-97980c32c3a2'},
'text': '\n ハッセルバックのアップルケーキでおやつはいかがでしょうか。\r...\n ',
'thumbnail_image_url': 'https://video.kurashiru.com/production/videos/4c7c5209-5581-4275-baa5-97980c32c3a2/compressed_thumbnail_square_normal.jpg?1639367889',
'title': '\n 切って乗せるだけ ハッセルバックアップ...\n '}]
「columns」の中身
type(columns)
>>list
[{"actions": [{"label": "\u6599\u7406\u3092\u898b\u308b", "type": "uri", "uri": "https://www.kurashiru.com/recipes/edf70dec-925c-468d-ae4e-4495c3adea71"}], "text": "\n \u53ef\u611b\u3044\uff01\u7c21\u5358\uff01\u7f8e\u5473\u3057\u3044\uff01\u30d0\u30e9\u306e\u30a2\u30c3\u30d7\u30eb\u30d1\u30a4\u306e\u7d39\u4ecb\u3067\u3059\u3002\u305f\u304f\u3055...\n ", "thumbnailImageUrl": "https://video.kurashiru.com/production/videos/edf70dec-925c-468d-ae4e-4495c3adea71/compressed_thumbnail_square_normal.jpg?1639367889", "title": "\n \u53ef\u611b\u3044\uff01\u6750\u65995\u3064\u3067\u30d0\u30e9\u306e\u30a2\u30c3\u30d7\u30eb\u30d1\u30a4\n "},
{"actions": [{"label": "\u6599\u7406\u3092\u898b\u308b", "type": "uri", "uri": "https://www.kurashiru.com/recipes/203d96c1-4816-42f1-b966-61e27d59fc78"}], "text": "\n \u308a\u3093\u3054\u3092\u706b\u3067\u7092\u3081\u308b\u624b\u9593\u3082\u7121\u304f\u3001\u30d1\u30a4\u30b7\u30fc\u30c8\u3067\u98fe\u308b\u624b\u9593\u3082\u306a\u3044\u306e\u306b...\n ", "thumbnailImageUrl": "https://video.kurashiru.com/production/videos/203d96c1-4816-42f1-b966-61e27d59fc78/compressed_thumbnail_square_normal.jpg?1639367889", "title": "\n \u51b7\u51cd\u30d1\u30a4\u30b7\u30fc\u30c8\u3092\u4f7f\u3063\u3066\u7c21\u5358\uff01\u30d0\u30e9\u306e\u3088\u3046...\n "},
{"actions": [{"label": "\u6599\u7406\u3092\u898b\u308b", "type": "uri", "uri": "https://www.kurashiru.com/recipes/8ec96aba-61d6-4bf9-aae1-2afd006c9584"}], "text": "\n \u30b5\u30af\u30b5\u30af\u3068\u3057\u305f\u98df\u611f\u304c\u305f\u307e\u3089\u306a\u3044\u3001\u624b\u4f5c\u308a\u30a2\u30c3\u30d7\u30eb\u30d1\u30a4\u306f\u3044\u304b\u304c\u3067...\n ", "thumbnailImageUrl": "https://video.kurashiru.com/production/videos/8ec96aba-61d6-4bf9-aae1-2afd006c9584/compressed_thumbnail_square_normal.jpg?1639367889", "title": "\n \u7c21\u5358\u30b5\u30af\u30b5\u30af\u4e09\u89d2\u30a2\u30c3\u30d7\u30eb\u30d1\u30a4\n "},
{"actions": [{"label": "\u6599\u7406\u3092\u898b\u308b", "type": "uri", "uri": "https://www.kurashiru.com/recipes/47f5a9fc-c5f6-44bd-ba84-7116ae74a873"}], "text": "\n \u30d5\u30ec\u30c3\u30b7\u30e5\u306a\u308a\u3093\u3054\u304c\u305f\u3063\u3077\u308a\u3001\u30af\u30ea\u30fc\u30e0\u30c1\u30fc\u30ba\u5165\u308a\u30d1\u30a6\u30f3\u30c9\u30b1\u30fc...\n ", "thumbnailImageUrl": "https://video.kurashiru.com/production/videos/47f5a9fc-c5f6-44bd-ba84-7116ae74a873/compressed_thumbnail_square_normal.jpg?1639367889", "title": "\n HM\u3067\u7c21\u5358 \u308a\u3093\u3054\u3068\u30af\u30ea\u30fc\u30e0\u30c1\u30fc\u30ba\u306e\u30d1...\n "},
{"actions": [{"label": "\u6599\u7406\u3092\u898b\u308b", "type": "uri", "uri": "https://www.kurashiru.com/recipes/4c7c5209-5581-4275-baa5-97980c32c3a2"}], "text": "\n \u30cf\u30c3\u30bb\u30eb\u30d0\u30c3\u30af\u306e\u30a2\u30c3\u30d7\u30eb\u30b1\u30fc\u30ad\u3067\u304a\u3084\u3064\u306f\u3044\u304b\u304c\u3067\u3057\u3087\u3046\u304b\u3002\r...\n ", "thumbnailImageUrl": "https://video.kurashiru.com/production/videos/4c7c5209-5581-4275-baa5-97980c32c3a2/compressed_thumbnail_square_normal.jpg?1639367889", "title": "\n \u5207\u3063\u3066\u4e57\u305b\u308b\u3060\u3051 \u30cf\u30c3\u30bb\u30eb\u30d0\u30c3\u30af\u30a2\u30c3\u30d7...\n "}]
「messages」の中身
messages = TemplateSendMessage(
alt_text="オススメのメニューを紹介します。",
template=CarouselTemplate(columns=columns),
)
type(messages)
>>linebot.models.template.TemplateSendMessage
Google Colaboratoryで挙動を確認しながら実装したところ、上記のように問題なく処理ができています。
公式リファレンスとGitHubの通りに実装していますが、レスポンスが返りません。
次のコード以降から問題があると考えています。
該当するソースコード?
lambda_function.py
line_bot_api.reply_message(event.reply_token, messages=messages)
自分で試したこと
- Lambda関数のレスポンスをjson形式にしようとして、FlexSendMessageを使用してjson形式のままレスポンスするよう記述もしましたが同様にレスポンスが返りませんでした。
- Lambdaのレスポンス形式に合ってないわけではないような気がします。
- オウム返しは前段でできているので、AWSサービスの権限の問題でもなさそうです。
三日くらいこの状態が続いているので、助けを求めています。
どうかよろしくお願いします。
0