|
37 | 37 | from sentry.models.group import Group |
38 | 38 | from sentry.models.options.organization_option import OrganizationOption |
39 | 39 | from sentry.notifications.additional_attachment_manager import get_additional_attachment |
| 40 | +from sentry.notifications.models.notificationthread import ( |
| 41 | + NotificationThread, |
| 42 | + NotificationThreadObjectType, |
| 43 | +) |
40 | 44 | from sentry.notifications.notifications.activity.archive import ArchiveActivityNotification |
41 | 45 | from sentry.notifications.notifications.activity.assigned import AssignedActivityNotification |
42 | 46 | from sentry.notifications.notifications.activity.base import GroupActivityNotification |
|
58 | 62 | from sentry.notifications.notifications.activity.unassigned import UnassignedActivityNotification |
59 | 63 | from sentry.notifications.notifications.activity.unresolved import UnresolvedActivityNotification |
60 | 64 | from sentry.notifications.notifications.base import BaseNotification |
| 65 | +from sentry.notifications.platform.rollout import NotificationRolloutService |
| 66 | +from sentry.notifications.platform.types import SLACK_PROVIDERS, NotificationSource |
61 | 67 | from sentry.notifications.utils.open_period import open_period_start_for_group |
62 | 68 | from sentry.silo.base import SiloMode |
63 | 69 | from sentry.types.activity import ActivityType |
@@ -249,6 +255,25 @@ def _notify_all_threads_for_activity( |
249 | 255 | group_ids=[group.id], |
250 | 256 | ) |
251 | 257 |
|
| 258 | + # Also query platform threads for issue alerts sent via notification platform. Only orgs in |
| 259 | + # a platform rollout tier have them, so skip the query for everyone else. This checks the |
| 260 | + # tier, not the per-send random rollout rate, so replies reach every existing thread. |
| 261 | + platform_threads = NotificationThread.objects.none() |
| 262 | + if NotificationRolloutService(organization=group.organization).has_feature_flag_access(): |
| 263 | + platform_threads = NotificationThread.objects.filter( |
| 264 | + object_type=NotificationThreadObjectType.GROUP, |
| 265 | + object_id=group.id, |
| 266 | + key_type=NotificationSource.ISSUE.value, |
| 267 | + provider_key__in=SLACK_PROVIDERS, |
| 268 | + ) |
| 269 | + if use_open_period_start: |
| 270 | + # The platform thread key stores the open period start as an ISO string |
| 271 | + platform_threads = platform_threads.filter( |
| 272 | + key_data__open_period_start=( |
| 273 | + open_period_start.isoformat() if open_period_start else None |
| 274 | + ) |
| 275 | + ) |
| 276 | + |
252 | 277 | # We don't wrap this in a lifecycle because _handle_parent_notification is already wrapped in a lifecycle |
253 | 278 | parent_notification_count = 0 |
254 | 279 | for parent_notification in parent_notifications: |
@@ -307,6 +332,34 @@ def _notify_all_threads_for_activity( |
307 | 332 | }, |
308 | 333 | ) |
309 | 334 |
|
| 335 | + # Send to platform threads |
| 336 | + for platform_thread in platform_threads: |
| 337 | + with MessagingInteractionEvent( |
| 338 | + interaction_type=MessagingInteractionType.SEND_ACTIVITY_NOTIFICATION, |
| 339 | + spec=SlackMessagingSpec(), |
| 340 | + ).capture() as lifecycle: |
| 341 | + lifecycle.add_extras( |
| 342 | + { |
| 343 | + "activity_id": activity.id, |
| 344 | + "platform_thread_id": platform_thread.id, |
| 345 | + "integration_id": client.integration_id, |
| 346 | + "group_id": group.id, |
| 347 | + "project_id": activity.project.id, |
| 348 | + } |
| 349 | + ) |
| 350 | + try: |
| 351 | + self._send_notification_to_slack_channel( |
| 352 | + channel_id=platform_thread.target_id, |
| 353 | + message_identifier=platform_thread.thread_identifier, |
| 354 | + notification_to_send=notification_to_send, |
| 355 | + client=client, |
| 356 | + ) |
| 357 | + except Exception as err: |
| 358 | + if isinstance(err, SlackApiError): |
| 359 | + record_lifecycle_termination_level(lifecycle, err) |
| 360 | + else: |
| 361 | + lifecycle.record_failure(err) |
| 362 | + |
310 | 363 | def _get_channel_id_from_parent_notification_notification_action( |
311 | 364 | self, |
312 | 365 | parent_notification: NotificationActionNotificationMessage, |
|
0 commit comments