Skip to content

feat(msteams): Wire Teams Marketplace installs through the API pipeline modal#116488

Merged
evanpurkhiser merged 1 commit into
masterfrom
evanpurkhiser/feat-msteams-wire-teams-marketplace-installs-through-the-api-pipeline-modal
May 29, 2026
Merged

feat(msteams): Wire Teams Marketplace installs through the API pipeline modal#116488
evanpurkhiser merged 1 commit into
masterfrom
evanpurkhiser/feat-msteams-wire-teams-marketplace-installs-through-the-api-pipeline-modal

Conversation

@evanpurkhiser
Copy link
Copy Markdown
Member

VDY-101: Microsoft Teams: API-driven integration setup

When a user installs the Sentry app from the Microsoft Teams Marketplace, the Sentry bot posts a card linking to /extensions/msteams/configure/ with a signed signed_params blob. That forwards to /extensions/msteams/link/ (the org picker), and from there the install needs to drive the API pipeline modal. This wires up the frontend side:

  • Adds msTeamsParams in the org-link view, returning {signedParams} when signed_params is present in the URL query, and routes handleInstallClick through it via the existing gitHubAppListingParams ?? discordAppDirectoryParams ?? msTeamsParams chain.
  • Adds the integrationMsTeams pipeline definition. Its single step has no interactive UI; all install data arrives already bound to pipeline state, so it auto-advances when the backend returns appDirectoryInstall, rendering a brief "Finishing up..." message (guarded by a ref against React strict-mode double-fire).
  • Registers the pipeline and adds msteams to UNCONDITIONAL_API_PIPELINE_PROVIDERS.

Depends on the backend support (separate PR) and must not deploy before it: the modal calls the API pipeline initialize endpoint for msteams, which only works once the backend serializer / step / can_add_externally changes are live. The /extensions/msteams/configure/ URL still routes through the legacy server-rendered view until a follow-up swaps it to a redirect.

…ne modal

When a user installs the Sentry app from the Microsoft Teams Marketplace,
the Sentry bot posts a card linking to `/extensions/msteams/configure/` with
a signed `signed_params` blob. That forwards to `/extensions/msteams/link/`
(the org picker), and from there the install needs to drive the API pipeline
modal.

This wires up the frontend side:

- Adds `msTeamsParams` in the org-link view, returning `{signed_params}` when
  present in the URL query, and routes `handleInstallClick` through it via the
  existing `gitHubAppListingParams ?? discordAppDirectoryParams ??
  msTeamsParams` chain.
- Adds the `integrationMsTeams` pipeline definition. Its single step has no
  interactive UI; all install data arrives bound to pipeline state, so it
  auto-advances when the backend returns `appDirectoryInstall`, rendering a
  brief "Finishing up..." message (guarded by a ref against strict-mode
  double-fire).
- Registers the pipeline and adds `msteams` to
  `UNCONDITIONAL_API_PIPELINE_PROVIDERS`.

Backend support ships separately. The configure URL still routes through the
legacy server-rendered view until a follow-up swaps it to a redirect.
@evanpurkhiser evanpurkhiser requested review from a team as code owners May 29, 2026 15:36
@evanpurkhiser evanpurkhiser requested review from jaydgoss, leeandher and mujacica and removed request for a team May 29, 2026 15:36
@github-actions github-actions Bot added the Scope: Frontend Automatically applied to PRs that change frontend components label May 29, 2026
if (typeof signedParams !== 'string') {
return null;
}
return {signedParams};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The msTeamsParams object uses a camelCase key signedParams, but the backend will expect the snake_case key signed_params, causing the integration flow to fail.
Severity: HIGH

Suggested Fix

In integrationOrganizationLink/index.tsx:237, change the returned object from return {signedParams}; to return {signed_params: signedParams}; to ensure the key name matches the expected snake_case format.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: static/app/views/integrationOrganizationLink/index.tsx#L237

Potential issue: The code at `integrationOrganizationLink/index.tsx:237` returns an
object with a camelCase key, `{signedParams}`. This object is sent to the backend as
`initialData` for the MS Teams integration pipeline. Although the backend currently
lacks a serializer for this data, the PR description indicates one will be added. This
future serializer will almost certainly expect the key to be `signed_params`
(snake_case) to align with Python conventions and the parameter name in the URL. The
current camelCase key `signedParams` will cause this future backend validation to fail,
breaking the MS Teams installation flow.

Did we get this right? 👍 / 👎 to inform future reviews.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the initial data serializer will be a CamelCaseSerializer

@github-actions
Copy link
Copy Markdown
Contributor

📊 Type Coverage Diff

✅ No new type safety issues introduced. Coverage: 93.59%

* pipeline with `gitHubAppListingParams`.
*
* - Discord
* `/extensions/discord/link/?code=&guild_id=` (redirected from
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

annoying AI shit

evanpurkhiser added a commit that referenced this pull request May 29, 2026
…6490)

[VDY-101: Microsoft Teams: API-driven integration
setup](https://linear.app/getsentry/issue/VDY-101/microsoft-teams-api-driven-integration-setup)

Adds the API-mode pipeline machinery for Microsoft Teams alongside the
existing server-rendered configure flow, without changing the entry
point yet. This is the first of three deploy-safe steps: the legacy
`MsTeamsExtensionConfigurationView` and the
`/extensions/msteams/configure/` URL are left untouched, so nothing
changes for users until the frontend can drive the modal and the
configure URL is later swapped to a redirect.

- `MsTeamsInitialDataSerializer` unsigns the bot's `signed_params` blob
and binds each field to top-level pipeline state.
- `MsTeamsApiStep` has no interactive UI; it signals the frontend to
auto-advance, which runs `build_integration` on the bound state.
- `build_integration` now reads top-level state, falling back to the
nested `state["msteams"]` the legacy view binds, so both flows work
during the transition.

Also adds a `can_add_externally` marker to `IntegrationProvider` for
integrations whose install is initiated from the third party's app
directory or marketplace and completed through the pipeline modal. MS
Teams sets `can_add = False` to hide the in-app install button, so the
pipeline endpoint needs this opt-in to allow the externally-initiated
install. The other already-external providers (Discord, GitHub, and
GitHub Enterprise via subclassing) are marked for consistency; it's a
no-op for them since they're `can_add = True`.

Note: mypy will be red until #116486 (typing `utils.signing.unsign` as
`Any`) merges, since the serializer's `validate()` returns a `TypedDict`
from `unsign()`. The frontend follow-up is #116488.
@evanpurkhiser evanpurkhiser merged commit 201dd5a into master May 29, 2026
77 checks passed
@evanpurkhiser evanpurkhiser deleted the evanpurkhiser/feat-msteams-wire-teams-marketplace-installs-through-the-api-pipeline-modal branch May 29, 2026 20:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants