feat(teams): Microsoft Teams integration via Graph API#292
feat(teams): Microsoft Teams integration via Graph API#292Shubhank-Jonnada wants to merge 1 commit into
Conversation
14 actions: list/get teams, list/get/create channels, list/get/send channel messages, list/add/remove members, list chats, list/send chat messages. Full 2-way read+write support using OAuth2 + Graph API.
🔍 Integration Validation ResultsCommit: Changed directories:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e038cd5c3a
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| response = await context.fetch( | ||
| f"{BASE_URL}/teams/{team_id}/channels", | ||
| method="POST", | ||
| headers=_headers(context), | ||
| body=body, |
There was a problem hiding this comment.
Use JSON/data args for POST payloads in
context.fetch
These POST actions pass request content via body=..., but integration code in this repo consistently uses json=/data= with ExecutionContext.fetch; using body here can cause the payload to be dropped (or raise an unexpected-argument error), so write operations fail or send malformed requests. This impacts all new write paths that use this pattern, including create_channel, send_channel_message, add_member, and send_chat_message.
Useful? React with 👍 / 👎.
| "@odata.type": "#microsoft.graph.aadUserConversationMember", | ||
| "roles": roles, | ||
| "user@odata.bind": f"https://graph.microsoft.com/v1.0/users/{user_id}", | ||
| } |
There was a problem hiding this comment.
Build
user@odata.bind using OData key format
The member-add payload binds the user as .../users/{user_id} even though this endpoint expects an OData entity reference form (users('{id-or-upn}')). As written, valid user_id inputs (especially UPN/email-style values) can be rejected as an invalid bind URL, causing add_member to fail despite otherwise correct permissions.
Useful? React with 👍 / 👎.
TheRealAgentK
left a comment
There was a problem hiding this comment.
Thanks for tackling the broken Bot-Framework Teams integration with a Graph API rewrite — the action surface looks reasonable. There are several blockers before this can land though, with the test gap being the most pressing.
Unit tests — missing
There are no pytest-collectable unit tests for any of the 14 new actions. teams/tests/test_teams.py is a manual asyncio script intended to be run as python test_teams.py <token> against the live Microsoft Graph API — it's not a pytest module, has no markers, no mocked ExecutionContext, and is not picked up by our python_files = ["test_*_unit.py"] filter. Locally pytest teams/ -v collects 0 tests.
For a brand-new 1255-line integration with 14 actions and zero unit coverage, this is below the bar set by every other recent integration in the repo (e.g. salesforce 56, hubspot 264, harvest 42).
Action required: add teams/tests/test_teams_unit.py following the writing-unit-tests skill. Each action should have at minimum: happy path, request verification (URL/method/headers/body), and at least one error path. Target 4–5 tests per action like the rest of the SDK-v2 PRs in this batch (#284 float = 71, #287 freshdesk = 88, #290 xero = 100).
Integration tests — missing
No teams/tests/test_teams_integration.py. The current test_teams.py script is the closest thing but it doesn't follow the live_context fixture pattern, doesn't use the integration marker, and isn't excluded from CI through the standard double-mechanism (file glob + marker filter).
Action required: convert test_teams.py into a proper test_teams_integration.py per the writing-integration-tests skill, with pytestmark = pytest.mark.integration, env-var token (TEAMS_ACCESS_TOKEN), and @pytest.mark.destructive on add_member / remove_member / send_*_message.
Other blockers I want addressed in the same PR
These aren't about tests but they're shipping defects that would force an immediate follow-up PR:
- SDK 1.1.1 instead of 2.0.0.
requirements.txtpinsautohive-integrations-sdk~=1.1.1. Every other new integration in the last 2 weeks ships on 2.0.0, and we're actively migrating off the 1.x error pattern across this batch (#274, #287, #288, #289, #290) because it crashes Lambda. Please bump to~=2.0.0and follow theupgrading-sdk-v2skill. - All error paths use
ActionResult(data={"result": False, "error": str(e)}). This is the exact pattern that just caused 232 production failures in #274 (github), several in #289 (sheets) and #290 (xero). On SDK 2.0.0 it fails output-schema validation and returns "Unhandled" to the caller. Switch toActionError(message=...)and removeresult/errorfrom theoutput_schemablocks. - No
ConnectedAccountHandler. Same defect as #273 (stripe) — the platform calls the connected-account endpoint after OAuth and will raiseValidationError: No connected account handler registered, surfacing as a connect-time crash in Raygun. Add aTeamsConnectedAccountHandlerthat calls/meon Graph and returnsConnectedAccountInfo(username=display_name, user_id=id). - README claims this "replaces the previous Teams integration" but I can't find a
teams/folder inmasteror in any prior closed PR. Please clarify what's being replaced — if there's a private-repo predecessor, link it.
Process
- Branch name
feature/teams-integrationdoesn't follow the<type>/<issue-number>/<short-description>convention from AGENTS.md. - No linked GitHub issue.
Local CI status
validate_integration.py ✅, check_code.py ✅, ruff check ✅, ruff format ✅, pytest teams/ result/error fields — once you bump to v2 and remove them, the existing error returns will start failing schema validation, which is exactly the prod issue we want to surface in tests.
|
Closing this for now, reworking the Teams bot to handle admin approval flow. |
Summary
Actions
list_teamsget_teamlist_channelsget_channelcreate_channellist_messagesget_messagesend_channel_messagelist_membersadd_memberremove_memberlist_chatslist_chat_messagessend_chat_messageWhy this replaces the previous integration
The previous Teams integration (in Teams.zip) used the Microsoft Bot Framework SDK with hardcoded bot credentials. It could not read messages, had no real auth flow for customers, and
send_messagewould fail without a pre-existing bot conversation context. This integration uses the standard Graph API with proper OAuth2, giving full read+write capability.Test plan
python tests/test_teams.py <access_token>— verifies list_teams, list_chats, list_channels, list_messagessend_channel_messageandsend_chat_messageadd_member/remove_memberwith an admin-consented account