Condividi tramite


Libreria client REST di AzureCommunicationRoutingService per JavaScript

Servizio di routing delle comunicazioni di Azure

Per usare questa libreria, fare affidamento principalmente sulla documentazione del client REST

Collegamenti principali:

Introduzione

Ambienti attualmente supportati

  • Versioni LTS di Node.js

Prerequisiti

Avere una risorsa ACS

Creare una risorsa ACS nel portale di Azure o usare una risorsa esistente.

Installare il pacchetto @azure-rest/communication-job-router

Installare la libreria client REST client REST di AzureCommunicationRoutingService per JavaScript con npm:

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

Creare e autenticare un oggetto AzureCommunicationRoutingServiceClient

Per usare una credenziale del token di Azure Active Directory (AAD), specificare un'istanza del tipo di credenziale desiderato ottenuto dalla libreria di @azure/identità .

Per eseguire l'autenticazione con AAD, è prima necessario npm installare @azure/identity

Dopo l'installazione, è possibile scegliere il tipo di credenziale da @azure/identity usare. Ad esempio, DefaultAzureCredential può essere usato per autenticare il client.

Impostare i valori dell'ID client, dell'ID tenant e del segreto client dell'applicazione AAD come variabili di ambiente: AZURE_CLIENT_ID, AZURE_TENANT_ID AZURE_CLIENT_SECRET

Esercitazione: Indirizzare i processi ai ruoli di lavoro usando l'SDK REST del router del processo Servizi di comunicazione di Azure (ACS)

In questa esercitazione si apprenderà:

  • Come creare una coda.
  • Come creare i ruoli di lavoro e assegnarli a una coda.
  • Come instradare i processi ai ruoli di lavoro.
  • Come sottoscrivere e gestire gli eventi del router del processo.
  • Come completare e chiudere i processi.

Avviare un server NodeJS Express

In una shell (cmd, PowerShell, Bash e così via), creare una cartella denominata RouterQuickStart e all'interno di questa cartella eseguire npx express-generator. Verrà generato un semplice progetto Express che sarà in ascolto su port 3000.

Esempio

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

Installare Azure ACS Job Router SDK

RouterQuickStart Nella cartella installare ACS Job Router SDK eseguendo npm install @azure-rest/communication-job-router --save.

Routing dei processi

Costruire AzureCommunicationRoutingServiceClient

Prima di tutto è necessario costruire un oggetto 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);

Creare un criterio di distribuzione

Questi criteri determinano quali ruoli di lavoro riceveranno offerte di lavoro man mano che i processi vengono distribuiti dalle code.

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,
    },
  }
});

Creare una coda

Questa coda offre processi ai ruoli di lavoro in base ai criteri di distribuzione creati in precedenza.

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: {},
  }
});

Creare ruoli di lavoro

Questi ruoli di lavoro vengono assegnati alla coda "Sales" creata in precedenza e hanno alcune etichette.

  • impostare su availableForOfferstrue significa che questi lavoratori sono pronti ad accettare offerte di lavoro.
  • Fare riferimento alla documentazione delle etichette per comprendere meglio le etichette e i selettori di etichetta.
  // 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 di vita del processo

Fare riferimento alla documentazione del ciclo di vita del processo per comprendere meglio il ciclo di vita di un processo.

Creare un processo

Questo processo viene accodato nella coda "Sales" creata in precedenza.

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: {},
  }
});

(Facoltativo) Creare un processo con criteri di classificazione

Creare criteri di classificazione

Questo criterio classifica i processi al momento della creazione.

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)"
    }
  }
});

Creare e classificare il processo

Questo processo verrà classificato con i criteri di classificazione creati in precedenza. Ha anche un'etichetta.

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"
}

Sottoscrizione di eventi

Un modo per sottoscrivere gli eventi del router di processo ACS consiste nell'usare il portale di Azure.

  1. Passare alla risorsa ACS nel portale di Azure e aprire il pannello "Eventi".
  2. Aggiungere una sottoscrizione di eventi per l'evento "RouterWorkerOfferIssued".
  3. Selezionare un mezzo appropriato per ricevere l'evento , ad esempio webhook, Funzioni di Azure, bus di servizio.

Per comprendere meglio la sottoscrizione agli eventi del router di processo, vedere la documentazione relativa alla sottoscrizione degli eventi del router di processo.

La route nell'applicazione NodeJS che riceve eventi può essere simile alla seguente:

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 ...
    });
    ...
});

Accettare o rifiutare l'offerta di processo

Dopo aver ricevuto un RouterWorkerOfferIssued evento, è possibile accettare o rifiutare l'offerta di processo.

  • workerid - ID del lavoratore che accetta l'offerta di processo.
  • offerId - ID dell'offerta accettata o rifiutata.
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();

Completare il processo

L'oggetto assignmentId ricevuto dalla risposta del passaggio precedente è necessario per completare il processo.

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()}`
  }
});

Chiudere il processo

Dopo aver completato la fase di wrapping del processo, jobRouterClient il ruolo di lavoro può chiudere il processo e allegare un codice di eliminazione a esso per riferimento futuro.

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()}`
  }
});

Risoluzione dei problemi

Registrazione

L'abilitazione della registrazione consente di individuare informazioni utili sugli errori. Per visualizzare un log di richieste e risposte HTTP, impostare la variabile di ambiente AZURE_LOG_LEVEL su info. In alternativa, la registrazione può essere abilitata in fase di esecuzione chiamando setLogLevel in @azure/logger:

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

setLogLevel("info");

Per istruzioni più dettagliate su come abilitare i log, è possibile esaminare la documentazione del pacchetto di @azure/logger.