You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

82 lines
2.4 KiB

import datetime
import hashlib
import hmac
import json
import logging
import os
import flask
import flask_apscheduler
import flask_restful
import flask_restful.reqparse
from sender import Sender
subscriptions = {}
app = flask.Flask(__name__)
app.logger.setLevel(logging.INFO)
app.config.update(
ERROR_404_HELP=False,
SCHEDULER_TIMEZONE='UTC',
SCHEDULER_JOBS=[
dict(id='subscribe',
func='twitch:Twitch.subscribe',
args=(app, subscriptions, 86400),
max_instances=1,
trigger='interval',
seconds=3600,
next_run_time=datetime.datetime.utcnow() + datetime.timedelta(seconds=10))])
scheduler = flask_apscheduler.APScheduler()
scheduler.init_app(app)
api = flask_restful.Api(app)
sender = Sender(app)
verification_parser = flask_restful.reqparse.RequestParser()
verification_parser.add_argument('hub.challenge', type=str, required=True)
verification_parser.add_argument('hub.lease_seconds', type=int, required=True)
verification_parser.add_argument('hub.mode', type=str, required=True)
verification_parser.add_argument('hub.topic', type=str, required=True)
class WebhooksResource(flask_restful.Resource):
def get(self):
args = verification_parser.parse_args()
verified = False
for sub in subscriptions.values():
h = '{0[hub.mode]}|{0[hub.topic]}|{0[hub.lease_seconds]}'.format(args)
if hashlib.sha256(h.encode()).hexdigest() == sub['request_hash']:
verified = True
break
if not verified:
flask_restful.abort(400, message='Verification failed')
r = app.make_response(args['hub.challenge'])
r.mimetype = 'text/plain'
r.status_code = 200
return r
def post(self):
sha, signature = flask.request.headers.get('X-Hub-Signature').split('=')
data = flask.request.data
for topic, sub in subscriptions.items():
mac = hmac.new(sub['secret'].encode(), data, getattr(hashlib, sha))
if not hmac.compare_digest(mac.hexdigest(), signature):
continue
message = flask.request.get_json(force=True)
message['topic'] = topic
sender.send(json.dumps(message).encode())
return None, 204
api.add_resource(WebhooksResource, '/webhooks')
if __name__ == '__main__':
scheduler.start()
app.run(host='0.0.0.0', threaded=True, debug=False)