|
58 | 58 | from sentry.notifications.notifications.activity.unassigned import UnassignedActivityNotification |
59 | 59 | from sentry.notifications.notifications.activity.unresolved import UnresolvedActivityNotification |
60 | 60 | from sentry.notifications.notifications.base import BaseNotification |
| 61 | +from sentry.notifications.platform.threading import ThreadingService |
| 62 | +from sentry.notifications.platform.types import NotificationProviderKey, NotificationSource |
61 | 63 | from sentry.notifications.utils.open_period import open_period_start_for_group |
62 | 64 | from sentry.silo.base import SiloMode |
63 | 65 | from sentry.types.activity import ActivityType |
@@ -249,6 +251,11 @@ def _notify_all_threads_for_activity( |
249 | 251 | group_ids=[group.id], |
250 | 252 | ) |
251 | 253 |
|
| 254 | + # Also query platform threads for issue alerts sent via notification platform |
| 255 | + platform_threads = self._get_platform_threads_for_group( |
| 256 | + group=group, integration=integration |
| 257 | + ) |
| 258 | + |
252 | 259 | # We don't wrap this in a lifecycle because _handle_parent_notification is already wrapped in a lifecycle |
253 | 260 | parent_notification_count = 0 |
254 | 261 | for parent_notification in parent_notifications: |
@@ -307,6 +314,64 @@ def _notify_all_threads_for_activity( |
307 | 314 | }, |
308 | 315 | ) |
309 | 316 |
|
| 317 | + # Send to platform threads |
| 318 | + for platform_thread in platform_threads: |
| 319 | + with MessagingInteractionEvent( |
| 320 | + interaction_type=MessagingInteractionType.SEND_ACTIVITY_NOTIFICATION, |
| 321 | + spec=SlackMessagingSpec(), |
| 322 | + ).capture() as lifecycle: |
| 323 | + lifecycle.add_extras( |
| 324 | + { |
| 325 | + "activity_id": activity.id, |
| 326 | + "platform_thread_id": platform_thread.id, |
| 327 | + "notification_to_send": notification_to_send, |
| 328 | + "integration_id": client.integration_id, |
| 329 | + "group_id": group.id, |
| 330 | + "project_id": activity.project.id, |
| 331 | + } |
| 332 | + ) |
| 333 | + try: |
| 334 | + self._send_notification_to_slack_channel( |
| 335 | + channel_id=platform_thread.target_id, |
| 336 | + message_identifier=platform_thread.thread_identifier, |
| 337 | + notification_to_send=notification_to_send, |
| 338 | + client=client, |
| 339 | + ) |
| 340 | + except Exception as err: |
| 341 | + if isinstance(err, SlackApiError): |
| 342 | + record_lifecycle_termination_level(lifecycle, err) |
| 343 | + else: |
| 344 | + lifecycle.record_failure(err) |
| 345 | + |
| 346 | + def _get_platform_threads_for_group( |
| 347 | + self, group: Group, integration: Integration |
| 348 | + ) -> list[NotificationThread]: |
| 349 | + """ |
| 350 | + Query NotificationThread for issue alerts sent via the notification platform. |
| 351 | + |
| 352 | + Returns threads for the given group that were sent via Slack, filtering by integration |
| 353 | + to ensure we only send to threads from this specific Slack workspace. |
| 354 | + """ |
| 355 | + from sentry.notifications.models.notificationthread import NotificationThread |
| 356 | + |
| 357 | + # Query for issue alert threads for this group |
| 358 | + # Note: We query by key_type and key_data separately since we can't easily |
| 359 | + # hash the exact key without knowing all action_ids |
| 360 | + threads = NotificationThread.objects.filter( |
| 361 | + key_type=NotificationSource.ISSUE.value, |
| 362 | + key_data__group_id=group.id, |
| 363 | + provider_key__in=[ |
| 364 | + NotificationProviderKey.SLACK.value, |
| 365 | + NotificationProviderKey.SLACK_STAGING.value, |
| 366 | + ], |
| 367 | + ) |
| 368 | + |
| 369 | + # Filter to only threads from this integration by checking target_id against |
| 370 | + # the integration's channels (Note: This is best-effort; the platform path |
| 371 | + # stores channel_id in target_id, which should match across integrations) |
| 372 | + # For simplicity, we return all Slack threads for this group |
| 373 | + return list(threads) |
| 374 | + |
310 | 375 | def _get_channel_id_from_parent_notification_notification_action( |
311 | 376 | self, |
312 | 377 | parent_notification: NotificationActionNotificationMessage, |
|
0 commit comments