mirror of
https://github.com/dgtlmoon/changedetection.io.git
synced 2025-12-12 02:55:43 +00:00
Using Jinja2 templating actually simplifies slightly the code, but, most importantly, enables a much greater flexibility
to customize the notifications' content.
This change is breaking: the tokens like `{base_url}` should instead be written s `{{ base_url }}`. It would be very easy
to make it non-breaking, but I think it would be preferable to stick to the default Jinja2 syntax. To make it non-breaking,
the Jinja2 environment should be configured this way:
```
jinja2_env = Environment(
loader=BaseLoader,
variable_start_string='{',
variable_end_string='}',
)
```
NB: This change could enable a few more follow-up enhancements:
* It could make sense as a later evolution to implement the same for the URL list. This could enable features like:
- Customizing the sender based on the watch parameters through global settings
- Sending the notification to a different email/channel/group based on a watch attribute, like its tag
* Jinja2 plays fine with complex variables. It would be relatively easy to expose many more variables that could be used
in the notification.
Changes
=======
* Use Jinja2 template rendering to parse tokens in the notification body and title.
* Replace the settings validator to check that the body and title are both valid Jinja2 templates
and that they do not contain any invalid token/variable.
* Update the corresponding documentation, setting pages and tests.
84 lines
2.7 KiB
Python
84 lines
2.7 KiB
Python
import apprise
|
|
from jinja2 import Environment, BaseLoader
|
|
|
|
valid_tokens = {
|
|
'base_url': '',
|
|
'watch_url': '',
|
|
'watch_uuid': '',
|
|
'watch_title': '',
|
|
'watch_tag': '',
|
|
'diff_url': '',
|
|
'preview_url': '',
|
|
'current_snapshot': ''
|
|
}
|
|
|
|
|
|
def process_notification(n_object, datastore):
|
|
import logging
|
|
log = logging.getLogger('apprise')
|
|
log.setLevel('TRACE')
|
|
apobj = apprise.Apprise(debug=True)
|
|
|
|
for url in n_object['notification_urls']:
|
|
url = url.strip()
|
|
print (">> Process Notification: AppRise notifying {}".format(url))
|
|
apobj.add(url)
|
|
|
|
# Insert variables into the notification content
|
|
notification_parameters = create_notification_parameters(n_object, datastore)
|
|
|
|
# Get the notification body from datastore
|
|
jinja2_env = Environment(loader=BaseLoader)
|
|
n_body = jinja2_env.from_string(n_object['notification_body']).render(**notification_parameters)
|
|
n_title = jinja2_env.from_string(n_object['notification_title']).render(**notification_parameters)
|
|
|
|
apobj.notify(
|
|
body=n_body,
|
|
title=n_title
|
|
)
|
|
|
|
# Notification title + body content parameters get created here.
|
|
def create_notification_parameters(n_object, datastore):
|
|
from copy import deepcopy
|
|
|
|
# in the case we send a test notification from the main settings, there is no UUID.
|
|
uuid = n_object['uuid'] if 'uuid' in n_object else ''
|
|
|
|
if uuid != '':
|
|
watch_title = datastore.data['watching'][uuid]['title']
|
|
watch_tag = datastore.data['watching'][uuid]['tag']
|
|
else:
|
|
watch_title = 'Change Detection'
|
|
watch_tag = ''
|
|
|
|
# Create URLs to customise the notification with
|
|
base_url = datastore.data['settings']['application']['base_url']
|
|
|
|
watch_url = n_object['watch_url']
|
|
|
|
# Re #148 - Some people have just {{ base_url }} in the body or title, but this may break some notification services
|
|
# like 'Join', so it's always best to atleast set something obvious so that they are not broken.
|
|
if base_url == '':
|
|
base_url = "<base-url-env-var-not-set>"
|
|
|
|
diff_url = "{}/diff/{}".format(base_url, uuid)
|
|
preview_url = "{}/preview/{}".format(base_url, uuid)
|
|
|
|
# Not sure deepcopy is needed here, but why not
|
|
tokens = deepcopy(valid_tokens)
|
|
|
|
# Valid_tokens also used as a field validator
|
|
tokens.update(
|
|
{
|
|
'base_url': base_url if base_url is not None else '',
|
|
'watch_url': watch_url,
|
|
'watch_uuid': uuid,
|
|
'watch_title': watch_title if watch_title is not None else '',
|
|
'watch_tag': watch_tag if watch_tag is not None else '',
|
|
'diff_url': diff_url,
|
|
'preview_url': preview_url,
|
|
'current_snapshot': n_object['current_snapshot'] if 'current_snapshot' in n_object else ''
|
|
})
|
|
|
|
return tokens
|