mirror of
https://github.com/caronc/apprise.git
synced 2025-01-17 03:19:23 +01:00
Refactored Slack plugin to allow users to switch between payload types (#482)
This commit is contained in:
parent
a9ce6b3556
commit
76700bfa1d
@ -73,6 +73,7 @@ import re
|
||||
import requests
|
||||
from json import dumps
|
||||
from json import loads
|
||||
from time import time
|
||||
|
||||
from .NotifyBase import NotifyBase
|
||||
from ..common import NotifyImageSize
|
||||
@ -254,6 +255,14 @@ class NotifySlack(NotifyBase):
|
||||
'default': True,
|
||||
'map_to': 'include_footer',
|
||||
},
|
||||
# Use Payload in Blocks (vs legacy way):
|
||||
# See: https://api.slack.com/reference/messaging/payload
|
||||
'blocks': {
|
||||
'name': _('Use Blocks'),
|
||||
'type': 'bool',
|
||||
'default': False,
|
||||
'map_to': 'use_blocks',
|
||||
},
|
||||
'to': {
|
||||
'alias_of': 'targets',
|
||||
},
|
||||
@ -265,7 +274,7 @@ class NotifySlack(NotifyBase):
|
||||
|
||||
def __init__(self, access_token=None, token_a=None, token_b=None,
|
||||
token_c=None, targets=None, include_image=True,
|
||||
include_footer=True, **kwargs):
|
||||
include_footer=True, use_blocks=None, **kwargs):
|
||||
"""
|
||||
Initialize Slack Object
|
||||
"""
|
||||
@ -316,6 +325,11 @@ class NotifySlack(NotifyBase):
|
||||
# specify a full email as a recipient via slack
|
||||
self._lookup_users = {}
|
||||
|
||||
self.use_blocks = parse_bool(
|
||||
use_blocks, self.template_args['blocks']['default']) \
|
||||
if use_blocks is not None \
|
||||
else self.template_args['blocks']['default']
|
||||
|
||||
# Build list of channels
|
||||
self.channels = parse_list(targets)
|
||||
if len(self.channels) == 0:
|
||||
@ -359,19 +373,15 @@ class NotifySlack(NotifyBase):
|
||||
# error tracking (used for function return)
|
||||
has_error = False
|
||||
|
||||
# Perform Formatting
|
||||
title = self._re_formatting_rules.sub( # pragma: no branch
|
||||
lambda x: self._re_formatting_map[x.group()], title,
|
||||
)
|
||||
# Only for NONE markdown, otherwise eg links wont work
|
||||
if self.notify_format != NotifyFormat.MARKDOWN:
|
||||
body = self._re_formatting_rules.sub( # pragma: no branch
|
||||
lambda x: self._re_formatting_map[x.group()], body,
|
||||
)
|
||||
|
||||
#
|
||||
# Prepare JSON Object (applicable to both WEBHOOK and BOT mode)
|
||||
#
|
||||
if self.use_blocks:
|
||||
# Our slack format
|
||||
_slack_format = 'mrkdwn' \
|
||||
if self.notify_format == NotifyFormat.MARKDOWN else 'plain_text'
|
||||
if self.notify_format == NotifyFormat.MARKDOWN \
|
||||
else 'plain_text'
|
||||
|
||||
payload = {
|
||||
'username': self.user if self.user else self.app_id,
|
||||
'attachments': [{
|
||||
@ -397,20 +407,14 @@ class NotifySlack(NotifyBase):
|
||||
}
|
||||
})
|
||||
|
||||
# Prepare our URL (depends on mode)
|
||||
if self.mode is SlackMode.WEBHOOK:
|
||||
url = '{}/{}/{}/{}'.format(
|
||||
self.webhook_url,
|
||||
self.token_a,
|
||||
self.token_b,
|
||||
self.token_c,
|
||||
)
|
||||
|
||||
else: # SlackMode.BOT
|
||||
url = self.api_url.format('chat.postMessage')
|
||||
|
||||
# Include the footer only if specified to do so
|
||||
if self.include_footer:
|
||||
|
||||
# Acquire our to-be footer icon if configured to do so
|
||||
image_url = None if not self.include_image \
|
||||
else self.image_url(notify_type)
|
||||
|
||||
# Prepare our footer based on the block structure
|
||||
_footer = {
|
||||
'type': 'context',
|
||||
'elements': [{
|
||||
@ -419,10 +423,6 @@ class NotifySlack(NotifyBase):
|
||||
}]
|
||||
}
|
||||
|
||||
# Acquire our to-be footer icon if configured to do so
|
||||
image_url = None if not self.include_image \
|
||||
else self.image_url(notify_type)
|
||||
|
||||
if image_url:
|
||||
payload['icon_url'] = image_url
|
||||
|
||||
@ -434,12 +434,67 @@ class NotifySlack(NotifyBase):
|
||||
|
||||
payload['attachments'][0]['blocks'].append(_footer)
|
||||
|
||||
else:
|
||||
#
|
||||
# Legacy API Formatting
|
||||
#
|
||||
if self.notify_format == NotifyFormat.MARKDOWN:
|
||||
body = self._re_formatting_rules.sub( # pragma: no branch
|
||||
lambda x: self._re_formatting_map[x.group()], body,
|
||||
)
|
||||
|
||||
# Perform Formatting on title here; this is not needed for block
|
||||
# mode above
|
||||
title = self._re_formatting_rules.sub( # pragma: no branch
|
||||
lambda x: self._re_formatting_map[x.group()], title,
|
||||
)
|
||||
|
||||
# Prepare JSON Object (applicable to both WEBHOOK and BOT mode)
|
||||
payload = {
|
||||
'username': self.user if self.user else self.app_id,
|
||||
# Use Markdown language
|
||||
'mrkdwn': (self.notify_format == NotifyFormat.MARKDOWN),
|
||||
'attachments': [{
|
||||
'title': title,
|
||||
'text': body,
|
||||
'color': self.color(notify_type),
|
||||
# Time
|
||||
'ts': time(),
|
||||
}],
|
||||
}
|
||||
# Acquire our to-be footer icon if configured to do so
|
||||
image_url = None if not self.include_image \
|
||||
else self.image_url(notify_type)
|
||||
|
||||
if image_url:
|
||||
payload['icon_url'] = image_url
|
||||
|
||||
# Include the footer only if specified to do so
|
||||
if self.include_footer:
|
||||
if image_url:
|
||||
payload['attachments'][0]['footer_icon'] = image_url
|
||||
|
||||
# Include the footer only if specified to do so
|
||||
payload['attachments'][0]['footer'] = self.app_id
|
||||
|
||||
if attach and self.mode is SlackMode.WEBHOOK:
|
||||
# Be friendly; let the user know why they can't send their
|
||||
# attachments if using the Webhook mode
|
||||
self.logger.warning(
|
||||
'Slack Webhooks do not support attachments.')
|
||||
|
||||
# Prepare our Slack URL (depends on mode)
|
||||
if self.mode is SlackMode.WEBHOOK:
|
||||
url = '{}/{}/{}/{}'.format(
|
||||
self.webhook_url,
|
||||
self.token_a,
|
||||
self.token_b,
|
||||
self.token_c,
|
||||
)
|
||||
|
||||
else: # SlackMode.BOT
|
||||
url = self.api_url.format('chat.postMessage')
|
||||
|
||||
# Create a copy of the channel list
|
||||
channels = list(self.channels)
|
||||
|
||||
@ -875,6 +930,7 @@ class NotifySlack(NotifyBase):
|
||||
params = {
|
||||
'image': 'yes' if self.include_image else 'no',
|
||||
'footer': 'yes' if self.include_footer else 'no',
|
||||
'blocks': 'yes' if self.use_blocks else 'no',
|
||||
}
|
||||
|
||||
# Extend our parameters
|
||||
@ -978,6 +1034,10 @@ class NotifySlack(NotifyBase):
|
||||
results['include_image'] = \
|
||||
parse_bool(results['qsd'].get('image', True))
|
||||
|
||||
# Get Payload structure (use blocks?)
|
||||
if 'blocks' in results['qsd'] and len(results['qsd']['blocks']):
|
||||
results['use_blocks'] = parse_bool(results['qsd']['blocks'])
|
||||
|
||||
# Get Footer Flag
|
||||
results['include_footer'] = \
|
||||
parse_bool(results['qsd'].get('footer', True))
|
||||
|
@ -694,10 +694,7 @@ def parse_url(url, default_schema='http', verify_host=True):
|
||||
|
||||
def parse_bool(arg, default=False):
|
||||
"""
|
||||
NZBGet uses 'yes' and 'no' as well as other strings such as 'on' or
|
||||
'off' etch to handle boolean operations from it's control interface.
|
||||
|
||||
This method can just simplify checks to these variables.
|
||||
Support string based boolean settings.
|
||||
|
||||
If the content could not be parsed, then the default is returned.
|
||||
"""
|
||||
|
@ -4859,6 +4859,33 @@ TEST_URLS = (
|
||||
},
|
||||
},
|
||||
}),
|
||||
# Test blocks mode
|
||||
('slack://?token=T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/'
|
||||
'&to=#chan&blocks=yes&footer=yes',
|
||||
{
|
||||
'instance': plugins.NotifySlack,
|
||||
'requests_response_text': 'ok'}),
|
||||
('slack://?token=T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/'
|
||||
'&to=#chan&blocks=yes&footer=no',
|
||||
{
|
||||
'instance': plugins.NotifySlack,
|
||||
'requests_response_text': 'ok'}),
|
||||
('slack://?token=T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/'
|
||||
'&to=#chan&blocks=yes&footer=yes&image=no',
|
||||
{
|
||||
'instance': plugins.NotifySlack,
|
||||
'requests_response_text': 'ok'}),
|
||||
('slack://?token=T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/'
|
||||
'&to=#chan&blocks=yes&format=text',
|
||||
{
|
||||
'instance': plugins.NotifySlack,
|
||||
'requests_response_text': 'ok'}),
|
||||
('slack://?token=T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/'
|
||||
'&to=#chan&blocks=no&format=text',
|
||||
{
|
||||
'instance': plugins.NotifySlack,
|
||||
'requests_response_text': 'ok'}),
|
||||
|
||||
# Test using a bot-token as argument
|
||||
('slack://?token=xoxb-1234-1234-abc124&to=#nuxref&footer=no&user=test', {
|
||||
'instance': plugins.NotifySlack,
|
||||
|
Loading…
Reference in New Issue
Block a user