mirror of https://github.com/caronc/apprise
Telegram control over attachments displayed before or after content (#883)
parent
c60e35841f
commit
3346977297
|
@ -84,6 +84,23 @@ IS_CHAT_ID_RE = re.compile(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TelegramContentPlacement:
|
||||||
|
"""
|
||||||
|
The Telegram Content Placement
|
||||||
|
"""
|
||||||
|
# Before Attachments
|
||||||
|
BEFORE = "before"
|
||||||
|
# After Attachments
|
||||||
|
AFTER = "after"
|
||||||
|
|
||||||
|
|
||||||
|
# Identify Placement Categories
|
||||||
|
TELEGRAM_CONTENT_PLACEMENT = (
|
||||||
|
TelegramContentPlacement.BEFORE,
|
||||||
|
TelegramContentPlacement.AFTER,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class NotifyTelegram(NotifyBase):
|
class NotifyTelegram(NotifyBase):
|
||||||
"""
|
"""
|
||||||
A wrapper for Telegram Notifications
|
A wrapper for Telegram Notifications
|
||||||
|
@ -319,11 +336,17 @@ class NotifyTelegram(NotifyBase):
|
||||||
'to': {
|
'to': {
|
||||||
'alias_of': 'targets',
|
'alias_of': 'targets',
|
||||||
},
|
},
|
||||||
|
'content': {
|
||||||
|
'name': _('Content Placement'),
|
||||||
|
'type': 'choice:string',
|
||||||
|
'values': TELEGRAM_CONTENT_PLACEMENT,
|
||||||
|
'default': TelegramContentPlacement.BEFORE,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
def __init__(self, bot_token, targets, detect_owner=True,
|
def __init__(self, bot_token, targets, detect_owner=True,
|
||||||
include_image=False, silent=None, preview=None, topic=None,
|
include_image=False, silent=None, preview=None, topic=None,
|
||||||
**kwargs):
|
content=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Initialize Telegram Object
|
Initialize Telegram Object
|
||||||
"""
|
"""
|
||||||
|
@ -349,6 +372,15 @@ class NotifyTelegram(NotifyBase):
|
||||||
self.preview = self.template_args['preview']['default'] \
|
self.preview = self.template_args['preview']['default'] \
|
||||||
if preview is None else bool(preview)
|
if preview is None else bool(preview)
|
||||||
|
|
||||||
|
# Setup our content placement
|
||||||
|
self.content = self.template_args['content']['default'] \
|
||||||
|
if not isinstance(content, str) else content.lower()
|
||||||
|
if self.content and self.content not in TELEGRAM_CONTENT_PLACEMENT:
|
||||||
|
msg = 'The content placement specified ({}) is invalid.'\
|
||||||
|
.format(content)
|
||||||
|
self.logger.warning(msg)
|
||||||
|
raise TypeError(msg)
|
||||||
|
|
||||||
if topic:
|
if topic:
|
||||||
try:
|
try:
|
||||||
self.topic = int(topic)
|
self.topic = int(topic)
|
||||||
|
@ -713,6 +745,15 @@ class NotifyTelegram(NotifyBase):
|
||||||
'Failed to send Telegram type image to {}.',
|
'Failed to send Telegram type image to {}.',
|
||||||
payload['chat_id'])
|
payload['chat_id'])
|
||||||
|
|
||||||
|
if attach and self.content == TelegramContentPlacement.AFTER:
|
||||||
|
# Send our attachments now (if specified and if it exists)
|
||||||
|
if not self._send_attachments(
|
||||||
|
chat_id=payload['chat_id'], notify_type=notify_type,
|
||||||
|
attach=attach):
|
||||||
|
|
||||||
|
has_error = True
|
||||||
|
continue
|
||||||
|
|
||||||
# Always call throttle before any remote server i/o is made;
|
# Always call throttle before any remote server i/o is made;
|
||||||
# Telegram throttles to occur before sending the image so that
|
# Telegram throttles to occur before sending the image so that
|
||||||
# content can arrive together.
|
# content can arrive together.
|
||||||
|
@ -775,19 +816,35 @@ class NotifyTelegram(NotifyBase):
|
||||||
|
|
||||||
self.logger.info('Sent Telegram notification.')
|
self.logger.info('Sent Telegram notification.')
|
||||||
|
|
||||||
if attach:
|
if attach and self.content == TelegramContentPlacement.BEFORE:
|
||||||
# Send our attachments now (if specified and if it exists)
|
# Send our attachments now (if specified and if it exists) as
|
||||||
for attachment in attach:
|
# it was identified to send the content before the attachments
|
||||||
if not self.send_media(
|
# which is now done.
|
||||||
payload['chat_id'], notify_type,
|
if not self._send_attachments(
|
||||||
attach=attachment):
|
chat_id=payload['chat_id'],
|
||||||
|
notify_type=notify_type,
|
||||||
|
attach=attach):
|
||||||
|
|
||||||
# We failed; don't continue
|
has_error = True
|
||||||
has_error = True
|
continue
|
||||||
break
|
|
||||||
|
|
||||||
self.logger.info(
|
return not has_error
|
||||||
'Sent Telegram attachment: {}.'.format(attachment))
|
|
||||||
|
def _send_attachments(self, chat_id, notify_type, attach):
|
||||||
|
"""
|
||||||
|
Sends our attachments
|
||||||
|
"""
|
||||||
|
has_error = False
|
||||||
|
# Send our attachments now (if specified and if it exists)
|
||||||
|
for attachment in attach:
|
||||||
|
if not self.send_media(chat_id, notify_type, attach=attachment):
|
||||||
|
|
||||||
|
# We failed; don't continue
|
||||||
|
has_error = True
|
||||||
|
break
|
||||||
|
|
||||||
|
self.logger.info(
|
||||||
|
'Sent Telegram attachment: {}.'.format(attachment))
|
||||||
|
|
||||||
return not has_error
|
return not has_error
|
||||||
|
|
||||||
|
@ -802,6 +859,7 @@ class NotifyTelegram(NotifyBase):
|
||||||
'detect': 'yes' if self.detect_owner else 'no',
|
'detect': 'yes' if self.detect_owner else 'no',
|
||||||
'silent': 'yes' if self.silent else 'no',
|
'silent': 'yes' if self.silent else 'no',
|
||||||
'preview': 'yes' if self.preview else 'no',
|
'preview': 'yes' if self.preview else 'no',
|
||||||
|
'content': self.content,
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.topic:
|
if self.topic:
|
||||||
|
@ -885,6 +943,10 @@ class NotifyTelegram(NotifyBase):
|
||||||
# Store our chat ids (as these are the remaining entries)
|
# Store our chat ids (as these are the remaining entries)
|
||||||
results['targets'] = entries
|
results['targets'] = entries
|
||||||
|
|
||||||
|
# content to be displayed 'before' or 'after' attachments
|
||||||
|
if 'content' in results['qsd'] and len(results['qsd']['content']):
|
||||||
|
results['content'] = results['qsd']['content']
|
||||||
|
|
||||||
# Support the 'to' variable so that we can support rooms this way too
|
# Support the 'to' variable so that we can support rooms this way too
|
||||||
# The 'to' makes it easier to use yaml configuration
|
# The 'to' makes it easier to use yaml configuration
|
||||||
if 'to' in results['qsd'] and len(results['qsd']['to']):
|
if 'to' in results['qsd'] and len(results['qsd']['to']):
|
||||||
|
|
|
@ -106,6 +106,10 @@ apprise_url_tests = (
|
||||||
('tgram://bottest@123456789:abcdefg_hijklmnop/id1/?topic=invalid', {
|
('tgram://bottest@123456789:abcdefg_hijklmnop/id1/?topic=invalid', {
|
||||||
'instance': TypeError,
|
'instance': TypeError,
|
||||||
}),
|
}),
|
||||||
|
# content must be 'before' or 'after'
|
||||||
|
('tgram://bottest@123456789:abcdefg_hijklmnop/id1/?content=invalid', {
|
||||||
|
'instance': TypeError,
|
||||||
|
}),
|
||||||
# Testing image
|
# Testing image
|
||||||
('tgram://123456789:abcdefg_hijklmnop/lead2gold/?image=Yes', {
|
('tgram://123456789:abcdefg_hijklmnop/lead2gold/?image=Yes', {
|
||||||
'instance': NotifyTelegram,
|
'instance': NotifyTelegram,
|
||||||
|
@ -413,18 +417,26 @@ def test_plugin_telegram_general(mock_post):
|
||||||
assert payload['text'] == \
|
assert payload['text'] == \
|
||||||
'<b>special characters</b>\r\n\'"This can\'t\t\r\nfail us"\'\r\n'
|
'<b>special characters</b>\r\n\'"This can\'t\t\r\nfail us"\'\r\n'
|
||||||
|
|
||||||
# Test sending attachments
|
for content in ('before', 'after'):
|
||||||
attach = AppriseAttachment(os.path.join(TEST_VAR_DIR, 'apprise-test.gif'))
|
# Test our content settings
|
||||||
assert obj.notify(
|
obj = NotifyTelegram(
|
||||||
body='body', title='title', notify_type=NotifyType.INFO,
|
bot_token=bot_token, targets='12345', content=content)
|
||||||
attach=attach) is True
|
# Reset our mock
|
||||||
|
mock_post.reset_mock()
|
||||||
|
# Test sending attachments
|
||||||
|
attach = AppriseAttachment(
|
||||||
|
os.path.join(TEST_VAR_DIR, 'apprise-test.gif'))
|
||||||
|
assert obj.notify(
|
||||||
|
body='body', title='title', notify_type=NotifyType.INFO,
|
||||||
|
attach=attach) is True
|
||||||
|
|
||||||
# An invalid attachment will cause a failure
|
# An invalid attachment will cause a failure
|
||||||
path = os.path.join(TEST_VAR_DIR, '/invalid/path/to/an/invalid/file.jpg')
|
path = os.path.join(
|
||||||
attach = AppriseAttachment(path)
|
TEST_VAR_DIR, '/invalid/path/to/an/invalid/file.jpg')
|
||||||
assert obj.notify(
|
attach = AppriseAttachment(path)
|
||||||
body='body', title='title', notify_type=NotifyType.INFO,
|
assert obj.notify(
|
||||||
attach=path) is False
|
body='body', title='title', notify_type=NotifyType.INFO,
|
||||||
|
attach=path) is False
|
||||||
|
|
||||||
obj = NotifyTelegram(bot_token=bot_token, targets=None)
|
obj = NotifyTelegram(bot_token=bot_token, targets=None)
|
||||||
# No user detected; this happens after our firsst notification
|
# No user detected; this happens after our firsst notification
|
||||||
|
|
Loading…
Reference in New Issue