無事作成することができました。 ご丁寧にご教示いただきありがとうございました。
- 1
flex_message_json_string の中身のJSON文字列の中身が間違っているかと思います.
# type = flex
{
"type": "flex",
"altText": "Flex Message",
"contents": {
"type": "bubble",
"direction": "ltr",
...
ではなく,
# type = bubble or carousel
{
"type": "bubble",
"direction": "ltr",
...
}
で flex_message_json_string を初期化するようにしてください,
また, FlexSendMessage(alt_text="hoge", contents=flex_message_json_dict)
が, メッセージ送信時にどのようなJSONになっているかは
print( FlexSendMessage(alt_text="hoge", contents=flex_message_json_dict) )
すれば確認できます.(TextSendMessageなど他のクラスでも同様に確認できます)
※それと, JSON文字列のダブルクオーテーションもお忘れなく.
- 0
ご回答ありがとうございます。 試しに
main.py
from flask import Flask, request, abort
import os
import json
from linebot import (
LineBotApi, WebhookHandler
)
from linebot.exceptions import (
InvalidSignatureError
)
from linebot.models import (
MessageEvent, TextMessage, TextSendMessage,
SourceUser, SourceGroup, SourceRoom,
TemplateSendMessage, ConfirmTemplate, MessageAction,
ButtonsTemplate, ImageCarouselTemplate, ImageCarouselColumn, URIAction,
PostbackAction, DatetimePickerAction,
CameraAction, CameraRollAction, LocationAction,
CarouselTemplate, CarouselColumn, PostbackEvent,
StickerMessage, StickerSendMessage, LocationMessage, LocationSendMessage,
ImageMessage, VideoMessage, AudioMessage, FileMessage,
UnfollowEvent, FollowEvent, JoinEvent, LeaveEvent, BeaconEvent,
MemberJoinedEvent, MemberLeftEvent,
FlexSendMessage, BubbleContainer, ImageComponent, BoxComponent,
TextComponent, SpacerComponent, IconComponent, ButtonComponent,
SeparatorComponent, QuickReply, QuickReplyButton,
ImageSendMessage)
app = Flask(__name__)
flex_message_json_string="""
{
type: flex,
altText: Flex Message,
contents: {
type: bubble,
direction: ltr,
header: {
type: box,
layout: vertical,
contents: [
{
type: text,
text: ,
align: center
}
]
},
hero: {
type: image,
url: https://images-na.ssl-images-amazon.com/images/I/81dkWPlc-AL._SX522_.jpg,
size: full,
aspectRatio: 1.51:1,
aspectMode: fit
},
footer: {
type: box,
layout: horizontal,
contents: [
{
type: button,
action: {
type: uri,
label: 購入,
uri: https://www.amazon.co.jp/天然水-【Amazon-co-jp-限定】サントリー-南アルプスの天然水-2L×9本/dp/B07F1CCSJZ/ref=sr_1_1_sspa?__mk_ja_JP=カタカナ&keywords=水&qid=1563628084&s=gateway&sr=8-1-spons&psc=1
}
}
]
}
}
}
"""
flex_message_json_dict = json.loads(flex_message_json_string)
#環境変数取得
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)
@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_message(event):
line_bot_api.reply_message(
event.reply_token,
FlexSendMessage(
alt_text=alt_text,
contents=flex_message_json_dict
)
)
if __name__ == __main__:
# app.run()
port = int(os.getenv(PORT))
app.run(host=0.0.0.0, port=port)
を作成してみたのですが
2019-07-31T15:26:22.885896+00:00 app[web.1]: File "main.py", line 98, in callback 2019-07-31T15:26:22.885899+00:00 app[web.1]: handler.handle(body, signature) 2019-07-31T15:26:22.885901+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/linebot/webhook.py", line 260, in handle 2019-07-31T15:26:22.885904+00:00 app[web.1]: func(event) 2019-07-31T15:26:22.885906+00:00 app[web.1]: File "main.py", line 110, in handle_message 2019-07-31T15:26:22.885908+00:00 app[web.1]: contents=flex_message_json_dict 2019-07-31T15:26:22.885911+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/linebot/api.py", line 101, in reply_message 2019-07-31T15:26:22.885913+00:00 app[web.1]: '/v2/bot/message/reply', data=json.dumps(data), timeout=timeout 2019-07-31T15:26:22.885918+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/linebot/api.py", line 903, in _post 2019-07-31T15:26:22.885920+00:00 app[web.1]: self.__check_error(response) 2019-07-31T15:26:22.885922+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/linebot/api.py", line 926, in __check_error 2019-07-31T15:26:22.885924+00:00 app[web.1]: raise LineBotApiError(response.status_code, error) 2019-07-31T15:26:22.885927+00:00 app[web.1]: linebot.exceptions.LineBotApiError: LineBotApiError: status_code=400, error_response={"details": [{"message": "May not be empty", "property": "messages[0].contents"}], "message": "The request body has 1 error(s)"}
と言ったエラーになってしまい 色々試したのですが解決できず もう一度お力添えいただければ幸いです よろしくお願いいたします。
- 0
実は,line-bot-sdk-python は dict(辞書)
をメッセージの中身として送信できます.
なので下のように,送信したいJSON文字列を json.loads
で dict
に変換して,FlexSendMessage.contents
に渡せば,Flex Message Simulator で作成したJSONをそのまま使えます.
import json
# 送信したいJSON文字列
flex_message_json_string="""
{
"type": "bubble",
"hero": ...,
...
"""
# JSON文字列をdict型に変換
flex_message_json_dict = json.loads(flex_message_json_string)
line_bot_api.reply_message(
event.reply_token,
FlexSendMessage(
alt_text='alt_text',
# contentsパラメタに, dict型の値を渡す
contents=flex_message_json_dict
)
)
不明点あれば,お気軽に返信ください.
- 1