Browse Source

Set the "title" and "summary" fields in MS Teams notifications

Fixes: #435
pull/456/head
Pēteris Caune 4 years ago
parent
commit
463ec8c988
No known key found for this signature in database GPG Key ID: E28D7679E9A9EDE2
4 changed files with 36 additions and 12 deletions
  1. +1
    -0
      CHANGELOG.md
  2. +10
    -3
      hc/api/tests/test_notify.py
  3. +24
    -7
      hc/api/transports.py
  4. +1
    -2
      templates/integrations/msteams_message.json

+ 1
- 0
CHANGELOG.md View File

@ -21,6 +21,7 @@ All notable changes to this project will be documented in this file.
- Fix missing Resume button (#421)
- When decoding inbound emails, decode encoded headers (#420)
- Escape markdown in MS Teams notifications (#426)
- Set the "title" and "summary" fields in MS Teams notifications (#435)
## v1.16.0 - 2020-08-04


+ 10
- 3
hc/api/tests/test_notify.py View File

@ -859,6 +859,8 @@ class NotifyTestCase(BaseTestCase):
self._setup_data("msteams", "http://example.com/webhook")
mock_post.return_value.status_code = 200
self.check.name = "_underscores_ & more"
self.channel.notify(self.check)
assert Notification.objects.count() == 1
@ -866,19 +868,24 @@ class NotifyTestCase(BaseTestCase):
payload = kwargs["json"]
self.assertEqual(payload["@type"], "MessageCard")
# summary and title should be the same, except
# title should have any special HTML characters escaped
self.assertEqual(payload["summary"], "“_underscores_ & more” is DOWN.")
self.assertEqual(payload["title"], "“_underscores_ & more” is DOWN.")
@patch("hc.api.transports.requests.request")
def test_msteams_escapes_markdown(self, mock_post):
def test_msteams_escapes_html_and_markdown_in_desc(self, mock_post):
self._setup_data("msteams", "http://example.com/webhook")
mock_post.return_value.status_code = 200
self.check.name = """
self.check.desc = """
TEST _underscore_ `backticks` <u>underline</u> \\backslash\\ "quoted"
"""
self.channel.notify(self.check)
args, kwargs = mock_post.call_args
text = kwargs["json"]["text"]
text = kwargs["json"]["sections"][0]["text"]
self.assertIn(r"\_underscore\_", text)
self.assertIn(r"\`backticks\`", text)


+ 24
- 7
hc/api/transports.py View File

@ -580,17 +580,34 @@ class Apprise(HttpTransport):
class MsTeams(HttpTransport):
def escape_md(self, s):
# Escape special HTML characters
s = escape(s)
# Escape characters that have special meaning in Markdown
for c in r"\`*_{}[]()#+-.!|":
s = s.replace(c, "\\" + c)
return s
def notify(self, check):
text = tmpl("msteams_message.json", check=check)
payload = json.loads(text)
# Escape special HTML characters in check's name
safe_name = escape(check.name_then_code())
# Escape characters that have special meaning in Markdown
for c in r"\`*_{}[]()#+-.!|":
safe_name = safe_name.replace(c, "\\" + c)
payload["text"] = f"“{safe_name}” is {check.status.upper()}."
# MS Teams escapes HTML special characters in the summary field.
# It does not interpret summary content as Markdown.
name = check.name_then_code()
payload["summary"] = f"“{name}” is {check.status.upper()}."
# MS teams *strips* HTML special characters from the title field.
# To avoid that, we use escape().
# It does not interpret title as Markdown.
safe_name = escape(name)
payload["title"] = f"“{safe_name}” is {check.status.upper()}."
# MS teams allows some HTML in the section text.
# It also interprets the section text as Markdown.
# We want to display the raw content, angle brackets and all,
# so we run escape() and then additionally escape Markdown:
payload["sections"][0]["text"] = self.escape_md(check.desc)
return self.post(self.channel.value, json=payload)


+ 1
- 2
templates/integrations/msteams_message.json View File

@ -35,8 +35,7 @@
"name": "Total Pings:",
"value": "{{ check.n_pings }}"
}
],
"text": "{{ check.desc|escapejs }}"
]
}
],
"potentialAction": [


Loading…
Cancel
Save