Add custom headers to Webhook notification agent

This commit is contained in:
JonnyWong16 2019-11-11 15:17:49 -08:00
parent f5794a5bae
commit ddbd486500
3 changed files with 71 additions and 27 deletions

View file

@ -243,6 +243,11 @@
</div> </div>
<ul class="submenu"> <ul class="submenu">
<li> <li>
<div class="form-group">
<label for="${action['name']}_subject">JSON Headers</label>
<textarea class="form-control" id="${action['name']}_subject" name="${action['name']}_subject" data-parsley-trigger="change" data-autoresize required>${notifier['notify_text'][action['name']]['subject']}</textarea>
<p class="help-block">Set custom JSON headers.</p>
</div>
<div class="form-group"> <div class="form-group">
<label for="${action['name']}_body">JSON Data</label> <label for="${action['name']}_body">JSON Data</label>
<textarea class="form-control" id="${action['name']}_body" name="${action['name']}_body" data-parsley-trigger="change" data-autoresize required>${notifier['notify_text'][action['name']]['body']}</textarea> <textarea class="form-control" id="${action['name']}_body" name="${action['name']}_body" data-parsley-trigger="change" data-autoresize required>${notifier['notify_text'][action['name']]['body']}</textarea>
@ -326,6 +331,15 @@
<p class="help-block">Set custom arguments passed to the script.</p> <p class="help-block">Set custom arguments passed to the script.</p>
</div> </div>
% elif notifier['agent_name'] == 'webhook': % elif notifier['agent_name'] == 'webhook':
<div class="form-group">
<label for="test_subject">JSON Headers</label>
<div class="row">
<div class="col-md-12">
<textarea class="form-control" id="test_subject" name="test_subject" data-autoresize></textarea>
</div>
</div>
<p class="help-block">Set custom JSON headers sent to the webhook.</p>
</div>
<div class="form-group"> <div class="form-group">
<label for="test_body">JSON Data</label> <label for="test_body">JSON Data</label>
<div class="row"> <div class="row">

View file

@ -17,6 +17,7 @@
import arrow import arrow
import bleach import bleach
from collections import Counter, defaultdict from collections import Counter, defaultdict
from functools import partial
import hashlib import hashlib
from itertools import groupby from itertools import groupby
import json import json
@ -1086,11 +1087,11 @@ def build_notify_text(subject='', body='', notify_action=None, parameters=None,
if test: if test:
return subject, body return subject, body
custom_formatter = CustomFormatter() str_formatter = partial(str_format, parameters=parameters)
if agent_id == 15: if agent_id == 15:
try: try:
script_args = [custom_formatter.format(arg, **parameters) for arg in helpers.split_args(subject)] script_args = [str_formatter(arg) for arg in helpers.split_args(subject)]
except LookupError as e: except LookupError as e:
logger.error(u"Tautulli NotificationHandler :: Unable to parse parameter %s in script argument. Using fallback." % e) logger.error(u"Tautulli NotificationHandler :: Unable to parse parameter %s in script argument. Using fallback." % e)
script_args = [] script_args = []
@ -1098,41 +1099,53 @@ def build_notify_text(subject='', body='', notify_action=None, parameters=None,
logger.error(u"Tautulli NotificationHandler :: Unable to parse custom script arguments: %s. Using fallback." % e) logger.error(u"Tautulli NotificationHandler :: Unable to parse custom script arguments: %s. Using fallback." % e)
script_args = [] script_args = []
try: elif agent_id == 25:
subject = custom_formatter.format(unicode(subject), **parameters) if subject:
except LookupError as e: try:
logger.error(u"Tautulli NotificationHandler :: Unable to parse parameter %s in notification subject. Using fallback." % e) subject = json.loads(subject)
subject = unicode(default_subject).format(**parameters) except ValueError as e:
except Exception as e: logger.error(u"Tautulli NotificationHandler :: Unable to parse custom webhook json header data: %s. Using fallback." % e)
logger.error(u"Tautulli NotificationHandler :: Unable to parse custom notification subject: %s. Using fallback." % e) subject = ''
subject = unicode(default_subject).format(**parameters) if subject:
try:
subject = json.dumps(helpers.traverse_map(subject, str_formatter))
except LookupError as e:
logger.error(u"Tautulli NotificationHandler :: Unable to parse parameter %s in webhook header data. Using fallback." % e)
subject = ''
except Exception as e:
logger.error(u"Tautulli NotificationHandler :: Unable to parse custom webhook header data: %s. Using fallback." % e)
subject = ''
if agent_id == 25:
if body: if body:
try: try:
body = json.loads(body) body = json.loads(body)
except ValueError as e: except ValueError as e:
logger.error(u"Tautulli NotificationHandler :: Unable to parse custom webhook json data: %s. Using fallback." % e) logger.error(u"Tautulli NotificationHandler :: Unable to parse custom webhook json body data: %s. Using fallback." % e)
body = '' body = ''
if body: if body:
def str_format(s):
if isinstance(s, basestring):
return custom_formatter.format(unicode(s), **parameters)
return s
try: try:
body = json.dumps(helpers.traverse_map(body, str_format)) body = json.dumps(helpers.traverse_map(body, str_formatter))
except LookupError as e: except LookupError as e:
logger.error(u"Tautulli NotificationHandler :: Unable to parse parameter %s in webhook data. Using fallback." % e) logger.error(u"Tautulli NotificationHandler :: Unable to parse parameter %s in webhook body data. Using fallback." % e)
body = '' body = ''
except Exception as e: except Exception as e:
logger.error(u"Tautulli NotificationHandler :: Unable to parse custom webhook data: %s. Using fallback." % e) logger.error(u"Tautulli NotificationHandler :: Unable to parse custom webhook body data: %s. Using fallback." % e)
body = '' body = ''
else: else:
try: try:
body = custom_formatter.format(unicode(body), **parameters) subject = str_formatter(subject)
except LookupError as e:
logger.error(
u"Tautulli NotificationHandler :: Unable to parse parameter %s in notification subject. Using fallback." % e)
subject = unicode(default_subject).format(**parameters)
except Exception as e:
logger.error(
u"Tautulli NotificationHandler :: Unable to parse custom notification subject: %s. Using fallback." % e)
subject = unicode(default_subject).format(**parameters)
try:
body = str_formatter(body)
except LookupError as e: except LookupError as e:
logger.error(u"Tautulli NotificationHandler :: Unable to parse parameter %s in notification body. Using fallback." % e) logger.error(u"Tautulli NotificationHandler :: Unable to parse parameter %s in notification body. Using fallback." % e)
body = unicode(default_body).format(**parameters) body = unicode(default_body).format(**parameters)
@ -1572,6 +1585,13 @@ def lookup_musicbrainz_info(musicbrainz_type=None, rating_key=None, artist=None,
return musicbrainz_info return musicbrainz_info
def str_format(s, parameters):
custom_formatter = CustomFormatter()
if isinstance(s, basestring):
return custom_formatter.format(unicode(s), **parameters)
return s
class CustomFormatter(Formatter): class CustomFormatter(Formatter):
def __init__(self, default='{{{0}}}'): def __init__(self, default='{{{0}}}'):
self.default = default self.default = default

View file

@ -3613,19 +3613,29 @@ class WEBHOOK(Notifier):
} }
def agent_notify(self, subject='', body='', action='', **kwargs): def agent_notify(self, subject='', body='', action='', **kwargs):
if subject:
try:
webhook_headers = json.loads(subject)
except ValueError as e:
logger.error(u"Tautulli Notifiers :: Invalid {name} json header data: {e}".format(name=self.NAME, e=e))
return False
else:
webhook_headers = None
if body: if body:
try: try:
webhook_data = json.loads(body) webhook_body = json.loads(body)
except ValueError as e: except ValueError as e:
logger.error(u"Tautulli Notifiers :: Invalid {name} json data: {e}".format(name=self.NAME, e=e)) logger.error(u"Tautulli Notifiers :: Invalid {name} json body data: {e}".format(name=self.NAME, e=e))
return False return False
else: else:
webhook_data = None webhook_body = None
headers = {'Content-type': 'application/json'} headers = {'Content-type': 'application/json'}
if webhook_headers:
headers.update(webhook_headers)
return self.make_request(self.config['hook'], method=self.config['method'], headers=headers, json=webhook_data) return self.make_request(self.config['hook'], method=self.config['method'], headers=headers, json=webhook_body)
def _return_config_options(self): def _return_config_options(self):
config_option = [{'label': 'Webhook URL', config_option = [{'label': 'Webhook URL',