Repository: getsentry/sentry

Issue:
Convert issue notifications to use block kit
Convert the `IssueNotificationMessageBuilder` to use block kit (code [here](https://github.com/getsentry/sentry/blob/master/src/sentry/integrations/slack/message_builder/notifications/issues.py)) - note that these are the notifications an individual user receives if an issue alert is set to notify a specific user, and it is different from the notification that goes to a channel in that it does not have any actions (buttons). 


Discussion:

Resolving patch:
diff --git a/src/sentry/integrations/slack/message_builder/notifications/issues.py b/src/sentry/integrations/slack/message_builder/notifications/issues.py
--- a/src/sentry/integrations/slack/message_builder/notifications/issues.py
+++ b/src/sentry/integrations/slack/message_builder/notifications/issues.py
@@ -2,7 +2,7 @@
 
 from typing import Any, Mapping
 
-from sentry.integrations.slack.message_builder import SlackBody
+from sentry.integrations.slack.message_builder import SlackAttachment, SlackBlock
 from sentry.integrations.slack.message_builder.issues import SlackIssuesMessageBuilder
 from sentry.notifications.notifications.base import ProjectNotification
 from sentry.services.hybrid_cloud.actor import RpcActor
@@ -20,7 +20,7 @@ def __init__(
         super().__init__(notification, context, recipient)
         self.notification: ProjectNotification = notification
 
-    def build(self) -> SlackBody:
+    def build(self) -> SlackAttachment | SlackBlock:
         group = getattr(self.notification, "group", None)
         return SlackIssuesMessageBuilder(
             group=group,
diff --git a/src/sentry/integrations/slack/notifications.py b/src/sentry/integrations/slack/notifications.py
--- a/src/sentry/integrations/slack/notifications.py
+++ b/src/sentry/integrations/slack/notifications.py
@@ -86,6 +86,10 @@ def _notify_recipient(
             if attachment_blocks:
                 for attachment in attachment_blocks:
                     blocks.append(attachment)
+            if len(blocks) >= 2 and blocks[1].get("block_id"):
+                # block id needs to be in the first block
+                blocks[0]["block_id"] = blocks[1]["block_id"]
+                del blocks[1]["block_id"]
             additional_attachment = get_additional_attachment(
                 integration, notification.organization
             )


Test patch:
diff --git a/tests/sentry/integrations/slack/notifications/test_assigned.py b/tests/sentry/integrations/slack/notifications/test_assigned.py
--- a/tests/sentry/integrations/slack/notifications/test_assigned.py
+++ b/tests/sentry/integrations/slack/notifications/test_assigned.py
@@ -8,8 +8,9 @@
 from sentry.models.integrations.integration import Integration
 from sentry.notifications.notifications.activity.assigned import AssignedActivityNotification
 from sentry.testutils.cases import PerformanceIssueTestCase, SlackActivityNotificationTest
+from sentry.testutils.helpers.features import with_feature
 from sentry.testutils.helpers.notifications import TEST_ISSUE_OCCURRENCE, TEST_PERF_ISSUE_OCCURRENCE
-from sentry.testutils.helpers.slack import get_attachment
+from sentry.testutils.helpers.slack import get_attachment, get_blocks_and_fallback_text
 from sentry.testutils.skips import requires_snuba
 from sentry.types.activity import ActivityType
 from sentry.types.integrations import ExternalProviders
@@ -134,6 +135,28 @@ def test_assignment(self):
             == f"{self.project.slug} | <http://testserver/settings/account/notifications/workflow/?referrer=assigned_activity-slack-user&notification_uuid={notification_uuid}|Notification Settings>"
         )
 
+    @responses.activate
+    @with_feature("organizations:slack-block-kit")
+    def test_assignment_block(self):
+        """
+        Test that a Slack message is sent with the expected payload when an issue is assigned
+        and block kit is enabled.
+        """
+        with self.tasks():
+            self.create_notification(self.group, AssignedActivityNotification).send()
+        blocks, fallback_text = get_blocks_and_fallback_text()
+        assert fallback_text == f"Issue assigned to {self.name} by themselves"
+        assert blocks[0]["text"]["text"] == fallback_text
+        notification_uuid = self.get_notification_uuid(blocks[1]["text"]["text"])
+        assert (
+            blocks[1]["text"]["text"]
+            == f"<http://testserver/organizations/{self.organization.slug}/issues/{self.group.id}/?referrer=assigned_activity-slack&notification_uuid={notification_uuid}|*{self.group.title}*>  \n"
+        )
+        assert (
+            blocks[2]["elements"][0]["text"]
+            == f"{self.project.slug} | <http://testserver/settings/account/notifications/workflow/?referrer=assigned_activity-slack-user&notification_uuid={notification_uuid}|Notification Settings>"
+        )
+
     @responses.activate
     @mock.patch(
         "sentry.eventstore.models.GroupEvent.occurrence",
@@ -157,6 +180,36 @@ def test_assignment_generic_issue(self, occurrence):
             attachment, self.project.slug, "assigned_activity-slack-user"
         )
 
+    @responses.activate
+    @mock.patch(
+        "sentry.eventstore.models.GroupEvent.occurrence",
+        return_value=TEST_ISSUE_OCCURRENCE,
+        new_callable=mock.PropertyMock,
+    )
+    @with_feature("organizations:slack-block-kit")
+    def test_assignment_generic_issue_block(self, occurrence):
+        """
+        Test that a Slack message is sent with the expected payload when a generic issue type is assigned
+        and block kit is enabled.
+        """
+        event = self.store_event(
+            data={"message": "Hellboy's world", "level": "error"}, project_id=self.project.id
+        )
+        group_event = event.for_group(event.groups[0])
+
+        with self.tasks():
+            self.create_notification(group_event.group, AssignedActivityNotification).send()
+        blocks, fallback_text = get_blocks_and_fallback_text()
+        assert fallback_text == f"Issue assigned to {self.name} by themselves"
+        assert blocks[0]["text"]["text"] == fallback_text
+        self.assert_generic_issue_blocks(
+            blocks,
+            group_event.organization.slug,
+            group_event.project.slug,
+            group_event.group,
+            "assigned_activity-slack",
+        )
+
     @responses.activate
     @mock.patch(
         "sentry.eventstore.models.GroupEvent.occurrence",
@@ -177,6 +230,33 @@ def test_assignment_performance_issue(self, occurrence):
             attachment, self.project.slug, "assigned_activity-slack-user"
         )
 
+    @responses.activate
+    @mock.patch(
+        "sentry.eventstore.models.GroupEvent.occurrence",
+        return_value=TEST_PERF_ISSUE_OCCURRENCE,
+        new_callable=mock.PropertyMock,
+    )
+    @with_feature("organizations:slack-block-kit")
+    def test_assignment_performance_issue_block(self, occurrence):
+        """
+        Test that a Slack message is sent with the expected payload when a performance issue is assigned
+        and block kit is enabled.
+        """
+        event = self.create_performance_issue()
+        with self.tasks():
+            self.create_notification(event.group, AssignedActivityNotification).send()
+
+        blocks, fallback_text = get_blocks_and_fallback_text()
+        assert fallback_text == f"Issue assigned to {self.name} by themselves"
+        assert blocks[0]["text"]["text"] == fallback_text
+        self.assert_performance_issue_blocks(
+            blocks,
+            event.organization.slug,
+            event.project.slug,
+            event.group,
+            "assigned_activity-slack",
+        )
+
     def test_automatic_assignment(self):
         notification = AssignedActivityNotification(
             Activity(
diff --git a/tests/sentry/integrations/slack/notifications/test_issue_alert.py b/tests/sentry/integrations/slack/notifications/test_issue_alert.py
--- a/tests/sentry/integrations/slack/notifications/test_issue_alert.py
+++ b/tests/sentry/integrations/slack/notifications/test_issue_alert.py
@@ -25,8 +25,9 @@
 from sentry.silo import SiloMode
 from sentry.tasks.digests import deliver_digest
 from sentry.testutils.cases import PerformanceIssueTestCase, SlackActivityNotificationTest
+from sentry.testutils.helpers.features import with_feature
 from sentry.testutils.helpers.notifications import TEST_ISSUE_OCCURRENCE, TEST_PERF_ISSUE_OCCURRENCE
-from sentry.testutils.helpers.slack import get_attachment
+from sentry.testutils.helpers.slack import get_attachment, get_blocks_and_fallback_text
 from sentry.testutils.silo import assume_test_silo_mode, region_silo_test
 from sentry.testutils.skips import requires_snuba
 from sentry.types.integrations import ExternalProviders
@@ -84,6 +85,43 @@ def test_issue_alert_user(self):
             == f"http://testserver/organizations/{self.organization.slug}/issues/{event.group.id}/?referrer=issue_alert-slack&notification_uuid={notification_uuid}&alert_rule_id={self.rule.id}&alert_type=issue"
         )
 
+    @responses.activate
+    @with_feature("organizations:slack-block-kit")
+    def test_issue_alert_user_block(self):
+        """
+        Test that issues alert are sent to a Slack user with the proper payload when block kit is
+        enabled.
+        """
+        event = self.store_event(
+            data={"message": "Hello world", "level": "error"}, project_id=self.project.id
+        )
+        notification_uuid = str(uuid.uuid4())
+        notification = AlertRuleNotification(
+            Notification(event=event, rule=self.rule),
+            ActionTargetType.MEMBER,
+            self.user.id,
+            notification_uuid=notification_uuid,
+        )
+
+        with self.tasks():
+            notification.send()
+
+        blocks, fallback_text = get_blocks_and_fallback_text()
+        assert (
+            fallback_text
+            == f"Alert triggered <http://testserver/organizations/{event.organization.slug}/alerts/rules/{event.project.slug}/{self.rule.id}/details/|ja rule>"
+        )
+        assert blocks[0]["text"]["text"] == fallback_text
+        assert event.group
+        assert (
+            blocks[1]["text"]["text"]
+            == f"<http://testserver/organizations/{event.organization.slug}/issues/{event.group.id}/?referrer=issue_alert-slack&notification_uuid={notification_uuid}&alert_rule_id={self.rule.id}&alert_type=issue|*Hello world*>  \n"
+        )
+        assert (
+            blocks[2]["elements"][0]["text"]
+            == f"{event.project.slug} | <http://testserver/settings/account/notifications/alerts/?referrer=issue_alert-slack-user&notification_uuid={notification_uuid}|Notification Settings>"
+        )
+
     @responses.activate
     @mock.patch(
         "sentry.eventstore.models.GroupEvent.occurrence",
@@ -106,6 +144,43 @@ def test_performance_issue_alert_user(self, occurrence):
             attachment, self.project.slug, "issue_alert-slack-user", "alerts"
         )
 
+    @responses.activate
+    @mock.patch(
+        "sentry.eventstore.models.GroupEvent.occurrence",
+        return_value=TEST_PERF_ISSUE_OCCURRENCE,
+        new_callable=mock.PropertyMock,
+    )
+    @with_feature("organizations:slack-block-kit")
+    def test_performance_issue_alert_user_block(self, occurrence):
+        """
+        Test that performance issue alerts are sent to a Slack user with the proper payload when
+        block kit is enabled.
+        """
+
+        event = self.create_performance_issue()
+
+        notification = AlertRuleNotification(
+            Notification(event=event, rule=self.rule), ActionTargetType.MEMBER, self.user.id
+        )
+        with self.tasks():
+            notification.send()
+
+        blocks, fallback_text = get_blocks_and_fallback_text()
+        assert (
+            fallback_text
+            == f"Alert triggered <http://testserver/organizations/{event.organization.slug}/alerts/rules/{event.project.slug}/{self.rule.id}/details/|ja rule>"
+        )
+        assert blocks[0]["text"]["text"] == fallback_text
+        self.assert_performance_issue_blocks(
+            blocks,
+            event.organization.slug,
+            event.project.slug,
+            event.group,
+            "issue_alert-slack",
+            alert_type="alerts",
+            issue_link_extra_params=f"&alert_rule_id={self.rule.id}&alert_type=issue",
+        )
+
     @responses.activate
     @mock.patch(
         "sentry.eventstore.models.GroupEvent.occurrence",
@@ -130,6 +205,46 @@ def test_generic_issue_alert_user(self, occurrence):
             attachment, self.project.slug, "issue_alert-slack-user", "alerts"
         )
 
+    @responses.activate
+    @mock.patch(
+        "sentry.eventstore.models.GroupEvent.occurrence",
+        return_value=TEST_ISSUE_OCCURRENCE,
+        new_callable=mock.PropertyMock,
+    )
+    @with_feature("organizations:slack-block-kit")
+    def test_generic_issue_alert_user_block(self, occurrence):
+        """
+        Test that generic issue alerts are sent to a Slack user with the proper payload when
+        block kit is enabled.
+        """
+        event = self.store_event(
+            data={"message": "Hellboy's world", "level": "error"}, project_id=self.project.id
+        )
+        group_event = event.for_group(event.groups[0])
+
+        notification = AlertRuleNotification(
+            Notification(event=group_event, rule=self.rule), ActionTargetType.MEMBER, self.user.id
+        )
+        with self.tasks():
+            notification.send()
+
+        blocks, fallback_text = get_blocks_and_fallback_text()
+        assert (
+            fallback_text
+            == f"Alert triggered <http://testserver/organizations/{event.organization.slug}/alerts/rules/{event.project.slug}/{self.rule.id}/details/|ja rule>"
+        )
+        assert blocks[0]["text"]["text"] == fallback_text
+
+        self.assert_generic_issue_blocks(
+            blocks,
+            event.organization.slug,
+            event.project.slug,
+            event.group,
+            "issue_alert-slack",
+            alert_type="alerts",
+            issue_link_extra_params=f"&alert_rule_id={self.rule.id}&alert_type=issue",
+        )
+
     @responses.activate
     def test_disabled_org_integration_for_user(self):
         with assume_test_silo_mode(SiloMode.CONTROL):
@@ -192,6 +307,56 @@ def test_issue_alert_issue_owners(self):
             == f"{self.project.slug} | <http://testserver/settings/account/notifications/alerts/?referrer=issue_alert-slack-user&notification_uuid={notification_uuid}|Notification Settings>"
         )
 
+    @responses.activate
+    @with_feature("organizations:slack-block-kit")
+    def test_issue_alert_issue_owners_block(self):
+        """
+        Test that issue alerts are sent to issue owners in Slack with the proper payload when block
+        kit is enabled.
+        """
+
+        event = self.store_event(
+            data={"message": "Hello world", "level": "error"}, project_id=self.project.id
+        )
+        action_data = {
+            "id": "sentry.mail.actions.NotifyEmailAction",
+            "targetType": "IssueOwners",
+            "targetIdentifier": "",
+        }
+        rule = Rule.objects.create(
+            project=self.project,
+            label="ja rule",
+            data={
+                "match": "all",
+                "actions": [action_data],
+            },
+        )
+        ProjectOwnership.objects.create(project_id=self.project.id, fallthrough=True)
+
+        notification = AlertRuleNotification(
+            Notification(event=event, rule=rule), ActionTargetType.ISSUE_OWNERS, self.user.id
+        )
+
+        with self.tasks():
+            notification.send()
+
+        blocks, fallback_text = get_blocks_and_fallback_text()
+        notification_uuid = notification.notification_uuid
+        assert (
+            fallback_text
+            == f"Alert triggered <http://testserver/organizations/{event.organization.slug}/alerts/rules/{event.project.slug}/{rule.id}/details/|ja rule>"
+        )
+        assert blocks[0]["text"]["text"] == fallback_text
+        assert event.group
+        assert (
+            blocks[1]["text"]["text"]
+            == f"<http://testserver/organizations/{event.organization.slug}/issues/{event.group.id}/?referrer=issue_alert-slack&notification_uuid={notification_uuid}&alert_rule_id={rule.id}&alert_type=issue|*Hello world*>  \n"
+        )
+        assert (
+            blocks[2]["elements"][0]["text"]
+            == f"{event.project.slug} | <http://testserver/settings/account/notifications/alerts/?referrer=issue_alert-slack-user&notification_uuid={notification_uuid}|Notification Settings>"
+        )
+
     @responses.activate
     def test_issue_alert_issue_owners_environment(self):
         """Test that issue alerts are sent to issue owners in Slack with the environment in the query params when the alert rule filters by environment."""
@@ -242,6 +407,64 @@ def test_issue_alert_issue_owners_environment(self):
             == f"{self.project.slug} | {environment.name} | <http://testserver/settings/account/notifications/alerts/?referrer=issue_alert-slack-user&notification_uuid={notification_uuid}|Notification Settings>"
         )
 
+    @responses.activate
+    @with_feature("organizations:slack-block-kit")
+    def test_issue_alert_issue_owners_environment_block(self):
+        """
+        Test that issue alerts are sent to issue owners in Slack with the environment in the query
+        params when the alert rule filters by environment and block kit is enabled.
+        """
+
+        environment = self.create_environment(self.project, name="production")
+        event = self.store_event(
+            data={"message": "Hello world", "level": "error", "environment": environment.name},
+            project_id=self.project.id,
+        )
+        action_data = {
+            "id": "sentry.mail.actions.NotifyEmailAction",
+            "targetType": "IssueOwners",
+            "targetIdentifier": "",
+        }
+        rule = Rule.objects.create(
+            project=self.project,
+            label="ja rule",
+            data={
+                "match": "all",
+                "actions": [action_data],
+            },
+        )
+        rule = self.create_project_rule(
+            project=self.project,
+            action_match=[action_data],
+            name="ja rule",
+            environment_id=environment.id,
+        )
+        ProjectOwnership.objects.create(project_id=self.project.id, fallthrough=True)
+
+        notification = AlertRuleNotification(
+            Notification(event=event, rule=rule), ActionTargetType.ISSUE_OWNERS, self.user.id
+        )
+
+        with self.tasks():
+            notification.send()
+
+        blocks, fallback_text = get_blocks_and_fallback_text()
+        notification_uuid = notification.notification_uuid
+        assert (
+            fallback_text
+            == f"Alert triggered <http://testserver/organizations/{event.organization.slug}/alerts/rules/{event.project.slug}/{rule.id}/details/|ja rule>"
+        )
+        assert blocks[0]["text"]["text"] == fallback_text
+        assert event.group
+        assert (
+            blocks[1]["text"]["text"]
+            == f"<http://testserver/organizations/{event.organization.slug}/issues/{event.group.id}/?referrer=issue_alert-slack&notification_uuid={notification_uuid}&environment={environment.name}&alert_rule_id={rule.id}&alert_type=issue|*Hello world*>  \n"
+        )
+        assert (
+            blocks[2]["elements"][0]["text"]
+            == f"{event.project.slug} | {environment.name} | <http://testserver/settings/account/notifications/alerts/?referrer=issue_alert-slack-user&notification_uuid={notification_uuid}|Notification Settings>"
+        )
+
     @responses.activate
     def test_issue_alert_team_issue_owners(self):
         """Test that issue alerts are sent to a team in Slack via an Issue Owners rule action."""
@@ -333,6 +556,112 @@ def test_issue_alert_team_issue_owners(self):
             == f"{self.project.slug} | <http://testserver/settings/{self.organization.slug}/teams/{self.team.slug}/notifications/?referrer=issue_alert-slack-team&notification_uuid={notification_uuid}|Notification Settings>"
         )
 
+    @responses.activate
+    @with_feature("organizations:slack-block-kit")
+    def test_issue_alert_team_issue_owners_block(self):
+        """
+        Test that issue alerts are sent to a team in Slack via an Issue Owners rule action with the
+        proper payload when block kit is enabled.
+        """
+
+        # add a second user to the team so we can be sure it's only
+        # sent once (to the team, and not to each individual user)
+        user2 = self.create_user(is_superuser=False)
+        self.create_member(teams=[self.team], user=user2, organization=self.organization)
+        with assume_test_silo_mode(SiloMode.CONTROL):
+            self.idp = IdentityProvider.objects.create(
+                type="slack", external_id="TXXXXXXX2", config={}
+            )
+            self.identity = Identity.objects.create(
+                external_id="UXXXXXXX2",
+                idp=self.idp,
+                user=user2,
+                status=IdentityStatus.VALID,
+                scopes=[],
+            )
+        # update the team's notification settings
+        ExternalActor.objects.create(
+            team_id=self.team.id,
+            organization=self.organization,
+            integration_id=self.integration.id,
+            provider=ExternalProviders.SLACK.value,
+            external_name="goma",
+            external_id="CXXXXXXX2",
+        )
+        with assume_test_silo_mode(SiloMode.CONTROL):
+            # provider is disabled by default
+            NotificationSettingProvider.objects.create(
+                team_id=self.team.id,
+                scope_type="team",
+                scope_identifier=self.team.id,
+                provider="slack",
+                type="alerts",
+                value="always",
+            )
+
+        g_rule = GrammarRule(Matcher("path", "*"), [Owner("team", self.team.slug)])
+        ProjectOwnership.objects.create(
+            project_id=self.project.id, schema=dump_schema([g_rule]), fallthrough=True
+        )
+
+        event = self.store_event(
+            data={
+                "message": "Hello world",
+                "level": "error",
+                "stacktrace": {"frames": [{"filename": "foo.py"}]},
+            },
+            project_id=self.project.id,
+        )
+
+        action_data = {
+            "id": "sentry.mail.actions.NotifyEmailAction",
+            "targetType": "IssueOwners",
+            "targetIdentifier": "",
+        }
+        rule = Rule.objects.create(
+            project=self.project,
+            label="ja rule",
+            data={
+                "match": "all",
+                "actions": [action_data],
+            },
+        )
+
+        notification = AlertRuleNotification(
+            Notification(event=event, rule=rule), ActionTargetType.ISSUE_OWNERS, self.team.id
+        )
+
+        with self.tasks():
+            notification.send()
+
+        # check that only one was sent out - more would mean each user is being notified
+        # rather than the team
+        assert len(responses.calls) == 1
+
+        # check that the team got a notification
+        data = parse_qs(responses.calls[0].request.body)
+        assert data["channel"] == ["CXXXXXXX2"]
+        assert "blocks" in data
+        assert "text" in data
+        blocks = json.loads(data["blocks"][0])
+        fallback_text = data["text"][0]
+        notification_uuid = notification.notification_uuid
+
+        assert (
+            fallback_text
+            == f"Alert triggered <http://testserver/organizations/{event.organization.slug}/alerts/rules/{event.project.slug}/{rule.id}/details/|ja rule>"
+        )
+        assert blocks[0]["text"]["text"] == fallback_text
+        assert event.group
+        assert (
+            blocks[1]["text"]["text"]
+            == f"<http://testserver/organizations/{event.organization.slug}/issues/{event.group.id}/?referrer=issue_alert-slack&notification_uuid={notification_uuid}&alert_rule_id={rule.id}&alert_type=issue|*Hello world*>  \n"
+        )
+        assert (
+            blocks[2]["elements"][0]["text"]
+            == f"{event.project.slug} | <http://testserver/settings/{event.organization.slug}/teams/{self.team.slug}/notifications/?referrer=issue_alert-slack-team&notification_uuid={notification_uuid}|Notification Settings>"
+        )
+
     @responses.activate
     def test_disabled_org_integration_for_team(self):
         # update the team's notification settings
@@ -576,6 +905,100 @@ def test_issue_alert_team(self):
             == f"{self.project.slug} | <http://example.com/settings/{self.organization.slug}/teams/{self.team.slug}/notifications/?referrer=issue_alert-slack-team&notification_uuid={notification_uuid}|Notification Settings>"
         )
 
+    @responses.activate
+    @with_feature("organizations:slack-block-kit")
+    def test_issue_alert_team_block(self):
+        """Test that issue alerts are sent to a team in Slack when block kit is enabled."""
+        # add a second organization
+        org = self.create_organization(owner=self.user)
+        with assume_test_silo_mode(SiloMode.CONTROL):
+            OrganizationIntegration.objects.create(
+                organization_id=org.id, integration=self.integration
+            )
+
+        # add a second user to the team so we can be sure it's only
+        # sent once (to the team, and not to each individual user)
+        user2 = self.create_user(is_superuser=False)
+        self.create_member(teams=[self.team], user=user2, organization=self.organization)
+        with assume_test_silo_mode(SiloMode.CONTROL):
+            self.idp = IdentityProvider.objects.create(
+                type="slack", external_id="TXXXXXXX2", config={}
+            )
+            self.identity = Identity.objects.create(
+                external_id="UXXXXXXX2",
+                idp=self.idp,
+                user=user2,
+                status=IdentityStatus.VALID,
+                scopes=[],
+            )
+        # update the team's notification settings
+        ExternalActor.objects.create(
+            team_id=self.team.id,
+            organization=self.organization,
+            integration_id=self.integration.id,
+            provider=ExternalProviders.SLACK.value,
+            external_name="goma",
+            external_id="CXXXXXXX2",
+        )
+        with assume_test_silo_mode(SiloMode.CONTROL):
+            NotificationSettingProvider.objects.create(
+                team_id=self.team.id,
+                scope_type="team",
+                scope_identifier=self.team.id,
+                provider="slack",
+                type="alerts",
+                value="always",
+            )
+
+        event = self.store_event(
+            data={"message": "Hello world", "level": "error"}, project_id=self.project.id
+        )
+        action_data = {
+            "id": "sentry.mail.actions.NotifyEmailAction",
+            "targetType": "Team",
+            "targetIdentifier": str(self.team.id),
+        }
+        rule = Rule.objects.create(
+            project=self.project,
+            label="ja rule",
+            data={
+                "match": "all",
+                "actions": [action_data],
+            },
+        )
+        notification = Notification(event=event, rule=rule)
+
+        with self.options({"system.url-prefix": "http://example.com"}), self.tasks():
+            self.adapter.notify(notification, ActionTargetType.TEAM, self.team.id)
+
+        # check that only one was sent out - more would mean each user is being notified
+        # rather than the team
+        assert len(responses.calls) == 1
+
+        # check that the team got a notification
+        data = parse_qs(responses.calls[0].request.body)
+        assert data["channel"] == ["CXXXXXXX2"]
+        assert "blocks" in data
+        assert "text" in data
+        blocks = json.loads(data["blocks"][0])
+        fallback_text = data["text"][0]
+        notification_uuid = self.get_notification_uuid(blocks[1]["text"]["text"])
+
+        assert (
+            fallback_text
+            == f"Alert triggered <http://example.com/organizations/{event.organization.slug}/alerts/rules/{event.project.slug}/{rule.id}/details/|ja rule>"
+        )
+        assert blocks[0]["text"]["text"] == fallback_text
+        assert event.group
+        assert (
+            blocks[1]["text"]["text"]
+            == f"<http://example.com/organizations/{event.organization.slug}/issues/{event.group.id}/?referrer=issue_alert-slack&notification_uuid={notification_uuid}&alert_rule_id={rule.id}&alert_type=issue|*Hello world*>  \n"
+        )
+        assert (
+            blocks[2]["elements"][0]["text"]
+            == f"{event.project.slug} | <http://example.com/settings/{event.organization.slug}/teams/{self.team.slug}/notifications/?referrer=issue_alert-slack-team&notification_uuid={notification_uuid}|Notification Settings>"
+        )
+
     @responses.activate
     def test_issue_alert_team_new_project(self):
         """Test that issue alerts are sent to a team in Slack when the team has added a new project"""
@@ -798,3 +1221,44 @@ def test_digest_enabled(self, digests):
 
         assert attachment["title"] == "Hello world"
         assert attachment["text"] == ""
+
+    @responses.activate
+    @patch.object(sentry, "digests")
+    @with_feature("organizations:slack-block-kit")
+    def test_digest_enabled_block(self, digests):
+        """
+        Test that with digests enabled, but Slack notification settings
+        (and not email settings) enabled, we send a Slack notification with the proper
+        payload when block kit is enabled.
+        """
+        backend = RedisBackend()
+        digests.digest = backend.digest
+        digests.enabled.return_value = True
+
+        rule = Rule.objects.create(project=self.project, label="my rule")
+        ProjectOwnership.objects.create(project_id=self.project.id, fallthrough=True)
+        event = self.store_event(
+            data={"message": "Hello world", "level": "error"}, project_id=self.project.id
+        )
+        key = f"mail:p:{self.project.id}"
+        backend.add(key, event_to_record(event, [rule]), increment_delay=0, maximum_delay=0)
+
+        with self.tasks():
+            deliver_digest(key)
+
+        blocks, fallback_text = get_blocks_and_fallback_text()
+        notification_uuid = self.get_notification_uuid(blocks[1]["text"]["text"])
+        assert (
+            fallback_text
+            == f"Alert triggered <http://testserver/organizations/{event.organization.slug}/alerts/rules/{event.project.slug}/{rule.id}/details/|my rule>"
+        )
+        assert blocks[0]["text"]["text"] == fallback_text
+        assert event.group
+        assert (
+            blocks[1]["text"]["text"]
+            == f"<http://testserver/organizations/{event.organization.slug}/issues/{event.group.id}/?referrer=issue_alert-slack&notification_uuid={notification_uuid}&alert_rule_id={rule.id}&alert_type=issue|*Hello world*>  \n"
+        )
+        assert (
+            blocks[2]["elements"][0]["text"]
+            == f"{event.project.slug} | <http://testserver/settings/account/notifications/alerts/?referrer=issue_alert-slack-user&notification_uuid={notification_uuid}|Notification Settings>"
+        )
diff --git a/tests/sentry/integrations/slack/notifications/test_regression.py b/tests/sentry/integrations/slack/notifications/test_regression.py
--- a/tests/sentry/integrations/slack/notifications/test_regression.py
+++ b/tests/sentry/integrations/slack/notifications/test_regression.py
@@ -5,8 +5,9 @@
 from sentry.models.activity import Activity
 from sentry.notifications.notifications.activity.regression import RegressionActivityNotification
 from sentry.testutils.cases import PerformanceIssueTestCase, SlackActivityNotificationTest
+from sentry.testutils.helpers.features import with_feature
 from sentry.testutils.helpers.notifications import TEST_ISSUE_OCCURRENCE, TEST_PERF_ISSUE_OCCURRENCE
-from sentry.testutils.helpers.slack import get_attachment
+from sentry.testutils.helpers.slack import get_attachment, get_blocks_and_fallback_text
 from sentry.testutils.skips import requires_snuba
 from sentry.types.activity import ActivityType
 
@@ -43,6 +44,27 @@ def test_regression(self):
             == f"{self.project.slug} | <http://testserver/settings/account/notifications/workflow/?referrer=regression_activity-slack-user&notification_uuid={notification_uuid}|Notification Settings>"
         )
 
+    @responses.activate
+    @with_feature("organizations:slack-block-kit")
+    def test_regression_block(self):
+        """
+        Test that a Slack message is sent with the expected payload when an issue regresses
+        and block kit is enabled.
+        """
+        with self.tasks():
+            self.create_notification(self.group).send()
+
+        blocks, fallback_text = get_blocks_and_fallback_text()
+        assert fallback_text == "Issue marked as regression"
+        assert blocks[0]["text"]["text"] == fallback_text
+        notification_uuid = self.get_notification_uuid(blocks[1]["text"]["text"])
+        assert blocks[1]["text"]["text"] == (
+            f"<http://testserver/organizations/{self.organization.slug}/issues/{self.group.id}/?referrer=regression_activity-slack&notification_uuid={notification_uuid}|*{self.group.title}*>  \n"
+        )
+        assert blocks[2]["elements"][0]["text"] == (
+            f"{self.project.slug} | <http://testserver/settings/account/notifications/workflow/?referrer=regression_activity-slack-user&notification_uuid={notification_uuid}|Notification Settings>"
+        )
+
     @responses.activate
     def test_regression_with_release(self):
         """
@@ -65,6 +87,30 @@ def test_regression_with_release(self):
             == f"{self.project.slug} | <http://testserver/settings/account/notifications/workflow/?referrer=regression_activity-slack-user&notification_uuid={notification_uuid}|Notification Settings>"
         )
 
+    @responses.activate
+    @with_feature("organizations:slack-block-kit")
+    def test_regression_with_release_block(self):
+        """
+        Test that a Slack message is sent with the expected payload when an issue regresses
+        and block kit is enabled.
+        """
+        with self.tasks():
+            self.create_notification(self.group, {"version": "1.0.0"}).send()
+
+        blocks, fallback_text = get_blocks_and_fallback_text()
+        notification_uuid = self.get_notification_uuid(blocks[1]["text"]["text"])
+        assert (
+            fallback_text
+            == f"Issue marked as regression in release <http://testserver/organizations/baz/releases/1.0.0/?referrer=regression_activity&notification_uuid={notification_uuid}|1.0.0>"
+        )
+        assert blocks[0]["text"]["text"] == fallback_text
+        assert blocks[1]["text"]["text"] == (
+            f"<http://testserver/organizations/{self.organization.slug}/issues/{self.group.id}/?referrer=regression_activity-slack&notification_uuid={notification_uuid}|*{self.group.title}*>  \n"
+        )
+        assert blocks[2]["elements"][0]["text"] == (
+            f"{self.project.slug} | <http://testserver/settings/account/notifications/workflow/?referrer=regression_activity-slack-user&notification_uuid={notification_uuid}|Notification Settings>"
+        )
+
     @responses.activate
     @mock.patch(
         "sentry.eventstore.models.GroupEvent.occurrence",
@@ -85,6 +131,33 @@ def test_regression_performance_issue(self, occurrence):
             attachment, self.project.slug, "regression_activity-slack-user"
         )
 
+    @responses.activate
+    @mock.patch(
+        "sentry.eventstore.models.GroupEvent.occurrence",
+        return_value=TEST_PERF_ISSUE_OCCURRENCE,
+        new_callable=mock.PropertyMock,
+    )
+    @with_feature("organizations:slack-block-kit")
+    def test_regression_performance_issue_block(self, occurrence):
+        """
+        Test that a Slack message is sent with the expected payload when a performance issue regresses
+        and block kit is enabled.
+        """
+        event = self.create_performance_issue()
+        with self.tasks():
+            self.create_notification(event.group).send()
+
+        blocks, fallback_text = get_blocks_and_fallback_text()
+        assert fallback_text == "Issue marked as regression"
+        assert blocks[0]["text"]["text"] == fallback_text
+        self.assert_performance_issue_blocks(
+            blocks,
+            event.organization.slug,
+            event.project.slug,
+            event.group,
+            "regression_activity-slack",
+        )
+
     @responses.activate
     @mock.patch(
         "sentry.eventstore.models.GroupEvent.occurrence",
@@ -108,3 +181,34 @@ def test_regression_generic_issue(self, occurrence):
         self.assert_generic_issue_attachments(
             attachment, self.project.slug, "regression_activity-slack-user"
         )
+
+    @responses.activate
+    @mock.patch(
+        "sentry.eventstore.models.GroupEvent.occurrence",
+        return_value=TEST_ISSUE_OCCURRENCE,
+        new_callable=mock.PropertyMock,
+    )
+    @with_feature("organizations:slack-block-kit")
+    def test_regression_generic_issue_block(self, occurrence):
+        """
+        Test that a Slack message is sent with the expected payload when a generic issue type regresses
+        and block kit is enabled.
+        """
+        event = self.store_event(
+            data={"message": "Hellboy's world", "level": "error"}, project_id=self.project.id
+        )
+        group_event = event.for_group(event.groups[0])
+
+        with self.tasks():
+            self.create_notification(group_event.group).send()
+
+        blocks, fallback_text = get_blocks_and_fallback_text()
+        assert fallback_text == "Issue marked as regression"
+        assert blocks[0]["text"]["text"] == fallback_text
+        self.assert_generic_issue_blocks(
+            blocks,
+            group_event.organization.slug,
+            group_event.project.slug,
+            group_event.group,
+            "regression_activity-slack",
+        )
diff --git a/tests/sentry/integrations/slack/notifications/test_resolved.py b/tests/sentry/integrations/slack/notifications/test_resolved.py
--- a/tests/sentry/integrations/slack/notifications/test_resolved.py
+++ b/tests/sentry/integrations/slack/notifications/test_resolved.py
@@ -5,8 +5,9 @@
 from sentry.models.activity import Activity
 from sentry.notifications.notifications.activity.resolved import ResolvedActivityNotification
 from sentry.testutils.cases import PerformanceIssueTestCase, SlackActivityNotificationTest
+from sentry.testutils.helpers.features import with_feature
 from sentry.testutils.helpers.notifications import TEST_ISSUE_OCCURRENCE, TEST_PERF_ISSUE_OCCURRENCE
-from sentry.testutils.helpers.slack import get_attachment
+from sentry.testutils.helpers.slack import get_attachment, get_blocks_and_fallback_text
 from sentry.testutils.skips import requires_snuba
 from sentry.types.activity import ActivityType
 
@@ -44,6 +45,35 @@ def test_resolved(self):
             == f"{self.project.slug} | <http://testserver/settings/account/notifications/workflow/?referrer=resolved_activity-slack-user&notification_uuid={notification_uuid}|Notification Settings>"
         )
 
+    @responses.activate
+    @with_feature("organizations:slack-block-kit")
+    def test_resolved_block(self):
+        """
+        Test that a Slack message is sent with the expected payload when an issue is resolved
+        and block kit is enabled.
+        """
+        with self.tasks():
+            self.create_notification(self.group).send()
+
+        blocks, fallback_text = get_blocks_and_fallback_text()
+        notification_uuid = self.get_notification_uuid(fallback_text)
+        issue_link = (
+            f"http://testserver/organizations/{self.organization.slug}/issues/{self.group.id}"
+        )
+        assert (
+            fallback_text
+            == f"{self.name} marked <{issue_link}/?referrer=activity_notification&notification_uuid={notification_uuid}|{self.short_id}> as resolved"
+        )
+        assert blocks[0]["text"]["text"] == fallback_text
+        assert (
+            blocks[1]["text"]["text"]
+            == f"<{issue_link}/?referrer=resolved_activity-slack&notification_uuid={notification_uuid}|*{self.group.title}*>  \n"
+        )
+        assert (
+            blocks[2]["elements"][0]["text"]
+            == f"{self.project.slug} | <http://testserver/settings/account/notifications/workflow/?referrer=resolved_activity-slack-user&notification_uuid={notification_uuid}|Notification Settings>"
+        )
+
     @responses.activate
     @mock.patch(
         "sentry.eventstore.models.GroupEvent.occurrence",
@@ -68,6 +98,37 @@ def test_resolved_performance_issue(self, occurrence):
             attachment, self.project.slug, "resolved_activity-slack-user"
         )
 
+    @responses.activate
+    @mock.patch(
+        "sentry.eventstore.models.GroupEvent.occurrence",
+        return_value=TEST_PERF_ISSUE_OCCURRENCE,
+        new_callable=mock.PropertyMock,
+    )
+    @with_feature("organizations:slack-block-kit")
+    def test_resolved_performance_issue_block(self, occurrence):
+        """
+        Test that a Slack message is sent with the expected payload when a performance issue is resolved
+        and block kit is enabled.
+        """
+        event = self.create_performance_issue()
+        with self.tasks():
+            self.create_notification(event.group).send()
+
+        blocks, fallback_text = get_blocks_and_fallback_text()
+        notification_uuid = self.get_notification_uuid(blocks[0]["text"]["text"])
+        assert (
+            fallback_text
+            == f"{self.name} marked <http://testserver/organizations/{self.organization.slug}/issues/{event.group.id}/?referrer=activity_notification&notification_uuid={notification_uuid}|{self.project.slug.upper()}-{event.group.short_id}> as resolved"
+        )
+        assert blocks[0]["text"]["text"] == fallback_text
+        self.assert_performance_issue_blocks(
+            blocks,
+            event.organization.slug,
+            event.project.slug,
+            event.group,
+            "resolved_activity-slack",
+        )
+
     @responses.activate
     @mock.patch(
         "sentry.eventstore.models.GroupEvent.occurrence",
@@ -94,3 +155,38 @@ def test_resolved_generic_issue(self, occurrence):
         self.assert_generic_issue_attachments(
             attachment, self.project.slug, "resolved_activity-slack-user"
         )
+
+    @responses.activate
+    @mock.patch(
+        "sentry.eventstore.models.GroupEvent.occurrence",
+        return_value=TEST_ISSUE_OCCURRENCE,
+        new_callable=mock.PropertyMock,
+    )
+    @with_feature("organizations:slack-block-kit")
+    def test_resolved_generic_issue_block(self, occurrence):
+        """
+        Test that a Slack message is sent with the expected payload when a generic issue type is resolved
+        and block kit is enabled.
+        """
+        event = self.store_event(
+            data={"message": "Hellboy's world", "level": "error"}, project_id=self.project.id
+        )
+        group_event = event.for_group(event.groups[0])
+        with self.tasks():
+            self.create_notification(group_event.group).send()
+
+        blocks, fallback_text = get_blocks_and_fallback_text()
+        notification_uuid = self.get_notification_uuid(blocks[0]["text"]["text"])
+        assert event.group
+        assert (
+            fallback_text
+            == f"{self.name} marked <http://testserver/organizations/{self.organization.slug}/issues/{event.group.id}/?referrer=activity_notification&notification_uuid={notification_uuid}|{self.project.slug.upper()}-{event.group.short_id}> as resolved"
+        )
+        assert blocks[0]["text"]["text"] == fallback_text
+        self.assert_generic_issue_blocks(
+            blocks,
+            group_event.organization.slug,
+            group_event.project.slug,
+            group_event.group,
+            "resolved_activity-slack",
+        )
diff --git a/tests/sentry/integrations/slack/notifications/test_resolved_in_release.py b/tests/sentry/integrations/slack/notifications/test_resolved_in_release.py
--- a/tests/sentry/integrations/slack/notifications/test_resolved_in_release.py
+++ b/tests/sentry/integrations/slack/notifications/test_resolved_in_release.py
@@ -7,8 +7,9 @@
     ResolvedInReleaseActivityNotification,
 )
 from sentry.testutils.cases import PerformanceIssueTestCase, SlackActivityNotificationTest
+from sentry.testutils.helpers.features import with_feature
 from sentry.testutils.helpers.notifications import TEST_ISSUE_OCCURRENCE, TEST_PERF_ISSUE_OCCURRENCE
-from sentry.testutils.helpers.slack import get_attachment
+from sentry.testutils.helpers.slack import get_attachment, get_blocks_and_fallback_text
 from sentry.testutils.silo import region_silo_test
 from sentry.testutils.skips import requires_snuba
 from sentry.types.activity import ActivityType
@@ -49,6 +50,27 @@ def test_resolved_in_release(self):
             == f"{self.project.slug} | <http://testserver/settings/account/notifications/workflow/?referrer=resolved_in_release_activity-slack-user&notification_uuid={notification_uuid}|Notification Settings>"
         )
 
+    @responses.activate
+    @with_feature("organizations:slack-block-kit")
+    def test_resolved_in_release_block(self):
+        notification = self.create_notification(self.group)
+        with self.tasks():
+            notification.send()
+
+        blocks, fallback_text = get_blocks_and_fallback_text()
+        release_name = notification.activity.data["version"]
+        assert fallback_text == f"Issue marked as resolved in {release_name} by {self.name}"
+        assert blocks[0]["text"]["text"] == fallback_text
+        notification_uuid = self.get_notification_uuid(blocks[1]["text"]["text"])
+        assert (
+            blocks[1]["text"]["text"]
+            == f"<http://testserver/organizations/{self.organization.slug}/issues/{self.group.id}/?referrer=resolved_in_release_activity-slack&notification_uuid={notification_uuid}|*{self.group.title}*>  \n"
+        )
+        assert (
+            blocks[2]["elements"][0]["text"]
+            == f"{self.project.slug} | <http://testserver/settings/account/notifications/workflow/?referrer=resolved_in_release_activity-slack-user&notification_uuid={notification_uuid}|Notification Settings>"
+        )
+
     @responses.activate
     @mock.patch(
         "sentry.eventstore.models.GroupEvent.occurrence",
@@ -71,6 +93,35 @@ def test_resolved_in_release_performance_issue(self, occurrence):
             attachment, self.project.slug, "resolved_in_release_activity-slack-user"
         )
 
+    @responses.activate
+    @mock.patch(
+        "sentry.eventstore.models.GroupEvent.occurrence",
+        return_value=TEST_PERF_ISSUE_OCCURRENCE,
+        new_callable=mock.PropertyMock,
+    )
+    @with_feature("organizations:slack-block-kit")
+    def test_resolved_in_release_performance_issue_block(self, occurrence):
+        """
+        Test that a Slack message is sent with the expected payload when a performance issue is resolved in a release
+        and block kit is enabled.
+        """
+        event = self.create_performance_issue()
+        notification = self.create_notification(event.group)
+        with self.tasks():
+            notification.send()
+
+        blocks, fallback_text = get_blocks_and_fallback_text()
+        release_name = notification.activity.data["version"]
+        assert fallback_text == f"Issue marked as resolved in {release_name} by {self.name}"
+        assert blocks[0]["text"]["text"] == fallback_text
+        self.assert_performance_issue_blocks(
+            blocks,
+            event.organization.slug,
+            event.project.slug,
+            event.group,
+            "resolved_in_release_activity-slack",
+        )
+
     @responses.activate
     @mock.patch(
         "sentry.eventstore.models.GroupEvent.occurrence",
@@ -96,6 +147,38 @@ def test_resolved_in_release_generic_issue(self, occurrence):
             attachment, self.project.slug, "resolved_in_release_activity-slack-user"
         )
 
+    @responses.activate
+    @mock.patch(
+        "sentry.eventstore.models.GroupEvent.occurrence",
+        return_value=TEST_ISSUE_OCCURRENCE,
+        new_callable=mock.PropertyMock,
+    )
+    @with_feature("organizations:slack-block-kit")
+    def test_resolved_in_release_generic_issue_block(self, occurrence):
+        """
+        Test that a Slack message is sent with the expected payload when a generic issue type is resolved in a release
+        and block kit is enabled.
+        """
+        event = self.store_event(
+            data={"message": "Hellboy's world", "level": "error"}, project_id=self.project.id
+        )
+        group_event = event.for_group(event.groups[0])
+        notification = self.create_notification(group_event.group)
+        with self.tasks():
+            notification.send()
+
+        blocks, fallback_text = get_blocks_and_fallback_text()
+        release_name = notification.activity.data["version"]
+        assert fallback_text == f"Issue marked as resolved in {release_name} by {self.name}"
+        assert blocks[0]["text"]["text"] == fallback_text
+        self.assert_generic_issue_blocks(
+            blocks,
+            group_event.organization.slug,
+            group_event.project.slug,
+            group_event.group,
+            "resolved_in_release_activity-slack",
+        )
+
     @responses.activate
     def test_resolved_in_release_parsed_version(self):
         """
@@ -112,3 +195,22 @@ def test_resolved_in_release_parsed_version(self):
             attachment["footer"]
             == f"{self.project.slug} | <http://testserver/settings/account/notifications/workflow/?referrer=resolved_in_release_activity-slack-user&notification_uuid={notification_uuid}|Notification Settings>"
         )
+
+    @responses.activate
+    @with_feature("organizations:slack-block-kit")
+    def test_resolved_in_release_parsed_version_block(self):
+        """
+        Test that the release version is formatted to the short version when block kit is enabled.
+        """
+        notification = self.create_notification(self.group, version="frontend@1.0.0")
+        with self.tasks():
+            notification.send()
+
+        blocks, fallback_text = get_blocks_and_fallback_text()
+        assert fallback_text == f"Issue marked as resolved in 1.0.0 by {self.name}"
+        assert blocks[0]["text"]["text"] == fallback_text
+        notification_uuid = self.get_notification_uuid(blocks[1]["text"]["text"])
+        assert (
+            blocks[2]["elements"][0]["text"]
+            == f"{self.project.slug} | <http://testserver/settings/account/notifications/workflow/?referrer=resolved_in_release_activity-slack-user&notification_uuid={notification_uuid}|Notification Settings>"
+        )
diff --git a/tests/sentry/integrations/slack/notifications/test_unassigned.py b/tests/sentry/integrations/slack/notifications/test_unassigned.py
--- a/tests/sentry/integrations/slack/notifications/test_unassigned.py
+++ b/tests/sentry/integrations/slack/notifications/test_unassigned.py
@@ -5,8 +5,9 @@
 from sentry.models.activity import Activity
 from sentry.notifications.notifications.activity.unassigned import UnassignedActivityNotification
 from sentry.testutils.cases import PerformanceIssueTestCase, SlackActivityNotificationTest
+from sentry.testutils.helpers.features import with_feature
 from sentry.testutils.helpers.notifications import TEST_ISSUE_OCCURRENCE, TEST_PERF_ISSUE_OCCURRENCE
-from sentry.testutils.helpers.slack import get_attachment
+from sentry.testutils.helpers.slack import get_attachment, get_blocks_and_fallback_text
 from sentry.testutils.skips import requires_snuba
 from sentry.types.activity import ActivityType
 
@@ -42,6 +43,28 @@ def test_unassignment(self):
             == f"{self.project.slug} | <http://testserver/settings/account/notifications/workflow/?referrer=unassigned_activity-slack-user&notification_uuid={notification_uuid}|Notification Settings>"
         )
 
+    @responses.activate
+    @with_feature("organizations:slack-block-kit")
+    def test_unassignment_block(self):
+        """
+        Test that a Slack message is sent with the expected payload when an issue is unassigned
+        and block kit is enabled.
+        """
+        with self.tasks():
+            self.create_notification(self.group).send()
+
+        blocks, fallback_text = get_blocks_and_fallback_text()
+        assert fallback_text == f"Issue unassigned by {self.name}"
+        assert blocks[0]["text"]["text"] == fallback_text
+        notification_uuid = self.get_notification_uuid(blocks[1]["text"]["text"])
+        assert blocks[1]["text"]["text"] == (
+            f"<http://testserver/organizations/{self.organization.slug}/issues/{self.group.id}/?referrer=unassigned_activity-slack&notification_uuid={notification_uuid}|*{self.group.title}*>  \n"
+        )
+        assert (
+            blocks[2]["elements"][0]["text"]
+            == f"{self.project.slug} | <http://testserver/settings/account/notifications/workflow/?referrer=unassigned_activity-slack-user&notification_uuid={notification_uuid}|Notification Settings>"
+        )
+
     @responses.activate
     @mock.patch(
         "sentry.eventstore.models.GroupEvent.occurrence",
@@ -62,6 +85,33 @@ def test_unassignment_performance_issue(self, occurrence):
             attachment, self.project.slug, "unassigned_activity-slack-user"
         )
 
+    @responses.activate
+    @mock.patch(
+        "sentry.eventstore.models.GroupEvent.occurrence",
+        return_value=TEST_PERF_ISSUE_OCCURRENCE,
+        new_callable=mock.PropertyMock,
+    )
+    @with_feature("organizations:slack-block-kit")
+    def test_unassignment_performance_issue_block(self, occurrence):
+        """
+        Test that a Slack message is sent with the expected payload when a performance issue is unassigned
+        and block kit is enabled.
+        """
+        event = self.create_performance_issue()
+        with self.tasks():
+            self.create_notification(event.group).send()
+
+        blocks, fallback_text = get_blocks_and_fallback_text()
+        assert fallback_text == f"Issue unassigned by {self.name}"
+        assert blocks[0]["text"]["text"] == fallback_text
+        self.assert_performance_issue_blocks(
+            blocks,
+            event.organization.slug,
+            event.project.slug,
+            event.group,
+            "unassigned_activity-slack",
+        )
+
     @responses.activate
     @mock.patch(
         "sentry.eventstore.models.GroupEvent.occurrence",
@@ -84,3 +134,33 @@ def test_unassignment_generic_issue(self, occurrence):
         self.assert_generic_issue_attachments(
             attachment, self.project.slug, "unassigned_activity-slack-user"
         )
+
+    @responses.activate
+    @mock.patch(
+        "sentry.eventstore.models.GroupEvent.occurrence",
+        return_value=TEST_ISSUE_OCCURRENCE,
+        new_callable=mock.PropertyMock,
+    )
+    @with_feature("organizations:slack-block-kit")
+    def test_unassignment_generic_issue_block(self, occurrence):
+        """
+        Test that a Slack message is sent with the expected payload when a generic issue type is unassigned
+        and block kit is enabled.
+        """
+        event = self.store_event(
+            data={"message": "Hellboy's world", "level": "error"}, project_id=self.project.id
+        )
+        group_event = event.for_group(event.groups[0])
+        with self.tasks():
+            self.create_notification(group_event.group).send()
+
+        blocks, fallback_text = get_blocks_and_fallback_text()
+        assert fallback_text == f"Issue unassigned by {self.name}"
+        assert blocks[0]["text"]["text"] == fallback_text
+        self.assert_generic_issue_blocks(
+            blocks,
+            group_event.organization.slug,
+            group_event.project.slug,
+            group_event.group,
+            "unassigned_activity-slack",
+        )