Gerenciamento do ciclo de vida do aplicativo para análise em personalizações do modelo de dados
Aplica-se a: Dynamics 365 Customer Service
Este artigo apresenta informações detalhadas sobre o gerenciamento do ciclo de vida do aplicativo (ALM) para relatórios personalizados baseados em personalizações do modelo de dados do Omnicanal para Dynamics 365 Customer Service.
Visão geral da ALM
O ALM é uma etapa importante quando você deseja migrar as alterações necessárias para relatórios personalizados entre ambientes, mas também deseja envolvimento manual mínimo. Devidamente configurado, o ALM pode a reduzir erros manuais e economizar tempo.
Para personalização de relatórios, leve em consideração o ALM na implantação de relatórios do Power BI. Você pode conseguir essa implantação de maneiras diferentes:
- Você pode mover relatórios do Power BI entre ambientes usando pipelines de implantação do Power BI. Você também pode implantar manualmente relatórios do Power BI apontando para fontes de dados corretas.
- Como o Centro de administração do Customer Service é um aplicativo baseado em modelo, você pode inserir relatórios personalizados nele.
O ALM for Dynamics 365 envolve a configuração de relatórios no Centro de administração do Customer Service.
O diagrama a seguir ilustra as etapas. As caixas em azul contendo texto em branco representam tarefas feitas por você no Dynamics 365. As caixas em amarelo contendo texto em preto representam tarefas realizadas por você no Power BI.
Migração da configuração do relatório
Os relatórios adicionados no Dynamics 365 são armazenados em entidades do Dataverse.
As entidades/tabelas a seguir são usadas para armazenar as informações do relatório personalizado:
msdyn_dataanalyticsworkspaces
tem as informações do espaço de trabalho definidas durante a configuração inicial para análise do histórico/em tempo real.msdyn_dataanalyticsreport
armazena os relatórios personalizados adicionados no mapa do site.msdyn_reportid
: a ID do relatório no espaço de trabalho do Power BI.msdyn_dataanalyticsreportid
: a chave primária no Dynamics 365.msdyn_displayname
: o nome de exibição exibido no relatório personalizado no aplicativo baseado em modelo do Customer Service workspace.msdyn_name
: o nome do relatório no espaço de trabalho do Power BI.msdyn_workspaceid
: a ID do espaço de trabalho do espaço de trabalho do Power BI configurada na etapa anterior.msdyn_datainsightsandanalyticsfeatureid
: f2266eb4-226f-4cf1-b422-89c5f48b40cb é a ID do recurso para personalização do modelo de dados históricos, e 09c168be-efe2-4f08-a986-3aab7095c863 é a ID do recurso se destina à personalização do modelo de dados em tempo real.
Para migrar os relatórios adicionados ao mapa do site, você deve mover os dados das entidades/tabelas. Você pode usar a Ferramenta de migração da configuração com essa finalidade. Este artigo oferece um arquivo de esquema de amostra. Aprenda mais em Migrar dados de configuração entre ambientes e organizações usando a ferramenta de migração da configuração.
Depois da migração, você deverá atualizar as referências do relatório. Em outras palavras, você deve atualizar o espaço de trabalho do Power BI onde o relatório está hospedado e a ID do relatório do espaço de trabalho. Este artigo oferece um script do PowerShell de amostra para referência, mas você pode obter o mesmo resultado usando qualquer linguagem.
Scripts de amostra
Esta seção inclui os seguintes scripts de amostra:
- Arquivo do esquema de amostra
- Script do PowerShell de amostra
- Pipeline YAML do Azure DevOps de amostra
Arquivo do esquema de amostra
O arquivo de esquema XML a seguir consiste em relatórios personalizados criados e implementados no espaço de trabalho do Power BI. Você pode usá-lo para exportar dados da ferramenta de migração da configuração. Aprenda mais em Migrar dados de configuração entre ambientes e organizações usando a ferramenta de migração da configuração e Criar um esquema para exportar dados de configuração.
<entities>
<entity name="msdyn_dataanalyticsreport" displayname="Data Analytics Report" etc="10427" primaryidfield="msdyn_dataanalyticsreportid" primarynamefield="msdyn_name" disableplugins="false">
<fields>
<field displayname="Report Id" name="msdyn_reportid" type="string" customfield="true" />
<field displayname="Data Analytics Report" name="msdyn_dataanalyticsreportid" type="guid" primaryKey="true" />
<field displayname="Display name" name="msdyn_displayname" type="string" customfield="true" />
<field displayname="Name" name="msdyn_name" type="string" customfield="true" />
<field displayname="Report Display Order" name="msdyn_displayorder" type="number" customfield="true" />
<field displayname="Report Provision Status" name="msdyn_provisionstatus" type="bool" customfield="true" />
<field displayname="Report Page" name="msdyn_reportpage" type="string" customfield="true" />
<field displayname="Report Group" name="msdyn_reportgroup" type="string" customfield="true" />
<field displayname="Report Entity Name" name="msdyn_reportentityname" type="string" customfield="true" />
<field displayname="Report Template Id" name="msdyn_reporttemplateid" type="string" customfield="true" />
<field displayname="Dataset Id" name="msdyn_datasetid" type="string" customfield="true" />
<field displayname="Is Enabled" name="msdyn_isenabled" type="bool" customfield="true" />
<field displayname="Workspace Id" name="msdyn_workspaceid" type="string" customfield="true" />
<field displayname="datainsightsandanalyticsfeatureId" name="msdyn_datainsightsandanalyticsfeatureid" type="entityreference" lookupType="msdyn_datainsightsandanalyticsfeature" customfield="true" />
<field displayname="Analytics Checksum" name="msdyn_analyticschecksum" type="number" customfield="true" />
</fields>
<filter><filter type = 'and'>
<condition attribute = 'msdyn_datainsightsandanalyticsfeatureid' operator = 'eq' value = '<<Feature ID of the model customization>> '/>
<condition attribute = 'msdyn_displayname' operator = 'eq' value = '<<custom report name>>'/>
</filter></filter>
</entity>
</entities>
Use f2266eb4-226f-4cf1-b422-89c5f48b40cb como a ID do recurso para dados históricos, e xxxx como a ID do recurso para dados em tempo real.
Script do PowerShell de amostra
O script a seguir usa o mecanismo de autenticação de segredo da ID do cliente. No entanto, você pode usar qualquer tipo de autenticação modificando o script.
Este script se conecta ao Power BI por meio das APIs Rest do Power BI. Ele se conecta ao Dataverse por meio das APIs web do Dataverse.
#Get Power BI access token
function Get-PBIAccessToken {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
$TenantId,
[Parameter(Mandatory=$true)]
$PBIAppId,
[Parameter(Mandatory=$true)]
$PBIClientSecret
)
$authority = "https://login.microsoftonline.com/$TenantId/oauth2/token"
$resource = "https://analysis.windows.net/powerbi/api"
$body = @{
"grant_type" = "client_credentials"
"client_id" = $PBIAppId
"client_secret" = $PBIClientSecret
"resource" = $resource
}
Write-Host "Retreiving PBI Access Token"
$tokenResponse = Invoke-RestMethod -Method Post -Uri $authority -Body $body
return $tokenResponse.access_token
}
#Get Dataverse access token
function Get-DVAccessToken{
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
$tenantId,
[Parameter(Mandatory=$true)]
$clientId,
[Parameter(Mandatory=$true)]
$clientSecret,
[Parameter(Mandatory=$true)]
$dataVerseURL
)
$oAuthTokenEndpoint = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token"
# OAuth Body Access Token Request
$authBody = @{
client_id = $clientId;
client_secret = $ClientSecret;
scope = "$($dataVerseURL)/.default"
grant_type = 'client_credentials'
}
# Parameters for OAuth Access Token Request
$authParams = @{
URI = $oAuthTokenEndpoint
Method = 'POST'
ContentType = 'application/x-www-form-urlencoded'
Body = $authBody
}
Write-Host "Retreiving CRM Access Token"
# Get Access Token
$authResponseObject = Invoke-RestMethod @authParams -ErrorAction Stop
return $authResponseObject
}
function Get-DVWorkspaceId {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
$dvAuthResponseObject,
[Parameter(Mandatory=$true)]
$dataVerseURL
)
$getDataRequestUri = 'msdyn_dataanalyticsworkspaces?$top=5&$select=msdyn_workspaceid,msdyn_name&$filter=(msdyn_name ne ''Customer Service Managed Workspace'' and _msdyn_datainsightsandanalyticsfeatureid_value eq ''f2266eb4-226f-4cf1-b422-89c5f48b40cb'')'
# Set up web API call parameters, including a header for the access token
$getApiCallParams = @{
URI = "$($dataVerseURL)/api/data/v9.1/$($getDataRequestUri)"
Headers = @{
"Authorization" = "$($dvAuthResponseObject.token_type) $($dvAuthResponseObject.access_token)"
"Accept" = "application/json"
"OData-MaxVersion" = "4.0"
"OData-Version" = "4.0"
}
Method = 'GET'
}
Write-Host "Retreiving Dataverse DCCP Workspace Id"
# Call API to Get Response
$getApiResponseObject = Invoke-RestMethod @getApiCallParams -ErrorAction Stop
return $getApiResponseObject.value[0].msdyn_workspaceid
}
function Get-DVDCCPReports {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
$dvAuthResponseObject,
[Parameter(Mandatory=$true)]
$workspaceId,
[Parameter(Mandatory=$true)]
$dataVerseURL
)
Write-Host "Retreiving DV DCCP Reports"
$getDataRequestUri = 'msdyn_dataanalyticsreports?$select=msdyn_dataanalyticsreportid,msdyn_name,msdyn_workspaceid&$filter=(msdyn_workspaceid ne '''+$workspaceId+''' and _msdyn_datainsightsandanalyticsfeatureid_value eq ''f2266eb4-226f-4cf1-b422-89c5f48b40cb'')'
# Set up web API call parameters, including a header for the access token
$getApiCallParams = @{
URI = "$($dataVerseURL)/api/data/v9.1/$($getDataRequestUri)"
Headers = @{
"Authorization" = "$($dvAuthResponseObject.token_type) $($dvAuthResponseObject.access_token)"
"Accept" = "application/json"
"OData-MaxVersion" = "4.0"
"OData-Version" = "4.0"
}
Method = 'GET'
}
$getApiResponseObject = Invoke-RestMethod @getApiCallParams -ErrorAction Stop
# Output
$dvReports = $getApiResponseObject.value
return $dvReports
}
function Get-PBIReports {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
$accessToken,
[Parameter(Mandatory=$true)]
$workspaceId
)
Write-Host "Retreiving PBI Workspace Reports"
$headers = @{
"Authorization" = "Bearer $accessToken"
'Content-Type' = 'application/json'
}
$uri = "https://api.powerbi.com/v1.0/myorg/groups/$workspaceId/reports"
$response = Invoke-RestMethod -Uri $uri -Headers $headers -Method Get
$pbiReports = $response.value
return $pbiReports
}
function Update-DVReportReferences
{
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
$pbiAccessToken,
[Parameter(Mandatory=$true)]
$dvAuthResponseObject,
[Parameter(Mandatory=$true)]
$workspaceId,
[Parameter(Mandatory=$true)]
$dataVerseURL
)
$pbiReports = Get-PBIReports -accessToken $pbiAccessToken -workspaceId $workspaceId
Write-Host $pbiReports.Count
$dvReports = Get-DVDCCPReports -dvAuthResponseObject $dvAuthResponseObject -workspaceId $workspaceId -dataVerseURL $dataVerseURL
Write-Host $dvReports.Count
Write-Host "Updating DCCP report references"
$pbiReports
foreach ($item in $dvReports)
{
$item.msdyn_name
$report = $pbiReports.value | Where-Object {$_.name -eq $item.msdyn_name}
if($report -ne $null)
{
Write-Host "Updating report reference for $($item.msdyn_name) with PBI $($report.id)"
$dvReportId = $item.msdyn_dataanalyticsreportid
$patchRequestUri = "msdyn_dataanalyticsreports($($dvReportId))"+'?$select=msdyn_workspaceid,msdyn_dataanalyticsreportid'
$updateBody = @{
'msdyn_workspaceid' = ''+$workspaceId+''
'msdyn_reportid' = ''+$report.id+''
} | ConvertTo-Json
# Set up web API call parameters, including a header for the access token
$patchApiCallParams = @{
URI = "$($dataVerseURL)/api/data/v9.1/$($patchRequestUri)"
Headers = @{
"Authorization" = "$($dvAuthResponseObject.token_type) $($dvAuthResponseObject.access_token)"
"Accept" = "application/json"
"OData-MaxVersion" = "4.0"
"OData-Version" = "4.0"
"Content-Type" = "application/json; charset=utf-8"
"Prefer" = "return=representation" # in order to return data
"If-Match" = "*"
}
Method = 'PATCH'
Body = $updateBody
}
$patchApiResponseObject = Invoke-RestMethod @patchApiCallParams -ErrorAction Stop
}
else
{
Write-Host "Corresponding PBI report not found in PBI workspace with name $($item.msdyn_name)"
}
}
return $pbiReports
}
###Sample usage########
#$PBIAppId = '<<Client ID which has access to Power BI workspace>>'
#$TenantId = '<<Tenant Id of the DV/PBI organization>>'
#$PBIClientSecret = "<<Secret of application user PBI>>"
#$AppId = '<<Dataverse App id>>'
#$ClientSecret = '<<DV client Secret>>'
#$PowerPlatformEnvironmentUrl = "<<DV URL>>"
#$PBIAccessToken = Get-PBIAccessToken -TenantId $TenantId -PBIAppId $PBIAppId -PBIClientSecret $PBIClientSecret
#$CRMAccessToken = Get-DVAccessToken -tenantId $TenantId -dataVerseURL $PowerPlatformEnvironmentUrl -clientId $AppId -clientSecret $ClientSecret
#$workspaceId = Get-DVWorkspaceId -dvAuthResponseObject $CRMAccessToken -dataVerseURL $PowerPlatformEnvironmentUrl
#Update-DVReportReferences -pbiAccessToken $PBIAccessToken -dvAuthResponseObject $CRMAccessToken -workspaceId $workspaceId -dataVerseURL $PowerPlatformEnvironmentUrl
Pipeline YAML do Azure DevOps de amostra
# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml
trigger:
- main
pool:
vmImage: windows-latest
steps:
- task: CopyFiles@2
inputs:
Contents: '**'
TargetFolder: '$(Build.ArtifactStagingDirectory)'
CleanTargetFolder: true
ignoreMakeDirErrors: true
displayName: 'Copy files from Repo'
- task: PowerPlatformToolInstaller@2
inputs:
DefaultVersion: true
- task: PowerPlatformExportData@2
inputs:
authenticationType: 'PowerPlatformSPN'
PowerPlatformSPN: 'Optimize25CRM'
Environment: '$(BuildTools.EnvironmentUrl)'
SchemaFile: '$(Build.ArtifactStagingDirectory)\source\Optimize25Schema\schema_sample.xml'
DataFile: 'data.zip'
displayName: 'Export reports sitemap data from Source'
- task: PowerPlatformImportData@2
inputs:
authenticationType: 'PowerPlatformSPN'
PowerPlatformSPN: 'Optimize25POC'
Environment: '$(BuildTools.EnvironmentUrl)'
DataFile: 'data.zip'
displayName: 'Import reports sitemap data to Target'
- task: PowerShell@2
inputs:
targetType: 'inline'
script: |
$ScriptContent = Get-Content "$(Build.ArtifactStagingDirectory)\source\automation\PipelineScript.ps1" -Raw
Invoke-Expression $ScriptContent
# Write your PowerShell commands here.
Write-Host "Assigning connection variables"
$PBIAppId = '$(PBIClientId)'
$PBIClientSecret = '$(PBIClientSecret)'
$TenantId = '$(TenantId)'
$AppId = '$(CRMClientId)'
$ClientSecret = '$(CRMClientSecret)'
$PowerPlatformEnvironmentUrl = '$(GetConnectionVar.PowerPlatformEnvironmentUrl)'
$PBIAccessToken = Get-PBIAccessToken -TenantId $TenantId -PBIAppId $PBIAppId -PBIClientSecret $PBIClientSecret
$CRMAccessToken = Get-DVAccessToken -tenantId $TenantId -dataVerseURL $PowerPlatformEnvironmentUrl -clientId $AppId -clientSecret $ClientSecret
$featureId = 'f2266eb4-226f-4cf1-b422-89c5f48b40cb'
$workspaceId = Get-DVWorkspaceId -dvAuthResponseObject $CRMAccessToken -dataVerseURL $PowerPlatformEnvironmentUrl -featureId $featureId
Write-Host $workspaceId
Update-DVReportReferences -pbiAccessToken $PBIAccessToken -dvAuthResponseObject $CRMAccessToken -workspaceId $workspaceId -dataVerseURL $PowerPlatformEnvironmentUrl -featureId $featureId
Recursos relacionados
Os recursos a seguir podem ajudar você a aprender mais sobre os recursos de análise internos do Omnicanal para Dynamics 365 Customer Service Analytics.
- Visão geral do painel de análise em tempo real
- Análise histórica para roteamento unificado no Omnicanal para Customer Service
- Personalização do modelo de relatórios de análise histórica e em tempo real no Customer Service
- Microsoft Power Platform Build Tools para o Azure DevOps
- Migrar dados de configuração entre organizações
- Grupo de comandos de dados do Microsoft Power Platform CLI
- Visão geral dos pipelines de implantação do Power BI
- APIs REST do Power BI para análise integrada e automação