From c93ee5c5543ae26766e05e820c55012bd1322f4d Mon Sep 17 00:00:00 2001 From: Vadim Stepanov Date: Wed, 18 Jan 2023 16:08:15 +0000 Subject: [PATCH] Send a Slack DM when user is not in channel (#1144) # What this PR does Currently, when a user gets mentioned in an alert group thread and the user is not in the Slack channel, the Slack bot sends the following to the channel: > :warning: Tried to ask USER to look at incident. Unfortunately USER is not in this channel. Please, invite. This PR changes this behaviour to instead send a direct message to the user. The message contains a link to the main alert group message in Slack. Screenshot 2023-01-17 at 19 25 36 ## Checklist - [ ] Tests updated (N/A) - [ ] Documentation added (N/A) - [x] `CHANGELOG.md` updated --- CHANGELOG.md | 4 ++ engine/apps/slack/models/slack_message.py | 24 +---------- .../apps/slack/models/slack_user_identity.py | 43 +++++++++++++++++++ 3 files changed, 48 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 11ef9797..c59551f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Allow messaging backends to be enabled/disabled per organization ([#1151](https://github.com/grafana/oncall/pull/1151)) +### Changed + +- Send a Slack DM when user is not in channel ([#1144](https://github.com/grafana/oncall/pull/1144)) + ## v1.1.17 (2023-01-18) ### Changed diff --git a/engine/apps/slack/models/slack_message.py b/engine/apps/slack/models/slack_message.py index 96b3aae8..614ef5d2 100644 --- a/engine/apps/slack/models/slack_message.py +++ b/engine/apps/slack/models/slack_message.py @@ -212,29 +212,7 @@ class SlackMessage(models.Model): if slack_user_identity.slack_id not in channel_members: time.sleep(5) # 2 messages in the same moment are ratelimited by Slack. Dirty hack. - result = sc.api_call( - "chat.postMessage", - channel=channel_id, - text=f":warning: Tried to ask {user_verbal} to look at incident. " - f"Unfortunately {user_verbal} is not in this channel. Please, invite.", - ) - SlackMessage( - slack_id=result["ts"], - organization=self.organization, - _slack_team_identity=self.slack_team_identity, - channel_id=channel_id, - alert_group=alert_group, - ).save() - UserNotificationPolicyLogRecord( - author=user, - type=UserNotificationPolicyLogRecord.TYPE_PERSONAL_NOTIFICATION_FAILED, - notification_policy=notification_policy, - alert_group=alert_group, - reason="User is not in Slack channel", - notification_step=notification_policy.step, - notification_channel=notification_policy.notify_by, - notification_error_code=UserNotificationPolicyLogRecord.ERROR_NOTIFICATION_IN_SLACK_USER_NOT_IN_CHANNEL, - ).save() + slack_user_identity.send_link_to_slack_message(slack_message) except SlackAPITokenException as e: print(e) except SlackAPIException as e: diff --git a/engine/apps/slack/models/slack_user_identity.py b/engine/apps/slack/models/slack_user_identity.py index 4c0047fa..c9288baf 100644 --- a/engine/apps/slack/models/slack_user_identity.py +++ b/engine/apps/slack/models/slack_user_identity.py @@ -92,6 +92,49 @@ class SlackUserIdentity(models.Model): def __str__(self): return self.slack_login + def send_link_to_slack_message(self, slack_message): + blocks = [ + { + "type": "section", + "text": { + "type": "plain_text", + "text": "You are invited to look at an alert group!", + "emoji": True, + }, + }, + { + "type": "actions", + "elements": [ + { + "type": "button", + "text": {"type": "plain_text", "text": "➡️ Go to the alert group"}, + "url": slack_message.permalink, + "style": "primary", + } + ], + }, + { + "type": "context", + "elements": [ + { + "type": "mrkdwn", + "text": ( + f"You received this message because you're not a member of <#{slack_message.channel_id}>.\n" + "Please join the channel to get notified right in the alert group thread." + ), + } + ], + }, + ] + + sc = SlackClientWithErrorHandling(self.slack_team_identity.bot_access_token) + return sc.api_call( + "chat.postMessage", + channel=self.im_channel_id, + text="You are invited to look at an alert group!", + blocks=blocks, + ) + @property def slack_verbal(self): return (