def handle_follow(event): print(event.source.user_id) template = template_env.get_template('welcome_message.json') data = template.render() data = eval(data) flex_message = FlexSendMessage(alt_text='下次產檢注意事項',contents=BubbleContainer.new_from_json_dict(data)) line_bot_api.reply_message(event.reply_token, flex_message)
def ci_post(): data = request.json drone_repo_name = data[ "drone_repo_name"] if "drone_repo_name" in data else "-" drone_commit_branch = data[ "drone_commit_branch"] if "drone_commit_branch" in data else "-" drone_commit_author = data[ "drone_commit_author"] if "drone_commit_author" in data else "-" drone_commit_message = data[ "drone_commit_message"] if "drone_commit_message" in data else "-" drone_build_event = data[ "drone_build_event"] if "drone_build_event" in data else "-" drone_build_status = data[ "drone_commit_status"] if "drone_commit_status" in data else "-" drone_commit_link = data[ "drone_commit_link"] if "drone_commit_link" in data else "-" build_status_color = "#33aa55" if drone_build_status.lower( ) == "success" else "#cc3d33" ci_build_number = data[ "ci_build_number"] if "ci_build_number" in data else "-" template = template_env.get_template(FLEX_JSON_FP) rendered_template = template.render( build_status_color=build_status_color, drone_repo_name=drone_repo_name, drone_commit_branch=drone_commit_branch, drone_commit_author=drone_commit_author, drone_commit_message=drone_commit_message, drone_build_event=drone_build_event, drone_build_status=drone_build_status, drone_commit_link=drone_commit_link, ci_build_number=ci_build_number, ) dict_template = eval(rendered_template) print("[DEBUG][dict_template]", dict_template) ### Random Pick PR Reviewer if pr and build success collection = MongoClient( env["mongo"]["url"])[env["mongo"]["db"]][env["mongo"]["collection"]] repo = collection.find_one({"repo_name": drone_repo_name}) users = list(repo["users"]) group_id = [(item["name"], item["group_id"]) for item in env["projects"] if item["name"] == drone_repo_name][0][1] flex_message = FlexSendMessage( alt_text="{} repo 有最新更動!".format(drone_repo_name), contents=BubbleContainer.new_from_json_dict(dict_template)) messages = list() if drone_build_event == "pull_request" and drone_build_status == "success": try: text_message = TextMessage(text="請 *{}* 負責審 PR !".format( random.choice(users)["user_name"])) except: text_message = TextMessage(text="孤單寂寞,沒有人關心我,嗚...") messages.append(text_message) messages.append(flex_message) line_bot_api.push_message(group_id, messages) return 'OK'
def handle_follow(event): r.set(event.source.user_id, "01") line_bot_api.link_rich_menu_to_user( event.source.user_id, "richmenu-4318d8c8dba62fc14de3fced2943e413") json = { "type": "bubble", "hero": { "type": "image", "url": request.url_root.replace("http://", "https://") + "/imgs/mercari_info.png", "size": "full", "aspectRatio": "8:4", "aspectMode": "cover", }, "body": { "type": "box", "layout": "vertical", "contents": [{ "type": "text", "text": "友達追加ありがとう!画像を送るとメルカリの出品用に「専用」「送料込み」等のテキストを追加するBotだよ。\n\n気に入ったら友達にもオススメしてね!", "weight": "bold", "size": "md", "wrap": True, }], }, "footer": { "type": "box", "layout": "vertical", "spacing": "sm", "contents": [{ "type": "button", "style": "primary", "height": "sm", "action": { "type": "uri", "label": "画像を選択", "uri": "line://nv/cameraRoll/multi", }, }], "flex": 0, }, } line_bot_api.reply_message( event.reply_token, [ FlexSendMessage(alt_text="代替テキスト", contents=BubbleContainer.new_from_json_dict(json)) ], )
def show_menu_handler(group_id): print("[DEBUG] use show_menu_handler") template = template_env.get_template(PROJECTS_FLEX_JSON_FP) carousel_list = [] for proj in env["projects"]: if proj["group_id"] == group_id: rendered_template = template.render(project_name=proj["name"]) dict_template = eval(rendered_template) carousel_list.append( BubbleContainer.new_from_json_dict(dict_template)) template_opera = template_env.get_template(PROJECT_OPERA_FLEX_JSON_FP) dict_template_opera = eval(template_opera.render()) carousel_list.append( BubbleContainer.new_from_json_dict(dict_template_opera)) flex_message = FlexSendMessage(alt_text="請選擇專案加入", contents=CarouselContainer(carousel_list)) line_bot_api.push_message(group_id, flex_message)
def get_line_group(dir_name): files = sorted([filename for filename in os.listdir(dir_name)]) col = [] template = template_env.get_template('line_group.json') for file_name in files: print(file_name) with open('%s%s'%(dir_name,file_name)) as f: group = json.load(f) pprint(group) data = template.render(group) data = eval(data) col.append(BubbleContainer.new_from_json_dict(data)) message = FlexSendMessage(alt_text='加入群組', contents=CarouselContainer(contents=col)) return message
def article_fetching(tag): files = [filename for filename in os.listdir('./article/') if filename.startswith(tag)] col = [] template = template_env.get_template('article.json') for file_name in files: print(file_name) with open('article/%s'%(file_name)) as f: article = json.load(f) pprint(article) data = template.render(article) data = eval(data) col.append(BubbleContainer.new_from_json_dict(data)) message = FlexSendMessage(alt_text='推薦文章', contents=CarouselContainer(contents=col)) return message
def response_now(time, date): ss = client.open(Config.SPREADSHEET_NAME) ws = ss.get_worksheet(date.month - 1) threepm = ws.acell('J' + str(date.day + 4)).value sixpm = ws.acell('K' + str(date.day + 4)).value ninepm = ws.acell('L' + str(date.day + 4)).value if not (threepm or sixpm or ninepm): return TextSendMessage(text="No updates have been made today") if threepm: threepm = int(threepm) threepm = str("{:,}".format(threepm)) + "円" current = threepm else: threepm = 'TBA' if sixpm: sixpm = int(sixpm) sixpm = str("{:,}".format(sixpm)) + "円" current = sixpm else: sixpm = 'TBA' if ninepm: ninepm = int(ninepm) ninepm = str("{:,}".format(ninepm)) + "円" current = ninepm else: ninepm = 'TBA' objList = ws.acell('G' + str(date.day + 4)).value pastList = ws.acell('H' + str(date.day + 4)).value objList = objList.replace(',', '') pastList = pastList.replace(',', '') objList = int(objList) pastList = int(pastList) lastYearSales = int(pastList) objective = int(objList) date_o = date.strftime("%A, %B %d %Y") lastYearSales_o = str("{:,}".format(lastYearSales)) + "円" objective_o = str("{:,}".format(objective)) + "円" report = SalesUpdate(time, date_o, lastYearSales_o, objective_o, current, threepm, sixpm, ninepm) template = template_env.get_template('sales-update.json') data = template.render(dict(data=report)) return FlexSendMessage(alt_text="Sales Report " + time, contents=BubbleContainer.new_from_json_dict( json.loads(data)))
def set_reply(cls, cluster_content, user_id, user_refri_dict): def apriori_cal(cluster_content, user_choose, user_refri_dict): ''' :param cluster_number: int :param user_choose: list :param user_refri_dict: dict :return: ''' appointed_output = set(user_choose) my_refrigerator = set(user_refri_dict.keys()) total_i_list = get_total_ingredient_in_recipes( cluster_content, appointed_output) if total_i_list: recommended_fequent_set = get_frequent_set( total_i_list, appointed_output, my_refrigerator) return recommended_fequent_set else: # total_i_list = None 時該做的事 return [] user_choose = cls.user_choose[user_id] recommended_fequent_set = apriori_cal(cluster_content, user_choose, user_refri_dict) set_tmp = copy.deepcopy(cls.set_tmp) if recommended_fequent_set: for idx, per_fre_set in enumerate(recommended_fequent_set): # 調整button數量 if len(recommended_fequent_set) != 5: while len(recommended_fequent_set) != len( set_tmp["footer"]["contents"]): set_tmp["footer"]["contents"].pop() set_tmp["footer"]["contents"][idx]["action"][ "label"] = " ".join(per_fre_set[2]) set_tmp["footer"]["contents"][idx]["action"][ "text"] = " ".join(per_fre_set[2]) set_tmp["footer"]["contents"][idx]["action"][ "data"] += " ".join(per_fre_set[2]) bubbleContainer = BubbleContainer.new_from_json_dict(set_tmp) return FlexSendMessage(alt_text="hello", contents=bubbleContainer) else: print("Empty, delete related selection") cls.user_select_delete(user_id) # 選擇失敗做初始化 return TextSendMessage( text="很抱歉,您所選的食材組合無合適資訊,無法為您推薦\n請透過冰箱重新選擇一次食材組合")
def reply_user(event: MessageEvent, match: Match): user_name = match.group(1) items = qiita.get_user_items(user_name, 3) user = items[0].user template = template_env.get_template('user.json') data = template.render(dict(user=user, items=items)) print(data) line_bot_api.reply_message( event.reply_token, FlexSendMessage(alt_text='user', contents=BubbleContainer.new_from_json_dict( json.loads(data))))
def flex_weather(city): cw = crawler.Weather(city) cw.setData() weather_data = cw.getData() weather_flex_container_json = json.load(open("container/weather.json", 'r', encoding="utf-8")) weather_flex_container_json["header"]["contents"][0]["text"] = weather_data[0] weather_flex_container_json["body"]["contents"][0]["text"] = weather_data[1] weather_flex_container_json["body"]["contents"][1]["text"] = str((int(weather_data[2]) + int(weather_data[3])) // 2) weather_flex_container_json["body"]["contents"][2]["contents"][0]["text"] = '↑' + weather_data[2] weather_flex_container_json["body"]["contents"][2]["contents"][1]["text"] = '↓' + weather_data[3] weather_flex_container_json["body"]["contents"][3]["text"] = '降雨機率: ' + weather_data[3] weather_flex_container_json["footer"]["contents"][0]["text"] = weather_data[4] weather_bubble_container = BubbleContainer.new_from_json_dict(weather_flex_container_json) flex_bubble_send_message = FlexSendMessage(alt_text="Weather", contents=weather_bubble_container) return flex_bubble_send_message
def baby_talk(user_id): current_time = datetime.datetime.now() print(current_time) if user_id in user2baby_dict: update_time = user2baby_dict[user_id] print(update_time) print("timedelta") print((current_time - update_time).total_seconds()) if (current_time - update_time).total_seconds() >= 600: user2baby_dict[user_id] = current_time file = 'baby_week10.json' else: file = 'baby_week10_meaningless.json' else: user2baby_dict[user_id] = current_time file = 'baby_week10.json' template = template_env.get_template(file) data = template.render(hello="yoyo") data = eval(data) flex_message = FlexSendMessage(alt_text='baby_message',contents=BubbleContainer.new_from_json_dict(data)) return flex_message
def reminder(): if not request.content_type == 'application/json': abort(401) data = request.get_json() user_id = data.get('user_id') year = data.get('year') month = data.get('month') date = data.get('date') if not user_id: abort(401) print(user_id) profile = line_bot_api.get_profile(user_id) user_name = profile.display_name #line_bot_api.push_message(user_id, TextSendMessage(text='Hi, %s 媽咪!下次產檢在%s/%s/%s喔~以下為下次產檢的注意事項...bla bla bla' % (user_name, year, month, date))) #line_bot_api.push_message(user_id, TextSendMessage(text=str(user_id))) template = template_env.get_template('reminder.json') data = template.render(year=year, month=month, date=date) data = eval(data) flex_message = FlexSendMessage(alt_text='下次產檢注意事項',contents=BubbleContainer.new_from_json_dict(data)) line_bot_api.push_message(user_id, flex_message) return 'OK'
def callback_from_pay(): transaction_info = pay.confirm(request.args.get('transactionId')) print("trasaction: ", transaction_info) # push message to trasaction_info['user'] userId = transaction_info['user'] profile = line_bot_api.get_profile(userId).display_name # Up to kintone import upKintone price = "1500" syohin = transaction_info["productName"] resp = upKintone.PostToKintone(userId, price, syohin, profile) print(resp.text) with open("recipt.json", "r", encoding="utf-8") as f: json_data = json.load(f) line_bot_api.push_message(userId, [ FlexSendMessage( alt_text="レシート", contents=BubbleContainer.new_from_json_dict(json_data)), StickerSendMessage(package_id=2, sticker_id=41) ]) return render_template('purchased.html', **transaction_info)
def flex_lotto(type): lo = crawler.lotto() lotto_dict = lo.result_all(type) lotto_flex_container_json = json.load(open("container/lotto.json", 'r', encoding="utf-8")) lotto_flex_container_json["header"]["contents"][0]["text"] = lotto_dict["遊戲"] lotto_flex_container_json["body"]["contents"][0]["contents"][1]["text"] = lotto_dict["期別"] if type == 0 or type == 1: pass lotto_flex_container_json["body"]["contents"][2]["contents"][1]["text"] = ' '.join(lotto_dict['本期中獎號碼'][:-1]) lotto_flex_container_json["body"]["contents"][2]["contents"][2]["text"] = lotto_dict['本期中獎號碼'][-1] else: lotto_flex_container_json["body"]["contents"][2]["contents"][1]["text"] = ' '.join(lotto_dict['本期中獎號碼']) lotto_flex_container_json["body"]["contents"][2]["contents"][2]["text"] = ' ' lotto_flex_container_json["body"]["contents"][4]["contents"][1]["text"] = lotto_dict["開獎日期"] lotto_flex_container_json["body"]["contents"][5]["contents"][1]["text"] = lotto_dict["兌獎日期"] lotto_bubble_container = BubbleContainer.new_from_json_dict(lotto_flex_container_json) flex_bubble_send_message = FlexSendMessage(alt_text="Weather", contents=lotto_bubble_container) return flex_bubble_send_message
def get_weather_message(self, weather_data): bubble = { "type": "bubble", "styles": { "body": { "backgroundColor": "#ffffff" } }, "body": { "type": "box", "layout": "vertical", "spacing": "md", "contents": [{ "type": "box", "layout": "vertical", "contents": [{ "type": "box", "layout": "baseline", "spacing": "sm", "contents": [{ "type": "icon", "url": "https://static.thenounproject.com/png/14236-200.png" }, { "type": "text", "text": "{0} {1}".format( weather_data["address"]["formatted"], weather_data["address"]["annotations"] ["flag"]), "size": "sm", "wrap": True }] }, { "type": "text", "text": self.convert_time(weather_data["current"]["ob_time"], weather_data["current"]['timezone'], '%Y-%m-%d %H:%M', '%a, %d %B %H:%M %p %z'), "size": "xxs" }] }, { "type": "box", "layout": "vertical", "margin": "xs", "contents": [{ "type": "text", "text": "{0}º".format(int(weather_data["current"]['temp'])), "size": "5xl", "align": "center", "action": { "type": "postback", "data": "weather_hourly?lat={0}&lng={1}".format( weather_data["address"]["geometry"]["lat"], weather_data["address"]["geometry"]["lng"]) } }, { "type": "text", "text": weather_data["current"]["weather"]["description"], "weight": "bold", "size": "lg", "align": "center" }, { "type": "text", "text": "{0}º / {1}º".format( int(weather_data["daily"][0]["min_temp"]), int(weather_data["daily"][0]["max_temp"])), "size": "sm", "align": "center" }, { "type": "text", "text": "Feels Like: {0}º".format( int(weather_data["current"]["app_temp"])), "size": "xs", "align": "center" }, { "type": "text", "text": "Humidity: {0}%".format(weather_data["current"]["rh"]), "size": "xs", "align": "center" }, { "type": "text", "text": "SunRise/Set: {0} / {1}".format( self.convert_time( weather_data["current"]["sunrise"], weather_data["current"]['timezone'], '%H:%M', '%I:%M %p'), self.convert_time( weather_data["current"]["sunset"], weather_data["current"]['timezone'], '%H:%M', '%I:%M %p')), "size": "xs", "align": "center" }] }, { "type": "separator" }, { "type": "box", "layout": "vertical", "spacing": "xs", "contents": [] }] } } bubble_forecast_contents = bubble["body"]["contents"][3]["contents"] for index in range(1, 6): data = weather_data["daily"][index] bubble_forecast_contents.append({ "type": "box", "layout": "horizontal", "spacing": "xs", "contents": [{ "type": "box", "layout": "vertical", "flex": 4, "contents": [{ "type": "text", "text": self._format_date(data["datetime"]), "size": "xs" }, { "type": "text", "text": data["weather"]["description"], "size": "xxs" }] }, { "type": "image", "url": "https://www.weatherbit.io/static/img/icons/{0}.png". format(data["weather"]["icon"]), "size": "xxs", "flex": 2 }, { "type": "text", "text": "{0}º/{1}º".format(int(data["min_temp"]), int(data["max_temp"])), "size": "sm", "align": "end", "gravity": "center", "flex": 2 }] }) bubble_forecast_contents.append({"type": "separator"}) return BubbleContainer.new_from_json_dict(bubble)
def get_weather_aqi_message(self, weather_aqi_data): data = weather_aqi_data['data'] aqi_last = int(data['aqi']) aqi_level = 1 bg_color = '#FFFF00' aqi_level_text = 'Moderate' msg_text = '' if aqi_last > 0 and aqi_last <= 50: bg_color = '#009966' aqi_level_text = 'Good' aqi_level = 1 text_color = '#ffffff' elif aqi_last > 50 and aqi_last <= 100: bg_color = '#ffde33' aqi_level_text = 'Moderate' aqi_level = 2 text_color = '#000000' elif aqi_last > 100 and aqi_last <= 150: bg_color = '#ff9933' aqi_level_text = 'Unhealthy for Sensitive Groups' aqi_level = 3 text_color = '#000000' elif aqi_last > 150 and aqi_last <= 200: bg_color = '#cc0033' aqi_level_text = 'Unhealthy' aqi_level = 4 text_color = '#ffffff' elif aqi_last > 200 and aqi_last <= 300: bg_color = '#660099' aqi_level_text = 'Very Unhealthy' aqi_level = 5 text_color = '#ffffff' elif aqi_last > 300: bg_color = '#7e0023' aqi_level_text = 'Hazardous' aqi_level = 6 text_color = '#ffffff' bubble = { "type": "bubble", "direction": "ltr", "header": { "type": "box", "layout": "vertical", "contents": [{ "type": "box", "layout": "vertical", "contents": [{ "type": "text", "text": data['city']['name'], "align": "center", "size": "md", "wrap": True, "color": "#ffffff", "action": { "type": "uri", "label": "AQI Description", "uri": data['city']['url'] } }, { "type": "text", "text": data['time']['s'], "size": "xs", "align": "center", "color": "#ffffff", "action": { "type": "uri", "label": "AQI Description", "uri": data['city']['url'] } }, { "type": "text", "text": 'Click me to see more detail', "size": "xs", "align": "center", "color": "#ffffff" }] }] }, "body": { "type": "box", "layout": "vertical", "contents": [{ "type": "box", "layout": "horizontal", "contents": [{ "type": "box", "layout": "vertical", "flex": 1, "contents": [{ "type": "text", "text": "Air Quality Index", "size": "lg", "align": "center", "gravity": "top", "wrap": True, "weight": "bold", "color": text_color }, { "type": "text", "text": str(aqi_last), "size": "5xl", "align": "center", "gravity": "top", "wrap": True, "weight": "bold", "color": text_color }, { "type": "text", "text": aqi_level_text, "size": "lg", "weight": "bold", "wrap": True, "align": "center", "color": text_color }] }] }] }, "footer": { "type": "box", "layout": "vertical", "spacing": "md", "contents": [{ "type": "button", "style": "primary", "action": { "type": "postback", "label": "See Daily Forecast", "data": "aqi_daily?station_id={0}".format(data['idx']), "displayText": "AQI Daily Forecast" } }, { "type": "button", "style": "primary", "action": { "type": "postback", "label": "Cautionary Statement", "data": "aqi_statement?level={0}".format(aqi_level), "displayText": "Cautionary Statement for Air Pollution Level: \"{0}\"" .format(aqi_level_text) } }] }, "styles": { "header": { "backgroundColor": "#000000" }, "body": { "backgroundColor": bg_color } } } flex_message = BubbleContainer.new_from_json_dict(bubble) return FlexSendMessage(alt_text='Air Quality Index', contents=flex_message)
} }""" # In[ ]: #將bubble類型的json 進行轉換變成 Python可理解之類型物件,並將該物件封裝進 Flex Message中 #引用套件 from linebot.models import ( FlexSendMessage, BubbleContainer, ) import json #AWS樣板封裝 bubbleContainer_aws = BubbleContainer.new_from_json_dict( json.loads(flexBubbleContainerJsonString_AWS)) flexBubbleSendMessage_AWS = FlexSendMessage(alt_text="李秉鴻 老師 課程", contents=bubbleContainer_aws) #Linux樣板封裝 bubbleContainer_linux = BubbleContainer.new_from_json_dict( json.loads(flexBubbleContainerJsonString_Linux)) flexBubbleSendMessage_Linux = FlexSendMessage(alt_text="南風及牛鈍 老師 課程", contents=bubbleContainer_linux) #Internet樣板封裝 bubbleContainer_internet = BubbleContainer.new_from_json_dict( json.loads(flexBubbleContainerJsonString_Internet)) flexBubbleSendMessage_Internet = FlexSendMessage( alt_text="Travis 老師 課程", contents=bubbleContainer_internet)
def get_weather_forecast_hourly_data(self, hourly_data, limit=10): date = self._format_date(hourly_data['data'][0]['timestamp_local'], '%Y-%m-%dT%H:%M:%S', '%a, %-d %B %Y') data = hourly_data['data'] bubble = { "type": "bubble", "styles": { "body": { "backgroundColor": "#ffffff" } }, "body": { "type": "box", "layout": "vertical", "spacing": "sm", "contents": [{ "type": "box", "layout": "vertical", "spacing": "md", "contents": [{ "type": "box", "layout": "baseline", "spacing": "sm", "contents": [{ "type": "icon", "url": "https://static.thenounproject.com/png/14236-200.png" }, { "type": "text", "text": "{0}, {1}".format(hourly_data['city_name'], hourly_data['country_code']), "size": "lg" }] }, { "type": "text", "text": date, "size": "xs" }] }, { "type": "box", "layout": "horizontal", "contents": [{ "type": "text", "size": "xxs", "text": "Time", "flex": 8 }, { "type": "text", "size": "xxs", "text": "Temp", "flex": 2 }, { "type": "text", "size": "xxs", "text": "Feels Like", "flex": 3 }] }, { "type": "separator" }, { "type": "box", "layout": "vertical", "spacing": "xs", "contents": [] }] } } bubble_body_contents = bubble['body']['contents'][3]['contents'] for index in range(0, limit): bubble_body_contents.append({ "type": "box", "layout": "horizontal", "contents": [{ "type": "box", "layout": "vertical", "flex": 5, "contents": [{ "type": "text", "size": "xxs", "weight": "bold", "text": self._format_date(data[index]['timestamp_local'], '%Y-%m-%dT%H:%M:%S', '%-I%p') }, { "type": "text", "size": "xxs", "wrap": True, "text": data[index]['weather']['description'] }] }, { "type": "image", "url": "https://www.weatherbit.io/static/img/icons/{0}.png". format(data[index]['weather']['icon']), "size": "xxs", "flex": 3 }, { "type": "text", "size": "xs", "text": "{0}º".format(int(data[index]['temp'])), "gravity": "center", "align": "center", "flex": 2 }, { "type": "text", "size": "xs", "text": "{0}º".format(int(data[index]['app_temp'])), "gravity": "center", "align": "center", "flex": 3 }] }) bubble_body_contents.append({"type": "separator"}) return BubbleContainer.new_from_json_dict(bubble)
def handle_matches_by_team(event): print('handle_matches_by_team') team_id = event.postback.data.split('=')[1] team_fixtures = football_api.get_matches_by_team(team_id, 5) bubble = { "type": "bubble", "styles": { "header": { "backgroundColor": "#007a12" } }, "header": { "type": "box", "layout": "vertical", "contents": [{ "type": "text", "text": "{0} Fixtures".format(team_fixtures['team_name']), "weight": "bold", "wrap": True, "color": "#ffffff", "size": "md", "action": { "type": "postback", "data": "team={0}".format(team_id) } }] }, "body": { "type": "box", "layout": "vertical", "spacing": "md", "contents": [{ "type": "text", "text": "Upcoming Matches", "weight": "bold", "size": "xs", "align": "start" }, { "type": "separator" }] } } bubble_body_contents = bubble['body']['contents'] for match in team_fixtures['matches']: bubble_body_contents.append({ "type": "box", "layout": "horizontal", "spacing": "md", "contents": [{ "type": "text", "text": match['dt'], "wrap": True, "size": "xxs", "flex": 2 }, { "type": "separator" }, { "type": "text", "text": match['opponent_team_name'], "size": "xs", "wrap": True, "flex": 5, "action": { "type": "postback", "data": "matches_by_team={0}".format(match['opponent_team_id']) } }] }) bubble_body_contents.append({"type": "separator"}) bubble_container = BubbleContainer.new_from_json_dict(bubble) line_bot_api.reply_message(event.reply_token, messages=FlexSendMessage( alt_text='Team Fixtures', contents=bubble_container))
def handle_standings(event): print('handle_standings') data = event.postback.data league_name = str(data).split('=')[1] standings_data = football_api.get_standings(league_name) if len(standings_data['teams']) == 0: line_bot_api.reply_message( event.reply_token, messages=TextSendMessage(text='No Standings Data')) return carousel = CarouselContainer() pages = [ standings_data['teams'][i:i + 10] for i in range(0, len(standings_data['teams']), 10) ] for page in pages: bubble = { "type": "bubble", "styles": { "header": { "backgroundColor": fixtures_header_color[league_name] }, "body": { "separator": True } }, "header": { "type": "box", "layout": "vertical", "contents": [{ "type": "text", "text": "{0} - Standings".format( standings_data['competition_name']), "color": "#ffffff" }] }, "body": { "type": "box", "layout": "vertical", "spacing": "sm", "contents": [{ "type": "box", "layout": "horizontal", "contents": [{ "type": "text", "text": "#", "size": "xs", "weight": "bold", "flex": 2 }, { "type": "text", "text": "Team", "size": "xs", "weight": "bold", "flex": 11 }, { "type": "text", "text": "P", "size": "xs", "weight": "bold", "flex": 2 }, { "type": "text", "text": "Pts", "size": "xs", "weight": "bold", "flex": 3 }] }, { "type": "separator" }] } } bubble_body_contents = bubble['body']['contents'] for team in page: bubble_body_contents.append({ "type": "box", "layout": "horizontal", "contents": [{ "type": "text", "text": team['position'], "size": "xxs", "flex": 2 }, { "type": "text", "text": team['team_name'], "size": "xxs", "wrap": True, "flex": 11, "action": { "type": "postback", "data": "team={}".format(team['team_id']) } }, { "type": "text", "text": team['played'], "size": "xxs", "flex": 2 }, { "type": "text", "text": team['pts'], "size": "xxs", "flex": 3 }] }) bubble_container = BubbleContainer.new_from_json_dict(bubble) carousel.contents.append(bubble_container) line_bot_api.reply_message( event.reply_token, FlexSendMessage(alt_text='Standings', contents=carousel))
def generate_test_stat_message(self, data): job_name = data['job_name'] pass_rate_percentage = data['pass_rate_percentage'] last_success_since = data['last_success_since'] stat_images_contents = [] for test_result in data['test_result_history']: image = { "type": "box", "layout": "vertical", "contents": [ { "type": "image", "url": test_result['stat_image'], "size": "xxs", "align": "center" }, { "type": "text", "text": '#{}'.format(test_result['build_no']), "align": "center" } ] } stat_images_contents.append(image) bubble = { "type": "bubble", "styles": { "header": { "backgroundColor": "#367ced" } }, "header": { "type": "box", "layout": "vertical", "contents": [ { "type": "text", "text": "Test Statistic", "weight": "bold", "color": "#ffffff", "size": "md" } ] }, "body": { "type": "box", "layout": "vertical", "contents": [ { "type": "text", "text": job_name, "weight": "bold", "color": "#1b1c1b", "size": "xl" }, { "type": "separator", "margin": "md" }, { "type": "box", "layout": "horizontal", "margin": "md", "contents": [ { "type": "text", "text": "Pass Rate: {}%".format(pass_rate_percentage), "size": "sm", "weight": "bold", "color": "#1b1c1b" } ] }, { "type": "box", "layout": "horizontal", "margin": "md", "contents": [ { "type": "text", "text": "Test Result History:", "size": "sm", "weight": "bold", "color": "#1b1c1b" } ] }, { "type": "box", "layout": "horizontal", "margin": "md", "contents": stat_images_contents }, { "type": "box", "layout": "horizontal", "margin": "md", "contents": [ { "type": "text", "text": "Last Success:", "size": "sm", "weight": "bold", "color": "#1b1c1b", "flex": 4 }, { "type": "text", "text": last_success_since, "wrap": True, "size": "xs", "color": "#1b1c1b", "flex": 6 } ] } ] } } return BubbleContainer.new_from_json_dict(bubble)
def create_flight_route_message(self, data, paging=10): carousel_container = CarouselContainer() pages = [ data['flights'][i:i + paging] for i in range(0, len(data['flights']), paging) ] for page in pages: bubble = { "type": "bubble", "direction": "ltr", "body": { "type": "box", "layout": "vertical", "spacing": "sm", "contents": [{ "type": "box", "layout": "vertical", "contents": [{ "type": "text", "text": data['title'], "size": "sm", "align": "start", "weight": "bold", "color": "#000000" }, { "type": "text", "text": data['description'], "size": "xs", "color": "#929292", "wrap": True }] }, { "type": "separator" }] } } for flight in page: bubble_contents = bubble['body']['contents'].extend(({ "type": "box", "layout": "horizontal", "contents": [{ "type": "box", "layout": "vertical", "flex": 2, "contents": [{ "type": "text", "text": flight['time'], "size": "xs", "gravity": "top", "color": "#000000", "action": { "type": "postback", "label": "flight_info={0}".format(flight['flight_no']), "data": "flight_info={0}".format(flight['flight_no']) } }, { "type": "text", "text": flight['carrier_name'], "size": "xs", "color": "#878787", "wrap": True, "action": { "type": "postback", "label": "flight_info={0}".format(flight['flight_no']), "data": "flight_info={0}".format(flight['flight_no']) } }] }, { "type": "text", "text": flight['flight_no'], "size": "lg", "align": "center", "color": "#269CB0", "align": "center", "gravity": "center", "action": { "type": "postback", "label": "flight_info={0}".format(flight['flight_no']), "data": "flight_info={0}".format(flight['flight_no']) } }] }, { "type": "separator" })) bubble_container = BubbleContainer.new_from_json_dict(bubble) carousel_container.contents.append(bubble) if len(carousel_container.contents) == 7: break return carousel_container
def get_weather_aqi_message_v2(self, weather_aqi_data): data = weather_aqi_data['data'] detail_data = self.get_weather_aqi_forecast(data['idx']) normalized_data = self._normalize_aqi_detail_data_v2(detail_data) normalized_data['idx'] = data['idx'] bubble = { "type": "bubble", "direction": "ltr", "body": { "type": "box", "layout": "vertical", "contents": [{ "type": "box", "layout": "vertical", "spacing": "sm", "contents": [ { "type": "box", "layout": "baseline", "spacing": "sm", "contents": [{ "type": "icon", "url": "https://i.imgur.com/m0st7TA.png", "size": "xs" }, { "type": "text", "text": normalized_data['station_name'], "size": "xs", "color": "#C1C4C5", "wrap": True }] }, { "type": "separator" }, { "type": "box", "layout": "vertical", "contents": [{ "type": "box", "layout": "horizontal", "contents": [{ "type": "image", "url": normalized_data['level']['level_image'], "size": "xs" }, { "type": "text", "text": '{}'.format(normalized_data['aqi']), "size": "4xl", "gravity": "top", "color": normalized_data['level'] ['level_text_color'] }] }, { "type": "text", "text": normalized_data['level']['level_text'], "align": "center", "color": normalized_data['level']['level_text_color'] }, { "type": "text", "text": normalized_data['last_updated'], "size": "xs", "align": "center", "color": "#C1C4C5" }] }, { "type": "separator" }, { "type": "box", "layout": "horizontal", "spacing": "md", "contents": [{ "type": "image", "url": "https://i.imgur.com/bHg8stH.png", "flex": 0, "align": "start", "gravity": "top", "size": "xxs" }, { "type": "box", "layout": "vertical", "contents": [{ "type": "text", "text": "PM 2.5 (Today)", "size": "xs", "align": "start", "color": "#C1C4C5" }, { "type": "text", "text": "{0} ~ {1} μg/m3".format( normalized_data['pm25']['min'], normalized_data['pm25']['max']), "size": "xs", "color": "#C1C4C5" }] }] }, { "type": "separator" }, { "type": "box", "layout": "horizontal", "spacing": "md", "contents": [{ "type": "image", "url": "https://i.imgur.com/8Tb1qXF.png", "flex": 0, "align": "start", "gravity": "top", "size": "xxs" }, { "type": "box", "layout": "vertical", "contents": [{ "type": "text", "text": "Wind Speed", "size": "xs", "align": "start", "color": "#C1C4C5" }, { "type": "text", "text": "{0} m/s".format( normalized_data['wind_speed'] ['current']), "size": "xs", "color": "#C1C4C5" }] }] }, { "type": "separator" }, { "type": "box", "layout": "horizontal", "spacing": "md", "contents": [ { "type": "image", # "url": "https://i.imgur.com/uUQumwh.png", # "url": "https://i.imgur.com/onXsTU2.png", "url": "https://i.imgur.com/p5oOfCK.png", "flex": 0, "align": "start", "gravity": "top", "size": "xxs" }, { "type": "box", "layout": "vertical", "contents": [{ "type": "text", "text": "Outdoor Exertion", "size": "xs", "align": "start", "color": "#C1C4C5" }, { "type": "text", "text": normalized_data['level']['outdoor'] ['text'], "size": "xs", "color": normalized_data['level'] ['level_text_color'], "wrap": True }] } ] }, { "type": "separator" }, { "type": "box", "layout": "horizontal", "spacing": "md", "contents": [{ "type": "image", "url": "https://i.imgur.com/dpE8K8d.png", "flex": 0, "align": "start", "gravity": "top", "size": "xxs" }, { "type": "box", "layout": "vertical", "contents": [{ "type": "text", "text": "Hygienic Mask", "size": "xs", "align": "start", "color": "#C1C4C5" }, { "type": "text", "text": normalized_data['level']['mask']['text'], "size": "xs", "color": normalized_data['level'] ['level_text_color'], "wrap": True }] }] } ] }] }, "footer": { "type": "box", "layout": "horizontal", "contents": [{ "type": "box", "layout": "vertical", "spacing": "md", "contents": [{ "type": "button", "action": { "type": "uri", "label": "More Details", "uri": normalized_data['more_details_link'] }, "color": normalized_data['level']['level_text_color'], "style": "secondary" }, { "type": "button", "action": { "type": "postback", "label": "Daily Forecast", "text": "Daily Forecast", "data": "aqi_daily?station_id={0}".format( normalized_data['idx']) }, "color": normalized_data['level']['level_text_color'], "style": "secondary" }] }] }, "styles": { "body": { "backgroundColor": "#033C5A" }, "footer": { "backgroundColor": "#033C5A" } } } flex_message = BubbleContainer.new_from_json_dict(bubble) return FlexSendMessage(alt_text='Air Quality Index', contents=flex_message)
"flex": 0 } }""" ''' 將bubble類型的json 進行轉換變成 Python可理解之類型物件 將該物件封裝進 Flex Message中 ''' from linebot.models import (FlexSendMessage, BubbleContainer) import json bubbleContainer = BubbleContainer.new_from_json_dict( json.loads(flexBubbleContainerJsonString)) flexBubbleSendMessage = FlexSendMessage(alt_text="hello", contents=bubbleContainer) ''' 設計一個字典 當用戶輸入 [::flex:]carousel ,回傳 旋轉類型的Flex消息 當用戶輸入 [::flex:]bubble , 回傳 泡泡堆疊類型的Flex消息 ''' import json template_message_dict = {"登登登登~~~": flexBubbleSendMessage} '''
def create_flight_message(self, flight_no, adshex, payload): departure_airport = payload['static']['departureApt'] arrival_airport = payload['static']['arrivalApt'] print(json.dumps(payload)) bubble = { "type": "bubble", "direction": "ltr", "header": { "type": "box", "layout": "vertical", "contents": [{ "type": "text", "text": "{0} - {1}".format( flight_no, payload['aircraft']['aircraftOperator']).upper(), "size": "sm", "wrap": True, "align": "center", "weight": "bold", "color": "#383838" }] }, "body": { "type": "box", "layout": "vertical", "contents": [{ "type": "box", "layout": "vertical", "spacing": "md", "contents": [{ "type": "box", "layout": "horizontal", "contents": [{ "type": "box", "layout": "vertical", "flex": 1, "contents": [{ "type": "text", "text": self.get_airport_name_from_code( payload['static']['departureApt'])['city'], "align": "start", "gravity": "top", "wrap": True }, { "type": "text", "text": departure_airport, "size": "xxl", "action": { "type": "postback", "data": "airport={0}".format(departure_airport) } }] }, { "type": "image", "url": "https://i.ibb.co/mvg5f11/travel-icon-38032.png", "size": "xs", "backgroundColor": "#FFFFFF" }, { "type": "box", "layout": "vertical", "contents": [{ "type": "text", "text": self.get_airport_name_from_code( payload['static']['arrivalApt'])['city'], "align": "end", "gravity": "top", "wrap": True }, { "type": "text", "text": arrival_airport, "size": "xxl", "align": "end", "weight": "regular", "wrap": True, "action": { "type": "postback", "data": "airport={0}".format(arrival_airport) } }] }] }, { "type": "separator" }] }] } } if len(payload['photos']) > 0: aircraft_photo_url = payload['photos'][0]['url'] if aircraft_photo_url is not None: bubble['hero'] = { "type": "image", "url": aircraft_photo_url, "size": "full", "aspectRatio": "1.51:1", "aspectMode": "cover" } if payload['status']['depSchdLOC'] is None: flight_schedule = self.get_flight_schedule(flight_no) if flight_schedule is not None: payload['status']['depSchdLOC'] = flight_schedule[ 'departureTime'] payload['status']['depOffset'] = flight_schedule[ 'departureTZOffset'] payload['status']['arrSchdLOC'] = flight_schedule[ 'arrivalTime'] payload['status']['arrOffset'] = flight_schedule[ 'arrivalTZOffset'] next_day = flight_schedule['isNextDay'] if payload['status']['depSchdLOC'] is not None: next_day = False if payload['static']['arrivalDay'] == 'Next day': next_day = True bubble['body']['contents'][0]['contents'].extend(({ "type": "box", "layout": "vertical", "contents": [{ "type": "box", "layout": "horizontal", "contents": [{ "type": "text", "text": "Departure", "flex": 1, "size": "xs" }, { "type": "text", "text": "Arrival", "size": "xs", "align": "end" }] }, { "type": "box", "layout": "horizontal", "contents": [{ "type": "text", "text": self._convert_epoch_to_hm( hmp_format, payload['status']['depSchdLOC'], False), "size": "xs", "weight": "bold" }, { "type": "text", "text": self._convert_epoch_to_hm( hmp_format, payload['status']['arrSchdLOC'], next_day), "size": "xs", "align": "end", "weight": "bold" }] }, { "type": "box", "layout": "horizontal", "contents": [{ "type": "text", "text": 'UTC{0}'.format(payload['status']['depOffset']), "size": "xs" }, { "type": "text", "text": "UTC{0}".format(payload['status']['arrOffset']), "size": "xs", "align": "end" }] }] }, { "type": "separator" })) bubble['body']['contents'][0]['contents'].extend(({ "type": "box", "layout": "horizontal", "contents": [{ "type": "box", "layout": "vertical", "flex": 5, "contents": [{ "type": "text", "text": "Aircraft Type", "size": "xs" }, { "type": "text", "text": "{0} ({1})".format( payload['aircraft']['aircraftFullType'], payload['aircraft']['aircraftAgeString']), "size": "xs", "color": "#545454" }, { "type": "text", "text": "Seats: {0}".format(payload['static']['seats']), "size": "xs", "color": "#545454" }] }] }, { "type": "separator" }, { "type": "box", "layout": "horizontal", "contents": [{ "type": "box", "layout": "vertical", "contents": [{ "type": "text", "text": "Terminal", "size": "xs" }, { "type": "text", "text": payload['status']['departureTerminal'] if payload['status']['departureTerminal'] is not None else "N/A", "size": "xs", "color": "#545454" }] }, { "type": "box", "layout": "vertical", "contents": [{ "type": "text", "text": "Gate", "size": "xs" }, { "type": "text", "text": payload['status']['departureGate'] if payload['status']['departureGate'] is not None else "N/A", "size": "xs", "color": "#545454" }] }, { "type": "box", "layout": "vertical", "contents": [{ "type": "text", "text": "Travel Time", "size": "xs" }, { "type": "text", "text": payload['static']['journeyTime'], "size": "xs", "color": "#545454" }] }] }, { "type": "separator" }, { "type": "box", "layout": "vertical", "contents": [{ "type": "text", "text": "Code Share", "size": "xs" }, { "type": "text", "text": " / ".join(payload['static']['codeshares']) if payload['static']['codeshares'] is not None else 'N/A', "size": "xs", "color": "#545454", "wrap": True }] })) return BubbleContainer.new_from_json_dict(bubble)
def get_news_bubble(self, header_bg_color, data, header_text_color="#ffffff"): bubble = { "type": "bubble", "styles": { "header": { "backgroundColor": header_bg_color } }, "header": { "type": "box", "layout": "horizontal", "contents": [{ "type": "box", "layout": "vertical", "margin": "sm", "contents": [{ "type": "text", "text": data["feed_title"], "weight": "bold", "color": header_text_color, "size": "sm", "wrap": True, "action": { "type": "uri", "uri": data["feed_link"] } }, { "type": "text", "text": "Update: {0}".format( self._convert_epoch_to_str(data['feed_date'])), "color": header_text_color, "size": "xxs" }] }] }, "body": { "type": "box", "layout": "horizontal", "spacing": "sm", "contents": [{ "type": "box", "layout": "vertical", "spacing": "md", "contents": [] }] } } for entry in data['entries']: body_contents = bubble["body"]["contents"][0]["contents"] body_contents.append({ "type": "box", "layout": "horizontal", "spacing": "md", "contents": [{ "type": "image", "url": entry["image_url"], "aspectMode": "cover", "aspectRatio": "4:3", "margin": "md", "size": "md", "gravity": "top", "flex": 1, "action": { "type": "uri", "uri": entry["link"] } }, { "type": "text", "text": entry["title"], "size": "xxs", "wrap": True, "flex": 2, "action": { "type": "uri", "uri": entry["link"] } }] }) body_contents.append({"type": "separator"}) bubble_container = BubbleContainer.new_from_json_dict(bubble) return bubble_container
def create_airport_message(self, airport_data): carousel_container = CarouselContainer() departures_bubble = { "type": "bubble", "styles": { "header": { "backgroundColor": "#FFF800" }, "body": { "backgroundColor": "#000000" } }, "direction": "ltr", "header": { "type": "box", "layout": "vertical", "contents": [{ "type": "text", "text": 'DEPARTURES', "align": "start", "size": "xl", "weight": "bold" }, { "type": "text", "text": airport_data['departure_title'], "size": "xs", "align": "start", "wrap": True }] }, "body": { "type": "box", "layout": "vertical", "spacing": "sm", "contents": [{ "type": "box", "layout": "horizontal", "contents": [{ "type": "text", "text": "Time", "flex": 1, "size": "xs", "align": "start", "color": "#FFFFFF" }, { "type": "text", "text": "Destination", "flex": 2, "size": "xs", "align": "start", "color": "#FFFFFF" }, { "type": "text", "text": "Flight", "size": "xs", "align": "end", "color": "#FFFFFF" }] }, { "type": "separator" }] } } for departure in airport_data['departures']: departures_bubble['body']['contents'].append({ "type": "box", "layout": "horizontal", "contents": [{ "type": "text", "text": departure['time'], "flex": 1, "size": "xs", "align": "start", "color": "#FFFFFF" }, { "type": "text", "text": departure['destination'], "flex": 2, "size": "xs", "align": "start", "color": "#FFFFFF", "wrap": True, "action": { "type": "postback", "data": "airport={0}".format(departure['destination_code']) } }, { "type": "text", "text": departure['flight_no'], "size": "xs", "align": "end", "color": "#FFFFFF", "action": { "type": "postback", "data": "flight_info={0}".format(departure['flight_no']) } }] }) arrivals_bubble = { "type": "bubble", "styles": { "header": { "backgroundColor": "#9FE9FF" }, "body": { "backgroundColor": "#000000" } }, "direction": "ltr", "header": { "type": "box", "layout": "vertical", "contents": [{ "type": "text", "text": "ARRIVALS", "align": "start", "size": "xl", "weight": "bold" }, { "type": "text", "text": airport_data['arrival_title'], "align": "start", "size": "xs", "wrap": True }] }, "body": { "type": "box", "layout": "vertical", "spacing": "sm", "contents": [{ "type": "box", "layout": "horizontal", "contents": [{ "type": "text", "text": "Time", "flex": 1, "size": "xs", "align": "start", "color": "#FFFFFF" }, { "type": "text", "text": "Origin", "flex": 2, "size": "xs", "align": "start", "color": "#FFFFFF" }, { "type": "text", "text": "Flight", "size": "xs", "align": "end", "color": "#FFFFFF" }] }, { "type": "separator" }] } } for arrival in airport_data['arrivals']: arrivals_bubble['body']['contents'].append({ "type": "box", "layout": "horizontal", "contents": [{ "type": "text", "text": arrival['time'], "flex": 1, "size": "xs", "align": "start", "color": "#FFFFFF" }, { "type": "text", "text": arrival['origin'], "flex": 2, "size": "xs", "align": "start", "color": "#FFFFFF", "wrap": True, "action": { "type": "postback", "data": "airport={0}".format(arrival['origin_code']) } }, { "type": "text", "text": arrival['flight_no'], "size": "xs", "align": "end", "color": "#FFFFFF", "action": { "type": "postback", "data": "flight_info={0}".format(arrival['flight_no']) } }] }) departure_container = BubbleContainer.new_from_json_dict( departures_bubble) arrival_container = BubbleContainer.new_from_json_dict(arrivals_bubble) carousel_container.contents.append(departure_container) carousel_container.contents.append(arrival_container) return carousel_container
# } # }""" # In[ ]: #將bubble類型的json 進行轉換變成 Python可理解之類型物件,並將該物件封裝進 Flex Message中 #引用套件 from linebot.models import ( FlexSendMessage, BubbleContainer, ) import json #INTRO樣板封裝 bubbleContainer_intro = BubbleContainer.new_from_json_dict( json.loads(flexBubbleContainerJsonString_INTRO)) flexBubbleSendMessage_INTRO = FlexSendMessage(alt_text="李慶鴻 的個人介紹", contents=bubbleContainer_intro) # #WORK樣板封裝 bubbleContainer_work = BubbleContainer.new_from_json_dict( json.loads(flexBubbleContainerJsonString_WORK)) flexBubbleSendMessage_WORK = FlexSendMessage(alt_text="李慶鴻 的學習經歷", contents=bubbleContainer_work) # #SKILLS樣板封裝 # bubbleContainer_skills= BubbleContainer.new_from_json_dict(json.loads(flexBubbleContainerJsonString_SKILLS)) # flexBubbleSendMessage_SKILLS = FlexSendMessage(alt_text="yourName 的專長", contents=bubbleContainer_skills) # In[ ]:
def handle_text(event): if event.message.text == "機能リクエスト": json = { "type": "bubble", "body": { "type": "box", "layout": "vertical", "contents": [{ "type": "text", "text": "以下のフォームから入力してください♪", "weight": "bold", "size": "md", "wrap": True, }], }, "footer": { "type": "box", "layout": "vertical", "spacing": "sm", "contents": [{ "type": "button", "style": "primary", "height": "sm", "action": { "type": "uri", "label": "フォームを開く", "uri": "line://app/1636610661-exPKww1a", }, }], "flex": 0, }, } line_bot_api.reply_message( event.reply_token, FlexSendMessage(alt_text="代替テキスト", contents=BubbleContainer.new_from_json_dict(json)), ) return if event.message.text.startswith("送信完了"): r.rpush("inquiry", event.message.text) line_bot_api.reply_message(event.reply_token, [TextSendMessage(text="受け付けました♪")]) return reply_text = "" available_texts = ["専用", "SALE", "送料込み", "新品", "ほぼ新品"] if event.message.text in available_texts: r.set( event.source.user_id, str(available_texts.index(event.message.text) + 1).zfill(2), ) # Rich menu richmenu_list = [ "richmenu-4318d8c8dba62fc14de3fced2943e413", "richmenu-a9026960e6262156dcfb46f9ba4be03f", "richmenu-f327f9da90dda0fdffd31ffa04cda8f3", "richmenu-68ae2dde8a306b2ac5d83fe607bc5c45", "richmenu-5ce596509156820b2661d67cf3ca8cd0", ] line_bot_api.link_rich_menu_to_user( event.source.user_id, richmenu_list[available_texts.index(event.message.text)], ) json = { "type": "bubble", "hero": { "type": "image", "url": request.url_root.replace("http://", "https://") + "/imgs/mercari_%s.png" % (r.get(event.source.user_id)), "size": "full", "aspectRatio": "1:1", "aspectMode": "cover", }, "body": { "type": "box", "layout": "vertical", "contents": [{ "type": "text", "text": "「" + event.message.text + "」に変更したよ。画像を送ってね♪", "weight": "bold", "size": "md", "wrap": True, }], }, "footer": { "type": "box", "layout": "vertical", "spacing": "sm", "contents": [{ "type": "button", "style": "primary", "height": "sm", "action": { "type": "uri", "label": "画像を選択", "uri": "line://nv/cameraRoll/multi", }, }], "flex": 0, }, } line_bot_api.reply_message( event.reply_token, FlexSendMessage(alt_text="代替テキスト", contents=BubbleContainer.new_from_json_dict(json)), ) else: reply_text = ("載せたいテキストを変更したい時には↓をタップしてね。今は「" + available_texts[int(r.get(event.source.user_id)) - 1] + "」に設定されてるよ♪") line_bot_api.reply_message(event.reply_token, [TextSendMessage(text=reply_text)])
def handle_teams(event): print('handle_teams') postback_data = event.postback.data team_id = postback_data.split('=')[1] team_data = football_api.get_team(team_id) carousel = CarouselContainer() pages = [ team_data['players'][i:i + 10] for i in range(0, len(team_data['players']), 10) ] for page in pages: bubble = { "type": "bubble", "styles": { "header": { "backgroundColor": "#4a4b4c" } }, "header": { "type": "box", "layout": "vertical", "contents": [{ "type": "text", "text": team_data["team_name"], "weight": "bold", "size": "md", "color": "#ffffff", "action": { "type": "uri", "uri": team_data["team_website"] } }, { "type": "text", "text": "Coach: {}".format(team_data["head_coach"]), "size": "xs", "color": "#ffffff" }] }, "body": { "type": "box", "layout": "vertical", "spacing": "md", "contents": [{ "type": "box", "layout": "horizontal", "contents": [{ "type": "text", "text": "Full Name", "weight": "bold", "size": "xxs", "flex": 5 }, { "type": "text", "text": "Position", "weight": "bold", "size": "xxs", "flex": 2 }, { "type": "text", "text": "Age", "weight": "bold", "size": "xxs", "flex": 1 }] }, { "type": "separator" }] } } body_contents = bubble['body']['contents'] for player in page: body_contents.append({ "type": "box", "layout": "horizontal", "contents": [{ "type": "text", "text": player['name'], "size": "xxs", "wrap": True, "flex": 5 }, { "type": "text", "text": player['position'], "size": "xxs", "flex": 2 }, { "type": "text", "text": str(player['age']), "size": "xxs", "flex": 1 }] }) bubble_container = BubbleContainer.new_from_json_dict(bubble) carousel.contents.append(bubble_container) line_bot_api.reply_message( event.reply_token, FlexSendMessage(alt_text='Team', contents=carousel))