<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sahl Ebrahim</title>
    <description>The latest articles on DEV Community by Sahl Ebrahim (@sahl_ebrahim).</description>
    <link>https://dev.to/sahl_ebrahim</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4152582%2Fefe9bcb5-08f5-4bcc-a341-809fbd82855a.jpg</url>
      <title>DEV Community: Sahl Ebrahim</title>
      <link>https://dev.to/sahl_ebrahim</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sahl_ebrahim"/>
    <language>en</language>
    <item>
      <title>Chat with Salesforce in Microsoft Teams using a Copilot Studio agent</title>
      <dc:creator>Sahl Ebrahim</dc:creator>
      <pubDate>Wed, 30 Sep 2026 15:27:05 +0000</pubDate>
      <link>https://dev.to/sahl_ebrahim/chat-with-salesforce-in-microsoft-teams-using-a-copilot-studio-agent-10ai</link>
      <guid>https://dev.to/sahl_ebrahim/chat-with-salesforce-in-microsoft-teams-using-a-copilot-studio-agent-10ai</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://www.fluxvec.ai/blog/chat-with-salesforce-in-microsoft-teams-using-copilot-studio" rel="noopener noreferrer"&gt;fluxvec.ai&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Compare quotes, ask about opportunities, and much more with this simple setup.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What the agent does
&lt;/h2&gt;

&lt;p&gt;This is a read only Copilot Studio agent that queries Salesforce. You ask a question in plain English, it writes the SOQL, runs it and returns a table.&lt;/p&gt;

&lt;p&gt;Asked "What is the margin on the approved Litware quote?", it found the approved quote, Q-00071, returned its 7 lines and worked out the margin: 14,000 net, 3,000 gross profit, 21.43%.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvm6o49a9qrmmimmtiis9.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvm6o49a9qrmmimmtiis9.webp" alt="Agent answering the margin question for quote Q-00071" width="800" height="733"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;One question, a table back&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Every number matches Salesforce.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdd9rpnxe24qyfanexqr9.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdd9rpnxe24qyfanexqr9.webp" alt="Quote Q-00071 lines in Salesforce with unit cost and gross profit" width="800" height="182"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The same 7 lines in Salesforce&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The setup takes about 20 minutes. Most of it is standard, but one step makes the difference.&lt;/p&gt;




&lt;h2&gt;
  
  
  Put the field list in the agent instructions
&lt;/h2&gt;

&lt;p&gt;CPQ fields use the &lt;code&gt;SBQQ__&lt;/code&gt; prefix, and their API names don't match their labels. For example, the field labelled "Opportunity" on a quote is &lt;code&gt;SBQQ__Opportunity2__c&lt;/code&gt;. The agent can't guess names like that, so list them in the agent's Instructions box.&lt;/p&gt;

&lt;p&gt;Don't put them in the tool's "Description for AI" box. It looks like the natural place, but in testing the list there didn't reliably reach the agent. It still guessed field names and needed 4 to 6 tool calls per question. With the list in Instructions, the same question took 1.&lt;/p&gt;

&lt;p&gt;To check your own agent, ask it &lt;code&gt;what fields are available on the Opportunity object according to your instructions?&lt;/code&gt; If it runs a query instead of listing them, the list isn't reaching it.&lt;/p&gt;




&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Create the agent.&lt;/strong&gt; Remove "Search all websites" from Knowledge, so the agent answers from your Salesforce data, not the web.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Add one tool.&lt;/strong&gt; Click the + on Tools and search for "Execute a SOQL query" from the Salesforce connector. Having only this one read tool keeps the agent read only.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff9yisbw4vc55gm5c3hiy.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff9yisbw4vc55gm5c3hiy.webp" alt="Build page with one tool, no knowledge sources and the instructions" width="800" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;One tool, no knowledge sources, the instructions doing the work&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Create the connection.&lt;/strong&gt; Choose Login with Salesforce Account. Set the Login URI to Production for a live org or a Developer Edition org, or Sandbox for a sandbox. API version v58.0 is fine.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5p9kb2wt8u7a0c5d6kwu.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5p9kb2wt8u7a0c5d6kwu.webp" alt="Salesforce connection dialog with Login URI set to Production" width="672" height="644"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Production, even for a Developer Edition org&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Set the query input.&lt;/strong&gt; Set SOQL Query to Fill with AI. For authentication, End user account makes each user sign in with their own Salesforce login and see only what their permissions allow, which is the right choice in a company. Shared account gives everyone the access of your login, which is fine for a quick test.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjgon3iaj3mysv82rw18o.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjgon3iaj3mysv82rw18o.webp" alt="Tool details with Fill with AI and Shared account" width="800" height="409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Fill with AI, and a shared connection&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Paste the instructions.&lt;/strong&gt; Add the scope, how to answer, the field list and a few example queries. Mine are in &lt;a href="https://github.com/sahlebrahim/copilot-studio-salesforce-cpq/blob/main/copilot-studio/instructions.md" rel="noopener noreferrer"&gt;copilot-studio/instructions.md&lt;/a&gt;. Replace the field names with your own org's.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Save and test.&lt;/strong&gt; Save after every change and test in a new chat each time, since earlier questions in a chat can change later answers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Publish to Teams.&lt;/strong&gt; Under Channels, add Teams + Microsoft 365, click Publish, then add the agent in Teams. Choose where it's available carefully, since that can't be changed after publishing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fipl3p6zcqyug2kxn0fxa.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fipl3p6zcqyug2kxn0fxa.webp" alt="The agent answering a margin question in Microsoft Teams" width="800" height="586"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The same quote, a different question, answered in Teams&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Not using CPQ?
&lt;/h2&gt;

&lt;p&gt;The same tip applies. Standard fields like StageName are usually guessable, but custom fields ending in &lt;code&gt;__c&lt;/code&gt; aren't, and every org has them. The repo has a script that prints the fields, lookups, child relationships and picklist values of any object.&lt;/p&gt;

&lt;p&gt;With Python and the Salesforce CLI installed, log in once and give the org a nickname, then run the script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sf org login web &lt;span class="nt"&gt;--alias&lt;/span&gt; myorg
python scripts/describe_fields.py &lt;span class="nt"&gt;--org&lt;/span&gt; myorg &lt;span class="nt"&gt;--objects&lt;/span&gt; Opportunity Account Contact
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a sandbox, add &lt;code&gt;--instance-url https://test.salesforce.com&lt;/code&gt; to the login command. &lt;code&gt;sf org list&lt;/code&gt; shows your orgs and their nicknames.&lt;/p&gt;




&lt;h2&gt;
  
  
  What you'll need
&lt;/h2&gt;

&lt;p&gt;On the Microsoft side:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Environment Maker role in the Power Platform environment.&lt;/li&gt;
&lt;li&gt;Membership of the security group set in the Copilot Studio authors tenant setting, if one is set.&lt;/li&gt;
&lt;li&gt;Copilot Credits for that environment, either allocated or through a pay as you go billing plan.&lt;/li&gt;
&lt;li&gt;The Salesforce connector allowed by your data policies.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On the Salesforce side:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A user with API Enabled and read access to the objects the agent queries, plus a CPQ licence for CPQ objects.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Get the code
&lt;/h2&gt;

&lt;p&gt;Everything is in the repo: &lt;a href="https://github.com/sahlebrahim/copilot-studio-salesforce-cpq" rel="noopener noreferrer"&gt;github.com/sahlebrahim/copilot-studio-salesforce-cpq&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/sahlebrahim/copilot-studio-salesforce-cpq/blob/main/copilot-studio/instructions.md" rel="noopener noreferrer"&gt;&lt;code&gt;copilot-studio/instructions.md&lt;/code&gt;&lt;/a&gt;: the agent instructions, with the field list and example queries&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/sahlebrahim/copilot-studio-salesforce-cpq/blob/main/evals/questions.yaml" rel="noopener noreferrer"&gt;&lt;code&gt;evals/questions.yaml&lt;/code&gt;&lt;/a&gt;: sample questions with expected answers&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/sahlebrahim/copilot-studio-salesforce-cpq/blob/main/scripts/describe_fields.py" rel="noopener noreferrer"&gt;&lt;code&gt;scripts/describe_fields.py&lt;/code&gt;&lt;/a&gt;: prints the real field names, lookups and picklist values for any object&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Is it enough?
&lt;/h2&gt;

&lt;p&gt;In this setup the instructions do the heavy lifting, but instructions are guidance, not guarantees, and the agent won't always follow them. For strict rules and edge cases, the next step is a code first approach that enforces them in code.&lt;/p&gt;




&lt;p&gt;Fluxvec builds agents like this for teams that work in Salesforce, HubSpot and Dynamics 365. &lt;a href="https://www.fluxvec.ai/services/workflow-agents" rel="noopener noreferrer"&gt;See workflow agents&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Salesforce is a trademark of Salesforce, Inc. Microsoft, Copilot Studio, Microsoft Teams and Power Platform are trademarks of the Microsoft group of companies. This project is not affiliated with or endorsed by either.&lt;/p&gt;

</description>
      <category>copilotstudio</category>
      <category>salesforce</category>
      <category>microsoft</category>
      <category>lowcode</category>
    </item>
  </channel>
</rss>
