Biblioteca de clientes REST do AzureCommunicationRoutingService para JavaScript

Serviço de Roteamento de Comunicação do Azure

Confie fortemente em nossos documentos de cliente REST para usar esta biblioteca

Links principais:

Introdução

Ambientes com suporte no momento

  • Versões LTS do Node.js

Pré-requisitos

Ter um recurso do ACS

Crie um recurso do ACS no Portal do Azure ou use um recurso existente.

Instalar o pacote @azure-rest/communication-job-router

Instale a biblioteca de clientes REST do cliente REST do AzureCommunicationRoutingService para JavaScript com npm:

npm install @azure-rest/communication-job-router

Criar e autenticar um AzureCommunicationRoutingServiceClient

Para usar uma credencial de token do AAD (Azure Active Directory), forneça uma instância do tipo de credencial desejado obtido da biblioteca de @azure/identidade .

Para autenticar com o AAD, primeiro npm você deve instalar @azure/identity

Após a instalação, você pode escolher de qual tipo de credencial@azure/identity usar. Por exemplo, DefaultAzureCredential pode ser usado para autenticar o cliente.

Defina os valores da ID do cliente, da ID do locatário e do segredo do cliente do aplicativo AAD como variáveis de ambiente: AZURE_CLIENT_ID, AZURE_TENANT_ID AZURE_CLIENT_SECRET

Tutorial: Rotear trabalhos para trabalhadores usando o SDK rest do roteador de trabalho de Serviços de Comunicação do Azure (ACS)

Neste tutorial, você irá aprender:

  • Como criar uma fila.
  • Como criar trabalhos e atribuí-los a uma fila.
  • Como rotear trabalhos para os trabalhadores.
  • Como assinar e manipular eventos do Roteador de Trabalho.
  • Como concluir e fechar trabalhos.

Iniciar um servidor NodeJS Express

Em um shell (cmd, PowerShell, Bash etc.), crie uma pasta chamada RouterQuickStart e dentro dessa pasta execute npx express-generator. Isso gerará um projeto express simples que escutará em port 3000.

Exemplo

mkdir RouterQuickStart
cd RouterQuickStart
npx express-generator
npm install
DEBUG=routerquickstart:* npm start

Instalar o SDK do Roteador de Trabalho do ACS do Azure

RouterQuickStart Na pasta , instale o SDK do Roteador de Trabalho do ACS executando npm install @azure-rest/communication-job-router --save.

Trabalhos de roteamento

Construir AzureCommunicationRoutingServiceClient

Primeiro, precisamos construir um AzureCommunicationRoutingServiceClient.

const JobRouterClient = require("@azure-rest/communication-job-router").default;

const connectionString = "endpoint=https://<YOUR_ACS>.communication.azure.com/;accesskey=<YOUR_ACCESS_KEY>";
const routerClient = JobRouterClient(connectionString);

Criar uma política de distribuição

Essa política determina quais trabalhadores receberão ofertas de trabalho à medida que os trabalhos são distribuídos fora de suas filas.

const distributionPolicy = await routerClient.path("/routing/distributionPolicies/{id}", "distributionPolicy-1").patch({
  contentType: "application/merge-patch+json",
  body: {
    name: "distribution-policy-123",
    offerExpiresAfterSeconds: 30,
    mode: {
      kind: "longestIdle",
      minConcurrentOffers: 1,
      maxConcurrentOffers: 3,
    },
  }
});

criar uma fila

Essa fila oferece trabalhos aos trabalhadores de acordo com nossa política de distribuição criada anteriormente.

const salesQueueId = "queue-123";
await routerClient.path("/routing/queues/{id}", salesQueueId).patch({
  contentType: "application/merge-patch+json",
  body: {
    distributionPolicyId: distributionPolicy.body.id,
    name: "Main",
    labels: {},
  }
});

Criar Trabalhos

Esses trabalhadores são atribuídos à nossa fila "Vendas" criada anteriormente e têm alguns rótulos.

  • configuração availableForOffers para true significa que esses trabalhadores estão prontos para aceitar ofertas de trabalho.
  • consulte nossa documentação de rótulos para entender melhor os rótulos e os seletores de rótulos.
  // Create worker "Alice".
const workerAliceId = "773accfb-476e-42f9-a202-b211b41a4ea4";
const workerAliceResponse = await routerClient.path("/routing/workers/{workerId}", workerAliceId).patch({
  contentType: "application/merge-patch+json",
  body: {
    capacity: 120,
    queues: [salesQueueId],
    labels: {
      Xbox: 5,
      german: 4,
      name: "Alice"
    },
    channels: [
      {
        channelId: "CustomChatChannel",
        capacityCostPerJob: 10,
      },
      {
        channelId: "CustomVoiceChannel",
        capacityCostPerJob: 100,
      },
    ],
  }
});

// Create worker "Bob".
const workerBobId = "21837c88-6967-4078-86b9-1207821a8392";
const workerBobResponse = await routerClient.path("/routing/workers/{workerId}", workerBobId).patch({
  contentType: "application/merge-patch+json",
  body: {
    capacity: 100,
    queues: [salesQueueId],
    labels: {
      Xbox: 5,
      english: 3,
      name: "Alice"
    },
    channels: [
      {
        channelId: "CustomChatChannel",
        capacityCostPerJob: 10,
      },
      {
        channelId: "CustomVoiceChannel",
        capacityCostPerJob: 100,
      },
    ],
  }
});

Ciclo de vida do trabalho

Consulte nossa documentação do ciclo de vida do trabalho para entender melhor o ciclo de vida de um trabalho.

Crie um trabalho

Esse trabalho é enfileirado em nossa fila "Vendas" criada anteriormente.

const jobId = "router-job-123";
const result = await routerClient.path("/routing/jobs/{id}", jobId).patch({
  contentType: "application/merge-patch+json",
  body: {
    channelReference: "66e4362e-aad5-4d71-bb51-448672ebf492",
    channelId: "voice",
    priority: 2,
    queueId: "salesQueueId",
    labels: {},
  }
});

(Opcional) Criar trabalho com uma política de classificação

Criar uma política de classificação

Essa política classifica os trabalhos após a criação.

const classificationPolicyId = "classification-policy-123";
const result = await routerClient.path("/routing/classificationPolicies/{id}", classificationPolicyId).patch({
  contentType: "application/merge-patch+json",
  body: {
    name: "Default Classification Policy",
    fallbackQueueId: salesQueueId,
    queueSelectorAttachments: [
      {
        kind: "static",
        queueSelector: { key: "department", labelOperator: "equal", value: "xbox" }
      },
    ],
    workerSelectorAttachments: [{
      kind: "static",
      workerSelector: { key: "english", labelOperator: "greaterThan", value: 5 }
    }],
    prioritizationRule: {
      kind: "expression",
      language: "powerFx",
      expression: "If(job.department = \"xbox\", 2, 1)"
    }
  }
});

Criar e classificar trabalho

Esse trabalho será classificado com nossa política de classificação criada anteriormente. Ele também tem um rótulo.

const result = await routerClient.path("/routing/jobs/{id}", jobId).patch({
  contentType: "application/merge-patch+json",
  body: {
    channelReference: "66e4362e-aad5-4d71-bb51-448672ebf492",
    channelId: "voice",
    classificationPolicyId: classificationPolicy.id,
    labels: {
      department: "xbox"
    },
  }
});
``

## Events

Job Router events are delivered via Azure Event Grid. Refer to our [Azure Event Grid documentation](/azure/event-grid/overview) to better understand Azure Event Grid.

In the previous example:

- The job gets enqueued to the “Sales" queue.
- A worker is selected to handle the job, a job offer is issued to that worker, and a `RouterWorkerOfferIssued` event is sent via Azure Event Grid.

Example `RouterWorkerOfferIssued` JSON shape:

```json
{
  "id": "1027db4a-17fe-4a7f-ae67-276c3120a29f",
  "topic": "/subscriptions/{subscription-id}/resourceGroups/{group-name}/providers/Microsoft.Communication/communicationServices/{communication-services-resource-name}",
  "subject": "worker/{worker-id}/job/{job-id}",
  "data": {
    "workerId": "w100",
    "jobId": "7f1df17b-570b-4ae5-9cf5-fe6ff64cc712",
    "channelReference": "test-abc",
    "channelId": "FooVoiceChannelId",
    "queueId": "625fec06-ab81-4e60-b780-f364ed96ade1",
    "offerId": "525fec06-ab81-4e60-b780-f364ed96ade1",
    "offerTimeUtc": "2023-08-17T02:43:30.3847144Z",
    "expiryTimeUtc": "2023-08-17T02:44:30.3847674Z",
    "jobPriority": 5,
    "jobLabels": {
      "Locale": "en-us",
      "Segment": "Enterprise",
      "Token": "FooToken"
    },
    "jobTags": {
      "Locale": "en-us",
      "Segment": "Enterprise",
      "Token": "FooToken"
    }
  },
  "eventType": "Microsoft.Communication.RouterWorkerOfferIssued",
  "dataVersion": "1.0",
  "metadataVersion": "1",
  "eventTime": "2023-08-17T00:55:25.1736293Z"
}

Assinando eventos

Uma maneira de assinar eventos do Roteador de Trabalho do ACS é por meio do Portal do Azure.

  1. Navegue até o recurso do ACS no Portal do Azure e abra a folha "Eventos".
  2. Adicione uma assinatura de evento para o evento "RouterWorkerOfferIssued".
  3. Selecione um meio apropriado para receber o evento (por exemplo, Webhook, Azure Functions, Barramento de Serviço).

Consulte nossa documentação "Assinar eventos do Roteador de Trabalho" para entender melhor a assinatura de eventos do Roteador de Trabalho.

A rota em seu aplicativo NodeJS que recebe eventos pode ser semelhante a esta:

app.post('/event', (req, res) => {
    req.body.forEach(eventGridEvent => {
        // Deserialize the event data into the appropriate type
        if (eventGridEvent.eventType === "Microsoft.EventGrid.SubscriptionValidationEvent") {
            res.send({ validationResponse: eventGridEvent.data.validationCode });
        } else if (eventGridEvent.eventType === "Microsoft.Azure.CommunicationServices.RouterWorkerOfferIssued") {
           // RouterWorkerOfferIssued handling logic;
        } else if ...
    });
    ...
});

Aceitar ou recusar a oferta de trabalho

Depois de receber um RouterWorkerOfferIssued evento, você poderá aceitar ou recusar a oferta de trabalho.

  • workerid - A ID do trabalhador que aceita a oferta de trabalho.
  • offerId - A ID da oferta que está sendo aceita ou recusada.
const acceptResponse = await routerClient.path("/routing/workers/{workerId}/offers/{offerId}:accept", workerId, offerId).post();
// or
const declineResponse = await routerClient.path("/routing/workers/{workerId}/offers/{offerId}:decline", workerId, offerId).post();

Concluir o trabalho

O assignmentId recebido da resposta da etapa anterior é necessário para concluir o trabalho.

const completeJob = await routerClient.path("/routing/jobs/{id}/assignments/{assignmentId}:complete", jobId, acceptResponse.body.assignmentId).post({
  body: {
    note: `Job has been completed by ${workerId} at ${new Date()}`
  }
});

Fechar o trabalho

Depois que o trabalho tiver concluído a fase de encapsulamento do trabalho, o jobRouterClient poderá fechar o trabalho e anexar um código de disposição a ele para referência futura.

const closeJob = await routerClient.path("/routing/jobs/{id}/assignments/{assignmentId}:close", jobId, acceptResponse.body.assignmentId).post({
  body: {
    note: `Job has been closed by ${workerId} at ${new Date()}`
  }
});

Solução de problemas

Registro em log

A habilitação do log pode ajudar a descobrir informações úteis sobre falhas. Para ver um log de solicitações e respostas HTTP, defina a variável de ambiente AZURE_LOG_LEVEL como info. Como alternativa, o log pode ser habilitado no runtime chamando setLogLevel em @azure/logger:

const { setLogLevel } = require("@azure/logger");

setLogLevel("info");

Para obter instruções mais detalhadas sobre como habilitar logs, veja os documentos do pacote @azure/logger.