|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import datetime |
|
import errno |
|
import os |
|
import sys |
|
import logging |
|
import tempfile |
|
from argparse import ArgumentParser |
|
|
|
from flask import Flask, request, abort, send_from_directory |
|
import google.generativeai as genai |
|
import markdown |
|
from bs4 import BeautifulSoup |
|
|
|
from linebot.v3 import ( |
|
WebhookHandler |
|
) |
|
from linebot.v3.models import ( |
|
UnknownEvent |
|
) |
|
from linebot.v3.exceptions import ( |
|
InvalidSignatureError |
|
) |
|
from linebot.v3.webhooks import ( |
|
MessageEvent, |
|
TextMessageContent, |
|
LocationMessageContent, |
|
StickerMessageContent, |
|
ImageMessageContent, |
|
VideoMessageContent, |
|
AudioMessageContent, |
|
FileMessageContent, |
|
UserSource, |
|
RoomSource, |
|
GroupSource, |
|
FollowEvent, |
|
UnfollowEvent, |
|
JoinEvent, |
|
LeaveEvent, |
|
PostbackEvent, |
|
BeaconEvent, |
|
MemberJoinedEvent, |
|
MemberLeftEvent, |
|
) |
|
from linebot.v3.messaging import ( |
|
Configuration, |
|
ApiClient, |
|
MessagingApi, |
|
MessagingApiBlob, |
|
ReplyMessageRequest, |
|
PushMessageRequest, |
|
MulticastRequest, |
|
BroadcastRequest, |
|
TextMessage, |
|
ApiException, |
|
LocationMessage, |
|
StickerMessage, |
|
ImageMessage, |
|
TemplateMessage, |
|
FlexMessage, |
|
Emoji, |
|
QuickReply, |
|
QuickReplyItem, |
|
ConfirmTemplate, |
|
ButtonsTemplate, |
|
CarouselTemplate, |
|
CarouselColumn, |
|
ImageCarouselTemplate, |
|
ImageCarouselColumn, |
|
FlexBubble, |
|
FlexImage, |
|
FlexBox, |
|
FlexText, |
|
FlexIcon, |
|
FlexButton, |
|
FlexSeparator, |
|
FlexContainer, |
|
MessageAction, |
|
URIAction, |
|
PostbackAction, |
|
DatetimePickerAction, |
|
CameraAction, |
|
CameraRollAction, |
|
LocationAction, |
|
ErrorResponse |
|
) |
|
|
|
from linebot.v3.insight import ( |
|
ApiClient as InsightClient, |
|
Insight |
|
) |
|
|
|
app = Flask(__name__) |
|
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') |
|
app.logger.setLevel(logging.INFO) |
|
|
|
|
|
channel_secret = os.getenv('LINE_CHANNEL_SECRET', None) |
|
channel_access_token = os.getenv('LINE_CHANNEL_ACCESS_TOKEN', None) |
|
|
|
if channel_secret is None or channel_access_token is None: |
|
print('Specify LINE_CHANNEL_SECRET and LINE_CHANNEL_ACCESS_TOKEN as environment variables.') |
|
sys.exit(1) |
|
|
|
handler = WebhookHandler(channel_secret) |
|
|
|
static_tmp_path = os.path.join(os.path.dirname(__file__), 'static', 'tmp') |
|
|
|
configuration = Configuration( |
|
access_token=channel_access_token |
|
) |
|
|
|
genai.configure(api_key=os.getenv('GOOGLE_API_KEY', None)) |
|
model = genai.GenerativeModel('gemini-pro') |
|
chats: dict[str, genai.ChatSession] = {} |
|
|
|
|
|
def get_chat(user_id: str) -> genai.ChatSession: |
|
if user_id in chats: |
|
return chats.get(user_id) |
|
else: |
|
chat = model.start_chat() |
|
chats[user_id] = chat |
|
return chat |
|
|
|
|
|
@app.route("/") |
|
def home(): |
|
return {"message": "Line Webhook Server"} |
|
|
|
|
|
|
|
def make_static_tmp_dir(): |
|
try: |
|
os.makedirs(static_tmp_path) |
|
except OSError as exc: |
|
if exc.errno == errno.EEXIST and os.path.isdir(static_tmp_path): |
|
pass |
|
else: |
|
raise |
|
|
|
|
|
@app.route("/callback", methods=['POST']) |
|
def callback(): |
|
|
|
signature = request.headers['X-Line-Signature'] |
|
|
|
|
|
body = request.get_data(as_text=True) |
|
app.logger.info("Request body: " + body) |
|
|
|
|
|
try: |
|
handler.handle(body, signature) |
|
except ApiException as e: |
|
app.logger.warn("Got exception from LINE Messaging API: %s\n" % e.body) |
|
except InvalidSignatureError: |
|
abort(400) |
|
|
|
return 'OK' |
|
|
|
|
|
@handler.add(MessageEvent, message=TextMessageContent) |
|
def handle_text_message(event): |
|
text = event.message.text |
|
with ApiClient(configuration) as api_client: |
|
line_bot_api = MessagingApi(api_client) |
|
if text == 'profile': |
|
if isinstance(event.source, UserSource): |
|
profile = line_bot_api.get_profile(user_id=event.source.user_id) |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=[ |
|
TextMessage(text='Display name: ' + profile.display_name), |
|
TextMessage(text='Status message: ' + str(profile.status_message)) |
|
] |
|
) |
|
) |
|
else: |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=[TextMessage(text="Bot can't use profile API without user ID")] |
|
) |
|
) |
|
elif text == 'emojis': |
|
emojis = [Emoji(index=0, product_id="5ac1bfd5040ab15980c9b435", emoji_id="001"), |
|
Emoji(index=13, product_id="5ac1bfd5040ab15980c9b435", emoji_id="002")] |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=[TextMessage(text='$ LINE emoji $', emojis=emojis)] |
|
) |
|
) |
|
elif text == 'quota': |
|
quota = line_bot_api.get_message_quota() |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=[ |
|
TextMessage(text='type: ' + quota.type), |
|
TextMessage(text='value: ' + str(quota.value)) |
|
] |
|
) |
|
) |
|
elif text == 'quota_consumption': |
|
quota_consumption = line_bot_api.get_message_quota_consumption() |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=[ |
|
TextMessage(text='total usage: ' + str(quota_consumption.total_usage)) |
|
] |
|
) |
|
) |
|
elif text == 'push': |
|
line_bot_api.push_message( |
|
PushMessageRequest( |
|
to=event.source.user_id, |
|
messages=[TextMessage(text='PUSH!')] |
|
) |
|
) |
|
elif text == 'multicast': |
|
line_bot_api.multicast( |
|
MulticastRequest( |
|
to=[event.source.user_id], |
|
messages=[TextMessage(text="THIS IS A MULTICAST MESSAGE, but it's slower than PUSH.")] |
|
) |
|
) |
|
elif text == 'broadcast': |
|
line_bot_api.broadcast( |
|
BroadcastRequest( |
|
messages=[TextMessage(text='THIS IS A BROADCAST MESSAGE')] |
|
) |
|
) |
|
elif text.startswith('broadcast '): |
|
date = text.split(' ')[1] |
|
app.logger.info("Getting broadcast result: " + date) |
|
result = line_bot_api.get_number_of_sent_broadcast_messages(var_date=date) |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=[ |
|
TextMessage(text='Number of sent broadcast messages: ' + date), |
|
TextMessage(text='status: ' + str(result.status)), |
|
TextMessage(text='success: ' + str(result.success)), |
|
] |
|
) |
|
) |
|
elif text == 'bye': |
|
if isinstance(event.source, GroupSource): |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=[TextMessage(text="Leaving group")] |
|
) |
|
) |
|
line_bot_api.leave_group(event.source.group_id) |
|
elif isinstance(event.source, RoomSource): |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=[TextMessage(text="Leaving room")] |
|
) |
|
) |
|
line_bot_api.leave_room(room_id=event.source.room_id) |
|
else: |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=[ |
|
TextMessage(text="Bot can't leave from 1:1 chat") |
|
] |
|
) |
|
) |
|
elif text == 'image': |
|
url = 'https://placehold.co/400' |
|
app.logger.info("url=" + url) |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=[ |
|
ImageMessage(original_content_url=url, preview_image_url=url) |
|
] |
|
) |
|
) |
|
elif text == 'confirm': |
|
confirm_template = ConfirmTemplate( |
|
text='Do it?', |
|
actions=[ |
|
MessageAction(label='Yes', text='Yes!'), |
|
MessageAction(label='No', text='No!') |
|
] |
|
) |
|
template_message = TemplateMessage( |
|
alt_text='Confirm alt text', |
|
template=confirm_template |
|
) |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=[template_message] |
|
) |
|
) |
|
elif text == 'buttons': |
|
buttons_template = ButtonsTemplate( |
|
title='My buttons sample', |
|
text='Hello, my buttons', |
|
actions=[ |
|
URIAction(label='Go to line.me', uri='https://line.me'), |
|
PostbackAction(label='ping', data='ping'), |
|
PostbackAction(label='ping with text', data='ping', text='ping'), |
|
MessageAction(label='Translate Rice', text='米') |
|
]) |
|
template_message = TemplateMessage( |
|
alt_text='Buttons alt text', |
|
template=buttons_template |
|
) |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=[template_message] |
|
) |
|
) |
|
elif text == 'carousel': |
|
carousel_template = CarouselTemplate( |
|
columns=[ |
|
CarouselColumn( |
|
text='hoge1', |
|
title='fuga1', |
|
actions=[ |
|
URIAction(label='Go to line.me', uri='https://line.me'), |
|
PostbackAction(label='ping', data='ping') |
|
] |
|
), |
|
CarouselColumn( |
|
text='hoge2', |
|
title='fuga2', |
|
actions=[ |
|
PostbackAction(label='ping with text', data='ping', text='ping'), |
|
MessageAction(label='Translate Rice', text='米') |
|
] |
|
) |
|
] |
|
) |
|
template_message = TemplateMessage( |
|
alt_text='Carousel alt text', template=carousel_template) |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=[template_message] |
|
) |
|
) |
|
elif text == 'image_carousel': |
|
image_carousel_template = ImageCarouselTemplate(columns=[ |
|
ImageCarouselColumn(image_url='https://via.placeholder.com/1024x1024', |
|
action=DatetimePickerAction(label='datetime', |
|
data='datetime_postback', |
|
mode='datetime')), |
|
ImageCarouselColumn(image_url='https://via.placeholder.com/1024x1024', |
|
action=DatetimePickerAction(label='date', |
|
data='date_postback', |
|
mode='date')) |
|
]) |
|
template_message = TemplateMessage( |
|
alt_text='ImageCarousel alt text', template=image_carousel_template) |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=[template_message] |
|
) |
|
) |
|
elif text == 'imagemap': |
|
pass |
|
elif text == 'flex': |
|
bubble = FlexBubble( |
|
direction='ltr', |
|
hero=FlexImage( |
|
url='https://example.com/cafe.jpg', |
|
size='full', |
|
aspect_ratio='20:13', |
|
aspect_mode='cover', |
|
action=URIAction(uri='http://example.com', label='label') |
|
), |
|
body=FlexBox( |
|
layout='vertical', |
|
contents=[ |
|
|
|
FlexText(text='Brown Cafe', weight='bold', size='xl'), |
|
|
|
FlexBox( |
|
layout='baseline', |
|
margin='md', |
|
contents=[ |
|
FlexIcon(size='sm', url='https://example.com/gold_star.png'), |
|
FlexIcon(size='sm', url='https://example.com/grey_star.png'), |
|
FlexIcon(size='sm', url='https://example.com/gold_star.png'), |
|
FlexIcon(size='sm', url='https://example.com/gold_star.png'), |
|
FlexIcon(size='sm', url='https://example.com/grey_star.png'), |
|
FlexText(text='4.0', size='sm', color='#999999', margin='md', flex=0) |
|
] |
|
), |
|
|
|
FlexBox( |
|
layout='vertical', |
|
margin='lg', |
|
spacing='sm', |
|
contents=[ |
|
FlexBox( |
|
layout='baseline', |
|
spacing='sm', |
|
contents=[ |
|
FlexText( |
|
text='Place', |
|
color='#aaaaaa', |
|
size='sm', |
|
flex=1 |
|
), |
|
FlexText( |
|
text='Shinjuku, Tokyo', |
|
wrap=True, |
|
color='#666666', |
|
size='sm', |
|
flex=5 |
|
) |
|
], |
|
), |
|
FlexBox( |
|
layout='baseline', |
|
spacing='sm', |
|
contents=[ |
|
FlexText( |
|
text='Time', |
|
color='#aaaaaa', |
|
size='sm', |
|
flex=1 |
|
), |
|
FlexText( |
|
text="10:00 - 23:00", |
|
wrap=True, |
|
color='#666666', |
|
size='sm', |
|
flex=5, |
|
), |
|
], |
|
), |
|
], |
|
) |
|
], |
|
), |
|
footer=FlexBox( |
|
layout='vertical', |
|
spacing='sm', |
|
contents=[ |
|
|
|
FlexButton( |
|
style='link', |
|
height='sm', |
|
action=URIAction(label='CALL', uri='tel:000000'), |
|
), |
|
|
|
FlexSeparator(), |
|
|
|
FlexButton( |
|
style='link', |
|
height='sm', |
|
action=URIAction(label='WEBSITE', uri="https://example.com") |
|
) |
|
] |
|
), |
|
) |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=[FlexMessage(alt_text="hello", contents=bubble)] |
|
) |
|
) |
|
elif text == 'flex_update_1': |
|
bubble_string = """ |
|
{ |
|
"type": "bubble", |
|
"body": { |
|
"type": "box", |
|
"layout": "vertical", |
|
"contents": [ |
|
{ |
|
"type": "image", |
|
"url": "https://scdn.line-apps.com/n/channel_devcenter/img/flexsnapshot/clip/clip3.jpg", |
|
"position": "relative", |
|
"size": "full", |
|
"aspectMode": "cover", |
|
"aspectRatio": "1:1", |
|
"gravity": "center" |
|
}, |
|
{ |
|
"type": "box", |
|
"layout": "horizontal", |
|
"contents": [ |
|
{ |
|
"type": "box", |
|
"layout": "vertical", |
|
"contents": [ |
|
{ |
|
"type": "text", |
|
"text": "Brown Hotel", |
|
"weight": "bold", |
|
"size": "xl", |
|
"color": "#ffffff" |
|
}, |
|
{ |
|
"type": "box", |
|
"layout": "baseline", |
|
"margin": "md", |
|
"contents": [ |
|
{ |
|
"type": "icon", |
|
"size": "sm", |
|
"url": "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png" |
|
}, |
|
{ |
|
"type": "icon", |
|
"size": "sm", |
|
"url": "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png" |
|
}, |
|
{ |
|
"type": "icon", |
|
"size": "sm", |
|
"url": "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png" |
|
}, |
|
{ |
|
"type": "icon", |
|
"size": "sm", |
|
"url": "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png" |
|
}, |
|
{ |
|
"type": "icon", |
|
"size": "sm", |
|
"url": "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gray_star_28.png" |
|
}, |
|
{ |
|
"type": "text", |
|
"text": "4.0", |
|
"size": "sm", |
|
"color": "#d6d6d6", |
|
"margin": "md", |
|
"flex": 0 |
|
} |
|
] |
|
} |
|
] |
|
}, |
|
{ |
|
"type": "box", |
|
"layout": "vertical", |
|
"contents": [ |
|
{ |
|
"type": "text", |
|
"text": "¥62,000", |
|
"color": "#a9a9a9", |
|
"decoration": "line-through", |
|
"align": "end" |
|
}, |
|
{ |
|
"type": "text", |
|
"text": "¥42,000", |
|
"color": "#ebebeb", |
|
"size": "xl", |
|
"align": "end" |
|
} |
|
] |
|
} |
|
], |
|
"position": "absolute", |
|
"offsetBottom": "0px", |
|
"offsetStart": "0px", |
|
"offsetEnd": "0px", |
|
"backgroundColor": "#00000099", |
|
"paddingAll": "20px" |
|
}, |
|
{ |
|
"type": "box", |
|
"layout": "vertical", |
|
"contents": [ |
|
{ |
|
"type": "text", |
|
"text": "SALE", |
|
"color": "#ffffff" |
|
} |
|
], |
|
"position": "absolute", |
|
"backgroundColor": "#ff2600", |
|
"cornerRadius": "20px", |
|
"paddingAll": "5px", |
|
"offsetTop": "10px", |
|
"offsetEnd": "10px", |
|
"paddingStart": "10px", |
|
"paddingEnd": "10px" |
|
} |
|
], |
|
"paddingAll": "0px" |
|
} |
|
} |
|
""" |
|
message = FlexMessage(alt_text="hello", contents=FlexContainer.from_json(bubble_string)) |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=[message] |
|
) |
|
) |
|
elif text == 'quick_reply': |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=[TextMessage( |
|
text='Quick reply', |
|
quick_reply=QuickReply( |
|
items=[ |
|
QuickReplyItem( |
|
action=PostbackAction(label="label1", data="data1") |
|
), |
|
QuickReplyItem( |
|
action=MessageAction(label="label2", text="text2") |
|
), |
|
QuickReplyItem( |
|
action=DatetimePickerAction(label="label3", |
|
data="data3", |
|
mode="date") |
|
), |
|
QuickReplyItem( |
|
action=CameraAction(label="label4") |
|
), |
|
QuickReplyItem( |
|
action=CameraRollAction(label="label5") |
|
), |
|
QuickReplyItem( |
|
action=LocationAction(label="label6") |
|
), |
|
] |
|
) |
|
)] |
|
) |
|
) |
|
elif text == 'link_token' and isinstance(event.source, UserSource): |
|
link_token_response = line_bot_api.issue_link_token(user_id=event.source.user_id) |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=[TextMessage(text='link_token: ' + link_token_response.link_token)] |
|
) |
|
) |
|
elif text == 'insight_message_delivery': |
|
with InsightClient(configuration) as api_client: |
|
line_bot_insight_api = Insight(api_client) |
|
today = datetime.date.today().strftime("%Y%m%d") |
|
response = line_bot_insight_api.get_number_of_message_deliveries(var_date=today) |
|
if response.status == 'ready': |
|
messages = [ |
|
TextMessage(text='broadcast: ' + str(response.broadcast)), |
|
TextMessage(text='targeting: ' + str(response.targeting)), |
|
] |
|
else: |
|
messages = [TextMessage(text='status: ' + response.status)] |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=messages |
|
) |
|
) |
|
elif text == 'insight_followers': |
|
with InsightClient(configuration) as api_client: |
|
line_bot_insight_api = Insight(api_client) |
|
today = datetime.date.today().strftime("%Y%m%d") |
|
response = line_bot_insight_api.get_number_of_followers(var_date=today) |
|
if response.status == 'ready': |
|
messages = [ |
|
TextMessage(text='followers: ' + str(response.followers)), |
|
TextMessage(text='targetedReaches: ' + str(response.targeted_reaches)), |
|
TextMessage(text='blocks: ' + str(response.blocks)), |
|
] |
|
else: |
|
messages = [TextMessage(text='status: ' + response.status)] |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=messages |
|
) |
|
) |
|
elif text == 'insight_demographic': |
|
with InsightClient(configuration) as api_client: |
|
line_bot_insight_api = Insight(api_client) |
|
response = line_bot_insight_api.get_friends_demographics() |
|
if response.available: |
|
messages = ["{gender}: {percentage}".format(gender=it.gender, percentage=it.percentage) |
|
for it in response.genders] |
|
else: |
|
messages = [TextMessage(text='available: false')] |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=messages |
|
) |
|
) |
|
elif text == 'with http info': |
|
response = line_bot_api.reply_message_with_http_info( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=[TextMessage(text='see application log')] |
|
) |
|
) |
|
app.logger.info("Got response with http status code: " + str(response.status_code)) |
|
app.logger.info("Got x-line-request-id: " + response.headers['x-line-request-id']) |
|
app.logger.info("Got response with http body: " + str(response.data)) |
|
elif text == 'with http info error': |
|
try: |
|
line_bot_api.reply_message_with_http_info( |
|
ReplyMessageRequest( |
|
reply_token='invalid-reply-token', |
|
messages=[TextMessage(text='see application log')] |
|
) |
|
) |
|
except ApiException as e: |
|
app.logger.info("Got response with http status code: " + str(e.status)) |
|
app.logger.info("Got x-line-request-id: " + e.headers['x-line-request-id']) |
|
app.logger.info("Got response with http body: " + str(ErrorResponse.from_json(e.body))) |
|
else: |
|
chat = get_chat(event.source.user_id) |
|
response = chat.send_message(text) |
|
html_msg = markdown.markdown(response.text) |
|
soup = BeautifulSoup(html_msg, 'html.parser') |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=[TextMessage(text=soup.get_text())] |
|
) |
|
) |
|
|
|
|
|
@handler.add(MessageEvent, message=LocationMessageContent) |
|
def handle_location_message(event): |
|
with ApiClient(configuration) as api_client: |
|
line_bot_api = MessagingApi(api_client) |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=[LocationMessage( |
|
title='Location', |
|
address=event.message.address, |
|
latitude=event.message.latitude, |
|
longitude=event.message.longitude |
|
)] |
|
) |
|
) |
|
|
|
|
|
@handler.add(MessageEvent, message=StickerMessageContent) |
|
def handle_sticker_message(event): |
|
with ApiClient(configuration) as api_client: |
|
line_bot_api = MessagingApi(api_client) |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=[StickerMessage( |
|
package_id=event.message.package_id, |
|
sticker_id=event.message.sticker_id) |
|
] |
|
) |
|
) |
|
|
|
|
|
|
|
@handler.add(MessageEvent, message=(ImageMessageContent, |
|
VideoMessageContent, |
|
AudioMessageContent)) |
|
def handle_content_message(event): |
|
if isinstance(event.message, ImageMessageContent): |
|
ext = 'jpg' |
|
elif isinstance(event.message, VideoMessageContent): |
|
ext = 'mp4' |
|
elif isinstance(event.message, AudioMessageContent): |
|
ext = 'm4a' |
|
else: |
|
return |
|
|
|
with ApiClient(configuration) as api_client: |
|
line_bot_blob_api = MessagingApiBlob(api_client) |
|
message_content = line_bot_blob_api.get_message_content(message_id=event.message.id) |
|
with tempfile.NamedTemporaryFile(dir=static_tmp_path, prefix=ext + '-', delete=False) as tf: |
|
tf.write(message_content) |
|
tempfile_path = tf.name |
|
|
|
dist_path = tempfile_path + '.' + ext |
|
dist_name = os.path.basename(dist_path) |
|
os.rename(tempfile_path, dist_path) |
|
|
|
with ApiClient(configuration) as api_client: |
|
line_bot_api = MessagingApi(api_client) |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=[ |
|
TextMessage(text='Save content.'), |
|
TextMessage(text=request.host_url + os.path.join('static', 'tmp', dist_name)) |
|
] |
|
) |
|
) |
|
|
|
|
|
@handler.add(MessageEvent, message=FileMessageContent) |
|
def handle_file_message(event): |
|
with ApiClient(configuration) as api_client: |
|
line_bot_blob_api = MessagingApiBlob(api_client) |
|
message_content = line_bot_blob_api.get_message_content(message_id=event.message.id) |
|
with tempfile.NamedTemporaryFile(dir=static_tmp_path, prefix='file-', delete=False) as tf: |
|
tf.write(message_content) |
|
tempfile_path = tf.name |
|
|
|
dist_path = tempfile_path + '-' + event.message.file_name |
|
dist_name = os.path.basename(dist_path) |
|
os.rename(tempfile_path, dist_path) |
|
|
|
with ApiClient(configuration) as api_client: |
|
line_bot_api = MessagingApi(api_client) |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=[ |
|
TextMessage(text='Save file.'), |
|
TextMessage(text=request.host_url + os.path.join('static', 'tmp', dist_name)) |
|
] |
|
) |
|
) |
|
|
|
|
|
@handler.add(FollowEvent) |
|
def handle_follow(event): |
|
app.logger.info("Got Follow event:" + event.source.user_id) |
|
with ApiClient(configuration) as api_client: |
|
line_bot_api = MessagingApi(api_client) |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=[TextMessage(text='Got follow event')] |
|
) |
|
) |
|
|
|
|
|
@handler.add(UnfollowEvent) |
|
def handle_unfollow(event): |
|
app.logger.info("Got Unfollow event:" + event.source.user_id) |
|
|
|
|
|
@handler.add(JoinEvent) |
|
def handle_join(event): |
|
with ApiClient(configuration) as api_client: |
|
line_bot_api = MessagingApi(api_client) |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=[TextMessage(text='Joined this ' + event.source.type)] |
|
) |
|
) |
|
|
|
|
|
@handler.add(LeaveEvent) |
|
def handle_leave(): |
|
app.logger.info("Got leave event") |
|
|
|
|
|
@handler.add(PostbackEvent) |
|
def handle_postback(event: PostbackEvent): |
|
with ApiClient(configuration) as api_client: |
|
line_bot_api = MessagingApi(api_client) |
|
if event.postback.data == 'ping': |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=[TextMessage(text='pong')] |
|
) |
|
) |
|
elif event.postback.data == 'datetime_postback': |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=[TextMessage(text=event.postback.params['datetime'])] |
|
) |
|
) |
|
elif event.postback.data == 'date_postback': |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=[TextMessage(text=event.postback.params['date'])] |
|
) |
|
) |
|
|
|
|
|
@handler.add(BeaconEvent) |
|
def handle_beacon(event: BeaconEvent): |
|
with ApiClient(configuration) as api_client: |
|
line_bot_api = MessagingApi(api_client) |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=[TextMessage(text='Got beacon event. hwid={}, device_message(hex string)={}'.format( |
|
event.beacon.hwid, event.beacon.dm))] |
|
) |
|
) |
|
|
|
|
|
@handler.add(MemberJoinedEvent) |
|
def handle_member_joined(event): |
|
with ApiClient(configuration) as api_client: |
|
line_bot_api = MessagingApi(api_client) |
|
line_bot_api.reply_message( |
|
ReplyMessageRequest( |
|
reply_token=event.reply_token, |
|
messages=[TextMessage(text='Got memberJoined event. event={}'.format(event))] |
|
) |
|
) |
|
|
|
|
|
@handler.add(MemberLeftEvent) |
|
def handle_member_left(event): |
|
app.logger.info("Got memberLeft event") |
|
|
|
|
|
@handler.add(UnknownEvent) |
|
def handle_unknown_left(event): |
|
app.logger.info(f"unknown event {event}") |
|
|
|
|
|
@app.route('/static/<path:path>') |
|
def send_static_content(path): |
|
return send_from_directory('static', path) |
|
|