Skip to content

Commit 0d9e60c

Browse files
authored
feat(notifications platform): More robust message tab reply (#26581)
* feat(notifications platform): More robust message tab reply
1 parent 3f03e1e commit 0d9e60c

File tree

5 files changed

+80
-22
lines changed

5 files changed

+80
-22
lines changed

src/sentry/integrations/slack/event_endpoint.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,9 @@ def on_message(self, request, integration, token, data):
3535
# that will cause an infinite loop of messages
3636
if data.get("bot_id"):
3737
return self.respond()
38-
3938
access_token = self._get_access_token(integration)
4039
headers = {"Authorization": "Bearer %s" % access_token}
41-
payload = {"channel": channel, **SlackEventMessageBuilder().build()}
42-
40+
payload = {"channel": channel, **SlackEventMessageBuilder(integration).build()}
4341
client = SlackClient()
4442
try:
4543
client.post("/chat.postMessage", headers=headers, data=payload, json=True)

src/sentry/integrations/slack/message_builder/base/block.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ def get_markdown_block(text: str) -> SlackBlock:
3232
"text": {"type": "mrkdwn", "text": text},
3333
}
3434

35+
@staticmethod
36+
def get_divider() -> SlackBlock:
37+
return {"type": "divider"}
38+
3539
@staticmethod
3640
def get_action_block(actions: Sequence[Tuple[str, str, str]]) -> SlackBlock:
3741
return {
Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,70 @@
1+
from sentry import features
12
from sentry.integrations.slack.message_builder import SlackBody
23
from sentry.integrations.slack.message_builder.base.block import BlockSlackMessageBuilder
4+
from sentry.models import Integration
35

46
EVENT_MESSAGE = (
57
"Want to learn more about configuring alerts in Sentry? Check out our documentation."
68
)
9+
HEADER_MESSAGE = "Here are the commands you can use. Commands not working? Re-install the app!"
10+
DM_COMMAND_HEADER = "*Direct Message Commands:*"
11+
CHANNEL_COMMANDS_HEADER = "*Channel Commands:*"
12+
GENERAL_MESSAGE = "Just want to learn more about Sentry? Check out our documentation."
13+
14+
15+
DM_COMMANDS = {
16+
"link": "Link your Slack account to Sentry",
17+
"unlink": "Unlink your Slack account from Sentry",
18+
"help": "View this list of commands",
19+
}
20+
CHANNEL_COMMANDS = {
21+
"link team": "Type this into the channel in which you want your team to receive issue alert notifications"
22+
}
23+
24+
DM_COMMANDS_MESSAGE = "\n".join(
25+
(
26+
f"• `/sentry {command}`: {description}"
27+
for command, description in sorted(tuple(DM_COMMANDS.items()))
28+
)
29+
)
30+
31+
CHANNEL_COMMANDS_MESSAGE = "\n".join(
32+
(
33+
f"• `/sentry {command}`: {description}"
34+
for command, description in sorted(tuple(CHANNEL_COMMANDS.items()))
35+
)
36+
)
737

838

939
class SlackEventMessageBuilder(BlockSlackMessageBuilder):
40+
def __init__(self, integration: Integration) -> None:
41+
super().__init__()
42+
self.integration = integration
43+
1044
def build(self) -> SlackBody:
45+
action_block = self.get_action_block(
46+
[
47+
(
48+
"Sentry Docs",
49+
"https://docs.sentry.io/product/alerts-notifications/alerts/",
50+
"sentry_docs_link_clicked",
51+
)
52+
]
53+
)
54+
if not features.has(
55+
"organizations:notification-platform", self.integration.organizations.all()
56+
):
57+
return self._build_blocks(
58+
self.get_markdown_block(EVENT_MESSAGE),
59+
action_block,
60+
)
1161
return self._build_blocks(
12-
self.get_markdown_block(EVENT_MESSAGE),
13-
self.get_action_block(
14-
[
15-
(
16-
"Sentry Docs",
17-
"https://docs.sentry.io/product/alerts-notifications/alerts/",
18-
"sentry_docs_link_clicked",
19-
)
20-
]
21-
),
62+
self.get_markdown_block(HEADER_MESSAGE),
63+
self.get_markdown_block(DM_COMMAND_HEADER),
64+
self.get_markdown_block(DM_COMMANDS_MESSAGE),
65+
self.get_markdown_block(CHANNEL_COMMANDS_HEADER),
66+
self.get_markdown_block(CHANNEL_COMMANDS_MESSAGE),
67+
self.get_divider(),
68+
self.get_markdown_block(GENERAL_MESSAGE),
69+
action_block,
2270
)

src/sentry/integrations/slack/message_builder/help.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,12 @@
33
from sentry.integrations.slack.message_builder import SlackBody
44
from sentry.integrations.slack.message_builder.base.base import SlackMessageBuilder
55

6-
AVAILABLE_COMMANDS = {
7-
"help": "displays the available commands",
8-
"link": "kicks off linking Slack and Sentry",
9-
"unlink": "unlinks your identity",
10-
}
6+
from .event import DM_COMMANDS_MESSAGE
117

128

139
def get_message(command: Optional[str] = None) -> str:
1410
unknown_command = f"Unknown command: `{command}`\n" if command else ""
15-
commands_list = "\n".join(
16-
f"• *{command}* - {description}" for command, description in AVAILABLE_COMMANDS.items()
17-
)
18-
return f"{unknown_command}Available Commands:\n{commands_list}"
11+
return f"{unknown_command}Available Commands:\n{DM_COMMANDS_MESSAGE}"
1912

2013

2114
class SlackHelpMessageBuilder(SlackMessageBuilder):

tests/sentry/integrations/slack/test_event_endpoint.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,21 @@ def test_user_message_im(self):
190190
)
191191
assert self.get_block_type_text("actions", data) == "Sentry Docs"
192192

193+
@responses.activate
194+
def test_user_message_im_notification_platform(self):
195+
responses.add(responses.POST, "https://slack.com/api/chat.postMessage", json={"ok": True})
196+
with self.feature("organizations:notification-platform"):
197+
resp = self.post_webhook(event_data=json.loads(MESSAGE_IM_EVENT))
198+
assert resp.status_code == 200, resp.content
199+
request = responses.calls[0].request
200+
assert request.headers["Authorization"] == "Bearer xoxp-xxxxxxxxx-xxxxxxxxxx-xxxxxxxxxxxx"
201+
data = json.loads(request.body)
202+
assert (
203+
self.get_block_type_text("section", data)
204+
== "Here are the commands you can use. Commands not working? Re-install the app!"
205+
)
206+
assert self.get_block_type_text("actions", data) == "Sentry Docs"
207+
193208
def test_bot_message_im(self):
194209
resp = self.post_webhook(event_data=json.loads(MESSAGE_IM_BOT_EVENT))
195210
assert resp.status_code == 200, resp.content

0 commit comments

Comments
 (0)