diff --git a/scripts/tickets2slack.py b/scripts/tickets2slack.py new file mode 100755 index 00000000..692dce2b --- /dev/null +++ b/scripts/tickets2slack.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Post error tickets to slack on a 5 minute schedule. +# +# Proper use depends on having created a web-hook through Slack, and having set +# that value in your app's model as the value of global_settings.slack_hook. +# Details on creating web-hooks can be found at https://slack.com/integrations +# +# requires the Requests module for posting to slack, other requirements are +# standard or provided by web2py +# +# Usage (on Unices), replace myapp with the name of your application and run: +# nohup python web2py.py -S myapp -M -R scripts/tickets2slack.py & + +import sys +import os +import time +import pickle +import json + +try: + import requests +except ImportError as e: + print "missing module 'Requests', aborting." + sys.exit(1) + +from gluon import URL +from gluon.utils import md5_hash +from gluon.restricted import RestrictedError +from gluon.settings import global_settings + + +path = os.path.join(request.folder, 'errors') +sent_errors_file = os.path.join(path, 'slack_errors.pickle') +hashes = {} +if os.path.exists(sent_errors_file): + try: + with open(sent_errors_file, 'rb') as f: + hashes = pickle.load(f) + except Exception as _: + pass + +# ## CONFIGURE HERE +SLEEP_MINUTES = 5 +ALLOW_DUPLICATES = False +global_settings.slack_hook = global_settings.slack_hook or \ + 'https://hooks.slack.com/services/your_service' +# ## END CONFIGURATION + +while 1: + for file_name in os.listdir(path): + if file_name == 'slack_errors.pickle': + continue + + if not ALLOW_DUPLICATES: + key = md5_hash(file_name) + if key in hashes: + continue + hashes[key] = 1 + + error = RestrictedError() + + try: + error.load(request, request.application, file_name) + except Exception as _: + continue # not an exception file? + + url = URL(a='admin', f='ticket', args=[request.application, file], + scheme=True) + payload = json.dumps(dict(text="Error in %(app)s.\n%(url)s" % + dict(app=request.application, url=url))) + + requests.post(global_settings.slack_hook, data=dict(payload=payload)) + + with open(sent_errors_file, 'wb') as f: + pickle.dump(hashes, f) + time.sleep(SLEEP_MINUTES * 60)