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):
|
||||
"""
|
||||
A wrapper for Telegram Notifications
|
||||
|
@ -319,11 +336,17 @@ class NotifyTelegram(NotifyBase):
|
|||
'to': {
|
||||
'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,
|
||||
include_image=False, silent=None, preview=None, topic=None,
|
||||
**kwargs):
|
||||
content=None, **kwargs):
|
||||
"""
|
||||
Initialize Telegram Object
|
||||
"""
|
||||
|
@ -349,6 +372,15 @@ class NotifyTelegram(NotifyBase):
|
|||
self.preview = self.template_args['preview']['default'] \
|
||||
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:
|
||||
try:
|
||||
self.topic = int(topic)
|
||||
|
@ -713,6 +745,15 @@ class NotifyTelegram(NotifyBase):
|
|||
'Failed to send Telegram type image to {}.',
|
||||
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;
|
||||
# Telegram throttles to occur before sending the image so that
|
||||
# content can arrive together.
|
||||
|
@ -775,19 +816,35 @@ class NotifyTelegram(NotifyBase):
|
|||
|
||||
self.logger.info('Sent Telegram notification.')
|
||||
|
||||
if attach:
|
||||
# Send our attachments now (if specified and if it exists)
|
||||
for attachment in attach:
|
||||
if not self.send_media(
|
||||
payload['chat_id'], notify_type,
|
||||
attach=attachment):
|
||||
if attach and self.content == TelegramContentPlacement.BEFORE:
|
||||
# Send our attachments now (if specified and if it exists) as
|
||||
# it was identified to send the content before the attachments
|
||||
# which is now done.
|
||||
if not self._send_attachments(
|
||||
chat_id=payload['chat_id'],
|
||||
notify_type=notify_type,
|
||||
attach=attach):
|
||||
|
||||
# We failed; don't continue
|
||||
has_error = True
|
||||
break
|
||||
has_error = True
|
||||
continue
|
||||
|
||||
self.logger.info(
|
||||
'Sent Telegram attachment: {}.'.format(attachment))
|
||||
return not has_error
|
||||
|
||||
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
|
||||
|
||||
|
@ -802,6 +859,7 @@ class NotifyTelegram(NotifyBase):
|
|||
'detect': 'yes' if self.detect_owner else 'no',
|
||||
'silent': 'yes' if self.silent else 'no',
|
||||
'preview': 'yes' if self.preview else 'no',
|
||||
'content': self.content,
|
||||
}
|
||||
|
||||
if self.topic:
|
||||
|
@ -885,6 +943,10 @@ class NotifyTelegram(NotifyBase):
|
|||
# Store our chat ids (as these are the remaining 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
|
||||
# The 'to' makes it easier to use yaml configuration
|
||||
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', {
|
||||
'instance': TypeError,
|
||||
}),
|
||||
# content must be 'before' or 'after'
|
||||
('tgram://bottest@123456789:abcdefg_hijklmnop/id1/?content=invalid', {
|
||||
'instance': TypeError,
|
||||
}),
|
||||
# Testing image
|
||||
('tgram://123456789:abcdefg_hijklmnop/lead2gold/?image=Yes', {
|
||||
'instance': NotifyTelegram,
|
||||
|
@ -413,18 +417,26 @@ def test_plugin_telegram_general(mock_post):
|
|||
assert payload['text'] == \
|
||||
'<b>special characters</b>\r\n\'"This can\'t\t\r\nfail us"\'\r\n'
|
||||
|
||||
# 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
|
||||
for content in ('before', 'after'):
|
||||
# Test our content settings
|
||||
obj = NotifyTelegram(
|
||||
bot_token=bot_token, targets='12345', content=content)
|
||||
# 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
|
||||
path = os.path.join(TEST_VAR_DIR, '/invalid/path/to/an/invalid/file.jpg')
|
||||
attach = AppriseAttachment(path)
|
||||
assert obj.notify(
|
||||
body='body', title='title', notify_type=NotifyType.INFO,
|
||||
attach=path) is False
|
||||
# An invalid attachment will cause a failure
|
||||
path = os.path.join(
|
||||
TEST_VAR_DIR, '/invalid/path/to/an/invalid/file.jpg')
|
||||
attach = AppriseAttachment(path)
|
||||
assert obj.notify(
|
||||
body='body', title='title', notify_type=NotifyType.INFO,
|
||||
attach=path) is False
|
||||
|
||||
obj = NotifyTelegram(bot_token=bot_token, targets=None)
|
||||
# No user detected; this happens after our firsst notification
|
||||
|
|
Loading…
Reference in New Issue