Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :
Dynamics 365 Community / Blogs / Learn with Subs / Step by step: Setting up Su...

Step by step: Setting up Supplier Communication agent in D365F&O - quick tip

Subhad365 Profile Picture Subhad365 19 User Group Leader
Supplier Communications Agent in Dynamics 365 Supply Chain Management is cool new a feature that leverages AI to automate and streamline communication with suppliers. It helps with tasks like following up on purchase orders, processing vendor responses, and suggesting changes to purchase orders, ultimately improving procurement efficiency and freeing up procurement teams for higher-value activities. 
In this article, I would be discussing how to setup SCAs in D365F&O, prerequisites and the challenges you might face, and how to mitigate them.

Prerequisites

Check out the prerequisites in order to start with Supplier Comm Agents in D365

Immersive home

We must be having Immersive home enabled in D365F&O beforehand to start. Ensure the following feature to be already enabled in your instance:

Immersive home still not appearing? Change the Initial Page from User options >> Preferences:

Features

Ensure to turn on the below features from feature management:

Power platform configurations

Ensure the following to be enabled/installed by visiting PPAC >> Environments >> your environment >> resources >> D365 Apps:


Check out if any update available to proceed (recommended).

Agent identity

Use the User Management to create a agent user identity. What does this mean? In layman’s terms, this means to proceed with SCA installation, we have to have a user, which must not be a physical person (john.doe@abc.com) – this should be more likely an impersonated account, who is not susceptible to change or leave the organization (admin@abc.com).

Activating user email and group

Open PPAC >> Your environment >> Settings >> Email >>

Select Email settings >> Mailbox >> open the mailbox/user account you want to use >>Test and enable mailbox.
 
Select Users + permissions >> Teams to continue:

Create new team >> and fill out the necessary data and hit Ok:

Select additional users in the prompt, whom you want you to be part of the Team:

Click Next to Continue.
Select Finance and Operations Basic User and Basic user from the Roles to Save:
 

Manage connections

Hover over to https://make.powerapps.com >> correct environment and then choose connections. In case they are not visible, click on More >> Connections (pin them, so as not to lose sight of them):

Click on “Create a new connection” and search for ‘Dataverse’ >> and select the one with iconic green color of Dataverse:

Select Authentication type as oAuth:

And click create, by choosing the Admin account (Agent identity account) with which you would like to operate and finish the step.
Repeat the same exercise for Microsoft Copilot Studio and finish by choosing the Agent identity account explained above:

And now the connections page should like:

Additional settings

For testing purpose, you can select any vendor >> contact information >> create a new address with any personal email address.

Run Powershell script to make Power Automates be responsive by updating the Connection references

Ensure to install latest PowerShell software to on or more than Version 7. To check which version you are on, launch PowerShell >> and run the command (it searches for latest available PowerShell version):
winget search Microsoft.PowerShell
With the below command, it can help you update you to the latest version:
winget install --id Microsoft.PowerShell --source winget
And then you can get the version of the PowerShell as:
$PSVersionTable
Keep your Entra ID details handy. Environment Id and Dataverse URL : you can get from PPAC >> your environment. Save the following command as .ps1:
Param(
   [Parameter(Mandatory=$true, HelpMessage="Dataverse environment id")]
   [string]$environmentId = "",

[Parameter(Mandatory=$true, HelpMessage="Dataverse environment URL")]
   [string]$dataverseUrl = "",

[Parameter(Mandatory=$true, HelpMessage="Microsoft Dataverse connection name")]
   [string]$DVConnectionName = "",

[Parameter(Mandatory=$true, HelpMessage="Microsoft Copilot Studio connection name")]
   [string]$MCSConnectionName = ""
)

# Check PS version
if ($PSVersionTable.PSVersion.Major -lt 7) {
    Write-Error 'This script requires at least PowerShell version 7' -ErrorAction Stop
}

# Install the required modules if not already installed
if (-not (Get-Module -ListAvailable -Name Microsoft.PowerApps.PowerShell)) {
    Write-Warning -Message 'Installing module Microsoft.PowerApps.PowerShell'
    Install-Module -Name Microsoft.PowerApps.PowerShell -AllowClobber -Scope CurrentUser
}

# Install the required modules if not already installed
if (-not (Get-Module -ListAvailable -Name Az.Accounts | Where-Object Version -ge 2.17)) {
    Write-Warning -Message 'Installing required version of module Az.Accounts'
    Install-Module -Name Az.Accounts -AllowClobber -Scope CurrentUser -Force -MinimumVersion 2.17
}

# Import required modules
Import-Module Az.Accounts -MinimumVersion 2.17
Import-Module Microsoft.PowerApps.PowerShell

function Get-AccessToken {
    # Retrieve the access token for the Dataverse environment
    $accessToken = Get-AzAccessToken -ResourceUrl "$dataverseUrl" -AsSecureString
    $token = $accessToken.Token
    $userId = $accessToken.UserId
    Write-Host "Access token for $userId retrieved successfully." -ForegroundColor Green

return $token
}

function Get-ConnectionId {
    param (
        [string]$userProvidedName,
        [string]$providerName
    )

$matchedConnectionId = $null

$connections = Get-PowerAppConnection -EnvironmentName $environmentId -ConnectorNameFilter $providerName
    foreach ($con in $connections) {
        if (($con.ConnectionName -eq $userProvidedName) -or ($con.DisplayName -eq $userProvidedName))
        {
            $matchedConnectionId = $con.ConnectionName
            break
        }
    }

if ($null -eq $matchedConnectionId)
    {
        Write-Error -Message "Unable to find connection $userProvidedName ($providerName)" -ErrorAction Stop
    }

Write-Host "Found connection id $matchedConnectionId for connection $userProvidedName"

return $matchedConnectionId
}

function Get-ConnectionReferenceId {
    param(
        [string]$connectionReferenceLogicalName,
        [securestring]$accessToken
    )

$uri = "$dataverseUrl/api/data/v9.2/connectionreferences?`$filter=connectionreferencelogicalname eq '$connectionReferenceLogicalName'"
    $response = Invoke-RestMethod -Method Get -Uri $uri -Authentication Bearer -Token $accessToken -ContentType 'application/json'
       
   
    if ($null -eq $response) {
        Write-Error -Message "Connection reference not found for logical name $connectionReferenceLogicalName" -ErrorAction Stop
    }

$connectionReferenceDisplayName = $response.value[0].connectionreferencedisplayname
    $connectionReferenceId = $response.value[0].connectionreferenceid

Write-Host "Found connection reference id $connectionReferenceId for $connectionReferenceDisplayName ($connectionReferenceLogicalName)"

return $connectionReferenceId
}

function Set-ConnectionReferenceConnection {
    param (
        [string]$connectionReferenceLogicalName,
        [string]$userProvidedConnectionName,
        [string]$providerName,
        [securestring]$accessToken
    )

Write-Host "Updating connection reference ${connectionReferenceLogicalName}..."

$connectionReferenceId = Get-ConnectionReferenceId -connectionReferenceLogicalName $connectionReferenceLogicalName -accessToken $accessToken
    $connectionId = Get-ConnectionId -userProvidedName $userProvidedConnectionName -providerName $providerName

$body = @{
        "connectionid" = "$connectionId"
    } | ConvertTo-Json -Depth 1

$uri = "$dataverseUrl/api/data/v9.2/connectionreferences($connectionReferenceId)"
    Write-Host "Updating connection reference URI: $uri with connection id $connectionId"

Invoke-RestMethod -Method Patch -Uri $uri -Authentication Bearer -Token $accessToken -ContentType 'application/json' -Body $body
  
    Write-Host "Connection reference updated successfully." -ForegroundColor Green
    Write-Host
}

function ValidateUserEnvironment {
    param (
        [string]$environmentId
    )

$env = Get-PowerAppEnvironment -EnvironmentName $environmentId
    if ($null -eq $env) {
        Write-Error -Message "Environment $environmentId was not found" -ErrorAction Stop
    }

$displayName = $env.DisplayName
    Write-Host "Connected to environment: $displayName ($environmentId)"
}

function Enable-TriggerFlow {
    param (
        [string]$flowId,
        [securestring]$accessToken
    )

$flowUri = "$dataverseUrl/api/data/v9.2/workflows($flowId)"
    $flow = $null

Write-Host "Enabling flow $flowId with uri $flowUri"

try {
        $flow = Invoke-RestMethod -Method Get -Uri $flowUri -Authentication Bearer -Token $accessToken -ContentType 'application/json'
    }
    catch {
        Write-Error -Message $_.Exception -ErrorAction Stop
    }

$displayName = $flow.name
    Write-Host "Activating flow $displayName for id $flowId"

$body = @{
        "statecode" = 1  # Activated
        "statuscode" = 2 # Activated
    } | ConvertTo-Json -Depth 1 -Compress
   
    try {
        Invoke-RestMethod -Method Patch -Uri $flowUri -Authentication Bearer -Token $accessToken -ContentType 'application/json' -Body $body
    }
    catch {
        Write-Error -Message $_.Exception -ErrorAction Stop
    }

Write-Host "Activated flow $displayName" -ForegroundColor Green
    Write-Host
}

# Actual script body

Write-Host
Write-Host "Authenticating interactively..."
Write-Host

Connect-AzAccount -UseDeviceAuthentication
$accessToken = Get-AccessToken
ValidateUserEnvironment -environmentId $environmentId

Write-Host
Write-Host 'Setting up connection references...'
Write-Host

Set-ConnectionReferenceConnection -userProvidedConnectionName $DVConnectionName -providerName "/providers/Microsoft.PowerApps/apis/shared_commondataserviceforapps" -connectionReferenceLogicalName "new_sharedcommondataserviceforapps_6ae5d" -accessToken $accessToken

Set-ConnectionReferenceConnection -userProvidedConnectionName $MCSConnectionName -providerName "/providers/Microsoft.PowerApps/apis/shared_microsoftcopilotstudio" -connectionReferenceLogicalName "msdyn_sharedmicrosoftcopilotstudio_0be09" -accessToken $accessToken

Write-Host
Write-Host 'Activating flows...'
Write-Host

Enable-TriggerFlow -flowId 'c1061034-ff20-f011-9989-002248095ade' -accessToken $accessToken # (Self Heal) Speed up updates in purchase orders with Supplier Communications Agent
Enable-TriggerFlow -flowId '1db577aa-83fe-ef11-bae1-000d3a34a571' -accessToken $accessToken # Speed up updates in purchase orders with Supplier Communications Agent
Enable-TriggerFlow -flowId 'acd7bb36-07a1-ef11-a72d-6045bd0390ae' -accessToken $accessToken # Send follow-up emails to vendors with Supplier Communications Agent

Write-Host
Write-Host 'Supplier communications agent is ready for use' -ForegroundColor Green

And then either double click the file to run/you can launch it from Powershell prompt by:
powershell.exe -File <file path>\<file name>.ps1

Next is what

Reach out to your Agents’ library and choose the Supplier’s Communication Agent, to customize the Agent:

Click on select to reach out to the following screen:

Click on Activate to get the Agent started.

Comments

*This post is locked for comments