Skip to content

Add Microsoft Dynamics 365 CRM integration#378

Open
Shubhank-Jonnada wants to merge 5 commits into
masterfrom
sj/dynamics365-integration
Open

Add Microsoft Dynamics 365 CRM integration#378
Shubhank-Jonnada wants to merge 5 commits into
masterfrom
sj/dynamics365-integration

Conversation

@Shubhank-Jonnada

Copy link
Copy Markdown
Contributor

Summary

  • Adds Microsoft Dynamics 365 CRM integration with 17 actions across Accounts, Contacts, Leads, Opportunities, and Tasks
  • Platform OAuth2 auth (org_url auth approach needs follow-up — see note below)
  • OData v4 REST API at /api/data/v9.2/
  • Adds # -- Dynamics 365 -- section to .env.example (alphabetically between Coda and Dropbox)

Actions

Entity Actions
Accounts list, get, create, update
Contacts list, get, create, update
Leads list, get, create, qualify
Opportunities list, get, create
Tasks list, create

Auth note

Currently uses platform OAuth2, but org_url (required for the API base URL) cannot be collected from the user this way. Needs to be converted to custom auth (like iMIS) where the user supplies org_url, client_id, client_secret, and tenant_id and we handle the Azure AD token exchange in code.

Test plan

  • 32 unit tests passing locally
  • Integration tests require D365_ORG_URL and D365_ACCESS_TOKEN env vars
  • Convert to custom auth before merging

17 actions across Accounts, Contacts, Leads, Opportunities, and Tasks.
Uses platform OAuth2 with org_url from context.auth, OData v4 REST API.
32 unit tests passing, integration tests included.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 797cc34dde

ℹ️ 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".

Comment thread dynamics365/config.json
"provider": "Microsoft Dynamics 365",
"scopes": [
"offline_access",
"https://org.crm.dynamics.com/user_impersonation"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Use an environment-specific Dynamics scope

When a user connects to any real Dataverse environment, this static scope requests a token for the literal org.crm.dynamics.com audience, while _base_url later calls the user's own org_url. Dataverse OAuth scopes are environment-specific (<environment-url>/user_impersonation), so tokens minted with this scope won't be accepted by most org URLs and the integration can't authenticate unless the scope is built from the selected environment or supplied by provider metadata.

Useful? React with 👍 / 👎.

"OData-MaxVersion": "4.0",
"OData-Version": "4.0",
"Accept": "application/json",
"Prefer": 'odata.include-annotations="*"',

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Return created Dataverse record IDs

When Dataverse handles a normal POST, it returns 204 No Content plus the new record URI in OData-EntityId unless the request includes Prefer: return=representation; with the current headers every create_* action falls back to returning the submitted body, which has no generated accountid/contactid/leadid/opportunityid/activityid. That prevents follow-up workflow steps from updating or linking the record they just created, as the live account test already has to skip when accountid is missing.

Useful? React with 👍 / 👎.

@github-actions

Copy link
Copy Markdown

We require pull request titles to follow the Conventional Commits specification and it looks like your proposed title needs to be adjusted.
Details:

No release type found in pull request title "Add Microsoft Dynamics 365 CRM integration". Add a prefix to indicate what kind of release this pull request corresponds to. For reference, see https://www.conventionalcommits.org/

Available types:
 - feat: A new feature
 - fix: A bug fix
 - docs: Documentation only changes
 - style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
 - refactor: A code change that neither fixes a bug nor adds a feature
 - perf: A code change that improves performance
 - test: Adding missing tests or correcting existing tests
 - build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
 - ci: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
 - chore: Other changes that don't modify src or test files
 - revert: Reverts a previous commit

@github-actions

github-actions Bot commented Jun 18, 2026

Copy link
Copy Markdown

🔍 Integration Validation Results

Commit: 2c18ef71ed5c5c3564cbb8744d775f4af8c25d57 · Fix code check and README check failures
Updated: 2026-06-18T07:59:35Z

Changed directories: dynamics365

Check Result
Structure ⚠️ Passed with warnings
Code ✅ Passed
Tests ✅ Passed
README ✅ Passed
Version ✅ Passed
⚠️ Structure Check output
Validating 1 integration(s)...

============================================================
Integration: dynamics365
============================================================

Warnings (1):
  ⚠️ Potentially unused scopes (please verify): offline_access, https://org.crm.dynamics.com/user_impersonation

============================================================
SUMMARY
============================================================
Integrations validated: 1
Total errors: 0
Total warnings: 1

⚠️ Validation passed with warnings - please review
✅ Code Check output
----------------------------------------
Checking: dynamics365
----------------------------------------

📦 Installing dependencies...

🐍 Checking Python syntax...
   ✅ Syntax OK

📥 Checking imports...
   ✅ Imports OK

📄 Checking JSON files...
   ✅ JSON files OK

🔍 Linting with ruff...
   ✅ Lint OK

🎨 Checking formatting with ruff...
   ✅ Formatting OK

🔒 Scanning for security issues with bandit...
   ✅ Security OK

🛡️ Checking dependencies for vulnerabilities with pip-audit...
   ✅ Dependencies OK

🔗 Checking config-code sync...
   ✅ Config-code sync OK

🔄 Checking fetch patterns...
   ✅ Fetch patterns OK

========================================
✅ CODE CHECK PASSED
========================================
✅ Tests Check output

Integration     Tests  Coverage        Status
---------------------------------------------
dynamics365     32/32       82%      ✅ Passed
---------------------------------------------
Total           32/32            ✅ All passed

✅ Tests passed: dynamics365
✅ README Check output
========================================
✅ README CHECK PASSED
========================================
✅ Version Check output
✅ dynamics365: New integration with version 2.0.0

========================================
✅ VERSION CHECK PASSED
========================================

- Add README.md with full action docs and setup instructions
- Add 512x512 icon.png placeholder
- Add display_name to config.json
- Pin SDK version to ~=2.0.0 in requirements.txt
- Add dynamics365 entry to root README.md
- Run ruff format on all dynamics365 Python files
- Add table row for dynamics365 to main README.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant