Repository navigation
feat(reports): add native Microsoft Teams alert notifications - #45508
KristiDodaj wants to merge 29 commits into
Conversation
✅ Deploy Preview for superset-docs-preview ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #45508 +/- ##
==========================================
+ Coverage 84.63% 84.69% +0.05%
==========================================
Files 3069 3080 +11
Lines 205446 206187 +741
Branches 48306 48449 +143
==========================================
+ Hits 173879 174624 +745
+ Misses 28277 28265 -12
- Partials 3290 3298 +8
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
29b3d9c to
66c544b
Compare
2b8e173 to
056cfe9
Compare
| try: | ||
| destination = config.get_destination(recipient["target"]) | ||
| except ValueError: | ||
| raise TeamsRecipientValidationError( |
There was a problem hiding this comment.
These Teams validation messages (here, the "A configured Teams destination key is required" and "Invalid Teams recipient configuration" ones above, and the duplicate-key message in commands/report/base.py) are plain English and flow straight into the 422 response and the editor's error toast. A non-English user saving an alert whose Teams destination was removed will see "Teams destination is not approved" untranslated, while the neighbouring report validators wrap theirs in _(). Should these go through gettext (and into messages.pot) like the rest of the report validation errors?
| return InvokeResponse(status=result.status) | ||
|
|
||
| try: | ||
| server = HttpServer(adapter, messaging_endpoint=EVENTS_PATH) |
There was a problem hiding this comment.
A new HttpServer is built for every callback, so (assuming the SDK's validator builds its JWKS client per instance) none of the signing-key cache or refresh cooldown carries over between requests. An unauthenticated caller who posts a well-formed JWT with any kid then triggers a blocking fetch of the Bot Framework key set inside the Flask worker on every request, and if the egress IP gets throttled, legitimate installation events fail key lookup with a 401 and are never recorded (Teams does not redeliver). The tests monkeypatch the signing-key lookup, so this isn't exercised. Does the SDK cache keys across HttpServer instances, or should the server/validator be kept per process?
| ) | ||
| missing_sdk = MagicMock(side_effect=AssertionError("must not check SDK")) | ||
| monkeypatch.setattr(destinations, "is_teams_sdk_installed", missing_sdk) | ||
| monkeypatch.setitem(sys.modules, "superset.integrations.teams.adapter", None) |
There was a problem hiding this comment.
register_teams_api and base are imported at the top of this test, before sys.modules is blocked here. If a module-level import microsoft_teams were added to api.py or destinations.py, those modules would already be loaded with the SDK present, so this test would still pass in CI while a deployment without the optional extra fails at startup. Could this run the disabled-Teams startup in a fresh interpreter (or import the modules after the block) and assert the callback still returns 404?
SUMMARY
Add Microsoft Teams as an optional notification destination for attachment-free alerts.
Administrators configure a single tenant, bot credentials, and approved standard channels. Users select a destination in the alert editor. Each notification creates a new channel post containing the alert name, optional description, and optional link to Superset.
The integration is disabled by default behind
ALERT_REPORT_TEAMSand uses the optionalteamsdependency extra. Authenticated installation callbacks maintain routing information. Removing the bot disables delivery until it is reinstalled.Includes recipient validation, bounded retries, delivery error handling, setup documentation, and automated tests.
Initial scope excludes scheduled reports, private/shared channels, direct messages, file attachments, and interactive cards.
Related discussion: #45307
BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
Before: Microsoft Teams is not available as a notification destination.
After: Users can select an administrator-approved Teams destination and receive alert cards in its channel.
Teams destination selection
Delivered alerts, including successful delivery after bot reinstallation
Credentials are configured server-side, not through an administrator UI.
TESTING INSTRUCTIONS
teamsextra on the web server and Celery worker.ALERT_REPORT_TEAMSand configure the tenant, bot credentials, and approved destinations.Validation:
Browser creation/editing coverage is provided by an opt-in test against a locally configured Superset instance. It skips when Teams is unconfigured. The local browser flow passed during validation.
Live delivery was tested separately using a Microsoft test tenant: Celery delivery to a non-default standard channel, separate root posts, delivery after web and worker restarts, and fresh removal/reinstallation callbacks with delivery failure and recovery.
ADDITIONAL INFORMATION
Related discussion: Native Microsoft Teams notifications without Power Automate #45307
ALERT_REPORTS,ALERT_REPORT_TEAMS