|
|
|
@ -280,6 +280,40 @@ class NotifySlack(NotifyBase):
|
|
|
|
|
}, |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
# Formatting requirements are defined here: |
|
|
|
|
# https://api.slack.com/docs/message-formatting |
|
|
|
|
_re_formatting_map = { |
|
|
|
|
# New lines must become the string version |
|
|
|
|
r'\r\*\n': '\\n', |
|
|
|
|
# Escape other special characters |
|
|
|
|
r'&': '&', |
|
|
|
|
r'<': '<', |
|
|
|
|
r'>': '>', |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
# To notify a channel, one uses <!channel|channel> |
|
|
|
|
_re_channel_support = re.compile( |
|
|
|
|
r'(?P<match>(?:<|\<)?[ \t]*' |
|
|
|
|
r'!(?P<channel>[^| \n]+)' |
|
|
|
|
r'(?:[ \t]*\|[ \t]*(?:(?P<val>[^\n]+?)[ \t]*)?(?:>|\>)' |
|
|
|
|
r'|(?:>|\>)))', re.IGNORECASE) |
|
|
|
|
|
|
|
|
|
# To notify a user by their ID, one uses <@U6TTX1F9R> |
|
|
|
|
_re_user_id_support = re.compile( |
|
|
|
|
r'(?P<match>(?:<|\<)?[ \t]*' |
|
|
|
|
r'@(?P<userid>[^| \n]+)' |
|
|
|
|
r'(?:[ \t]*\|[ \t]*(?:(?P<val>[^\n]+?)[ \t]*)?(?:>|\>)' |
|
|
|
|
r'|(?:>|\>)))', re.IGNORECASE) |
|
|
|
|
|
|
|
|
|
# The markdown in slack isn't [desc](url), it's <url|desc> |
|
|
|
|
# |
|
|
|
|
# To accomodate this, we need to ensure we don't escape URLs that match |
|
|
|
|
_re_url_support = re.compile( |
|
|
|
|
r'(?P<match>(?:<|\<)?[ \t]*' |
|
|
|
|
r'(?P<url>(?:https?|mailto)://[^| \n]+)' |
|
|
|
|
r'(?:[ \t]*\|[ \t]*(?:(?P<val>[^\n]+?)[ \t]*)?(?:>|\>)' |
|
|
|
|
r'|(?:>|\>)))', re.IGNORECASE) |
|
|
|
|
|
|
|
|
|
def __init__(self, access_token=None, token_a=None, token_b=None, |
|
|
|
|
token_c=None, targets=None, include_image=True, |
|
|
|
|
include_footer=True, use_blocks=None, **kwargs): |
|
|
|
@ -344,39 +378,11 @@ class NotifySlack(NotifyBase):
|
|
|
|
|
None if self.mode is SlackMode.WEBHOOK |
|
|
|
|
else self.default_notification_channel) |
|
|
|
|
|
|
|
|
|
# Formatting requirements are defined here: |
|
|
|
|
# https://api.slack.com/docs/message-formatting |
|
|
|
|
self._re_formatting_map = { |
|
|
|
|
# New lines must become the string version |
|
|
|
|
r'\r\*\n': '\\n', |
|
|
|
|
# Escape other special characters |
|
|
|
|
r'&': '&', |
|
|
|
|
r'<': '<', |
|
|
|
|
r'>': '>', |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
# To notify a channel, one uses <!channel|channel> |
|
|
|
|
self._re_channel_support = re.compile( |
|
|
|
|
r'(?P<match>(?:<|\<)?[ \t]*' |
|
|
|
|
r'!(?P<channel>[^| \n]+)' |
|
|
|
|
r'(?:[ \t]*\|[ \t]*(?:(?P<val>[^\n]+?)[ \t]*)?(?:>|\>)' |
|
|
|
|
r'|(?:>|\>)))', re.IGNORECASE) |
|
|
|
|
|
|
|
|
|
# The markdown in slack isn't [desc](url), it's <url|desc> |
|
|
|
|
# |
|
|
|
|
# To accomodate this, we need to ensure we don't escape URLs that match |
|
|
|
|
self._re_url_support = re.compile( |
|
|
|
|
r'(?P<match>(?:<|\<)?[ \t]*' |
|
|
|
|
r'(?P<url>(?:https?|mailto)://[^| \n]+)' |
|
|
|
|
r'(?:[ \t]*\|[ \t]*(?:(?P<val>[^\n]+?)[ \t]*)?(?:>|\>)' |
|
|
|
|
r'|(?:>|\>)))', re.IGNORECASE) |
|
|
|
|
|
|
|
|
|
# Iterate over above list and store content accordingly |
|
|
|
|
self._re_formatting_rules = re.compile( |
|
|
|
|
r'(' + '|'.join(self._re_formatting_map.keys()) + r')', |
|
|
|
|
re.IGNORECASE, |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
# Place a thumbnail image inline with the message body |
|
|
|
|
self.include_image = include_image |
|
|
|
|
|
|
|
|
@ -478,6 +484,20 @@ class NotifySlack(NotifyBase):
|
|
|
|
|
body, |
|
|
|
|
re.IGNORECASE) |
|
|
|
|
|
|
|
|
|
# Support <@userid|desc>, <@channel> entries |
|
|
|
|
for match in self._re_user_id_support.findall(body): |
|
|
|
|
# Swap back any ampersands previously updaated |
|
|
|
|
user = match[1].strip() |
|
|
|
|
desc = match[2].strip() |
|
|
|
|
|
|
|
|
|
# Update our string |
|
|
|
|
body = re.sub( |
|
|
|
|
re.escape(match[0]), |
|
|
|
|
'<@{user}|{desc}>'.format(user=user, desc=desc) |
|
|
|
|
if desc else '<@{user}>'.format(user=user), |
|
|
|
|
body, |
|
|
|
|
re.IGNORECASE) |
|
|
|
|
|
|
|
|
|
# Support <url|desc>, <url> entries |
|
|
|
|
for match in self._re_url_support.findall(body): |
|
|
|
|
# Swap back any ampersands previously updaated |
|
|
|
|