We've spent this series in the form: events, field logic, lookups, subgrids, and calling the Web API. This last post is where it connects to the other thing you're probably building right now — a JavaScript-driven ribbon button that hands off to a Copilot Studio agent and brings the answer back onto the form.
The Pattern: Ribbon Button → JavaScript → Agent
There's no direct client-side SDK call from form JavaScript into a Copilot Studio agent. The reliable pattern is: a ribbon button runs a JavaScript function, that function calls an HTTP-triggered Power Automate flow (or an Azure Function) that invokes the agent's topic, and the response comes back as JSON that your script uses to update the form or show a notification.
Step 1: Add the Ribbon Button
Using the modern command bar designer (Power Apps maker portal → table → Forms → Command bar) or Ribbon Workbench, add a button with a JavaScript action pointing to a function in a form library, e.g. new_/ribbon/agentActions.js, function summarizeCaseWithAgent. Pass PrimaryControl as a parameter so your function gets the form context.
Step 2: Expose the Agent as a Callable Endpoint
In Copilot Studio, publish the topic you want to trigger, then wrap it with a Power Automate flow that starts with an HTTP request trigger, calls the agent (or the underlying logic the agent uses), and responds with the result. This gives you a stable HTTPS URL your form script can call — the same pattern used for any external integration, just fronting an agent instead of a plain API.
Step 3: Call It from the Button's JavaScript
async function summarizeCaseWithAgent(primaryControl) {
var formContext = primaryControl;
formContext.ui.setFormNotification("Asking the agent for a summary...", "INFO", "agent_call");
var caseId = formContext.data.entity.getId().replace("{", "").replace("}", "");
var description = formContext.getAttribute("description").getValue();
try {
var response = await fetch("https://your-flow-endpoint.example.com/trigger", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
caseId: caseId,
description: description
})
});
if (!response.ok) {
throw new Error("Flow returned " + response.status);
}
var result = await response.json();
formContext.ui.clearFormNotification("agent_call");
formContext.ui.setFormNotification(result.summary, "INFO", "agent_summary");
} catch (error) {
formContext.ui.clearFormNotification("agent_call");
formContext.ui.setFormNotification("Couldn't reach the agent right now.", "ERROR", "agent_error");
console.error(error);
}
}
A Practical Example: "Summarize This Case" Button
The function above is a working version of this: it reads the case description, calls the flow, and shows the agent's summary as a form notification instead of navigating anywhere. You can just as easily write the result into a field, or open it in a side panel — whatever fits the workflow.
A Word on Security
The agent's flow runs under its own connection identity, not the signed-in user's — so it can potentially see more (or less) than the user calling it. That's a topic on its own, and worth checking against your Dataverse security roles before you wire up anything that touches sensitive data.
Common Pitfalls
- No loading state. Agent calls can take a few seconds; always show a notification (or disable the button) while waiting, so users don't click twice.
- No timeout handling. Set a reasonable timeout on the fetch call and handle it gracefully — an agent call that hangs shouldn't hang the form.
- Trusting the response shape blindly. Validate the JSON structure before reading fields off it; an agent or flow change can silently alter the response.
- Hardcoding the endpoint URL. Store it in an environment variable or a configuration record instead, so it survives a move between environments.
Wrapping Up the Series
Five posts in, the throughline hasn't changed: form scripting is still the layer that makes everything else — Business Rules, Power Automate, Copilot agents — actually usable inside the form users work in every day. Knowing both the fundamentals and where they connect to AI is what keeps a CRM developer's skill set current without starting over. Thanks for following along.
No comments:
Post a Comment