-
Notifications
You must be signed in to change notification settings - Fork 1k
/
app.py
116 lines (92 loc) · 3.32 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# -*- coding: utf-8 -*-
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import os
import sys
from argparse import ArgumentParser
import asyncio
from aiohttp import web
import logging
from aiohttp.web_runner import TCPSite
from linebot.v3 import (
WebhookParser
)
from linebot.v3.messaging import (
Configuration,
AsyncApiClient,
AsyncMessagingApi,
TextMessage,
ReplyMessageRequest
)
from linebot.v3.exceptions import (
InvalidSignatureError
)
from linebot.v3.webhooks import (
MessageEvent,
TextMessageContent
)
# get channel_secret and channel_access_token from your environment variable
channel_secret = os.getenv('LINE_CHANNEL_SECRET', None)
channel_access_token = os.getenv('LINE_CHANNEL_ACCESS_TOKEN', None)
if channel_secret is None:
print('Specify LINE_CHANNEL_SECRET as environment variable.')
sys.exit(1)
if channel_access_token is None:
print('Specify LINE_CHANNEL_ACCESS_TOKEN as environment variable.')
sys.exit(1)
configuration = Configuration(
access_token=channel_access_token
)
class Handler:
def __init__(self, line_bot_api: AsyncMessagingApi, parser: WebhookParser):
self.line_bot_api = line_bot_api
self.parser = parser
async def echo(self, request):
signature = request.headers['X-Line-Signature']
body = await request.text()
try:
events = self.parser.parse(body, signature)
except InvalidSignatureError:
return web.Response(status=400, text='Invalid signature')
for event in events:
if not isinstance(event, MessageEvent):
continue
if not isinstance(event.message, TextMessageContent):
continue
await self.line_bot_api.reply_message(
ReplyMessageRequest(
reply_token=event.reply_token,
messages=[TextMessage(text=event.message.text)]
)
)
return web.Response(text="OK\n")
async def main(port=8000):
async_api_client = AsyncApiClient(configuration)
line_bot_api = AsyncMessagingApi(async_api_client)
parser = WebhookParser(channel_secret)
handler = Handler(line_bot_api, parser)
app = web.Application()
app.add_routes([web.post('/callback', handler.echo)])
runner = web.AppRunner(app)
await runner.setup()
site = TCPSite(runner=runner, port=port)
await site.start()
while True:
await asyncio.sleep(3600) # sleep forever
if __name__ == "__main__":
logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.INFO)
arg_parser = ArgumentParser(
usage='Usage: python ' + __file__ + ' [--port <port>] [--help]'
)
arg_parser.add_argument('-p', '--port', type=int, default=8000, help='port')
options = arg_parser.parse_args()
asyncio.run(main(options.port))