Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@ module = [
"sentry.integrations.github.integration",
"sentry.integrations.gitlab.issues",
"sentry.integrations.jira.integration",
"sentry.integrations.msteams.notifications",
"sentry.integrations.pagerduty.actions.form",
"sentry.integrations.pipeline",
"sentry.integrations.slack.message_builder.notifications.issues",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from sentry.integrations.types import ExternalProviders
from sentry.notifications.notifications.activity.base import GroupActivityNotification
from sentry.notifications.notifications.base import BaseNotification
from sentry.notifications.notifications.rules import AlertRuleNotification
from sentry.notifications.utils.actions import MessageAction
from sentry.types.actor import Actor

Expand Down Expand Up @@ -122,7 +123,7 @@ def build_notification_card(self):
class MSTeamsIssueNotificationsMessageBuilder(MSTeamsNotificationsMessageBuilder):
def __init__(
self,
notification: GroupActivityNotification,
notification: GroupActivityNotification | AlertRuleNotification,
context: Mapping[str, Any],
recipient: Actor,
):
Expand Down
32 changes: 25 additions & 7 deletions src/sentry/integrations/msteams/notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
from sentry.integrations.msteams.utils import get_user_conversation_id
from sentry.integrations.notifications import get_context, get_integrations_by_channel_by_recipient
from sentry.integrations.types import ExternalProviders
from sentry.models.team import Team
from sentry.notifications.notifications.activity.assigned import AssignedActivityNotification
from sentry.notifications.notifications.activity.base import GroupActivityNotification
from sentry.notifications.notifications.activity.escalating import EscalatingActivityNotification
from sentry.notifications.notifications.activity.note import NoteActivityNotification
from sentry.notifications.notifications.activity.regression import RegressionActivityNotification
Expand All @@ -25,7 +25,6 @@
from sentry.notifications.notifications.rules import AlertRuleNotification
from sentry.notifications.notify import register_notification_provider
from sentry.types.actor import Actor
from sentry.users.models.user import User
from sentry.utils import metrics

from .card_builder.notifications import (
Expand All @@ -47,8 +46,13 @@
RegressionActivityNotification,
EscalatingActivityNotification,
]
MESSAGE_BUILDERS = {

BASE_MESSAGE_BUILDERS = {
"SlackNotificationsMessageBuilder": MSTeamsNotificationsMessageBuilder,
}

# For Group-based notifications, it is possible we use a builder that is generic OR uses a group-specific builder
GROUP_MESSAGE_BUILDERS = BASE_MESSAGE_BUILDERS | {
"IssueNotificationMessageBuilder": MSTeamsIssueNotificationsMessageBuilder,
}

Expand All @@ -62,10 +66,19 @@ def is_supported_notification_type(notification: BaseNotification) -> bool:
)


def get_notification_card(
notification: BaseNotification, context: Mapping[str, Any], recipient: User | Team | Actor
def get_group_notification_card(
notification: GroupActivityNotification | AlertRuleNotification,
context: Mapping[str, Any],
recipient: Actor,
) -> AdaptiveCard:
cls = GROUP_MESSAGE_BUILDERS[notification.message_builder]
return cls(notification, context, recipient).build_notification_card()


def get_base_notification_card(
notification: BaseNotification, context: Mapping[str, Any], recipient: Actor
) -> AdaptiveCard:
cls = MESSAGE_BUILDERS[notification.message_builder]
cls = BASE_MESSAGE_BUILDERS[notification.message_builder]
return cls(notification, context, recipient).build_notification_card()


Expand Down Expand Up @@ -95,7 +108,12 @@ def send_notification_as_msteams(
context = get_context(notification, recipient, shared_context, extra_context)

with sentry_sdk.start_span(op="notification.send_msteams", name="gen_attachments"):
card = get_notification_card(notification, context, recipient)
if isinstance(notification, GroupActivityNotification) or isinstance(
notification, AlertRuleNotification
):
card = get_group_notification_card(notification, context, recipient)
else:
card = get_base_notification_card(notification, context, recipient)

for channel, integration in integrations_by_channel.items():
conversation_id = get_user_conversation_id(integration, channel)
Expand Down
4 changes: 2 additions & 2 deletions src/sentry/integrations/msteams/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
OpenPeriodContext,
)
from sentry.integrations.models.integration import Integration
from sentry.integrations.services.integration import integration_service
from sentry.integrations.services.integration import RpcIntegration, integration_service
from sentry.models.organization import Organization

from .client import MsTeamsClient, MsTeamsPreInstallClient, get_token_data
Expand Down Expand Up @@ -41,7 +41,7 @@ def channel_filter(channel, name):
return name.lower() == "general"


def get_user_conversation_id(integration: Integration, user_id: str) -> str:
def get_user_conversation_id(integration: Integration | RpcIntegration, user_id: str) -> str:
"""
Get the user_conversation_id even if `integration.metadata.tenant_id` is not set.
"""
Expand Down
Loading