Trabalhar com fluxos de nuvem usando código

Todos os fluxos são armazenados no Dataverse e você pode usar o SDK do Dataverse para .NET ou a API Web para gerenciá-los.

Este artigo aborda o gerenciamento de fluxos incluídos na guia Soluções no Power Automate. No momento, não há suporte para gerenciar fluxos em Meus Fluxos com código.

Interagir com APIs do Dataverse

O Dataverse fornece recursos equivalentes usando o SDK do Dataverse para .NET ou a API Web.

Qual método devo usar?

O melhor método depende da tecnologia do projeto e das suas habilidades.

Se seu projeto usar .NET, será recomendável usar o SDK. O SDK simplifica a experiência de desenvolvimento pois fornece um modelo de objeto tipado e métodos para autenticação.

Mais informações: Use o serviço da organização

Como se conectar?

A forma como você se conecta depende de estar usando o SDK do Dataverse para .NET ou a API Web.

Com o SDK, você precisa se conectar a um aplicativo cliente para obter acesso a uma instância IOrganizationService. IOrganizationService é uma interface que fornece métodos a serem usados para interagir com o Dataverse.

Mais informações:

Tabela do fluxo de trabalho

Os fluxos da nuvem são armazenados na tabela Processo (fluxo de trabalho) que é representada na API Web como o fluxo de trabalho EntityType

A seguinte tabela descreve colunas importantes na tabela de fluxo de trabalho:

Nome Lógico Type Description
category Opção A categoria do fluxo. Aqui estão as diferentes categorias.
0 - Fluxos de trabalho clássicos do Dataverse.
1 - Caixas de diálogo clássicas do Dataverse.
2 - Regras de negócios.
3 - Ações clássicas do Dataverse.
4 - Fluxos do processo empresarial.
5 - Fluxo Moderno (Fluxos automatizados, instantâneos ou agendados).
6 - Fluxos da área de trabalho.
clientdata String Uma cadeia de caracteres codificada JSON da definição de fluxo e suas connectionReferences.
createdby Pesquisar O usuário que criou o fluxo.
createdon DateTime A data em que o fluxo foi criado.
description String A descrição do fluxo fornecida pelo usuário.
ismanaged Bool Indica se o fluxo foi instalado por meio de uma solução gerenciada.
modifiedby Pesquisar O último usuário que atualizou o fluxo.
modifiedon DateTime A última vez que a tarefa foi atualizada.
name String O nome de exibição que você deu ao fluxo.
ownerid Pesquisar O usuário ou a equipe que possui o fluxo.
statecode Opção O status do fluxo. O status pode ser:
0 - Rascunho (Desligado)
1 - Ativado (Ligado)
2 - Suspenso.
type Opção Indica se o fluxo é um fluxo de execução ou um modelo que pode ser usado para criar mais fluxos.
1 - Definição,
2 - Ativação
3 - Modelo.
workflowid GUID O identificador exclusivo para um fluxo da nuvem em todas as importações.
workflowidunique GUID O identificador exclusivo para esta instalação do fluxo.

Observação

Com a API Web, os valores de pesquisa são propriedades de navegação de valor único que podem ser expandidas para obter detalhes do registro relacionado.

As colunas de pesquisa também têm propriedades de pesquisa GUID correspondentes que podem ser usadas em consultas. As propriedades de pesquisa têm esta convenção de nomenclatura: _<logical name>_value. Para o tipo de entidade de fluxo de trabalho na API Web, você pode fazer referência a estas propriedades de pesquisa: _createdby_value, _modifiedby_value e _ownerid_value.

Listar fluxos

Para recuperar uma lista de fluxos da nuvem, você pode consultar a tabela de fluxo de trabalho. A seguinte consulta retorna o primeiro fluxo automatizado, instantâneo ou agendado que está 'ativado' no momento:

Este método estático OutputFirstActiveFlow requer um cliente autenticado que implemente o IOrganizationService. Ele usa o método IOrganizationService.RetrieveMultiple.

/// <summary>
/// Outputs the first active flow
/// </summary>
/// <param name="service">Authenticated client implementing the IOrganizationService interface</param>
public static void OutputFirstActiveFlow(IOrganizationService service)
{
   var query = new QueryExpression("workflow")
   {
         ColumnSet = new ColumnSet("category",
                                    "createdby",
                                    "createdon",
                                    "description",
                                    "ismanaged",
                                    "modifiedby",
                                    "modifiedon",
                                    "name",
                                    "ownerid",
                                    "statecode",
                                    "type",
                                    "workflowid",
                                    "workflowidunique"),
         Criteria = new FilterExpression(LogicalOperator.And)
         {
            Conditions = {
            {  new ConditionExpression(
               "category",
                     ConditionOperator.Equal,
                     5) }, // Cloud Flow
            {  new ConditionExpression(
                     "statecode",
                     ConditionOperator.Equal,
                     1) } // Active
         }
         },
         TopCount = 1 // Limit to one record
   };

   EntityCollection workflows = service.RetrieveMultiple(query);

   Entity workflow = workflows.Entities.FirstOrDefault();

   Console.WriteLine($"category: {workflow.FormattedValues["category"]}");
   Console.WriteLine($"createdby: {workflow.FormattedValues["createdby"]}");
   Console.WriteLine($"createdon: {workflow.FormattedValues["createdon"]}");
   // Description may be null
   Console.WriteLine($"description: {workflow.GetAttributeValue<string>("description")}");
   Console.WriteLine($"ismanaged: {workflow.FormattedValues["ismanaged"]}");
   Console.WriteLine($"modifiedby: {workflow.FormattedValues["modifiedby"]}");
   Console.WriteLine($"modifiedon: {workflow.FormattedValues["modifiedon"]}");
   Console.WriteLine($"name: {workflow["name"]}");
   Console.WriteLine($"ownerid: {workflow.FormattedValues["ownerid"]}");
   Console.WriteLine($"statecode: {workflow.FormattedValues["statecode"]}");
   Console.WriteLine($"type: {workflow.FormattedValues["type"]}");
   Console.WriteLine($"workflowid: {workflow["workflowid"]}");
   Console.WriteLine($"workflowidunique: {workflow["workflowidunique"]}");
}

Para recuperar mais registros, remova o limite TopCount.

Saída

category: Modern Flow
createdby: SYSTEM
createdon: 5/20/2020 9:37 PM
description:
ismanaged: Unmanaged
modifiedby: Kiana Anderson
modifiedon: 5/6/2023 3:37 AM
name: When an account is updated -> Create a new record
ownerid: Monica Thomson
statecode: Activated
type: Definition
workflowid: d9e875bf-1c9b-ea11-a811-000d3a122b89
workflowidunique: c17af45c-10a1-43ca-b816-d9cc352718cf

Mais informações:

Criar um fluxo da nuvem

As propriedades necessárias para fluxos automatizados, instantâneos e agendados são: category, name, type, primaryentity e clientdata. Use none para o primaryentity para esses tipos de fluxos.

Este método estático requer um cliente autenticado que implemente o IOrganizationService. Ele usa o método IOrganizationService.Create.

/// <summary>
/// Creates a cloud flow
/// </summary>
/// <param name="service">Authenticated client implementing the IOrganizationService interface</param>
/// <returns>The workflowid</returns>
public static Guid CreateCloudFlow(IOrganizationService service)
{
   var workflow = new Entity("workflow")
   {
         Attributes = {
            {"category", new OptionSetValue(5) }, // Cloud flow
            {"name", "Sample flow name"},
            {"type", new OptionSetValue(1) }, //Definition
            {"description", "This flow reads some data from Dataverse." },
            {"primaryentity", "none" },
            {"clientdata", "{\"properties\":{\"connectionReferences\":{\"shared_commondataserviceforapps\":{\"impersonation\":{},\"runtimeSource\":\"embedded\",\"connection\":{\"name\":\"shared-commondataser-114efb88-a991-40c7-b75f-2693-b1ca6a0c\",\"connectionReferenceLogicalName\":\"crdcb_sharedcommondataserviceforapps_109ea\"},\"api\":{\"name\":\"shared_commondataserviceforapps\"}}},\"definition\":{\"$schema\":\"https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#\",\"contentVersion\":\"1.0.0.0\",\"parameters\":{\"$connections\":{\"defaultValue\":{},\"type\":\"Object\"},\"$authentication\":{\"defaultValue\":{},\"type\":\"SecureObject\"}},\"triggers\":{\"manual\":{\"metadata\":{\"operationMetadataId\":\"76f87a86-89b3-48b4-92a2-1b74539894a6\"},\"type\":\"Request\",\"kind\":\"Button\",\"inputs\":{\"schema\":{\"type\":\"object\",\"properties\":{},\"required\":[]}}}},\"actions\":{\"List_rows\":{\"runAfter\":{},\"metadata\":{\"operationMetadataId\":\"9725b30f-4a8e-4695-b6fd-9a4985808809\"},\"type\":\"OpenApiConnection\",\"inputs\":{\"host\":{\"apiId\":\"/providers/Microsoft.PowerApps/apis/shared_commondataserviceforapps\",\"connectionName\":\"shared_commondataserviceforapps\",\"operationId\":\"ListRecords\"},\"parameters\":{\"entityName\":\"accounts\",\"$select\":\"name\",\"$top\":1},\"authentication\":\"@parameters('$authentication')\"}}}}},\"schemaVersion\":\"1.0.0.0\"}" }
         }
   };

   return service.Create(workflow);
}

Mais informações: Criar linhas de tabela usando o serviço de organização

O statecode de todos os fluxos criados dessa maneira é definido como 0 (Rascunho ou 'Desligado'). O fluxo precisa ser ativado antes de poder ser usado.

A propriedade mais importante é a clientdata, que contém o connectionReferences usado pelo fluxo, e a definição do fluxo. Os connectionReferences são os mapeamentos para cada conexão usada pelo fluxo.

{
  "properties": {
    "connectionReferences": {
      "shared_commondataserviceforapps": {
        "runtimeSource": "embedded",
        "connection": {},
        "api": { 
         "name": "shared_commondataserviceforapps" 
         }
      }
    },
    "definition": {
      "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
      "contentVersion": "1.0.0.0",
      "parameters": {
        "$connections": { "defaultValue": {}, "type": "Object" },
        "$authentication": { "defaultValue": {}, "type": "SecureObject" }
      },
      "triggers": {
        "manual": {
          "metadata": {},
          "type": "Request",
          "kind": "Button",
          "inputs": {
            "schema": { "type": "object", "properties": {}, "required": [] }
          }
        }
      },
      "actions": {
        "List_rows": {
          "runAfter": {},
          "metadata": {},
          "type": "OpenApiConnection",
          "inputs": {
            "host": {
              "apiId": "/providers/Microsoft.PowerApps/apis/shared_commondataserviceforapps",
              "connectionName": "shared_commondataserviceforapps",
              "operationId": "ListRecords"
            },
            "parameters": {
              "entityName": "accounts",
              "$select": "name",
              "$top": 1
            },
            "authentication": "@parameters('$authentication')"
          }
        }
      }
    }
  },
  "schemaVersion": "1.0.0.0"
}

Atualizar um fluxo da nuvem

Para atualizar um fluxo, defina apenas as propriedades que você deseja alterar.

Este método estático requer um cliente autenticado que implemente o IOrganizationService. Ele usa o método IOrganizationService.Update para atualizar uma descrição de fluxo e definir o proprietário.

/// <summary>
/// Updates a cloud flow
/// </summary>
/// <param name="service">Authenticated client implementing the IOrganizationService interface</param>
/// <param name="workflowid">The ID of the flow to update.</param>
/// <param name="systemuserid">The id of the user to assign the flow to.</param>
public static void UpdateCloudFlow(IOrganizationService service, Guid workflowid, Guid systemuserid) {

   var workflow = new Entity("workflow",workflowid)
   {
         Attributes = {

            {"description", "This flow will ensure consistency across systems." },
            {"ownerid", new EntityReference("systemuser",systemuserid)},
            {"statecode", new OptionSetValue(1) } //Turn on the flow.
         }
   };

   service.Update(workflow);
}

Mais informações: Atualizar e excluir linhas da tabela usando o Serviço da Organização e Atualização básica

Excluir um fluxo da nuvem

Os exemplos a seguir mostram como excluir o registro de fluxo de trabalho que representa um fluxo da nuvem.

O método estático DeleteCloudFlow exclui um registro de fluxo de trabalho.

/// <summary>
/// Deletes a workflow
/// </summary>
/// <param name="service">Authenticated client implementing the IOrganizationService interface</param>
/// <param name="workflowId">The id of the cloud flow to delete.</param>
public static void DeleteCloudFlow(IOrganizationService service, Guid workflowId) { 

service.Delete(entityName:"workflow",id: workflowId);

}

Mais informações: Excluir um registro usando o SDK

Obter todos os usuários com quem um fluxo da nuvem é compartilhado

Use a mensagem RetrieveSharedPrincipalsAndAccess para obter uma lista de todos os usuários com os quais um fluxo de nuvem é compartilhado.

Com o SDK, use a classe RetrieveSharedPrincipalsAndAccessRequest e, com a API Web, use a função RetrieveSharedPrincipalsAndAccess.

Mais informações: Obter entidades com acesso a um registro

Compartilhar ou descompartilhar um fluxo da nuvem

Compartilhe um fluxo de nuvem como qualquer outro registro do Dataverse usando a mensagem GrantAccess. Com o SDK, use a classe GrantAccessRequest e, com a API Web, use a ação GrantAccess. Mais informações: Exemplo de GrantAccess

Se você desejar alterar os direitos de acesso concedidos ao compartilhar um registro, use a mensagem ModifyAccess. Com o SDK, use a classe ModifyAccessRequest e, com a API Web, use a ação ModifyAccess. Mais informações: Exemplo de ModifyAccess

Para descompartilhar um registro, use a mensagem RevokeAccess. Com o SDK, use a classe RevokeAccessRequest e, com a API Web, use a ação RevokeAccess. Mais informações: Revogar o acesso

Exportar fluxos

Quando um fluxo faz parte de uma solução, você pode exportá-lo exportando a solução que contém o fluxo por meio da mensagem ExportSolution.

O método de exemplo estático ExportSolution abaixo usa o ExportSolutionRequest para recuperar um byte[] contendo o arquivo ZIP da solução não gerenciada com UniqueName especificado.

/// <summary>
/// Exports an unmanaged solution
/// </summary>
/// <param name="service">Authenticated client implementing the IOrganizationService interface</param>
/// <param name="solutionUniqueName">The uniquename of the solution.</param>
/// <returns></returns>
public static byte[] ExportSolution(
   IOrganizationService service, 
   string solutionUniqueName) 
{
   ExportSolutionRequest request = new() { 
         SolutionName = solutionUniqueName,
         Managed = false
   };

   var response = (ExportSolutionResponse)service.Execute(request);

   return response.ExportSolutionFile;
}

Importe fluxos

Quando você tem um arquivo ZIP de solução, pode importá-lo usando a mensagem ImportSolution.

Ao importar fluxos, você deve definir os seguintes parâmetros:

Nome da propriedade Descrição
OverwriteUnmanagedCustomizations Se houver instâncias desses fluxos no Dataverse, esse sinalizador precisa ser definido como true para importá-las. Caso contrário, elas não serão substituídas.
PublishWorkflows Indica se Dataverse clássico para fluxos de trabalho será ativado durante a importação. Essa configuração não se aplica a outros tipos de fluxos.
CustomizationFile Um arquivo zip codificado de base 64 que contém a solução.

O método de exemplo estático ImportSolution mostra como importar um arquivo de solução usando a classe ImportSolutionRequest

/// <summary>
/// Imports a solution.
/// </summary>
/// <param name="service">Authenticated client implementing the IOrganizationService interface</param>
/// <param name="solutionFile">The byte[] data representing a solution file. </param>
public static void ImportSolution(
   IOrganizationService service, 
   byte[] solutionFile) {

   ImportSolutionRequest request = new() { 
         OverwriteUnmanagedCustomizations = true,
         CustomizationFile = solutionFile
   };

   service.Execute(request);
}

Confira também

Operações de classe de entidade usando o serviço de organização
Executar operações usando a API Web
Compartilhamento e atribuição
Verificar o acesso no código
Trabalhar com soluções usando o SDK do Dataverse