Share via


Azure Communication JobRouter Package-klientbibliotek för Python – version 1.0.0

Det här paketet innehåller en Python SDK för Azure Communication Services för JobRouter. Läs mer om Azure Communication Services här

| KällkodPaket (Pypi) | Produktdokumentation

Friskrivning

Stöd för Azure SDK Python-paket för Python 2.7 upphörde den 1 januari 2022. Mer information och frågor finns i https://github.com/Azure/azure-sdk-for-python/issues/20691

Komma igång

Förutsättningar

Du behöver en Azure-prenumeration och en kommunikationstjänstresurs för att kunna använda det här paketet.

Installera paketet

Installera Azure Communication JobRouter-klientbiblioteket för Python med pip:

pip install azure-communication-jobrouter

Viktiga begrepp

Jobb

Ett jobb representerar arbetsenheten som måste dirigeras till en tillgänglig Arbetare. Ett verkligt exempel på detta kan vara ett inkommande samtal eller en chatt i samband med ett kundtjänst.

Arbetare

En Worker representerar den tillgång som är tillgänglig för att hantera ett jobb. Varje arbetare registrerar sig med eller flera köer för att ta emot jobb. Ett verkligt exempel på detta kan vara en agent som arbetar i ett kundtjänst.

En kö representerar en ordnad lista över jobb som väntar på att hanteras av en arbetare. Arbetare registrerar sig i en kö för att ta emot arbete från den. Ett verkligt exempel på detta kan vara en samtalskö i ett kundtjänst.

Kanal

En kanal representerar en gruppering av jobb efter någon typ. När en arbetare registrerar sig för att ta emot arbete måste de också ange för vilka kanaler de kan hantera arbete och hur mycket av var och en som kan hanteras samtidigt. Ett verkligt exempel på detta kan vara voice calls eller chats i ett kundtjänst.

Erbjudande

Ett erbjudande utökas av JobRouter till en arbetare för att hantera ett visst jobb när det fastställer en matchning. Det här meddelandet levereras vanligtvis via EventGrid. Arbetaren kan antingen acceptera eller avvisa erbjudandet med hjälp av th JobRouter-API:et, eller så upphör det att gälla enligt den time to live-konfiguration som har konfigurerats för distributionsprincipen. Ett verkligt exempel på detta kan vara ringningen av en agent i ett kundtjänst.

Distributionsprincip

En distributionsprincip representerar en konfigurationsuppsättning som styr hur jobb i en kö distribueras till arbetare som är registrerade i kön. Den här konfigurationen omfattar hur länge ett erbjudande är giltigt innan det upphör att gälla och distributionsläget, som definierar i vilken ordning arbetare väljs när det finns flera tillgängliga.

Distributionsläge

De tre typerna av lägen är

  • Resursallokering: Arbetare sorteras efter Id och nästa arbetare efter den föregående som fick ett erbjudande väljs.
  • Längsta inaktivitet: Den arbetare som inte har arbetat med ett jobb under den längsta tid.
  • Best Worker: Du kan ange ett uttryck för att jämföra 2 arbetare för att avgöra vilken som ska väljas.

Etiketter

Du kan koppla etiketter till arbetare, jobb och köer. Det här är nyckel/värde-par som kan vara av string, number eller boolean datatyper. Ett verkligt exempel på detta kan vara kompetensnivån för en viss arbetare eller teamet eller den geografiska platsen.

Etikettväljare

Etikettväljare kan kopplas till ett jobb för att rikta in sig på en delmängd arbetare som betjänar kön. Ett verkligt exempel på detta kan vara ett villkor i ett inkommande samtal att agenten måste ha en miniminivå av kunskap om en viss produkt.

Klassificeringsprincip

En klassificeringsprincip kan användas för att dynamiskt välja en kö, fastställa jobbprioritet och koppla väljare för arbetsetiketter till ett jobb genom att använda en regelmotor.

Undantagsprincip

En undantagsprincip styr beteendet för ett jobb baserat på en utlösare och kör en önskad åtgärd. Undantagsprincipen är kopplad till en kö så att den kan styra beteendet för jobb i kön.

Exempel

Klientinitiering

För att initiera SMS-klienten kan anslutningssträng användas för att instansiera. Du kan också använda Active Directory-autentisering med DefaultAzureCredential.

from azure.communication.jobrouter import (
    JobRouterClient,
    JobRouterAdministrationClient
)

connection_string = "endpoint=ENDPOINT;accessKey=KEY"
router_client = JobRouterClient.from_connection_string(conn_str = connection_string)
router_admin_client = JobRouterAdministrationClient.from_connection_string(conn_str = connection_string)

Distributionsprincip

Innan vi kan skapa en kö behöver vi en distributionsprincip.

from azure.communication.jobrouter.models import (
    LongestIdleMode,
    DistributionPolicy
)

distribution_policy: DistributionPolicy = DistributionPolicy(
    offer_expires_after_seconds = 24 * 60 * 60,
    mode = LongestIdleMode(
        min_concurrent_offers = 1,
        max_concurrent_offers = 1
    )
)

distribution_policy: DistributionPolicy = router_admin_client.upsert_distribution_policy(
    "distribution-policy-1",
    distribution_policy
)

Nu kan vi skapa kön.

from azure.communication.jobrouter.models import (
    RouterQueue
)

queue: RouterQueue = RouterQueue(
    distribution_policy_id = "distribution-policy-1"
)

queue: RouterQueue = router_admin_client.upsert_queue(
    "queue-1",
    queue
)

Jobb

Nu kan vi skicka ett jobb direkt till kön, med en arbetsväljare som kräver att arbetaren har etiketten Some-Skill större än 10.

from azure.communication.jobrouter.models import (
    RouterJob,
    RouterWorkerSelector,
    LabelOperator
)

router_job: RouterJob = RouterJob(
    channel_id = "my-channel",
    queue_id = "queue-1",
    channel_reference = "12345",
    priority = 1,
    requested_worker_selectors = [
        RouterWorkerSelector(key = "Some-Skill", label_operator = LabelOperator.EQUAL, value = 10)
    ]
)

job: RouterJob = router_client.upsert_job(
    "jobId-1",
    router_job
)

Arbetare

Nu registrerar vi en arbetare för att ta emot arbete från kön, med en etikett på Some-Skill lika med 11.

from azure.communication.jobrouter.models import (
    RouterWorker,
    RouterChannel
)

router_worker: RouterWorker = RouterWorker(
    capacity = 1,
    queues = [
        "queue-1"
    ],
    labels = {
        "Some-Skill": 11
    },
    channels = [
        RouterChannel(channel_id = "my-channel", capacity_cost_per_job = 1)
    ],
    available_for_offers = True
)

worker = router_client.upsert_worker(
    "worker-1",
    router_worker
)

Erbjudande

Vi bör hämta en RouterWorkerOfferIssued från vår EventGrid-prenumeration.

Det finns flera olika Azure-tjänster som fungerar som händelsehanterare. I det här scenariot antar vi Webhooks för händelseleverans. Läs mer om leverans av Webhook-händelser

När händelser har levererats till händelsehanteraren kan vi deserialisera JSON-nyttolasten till en lista över händelser.

# Parse the JSON payload into a list of events
from azure.eventgrid import EventGridEvent
import json

## deserialize payload into a list of typed Events
events = [EventGridEvent.from_json(json.loads(msg)) for msg in payload]
offer_id = ""
for event in events:
    if event.event_type == "Microsoft.Communication.RouterWorkerOfferIssued":
        offer_id = event.data.offer_id
    else:
        continue

Men vi kan också vänta några sekunder och sedan fråga arbetaren direkt mot JobRouter-API:et för att se om ett erbjudande har utfärdats till det.

from azure.communication.jobrouter.models import (
    RouterWorker,
)

router_worker: RouterWorker = router_client.get_worker(worker_id = "worker-1")

for offer in router_worker.offers:
    print(f"Worker {router_worker.id} has an active offer for job {offer.job_id}")

Acceptera ett erbjudande

När en arbetare får ett erbjudande kan den vidta två möjliga åtgärder: acceptera eller avvisa. Vi ska acceptera erbjudandet.

from azure.communication.jobrouter.models import (
    RouterJobOffer,
    AcceptJobOfferResult,
    RouterJobStatus
)

# fetching the offer id
job_offer: RouterJobOffer = [offer for offer in router_worker.offers if offer.job_id == "jobId-1"][0]
offer_id = job_offer.offer_id

# accepting the offer sent to `worker-1`
accept_job_offer_result: AcceptJobOfferResult = router_client.accept_job_offer(
    worker_id = "worker-1",
    offer_id = offer_id
)

print(f"Offer: {job_offer.offer_id} sent to worker: {router_worker.id} has been accepted")
print(f"Job has been assigned to worker: {router_worker.id} with assignment: {accept_job_offer_result.assignment_id}")

# verify job assignment is populated when querying job
updated_job = router_client.get_job(job_id = "jobId-1")
print(f"Job assignment has been successful: {updated_job.job_status == RouterJobStatus.Assigned and accept_job_offer_result.assignment_id in updated_job.assignments}")

Slutföra ett jobb

När arbetaren är klar med jobbet måste arbetsarbetaren markera jobbet som completed.

import datetime
from azure.communication.jobrouter.models import (
    CompleteJobOptions
)
complete_job_result = router_client.complete_job(
    "jobId-1",
    accept_job_offer_result.assignment_id,
    CompleteJobOptions(
        note = f"Job has been completed by {router_worker.id} at {datetime.datetime.utcnow()}"
    )
)

print(f"Job has been successfully completed.")

Stänga ett jobb

När ett jobb har slutförts kan arbetaren utföra radbrytningsåtgärder till jobbet innan jobbet stängs och slutligen frigöra sin kapacitet för att acceptera fler inkommande jobb

from azure.communication.jobrouter.models import (
    RouterJob,
    RouterJobStatus,
    CloseJobOptions,
)

close_job_result = router_client.close_job(
    "jobId-1",
    accept_job_offer_result.assignment_id,
    CloseJobOptions(
        note = f"Job has been closed by {router_worker.id} at {datetime.datetime.utcnow()}"
    )
)

print(f"Job has been successfully closed.")

update_job: RouterJob = router_client.get_job(job_id = "jobId-1")
print(f"Updated job status: {update_job.job_status == RouterJobStatus.CLOSED}")
import time
from datetime import datetime, timedelta
from azure.communication.jobrouter.models import (
    RouterJob,
    RouterJobStatus,
    CloseJobOptions,
)

close_job_in_future_result = router_client.close_job(
    "jobId-1",
    accept_job_offer_result.assignment_id,
    CloseJobOptions(
        note = f"Job has been closed by {router_worker.id} at {datetime.utcnow()}",
        close_at = datetime.utcnow() + timedelta(seconds = 2)
    )
)

print(f"Job has been marked to close")
time.sleep(secs = 2)
update_job: RouterJob = router_client.get_job(job_id = "jobId-1")
print(f"Updated job status: {update_job.job_status == RouterJobStatus.CLOSED}")

Felsökning

Stöter du på problem? Det här avsnittet bör innehålla information om vad du ska göra där.

Nästa steg

Mer exempelkod

Ta en titt på exempelkatalogen för detaljerade exempel på hur du använder det här biblioteket.

Ge feedback

Om du stöter på buggar eller har förslag kan du skicka in ett problem i avsnittet Problem i projektet

Bidra

Det här projektet välkomnar bidrag och förslag. Merparten av bidragen kräver att du godkänner ett licensavtal för bidrag, där du deklarerar att du har behörighet att bevilja oss rättigheten att använda ditt bidrag, och att du dessutom uttryckligen gör så. Mer information finns i cla.microsoft.com.

Det här projektet använder sig av Microsofts uppförandekod för öppen källkod. Mer information finns i Vanliga frågor och svar om uppförandekoden eller kontakta opencode@microsoft.com med ytterligare frågor eller kommentarer.