openclaw-dynamics-365

Create and update CRM records in Microsoft Dynamics 365 — Opportunities, Leads, Contacts, Accounts, and Tasks via Dataverse Web API with Azure AD OAuth 2.0.

Safety Notice

This listing is from the official public ClawHub registry. Review SKILL.md and referenced scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "openclaw-dynamics-365" with this command: npx skills add vieiradiego/openclaw-dynamics-365

Dynamics 365 CRM Skill

When to activate

Activate this skill when the user mentions Microsoft Dynamics 365, D365, Dynamics CRM, or any of the following actions directed at a Dynamics 365 CRM:

  • Creating or updating an opportunity / deal / oportunidade
  • Creating or updating a lead
  • Creating or updating a contact / contacto
  • Creating or updating an account / empresa / conta
  • Creating a task / activity linked to a CRM record

Credentials required

VariableDescription
DYNAMICS365_CLIENT_IDAzure AD Application (client) ID
DYNAMICS365_CLIENT_SECRETAzure AD client secret
DYNAMICS365_TENANT_IDAzure AD Tenant ID — use common for multi-tenant
DYNAMICS365_INSTANCE_URLDynamics 365 instance URL, e.g. https://contoso.crm.dynamics.com

Step-by-step execution

1 — Identify intent and entity type

Determine from the user's message which entity to create or update:

User saysEntityAction
"create deal", "new opportunity", "deal com X"Opportunityupsert
"new lead", "criar lead", "prospect X"Leadupsert
"add contact", "criar contacto", "cliente X no CRM"Contactupsert
"new account", "empresa Y no CRM", "criar conta"Accountupsert
"create task", "follow-up", "lembrete para X"Taskcreate

2 — Extract fields from user input

Opportunity fields:

  • name — deal / opportunity name (required)
  • estimatedvalue — numeric value in local currency
  • stepname — pipeline stage: "Qualify" / "Develop" / "Propose" / "Close"
  • actualclosedate — expected close date (ISO: YYYY-MM-DD)

Lead fields:

  • fullname — full name (required)
  • emailaddress1 — email address
  • companyname — company name
  • telephone1 — phone number
  • jobtitle — job title

Contact fields:

  • fullname — full name (required)
  • emailaddress1 — email address
  • telephone1 — phone number
  • jobtitle — job title

Account fields:

  • name — company / account name (required)
  • emailaddress1 — email address
  • telephone1 — phone number
  • websiteurl — website

Task fields:

  • subject — task title (required)
  • description — details / notes
  • scheduledend — due date-time (ISO 8601)
  • prioritycode — 0 = Low, 1 = Normal, 2 = High

3 — Call the appropriate method

Use the Dynamics365Client from the openclaw-dynamics-365 npm package:

import { Dynamics365Client } from "openclaw-dynamics-365";

const client = new Dynamics365Client(
  process.env.DYNAMICS365_INSTANCE_URL,
  accessToken,  // obtained via OAuth flow
);

// Opportunity
const result = await client.upsertOpportunity({ name: "Deal Contoso", estimatedvalue: 50000 });

// Lead
const result = await client.upsertLead({ fullname: "João Silva", companyname: "TechNova" });

// Contact
const result = await client.upsertContact({ fullname: "Maria Santos", emailaddress1: "maria@techno.com" });

// Account
const result = await client.upsertAccount({ name: "TechNova Ltda" });

// Task
const taskId = await client.createTask({ subject: "Follow-up call", prioritycode: 2 });

4 — Format response to the user

On success:

✅ [Entity] "[name]" [created/updated] in Dynamics 365.
🔗 [record URL]

On error:

❌ Could not [create/update] [entity] in Dynamics 365: [error message]

OAuth setup

For initial authorization, use getAuthorizationUrl() to redirect the user to Microsoft's consent screen, then exchangeCodeForTokens() in the callback:

import { getAuthorizationUrl, exchangeCodeForTokens } from "openclaw-dynamics-365";

// 1. Redirect user
const url = getAuthorizationUrl(config, redirectUri, state);

// 2. In callback
const tokens = await exchangeCodeForTokens(config, code, redirectUri);

// 3. Refresh when expired (~1h)
if (isTokenExpired(tokens)) {
  tokens = await refreshAccessToken(config, tokens.refreshToken);
}

Notes

  • The Dataverse Web API uses OData v4 — all queries use $filter, $select, $top
  • Upsert operations search by name/email first to avoid duplicates
  • Lookup fields (e.g. linking a Contact to an Account) use OData binding syntax: "parentcustomerid_account@odata.bind": "/accounts({accountId})"
  • Rate limit: 6,000 requests / 5 minutes per user — well within typical usage
  • Access tokens expire after ~1 hour — implement refresh logic using refreshAccessToken()

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

Prospect List Tiering

Tier and prioritize a prospect list using the six-level Prospecting Pyramid framework — sorting every account from unknown contacts at the base to active buy...

Registry SourceRecently Updated
730Profile unavailable
General

Outlook Mcp

Production-grade MCP server for personal Outlook (Outlook.com / Hotmail / Live). 54 typed Graph tools across mail, calendar, contacts, to-do, drafts, attachm...

Registry SourceRecently Updated
2551Profile unavailable
General

Microsoft MarkItDown

Convert various document formats (PDF, Word, PowerPoint, Excel, images, audio, HTML, etc.) to Markdown using Microsoft's markitdown tool. Supports OCR, audio...

Registry SourceRecently Updated
1310Profile unavailable
General

Call

Call management system with preparation, real-time capture, and follow-up tracking. Use when user mentions phone calls, meetings, conversations, commitments...

Registry SourceRecently Updated
4010Profile unavailable