Skip to content

🔧 chore: use IntegrationProviderSlug.Slack instead of magic str #95390

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 14, 2025
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
5 changes: 3 additions & 2 deletions src/sentry/identity/slack/provider.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
from sentry import options
from sentry.identity.oauth2 import OAuth2CallbackView, OAuth2LoginView, OAuth2Provider
from sentry.identity.pipeline import IdentityPipeline
from sentry.integrations.types import IntegrationProviderSlug
from sentry.pipeline.views.base import PipelineView


class SlackIdentityProvider(OAuth2Provider):
key = "slack"
key = IntegrationProviderSlug.SLACK.value
name = "Slack"

# This identity provider is used for authorizing the Slack application
Expand Down Expand Up @@ -61,7 +62,7 @@ def build_identity(self, data):
data = data["data"]

return {
"type": "slack",
"type": IntegrationProviderSlug.SLACK.value,
# TODO(epurkhiser): See note above
"id": data["user"]["id"],
"email": data["user"]["email"],
Expand Down
9 changes: 7 additions & 2 deletions src/sentry/integrations/messaging/linkage.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@
from sentry.integrations.models.external_actor import ExternalActor
from sentry.integrations.models.integration import Integration
from sentry.integrations.services.integration import RpcIntegration, integration_service
from sentry.integrations.types import ExternalProviderEnum, ExternalProviders
from sentry.integrations.types import (
ExternalProviderEnum,
ExternalProviders,
IntegrationProviderSlug,
)
from sentry.integrations.utils.identities import get_identity_or_404
from sentry.models.organizationmember import OrganizationMember
from sentry.models.team import Team
Expand Down Expand Up @@ -460,7 +464,8 @@ def execute(
logger_params["team_id"] = team.id

idp = identity_service.get_provider(
provider_type="slack", provider_ext_id=integration.external_id
provider_type=IntegrationProviderSlug.SLACK.value,
provider_ext_id=integration.external_id,
)
logger_params["provider_ext_id"] = integration.external_id
if idp is None:
Expand Down
3 changes: 2 additions & 1 deletion src/sentry/integrations/slack/actions/notification.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
from sentry.integrations.slack.spec import SlackMessagingSpec
from sentry.integrations.slack.utils.channel import SlackChannelIdData, get_channel_id
from sentry.integrations.slack.utils.threads import NotificationActionThreadUtils
from sentry.integrations.types import IntegrationProviderSlug
from sentry.integrations.utils.metrics import EventLifecycle
from sentry.issues.grouptype import GroupCategory
from sentry.models.options.organization_option import OrganizationOption
Expand All @@ -51,7 +52,7 @@
class SlackNotifyServiceAction(IntegrationEventAction):
id = "sentry.integrations.slack.notify_action.SlackNotifyServiceAction"
prompt = "Send a Slack notification"
provider = "slack"
provider = IntegrationProviderSlug.SLACK.value
integration_key = "workspace"
label = "Send a notification to the {workspace} Slack workspace to {channel} (optionally, an ID: {channel_id}) and show tags {tags} and notes {notes} in notification"

Expand Down
4 changes: 2 additions & 2 deletions src/sentry/integrations/slack/integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ class SlackIntegrationProvider(IntegrationProvider):
def _identity_pipeline_view(self) -> PipelineView[IntegrationPipeline]:
return NestedPipelineView(
bind_key="identity",
provider_key="slack",
provider_key=IntegrationProviderSlug.SLACK.value,
pipeline_cls=IdentityPipeline,
config={
"oauth_scopes": self.identity_oauth_scopes,
Expand Down Expand Up @@ -184,7 +184,7 @@ def build_integration(self, state: Mapping[str, Any]) -> IntegrationData:
"external_id": team_id,
"metadata": metadata,
"user_identity": {
"type": "slack",
"type": IntegrationProviderSlug.SLACK.value,
"external_id": user_id_slack,
"scopes": [],
"data": {},
Expand Down
9 changes: 6 additions & 3 deletions src/sentry/integrations/slack/requests/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from sentry.identity.services.identity.model import RpcIdentityProvider
from sentry.integrations.messaging.commands import CommandInput
from sentry.integrations.services.integration import RpcIntegration, integration_service
from sentry.integrations.types import IntegrationProviderSlug
from sentry.users.services.user import RpcUser
from sentry.users.services.user.service import user_service
from sentry.utils.safe import get_path
Expand Down Expand Up @@ -99,7 +100,7 @@ def _get_context(self):
except Exception:
pass
context = integration_service.get_integration_identity_context(
integration_provider="slack",
integration_provider=IntegrationProviderSlug.SLACK.value,
integration_external_id=team_id,
identity_external_id=user_id,
identity_provider_external_id=team_id,
Expand Down Expand Up @@ -162,7 +163,7 @@ def get_identity(self) -> RpcIdentity | None:

if self._provider is None:
self._provider = identity_service.get_provider(
provider_type="slack", provider_ext_id=self.team_id
provider_type=IntegrationProviderSlug.SLACK.value, provider_ext_id=self.team_id
)

if self._provider is not None:
Expand Down Expand Up @@ -225,7 +226,9 @@ def _check_verification_token(self, verification_token: str) -> bool:
def validate_integration(self) -> None:
if not self._integration:
self._integration = integration_service.get_integration(
provider="slack", external_id=self.team_id, status=ObjectStatus.ACTIVE
provider=IntegrationProviderSlug.SLACK.value,
external_id=self.team_id,
status=ObjectStatus.ACTIVE,
)

if not self._integration:
Expand Down
3 changes: 2 additions & 1 deletion src/sentry/integrations/slack/sdk_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from sentry.integrations.models import Integration
from sentry.integrations.services.integration import integration_service
from sentry.integrations.services.integration.model import RpcIntegration
from sentry.integrations.types import IntegrationProviderSlug
from sentry.silo.base import SiloMode
from sentry.utils import metrics

Expand All @@ -32,7 +33,7 @@ def track_response_data(response: SlackResponse, method: str, error: str | None
)

extra = {
"integration": "slack",
"integration": IntegrationProviderSlug.SLACK.value,
"status_string": str(code),
"error": error,
"method": method,
Expand Down
3 changes: 2 additions & 1 deletion src/sentry/integrations/slack/spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
MessagingIdentityLinkViewSet,
MessagingIntegrationSpec,
)
from sentry.integrations.types import IntegrationProviderSlug
from sentry.models.organization import Organization
from sentry.notifications.models.notificationaction import ActionService
from sentry.rules.actions import IntegrationEventAction
Expand All @@ -20,7 +21,7 @@
class SlackMessagingSpec(MessagingIntegrationSpec):
@property
def provider_slug(self) -> str:
return "slack"
return IntegrationProviderSlug.SLACK.value

@property
def action_service(self) -> ActionService:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from sentry.incidents.serializers import AlertRuleSerializer
from sentry.integrations.slack.utils.constants import SLACK_RATE_LIMITED_MESSAGE
from sentry.integrations.slack.utils.rule_status import RedisRuleStatus
from sentry.integrations.types import IntegrationProviderSlug
from sentry.models.organization import Organization
from sentry.shared_integrations.exceptions import ApiRateLimitedError
from sentry.silo.base import SiloMode
Expand Down Expand Up @@ -85,7 +86,7 @@ def find_channel_id_for_alert_rule(

for trigger in data["triggers"]:
for action in trigger["actions"]:
if action["type"] == "slack":
if action["type"] == IntegrationProviderSlug.SLACK.value:
if action["targetIdentifier"] in mapped_ids:
action["input_channel_id"] = mapped_ids[action["targetIdentifier"]]
# This will conflict within the CamelCaseSerializer below.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
)
from sentry.integrations.slack.utils.constants import SLACK_RATE_LIMITED_MESSAGE
from sentry.integrations.slack.utils.rule_status import RedisRuleStatus
from sentry.integrations.types import IntegrationProviderSlug
from sentry.models.project import Project
from sentry.models.rule import Rule, RuleActivity, RuleActivityType
from sentry.projects.project_rules.creator import ProjectRuleCreator
Expand Down Expand Up @@ -60,7 +61,9 @@ def find_channel_id_for_rule(
break

integrations = integration_service.get_integrations(
organization_id=organization.id, providers=["slack"], integration_ids=[integration_id]
organization_id=organization.id,
providers=[IntegrationProviderSlug.SLACK.value],
integration_ids=[integration_id],
)
if not integrations:
redis_rule_status.set_value("failed")
Expand Down
6 changes: 4 additions & 2 deletions src/sentry/integrations/slack/webhooks/action.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
from sentry.integrations.slack.sdk_client import SlackSdkClient
from sentry.integrations.slack.spec import SlackMessagingSpec
from sentry.integrations.slack.utils.errors import MODAL_NOT_FOUND, unpack_slack_api_error
from sentry.integrations.types import ExternalProviderEnum
from sentry.integrations.types import ExternalProviderEnum, IntegrationProviderSlug
from sentry.integrations.utils.scope import bind_org_context_from_integration
from sentry.models.activity import ActivityIntegration
from sentry.models.group import Group
Expand Down Expand Up @@ -702,7 +702,9 @@ def handle_member_approval(self, slack_request: SlackActionRequest, action: str)
original_status = InviteStatus(member.invite_status)
try:
if action == "approve_member":
member.approve_member_invitation(identity_user, referrer="slack")
member.approve_member_invitation(
identity_user, referrer=IntegrationProviderSlug.SLACK.value
)
else:
member.reject_member_invitation(identity_user)
except Exception:
Expand Down
2 changes: 1 addition & 1 deletion src/sentry/middleware/integrations/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def _forward_response(self, result: _AsyncResult) -> Response | None:
class _AsyncSlackDispatcher(_AsyncRegionDispatcher):
@property
def log_code(self) -> str:
return "slack"
return IntegrationProviderSlug.SLACK.value

def unpack_payload(self, response: Response) -> Any:
return orjson.loads(response.content)
Expand Down
4 changes: 2 additions & 2 deletions src/sentry/notifications/notifications/digest.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
should_get_personalized_digests,
)
from sentry.eventstore.models import Event
from sentry.integrations.types import ExternalProviders
from sentry.integrations.types import ExternalProviders, IntegrationProviderSlug
from sentry.notifications.notifications.base import ProjectNotification
from sentry.notifications.notify import notify
from sentry.notifications.types import ActionTargetType, FallthroughChoiceType, UnsubscribeContext
Expand Down Expand Up @@ -151,7 +151,7 @@ def build_context(
"user_counts": digest.user_counts,
"has_alert_integration": has_alert_integration(project),
"project": project,
"slack_link": get_integration_link(organization, "slack"),
"slack_link": get_integration_link(organization, IntegrationProviderSlug.SLACK.value),
"rules_details": {rule.id: rule for rule in rule_details},
"link_params_for_rule": get_email_link_extra_params(
"digest_email",
Expand Down
10 changes: 8 additions & 2 deletions src/sentry/notifications/notifications/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
from sentry.db.models import Model
from sentry.eventstore.models import GroupEvent
from sentry.integrations.issue_alert_image_builder import IssueAlertImageBuilder
from sentry.integrations.types import ExternalProviderEnum, ExternalProviders
from sentry.integrations.types import (
ExternalProviderEnum,
ExternalProviders,
IntegrationProviderSlug,
)
from sentry.issues.grouptype import (
GROUP_CATEGORIES_CUSTOM_EMAIL,
GroupCategory,
Expand Down Expand Up @@ -194,7 +198,9 @@ def get_context(self) -> MutableMapping[str, Any]:
"enhanced_privacy": enhanced_privacy,
"commits": get_commits(self.project, self.event),
"environment": environment,
"slack_link": get_integration_link(self.organization, "slack", self.notification_uuid),
"slack_link": get_integration_link(
self.organization, IntegrationProviderSlug.SLACK.value, self.notification_uuid
),
"notification_reason": notification_reason,
"notification_settings_link": absolute_uri(
f"/settings/account/notifications/alerts/{sentry_query_params}"
Expand Down
4 changes: 2 additions & 2 deletions src/sentry/users/models/identity.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
)
from sentry.db.models.fields.jsonfield import JSONField
from sentry.db.models.manager.base import BaseManager
from sentry.integrations.types import ExternalProviders
from sentry.integrations.types import ExternalProviders, IntegrationProviderSlug
from sentry.users.services.user import RpcUser

if TYPE_CHECKING:
Expand Down Expand Up @@ -108,7 +108,7 @@ def link_identity(

analytics.record(
"integrations.identity_linked",
provider="slack",
provider=IntegrationProviderSlug.SLACK.value,
# Note that prior to circa March 2023 this was user.actor_id. It changed
# when actor ids were no longer stable between regions for the same user
actor_id=user.id,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from django.http import HttpRequest, HttpResponse
from django.views.generic import View

from sentry.integrations.types import IntegrationProviderSlug
from sentry.models.organization import Organization
from sentry.models.organizationmember import OrganizationMember
from sentry.notifications.notifications.organization_request.integration_request import (
Expand All @@ -22,7 +23,7 @@ def get(self, request: HttpRequest) -> HttpResponse:
org,
requester,
provider_type="first_party",
provider_slug="slack",
provider_slug=IntegrationProviderSlug.SLACK.value,
provider_name="Slack",
)

Expand Down
Loading