summaryrefslogtreecommitdiffhomepage
path: root/libs/apprise/plugins/NotifyTelegram.py
diff options
context:
space:
mode:
Diffstat (limited to 'libs/apprise/plugins/NotifyTelegram.py')
-rw-r--r--libs/apprise/plugins/NotifyTelegram.py120
1 files changed, 96 insertions, 24 deletions
diff --git a/libs/apprise/plugins/NotifyTelegram.py b/libs/apprise/plugins/NotifyTelegram.py
index 4bfd2d368..3d9d718ec 100644
--- a/libs/apprise/plugins/NotifyTelegram.py
+++ b/libs/apprise/plugins/NotifyTelegram.py
@@ -205,13 +205,23 @@ class NotifyTelegram(NotifyBase):
'default': True,
'map_to': 'detect_owner',
},
+ 'silent': {
+ 'name': _('Silent Notification'),
+ 'type': 'bool',
+ 'default': False,
+ },
+ 'preview': {
+ 'name': _('Web Page Preview'),
+ 'type': 'bool',
+ 'default': False,
+ },
'to': {
'alias_of': 'targets',
},
})
def __init__(self, bot_token, targets, detect_owner=True,
- include_image=False, **kwargs):
+ include_image=False, silent=None, preview=None, **kwargs):
"""
Initialize Telegram Object
"""
@@ -229,6 +239,14 @@ class NotifyTelegram(NotifyBase):
# Parse our list
self.targets = parse_list(targets)
+ # Define whether or not we should make audible alarms
+ self.silent = self.template_args['silent']['default'] \
+ if silent is None else bool(silent)
+
+ # Define whether or not we should display a web page preview
+ self.preview = self.template_args['preview']['default'] \
+ if preview is None else bool(preview)
+
# if detect_owner is set to True, we will attempt to determine who
# the bot owner is based on the first person who messaged it. This
# is not a fool proof way of doing things as over time Telegram removes
@@ -513,7 +531,12 @@ class NotifyTelegram(NotifyBase):
'sendMessage'
)
- payload = {}
+ payload = {
+ # Notification Audible Control
+ 'disable_notification': self.silent,
+ # Display Web Page Preview (if possible)
+ 'disable_web_page_preview': not self.preview,
+ }
# Prepare Email Message
if self.notify_format == NotifyFormat.MARKDOWN:
@@ -524,35 +547,73 @@ class NotifyTelegram(NotifyBase):
body,
)
- elif self.notify_format == NotifyFormat.HTML:
- payload['parse_mode'] = 'HTML'
-
- # HTML Spaces ( ) and tabs ( ) aren't supported
- # See https://core.telegram.org/bots/api#html-style
- body = re.sub(' ?', ' ', body, re.I)
+ else: # HTML or TEXT
- # Tabs become 3 spaces
- body = re.sub(' ?', ' ', body, re.I)
+ # Use Telegram's HTML mode
+ payload['parse_mode'] = 'HTML'
- if title:
+ # Telegram's HTML support doesn't like having HTML escaped
+ # characters passed into it. to handle this situation, we need to
+ # search the body for these sequences and convert them to the
+ # output the user expected
+ telegram_escape_html_dict = {
# HTML Spaces ( ) and tabs ( ) aren't supported
# See https://core.telegram.org/bots/api#html-style
- title = re.sub(' ?', ' ', title, re.I)
+ r'nbsp': ' ',
# Tabs become 3 spaces
- title = re.sub(' ?', ' ', title, re.I)
-
- payload['text'] = '{}{}'.format(
- '<b>{}</b>\r\n'.format(title) if title else '',
- body,
- )
+ r'emsp': ' ',
+
+ # Some characters get re-escaped by the Telegram upstream
+ # service so we need to convert these back,
+ r'apos': '\'',
+ r'quot': '"',
+ }
+
+ # Create a regular expression from the dictionary keys
+ html_regex = re.compile("&(%s);?" % "|".join(
+ map(re.escape, telegram_escape_html_dict.keys())).lower(),
+ re.I)
+
+ # For each match, look-up corresponding value in dictionary
+ # we look +1 to ignore the & that does not appear in the index
+ # we only look at the first 4 characters because we don't want to
+ # fail on &apos; as it's accepted (along with &apos - no
+ # semi-colon)
+ body = html_regex.sub( # pragma: no branch
+ lambda mo: telegram_escape_html_dict[
+ mo.string[mo.start():mo.end()][1:5]], body)
- else: # TEXT
- payload['parse_mode'] = 'HTML'
-
- # Escape content
- title = NotifyTelegram.escape_html(title, whitespace=False)
- body = NotifyTelegram.escape_html(body, whitespace=False)
+ if title:
+ # For each match, look-up corresponding value in dictionary
+ # Indexing is explained above (for how the body is parsed)
+ title = html_regex.sub( # pragma: no branch
+ lambda mo: telegram_escape_html_dict[
+ mo.string[mo.start():mo.end()][1:5]], title)
+
+ if self.notify_format == NotifyFormat.TEXT:
+ telegram_escape_text_dict = {
+ # We need to escape characters that conflict with html
+ # entity blocks (< and >) when displaying text
+ r'>': '&gt;',
+ r'<': '&lt;',
+ }
+
+ # Create a regular expression from the dictionary keys
+ text_regex = re.compile("(%s)" % "|".join(
+ map(re.escape, telegram_escape_text_dict.keys())).lower(),
+ re.I)
+
+ # For each match, look-up corresponding value in dictionary
+ body = text_regex.sub( # pragma: no branch
+ lambda mo: telegram_escape_text_dict[
+ mo.string[mo.start():mo.end()]], body)
+
+ if title:
+ # For each match, look-up corresponding value in dictionary
+ title = text_regex.sub( # pragma: no branch
+ lambda mo: telegram_escape_text_dict[
+ mo.string[mo.start():mo.end()]], title)
payload['text'] = '{}{}'.format(
'<b>{}</b>\r\n'.format(title) if title else '',
@@ -679,6 +740,8 @@ class NotifyTelegram(NotifyBase):
params = {
'image': self.include_image,
'detect': 'yes' if self.detect_owner else 'no',
+ 'silent': 'yes' if self.silent else 'no',
+ 'preview': 'yes' if self.preview else 'no',
}
# Extend our parameters
@@ -762,6 +825,15 @@ class NotifyTelegram(NotifyBase):
# Store our bot token
results['bot_token'] = bot_token
+ # Silent (Sends the message Silently); users will receive
+ # notification with no sound.
+ results['silent'] = \
+ parse_bool(results['qsd'].get('silent', False))
+
+ # Show Web Page Preview
+ results['preview'] = \
+ parse_bool(results['qsd'].get('preview', False))
+
# Include images with our message
results['include_image'] = \
parse_bool(results['qsd'].get('image', False))