mirror of
https://github.com/caronc/apprise.git
synced 2024-11-25 09:33:50 +01:00
Refactored the way Notifiarr Discord users are mentioned (#1153)
This commit is contained in:
parent
e053484fd1
commit
631ce107cd
@ -37,6 +37,7 @@ from ..locale import gettext_lazy as _
|
|||||||
from ..common import NotifyImageSize
|
from ..common import NotifyImageSize
|
||||||
from ..utils import parse_list, parse_bool
|
from ..utils import parse_list, parse_bool
|
||||||
from ..utils import validate_regex
|
from ..utils import validate_regex
|
||||||
|
from .discord import USER_ROLE_DETECTION_RE
|
||||||
|
|
||||||
# Used to break path apart into list of channels
|
# Used to break path apart into list of channels
|
||||||
CHANNEL_LIST_DELIM = re.compile(r'[ \t\r\n,#\\/]+')
|
CHANNEL_LIST_DELIM = re.compile(r'[ \t\r\n,#\\/]+')
|
||||||
@ -118,14 +119,6 @@ class NotifyNotifiarr(NotifyBase):
|
|||||||
'apikey': {
|
'apikey': {
|
||||||
'alias_of': 'apikey',
|
'alias_of': 'apikey',
|
||||||
},
|
},
|
||||||
'discord_user': {
|
|
||||||
'name': _('Ping Discord User'),
|
|
||||||
'type': 'int',
|
|
||||||
},
|
|
||||||
'discord_role': {
|
|
||||||
'name': _('Ping Discord Role'),
|
|
||||||
'type': 'int',
|
|
||||||
},
|
|
||||||
'event': {
|
'event': {
|
||||||
'name': _('Discord Event ID'),
|
'name': _('Discord Event ID'),
|
||||||
'type': 'int',
|
'type': 'int',
|
||||||
@ -149,7 +142,6 @@ class NotifyNotifiarr(NotifyBase):
|
|||||||
})
|
})
|
||||||
|
|
||||||
def __init__(self, apikey=None, include_image=None,
|
def __init__(self, apikey=None, include_image=None,
|
||||||
discord_user=None, discord_role=None,
|
|
||||||
event=None, targets=None, source=None, **kwargs):
|
event=None, targets=None, source=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Initialize Notifiarr Object
|
Initialize Notifiarr Object
|
||||||
@ -172,30 +164,6 @@ class NotifyNotifiarr(NotifyBase):
|
|||||||
if isinstance(include_image, bool) \
|
if isinstance(include_image, bool) \
|
||||||
else self.template_args['image']['default']
|
else self.template_args['image']['default']
|
||||||
|
|
||||||
# Set up our user if specified
|
|
||||||
self.discord_user = 0
|
|
||||||
if discord_user:
|
|
||||||
try:
|
|
||||||
self.discord_user = int(discord_user)
|
|
||||||
|
|
||||||
except (ValueError, TypeError):
|
|
||||||
msg = 'An invalid Notifiarr User ID ' \
|
|
||||||
'({}) was specified.'.format(discord_user)
|
|
||||||
self.logger.warning(msg)
|
|
||||||
raise TypeError(msg)
|
|
||||||
|
|
||||||
# Set up our role if specified
|
|
||||||
self.discord_role = 0
|
|
||||||
if discord_role:
|
|
||||||
try:
|
|
||||||
self.discord_role = int(discord_role)
|
|
||||||
|
|
||||||
except (ValueError, TypeError):
|
|
||||||
msg = 'An invalid Notifiarr Role ID ' \
|
|
||||||
'({}) was specified.'.format(discord_role)
|
|
||||||
self.logger.warning(msg)
|
|
||||||
raise TypeError(msg)
|
|
||||||
|
|
||||||
# Prepare our source (if set)
|
# Prepare our source (if set)
|
||||||
self.source = validate_regex(source)
|
self.source = validate_regex(source)
|
||||||
|
|
||||||
@ -244,12 +212,6 @@ class NotifyNotifiarr(NotifyBase):
|
|||||||
if self.source:
|
if self.source:
|
||||||
params['source'] = self.source
|
params['source'] = self.source
|
||||||
|
|
||||||
if self.discord_user:
|
|
||||||
params['discord_user'] = self.discord_user
|
|
||||||
|
|
||||||
if self.discord_role:
|
|
||||||
params['discord_role'] = self.discord_role
|
|
||||||
|
|
||||||
if self.event:
|
if self.event:
|
||||||
params['event'] = self.event
|
params['event'] = self.event
|
||||||
|
|
||||||
@ -287,6 +249,29 @@ class NotifyNotifiarr(NotifyBase):
|
|||||||
# Acquire image_url
|
# Acquire image_url
|
||||||
image_url = self.image_url(notify_type)
|
image_url = self.image_url(notify_type)
|
||||||
|
|
||||||
|
# Define our mentions
|
||||||
|
mentions = {
|
||||||
|
'pingUser': [],
|
||||||
|
'pingRole': [],
|
||||||
|
'content': [],
|
||||||
|
}
|
||||||
|
|
||||||
|
# parse for user id's <@123> and role IDs <@&456>
|
||||||
|
results = USER_ROLE_DETECTION_RE.findall(body)
|
||||||
|
if results:
|
||||||
|
for (is_role, no, value) in results:
|
||||||
|
if value:
|
||||||
|
# @everybody, @admin, etc - unsupported
|
||||||
|
mentions['content'].append(f'@{value}')
|
||||||
|
|
||||||
|
elif is_role:
|
||||||
|
mentions['pingRole'].append(no)
|
||||||
|
mentions['content'].append(f'<@&{no}>')
|
||||||
|
|
||||||
|
else: # is_user
|
||||||
|
mentions['pingUser'].append(no)
|
||||||
|
mentions['content'].append(f'<@{no}>')
|
||||||
|
|
||||||
for idx, channel in enumerate(self.targets['channels']):
|
for idx, channel in enumerate(self.targets['channels']):
|
||||||
# prepare Notifiarr Object
|
# prepare Notifiarr Object
|
||||||
payload = {
|
payload = {
|
||||||
@ -301,14 +286,17 @@ class NotifyNotifiarr(NotifyBase):
|
|||||||
'discord': {
|
'discord': {
|
||||||
'color': self.color(notify_type),
|
'color': self.color(notify_type),
|
||||||
'ping': {
|
'ping': {
|
||||||
'pingUser': self.discord_user
|
# Only 1 user is supported, so truncate the rest
|
||||||
if not idx and self.discord_user else 0,
|
'pingUser': 0 if not mentions['pingUser']
|
||||||
'pingRole': self.discord_role
|
else mentions['pingUser'][0],
|
||||||
if not idx and self.discord_role else 0,
|
# Only 1 role is supported, so truncate the rest
|
||||||
|
'pingRole': 0 if not mentions['pingRole']
|
||||||
|
else mentions['pingRole'][0],
|
||||||
},
|
},
|
||||||
'text': {
|
'text': {
|
||||||
'title': title,
|
'title': title,
|
||||||
'content': '',
|
'content': '' if not mentions['content']
|
||||||
|
else '👉 ' + ' '.join(mentions['content']),
|
||||||
'description': body,
|
'description': body,
|
||||||
'footer': self.app_desc,
|
'footer': self.app_desc,
|
||||||
},
|
},
|
||||||
@ -410,17 +398,6 @@ class NotifyNotifiarr(NotifyBase):
|
|||||||
# Get channels
|
# Get channels
|
||||||
results['targets'] = NotifyNotifiarr.split_path(results['fullpath'])
|
results['targets'] = NotifyNotifiarr.split_path(results['fullpath'])
|
||||||
|
|
||||||
if 'discord_user' in results['qsd'] and \
|
|
||||||
len(results['qsd']['discord_user']):
|
|
||||||
results['discord_user'] = \
|
|
||||||
NotifyNotifiarr.unquote(
|
|
||||||
results['qsd']['discord_user'])
|
|
||||||
|
|
||||||
if 'discord_role' in results['qsd'] and \
|
|
||||||
len(results['qsd']['discord_role']):
|
|
||||||
results['discord_role'] = \
|
|
||||||
NotifyNotifiarr.unquote(results['qsd']['discord_role'])
|
|
||||||
|
|
||||||
if 'event' in results['qsd'] and \
|
if 'event' in results['qsd'] and \
|
||||||
len(results['qsd']['event']):
|
len(results['qsd']['event']):
|
||||||
results['event'] = \
|
results['event'] = \
|
||||||
|
@ -27,9 +27,11 @@
|
|||||||
# POSSIBILITY OF SUCH DAMAGE.
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
from unittest import mock
|
||||||
from apprise.plugins.notifiarr import NotifyNotifiarr
|
from apprise.plugins.notifiarr import NotifyNotifiarr
|
||||||
from helpers import AppriseURLTester
|
from helpers import AppriseURLTester
|
||||||
|
from json import loads
|
||||||
|
from inspect import cleandoc
|
||||||
|
|
||||||
# Disable logging for a cleaner testing output
|
# Disable logging for a cleaner testing output
|
||||||
import logging
|
import logging
|
||||||
@ -52,12 +54,6 @@ apprise_url_tests = (
|
|||||||
# Our expected url(privacy=True) startswith() response:
|
# Our expected url(privacy=True) startswith() response:
|
||||||
'privacy_url': 'notifiarr://a...y',
|
'privacy_url': 'notifiarr://a...y',
|
||||||
}),
|
}),
|
||||||
('notifiarr://apikey/1234/?discord_user=invalid', {
|
|
||||||
'instance': TypeError,
|
|
||||||
}),
|
|
||||||
('notifiarr://apikey/1234/?discord_role=invalid', {
|
|
||||||
'instance': TypeError,
|
|
||||||
}),
|
|
||||||
('notifiarr://apikey/1234/?event=invalid', {
|
('notifiarr://apikey/1234/?event=invalid', {
|
||||||
'instance': TypeError,
|
'instance': TypeError,
|
||||||
}),
|
}),
|
||||||
@ -131,11 +127,6 @@ apprise_url_tests = (
|
|||||||
# Our expected url(privacy=True) startswith() response:
|
# Our expected url(privacy=True) startswith() response:
|
||||||
'privacy_url': 'notifiarr://m...y/#123/#325',
|
'privacy_url': 'notifiarr://m...y/#123/#325',
|
||||||
}),
|
}),
|
||||||
('notifiarr://12/?key=myapikey&discord_user=23'
|
|
||||||
'&discord_role=12&event=123', {
|
|
||||||
'instance': NotifyNotifiarr,
|
|
||||||
# Our expected url(privacy=True) startswith() response:
|
|
||||||
'privacy_url': 'notifiarr://m...y/#12'}),
|
|
||||||
('notifiarr://apikey/123/', {
|
('notifiarr://apikey/123/', {
|
||||||
'instance': NotifyNotifiarr,
|
'instance': NotifyNotifiarr,
|
||||||
}),
|
}),
|
||||||
@ -160,7 +151,7 @@ apprise_url_tests = (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_plugin_custom_notifiarr_urls():
|
def test_plugin_notifiarr_urls():
|
||||||
"""
|
"""
|
||||||
NotifyNotifiarr() Apprise URLs
|
NotifyNotifiarr() Apprise URLs
|
||||||
|
|
||||||
@ -168,3 +159,64 @@ def test_plugin_custom_notifiarr_urls():
|
|||||||
|
|
||||||
# Run our general tests
|
# Run our general tests
|
||||||
AppriseURLTester(tests=apprise_url_tests).run_all()
|
AppriseURLTester(tests=apprise_url_tests).run_all()
|
||||||
|
|
||||||
|
|
||||||
|
@mock.patch('requests.post')
|
||||||
|
def test_plugin_notifiarr_notifications(mock_post):
|
||||||
|
"""
|
||||||
|
NotifyNotifiarr() Notifications/Ping Support
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Test our header parsing when not lead with a header
|
||||||
|
body = cleandoc("""
|
||||||
|
# Heading
|
||||||
|
@everyone and @admin, wake and meet our new user <@123> and <@987>;
|
||||||
|
Attention Roles: <@&456> and <@&765>
|
||||||
|
""")
|
||||||
|
|
||||||
|
# Prepare a good response
|
||||||
|
response = mock.Mock()
|
||||||
|
response.status_code = requests.codes.ok
|
||||||
|
|
||||||
|
# Prepare Mock return object
|
||||||
|
mock_post.return_value = response
|
||||||
|
|
||||||
|
results = NotifyNotifiarr.parse_url('notifiarr://apikey/12345')
|
||||||
|
|
||||||
|
instance = NotifyNotifiarr(**results)
|
||||||
|
assert isinstance(instance, NotifyNotifiarr)
|
||||||
|
|
||||||
|
response = instance.send(body=body)
|
||||||
|
assert response is True
|
||||||
|
assert mock_post.call_count == 1
|
||||||
|
|
||||||
|
details = mock_post.call_args_list[0]
|
||||||
|
assert details[0][0] == \
|
||||||
|
'https://notifiarr.com/api/v1/notification/apprise'
|
||||||
|
|
||||||
|
payload = loads(details[1]['data'])
|
||||||
|
|
||||||
|
# First role and first user stored
|
||||||
|
assert payload == {
|
||||||
|
'source': 'Apprise',
|
||||||
|
'type': 'info',
|
||||||
|
'notification': {'update': False, 'name': 'Apprise', 'event': ''},
|
||||||
|
'discord': {
|
||||||
|
'color': '#3AA3E3', 'ping': {
|
||||||
|
# Only supports 1 entry each; so first one is parsed
|
||||||
|
'pingUser': '123',
|
||||||
|
'pingRole': '456',
|
||||||
|
},
|
||||||
|
'text': {
|
||||||
|
'title': '',
|
||||||
|
'content': '👉 @everyone @admin <@123> <@987> <@&456> <@&765>',
|
||||||
|
'description':
|
||||||
|
'# Heading\n@everyone and @admin, wake and meet our new '
|
||||||
|
'user <@123> and <@987>;\nAttention Roles: <@&456> and '
|
||||||
|
'<@&765>\n ',
|
||||||
|
'footer': 'Apprise Notifications',
|
||||||
|
},
|
||||||
|
'ids': {'channel': 12345},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user