-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
90 lines (78 loc) · 2.49 KB
/
Copy pathapp.py
File metadata and controls
90 lines (78 loc) · 2.49 KB
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
#!/usr/bin/env python3
import codecs
import facebook
import hmac
import io
import json
import logging
import os
import rules
from bottle import Bottle, request, route, run, abort
# Config
VERIFY_TOKEN = os.environ.get('JRF_VERIFY_TOKEN')
APP_SECRET = os.environ.get('JRF_APP_SECRET')
# Variables
app = Bottle()
logger = logging.getLogger('bot')
rules = [
rules.TimeRule(),
rules.HelpRule(),
rules.SearchRule(),
rules.TeachDialogRule(),
rules.DialogRule(),
rules.HelloRule(),
rules.FallbackRule(),
]
# Configure logger
log_path = os.path.join(os.environ.get('LOGDIR', '.'), 'jrf_bot.log')
logging.basicConfig(filename=log_path, level=logging.DEBUG)
@app.route('/hooks/messenger')
def verification_hook():
if request.query.get('hub.verify_token') == VERIFY_TOKEN:
return request.query.get('hub.challenge')
else:
return abort(400, 'Token illegal')
@app.post('/hooks/messenger')
def messenger_hook():
try:
reader = codecs.getreader('utf-8')
entity = json.load(reader(request.body))
except json.JSONDecodeError:
logger.warning('Malformed JSON received')
logger.debug(request.body.read().decode('latin1'))
return # Malformed JSON
if not check_signature():
pass #return abort(400, 'Invalid request')
messages = []
for entry_dict in entity['entry']:
for message_dict in entry_dict['messaging']:
message = facebook.parse_message(message_dict)
messages.append(message)
logger.debug(str(message))
for message in filter(None, messages):
for rule in rules:
text = rule.match(message)
if text:
facebook.send_message(message.sender, text)
break
def check_signature():
signature = request.get_header('X-Hub-Signature')
logger.debug('Signature [%s]', signature)
if not signature.startswith('sha1='):
logger.warning('Signature method invalid')
return False
# Read and encode non-ASCII string
buf = io.BytesIO()
with io.TextIOWrapper(request.body, newline='') as reader:
c = reader.read(1)
value = ord(c)
if value > 127:
buf.write(r'\u{:04x}'.format(value).encode())
else:
buf.write(c.encode())
# Hash it
h = hmac.new(APP_SECRET.encode(), buf.getbuffer(), 'sha1').hexdigest().lower()
logger.debug('Calculated signature [%s]', h)
return hmac.compare_digest(h, signature[4:])
if __name__ == '__main__':
app.run()