Biblioteka klienta pakietu JobRouter usługi Azure Communication dla języka Python — wersja 1.0.0

Ten pakiet zawiera zestaw SDK języka Python dla Azure Communication Services jobRouter. Dowiedz się więcej o Azure Communication Services tutaj

Kod | źródłowyPakiet (Pypi) | Dokumentacja produktu

Zrzeczenie odpowiedzialności

Obsługa pakietów języka Python zestawu Azure SDK dla języka Python 2.7 została zakończona 01 stycznia 2022 r. Aby uzyskać więcej informacji i pytań, zapoznaj się z artykułem https://github.com/Azure/azure-sdk-for-python/issues/20691

Wprowadzenie

Wymagania wstępne

Do korzystania z tego pakietu potrzebna jest subskrypcja platformy Azure i zasób usługi Communication Service .

Instalowanie pakietu

Zainstaluj bibliotekę klienta usługi Azure Communication JobRouter dla języka Python przy użyciu narzędzia pip:

pip install azure-communication-jobrouter

Kluczowe pojęcia

Zadanie

Zadanie reprezentuje jednostkę pracy, która musi być kierowana do dostępnego procesu roboczego. Rzeczywistym przykładem może być połączenie przychodzące lub czat w kontekście centrum telefonicznego.

Pracownik

Proces roboczy reprezentuje dostawę dostępną do obsługi zadania. Każdy proces roboczy rejestruje się z co najmniej większa liczba kolejek w celu odbierania zadań. Rzeczywistym przykładem może być agent pracujący w centrum telefonicznym.

Kolejka

Kolejka reprezentuje uporządkowaną listę zadań oczekujących na obsłużenie przez proces roboczy. Pracownicy zarejestrują się w kolejce, aby otrzymywać od niej pracę. Rzeczywistym przykładem może być kolejka połączeń w centrum połączeń.

Kanał

Kanał reprezentuje grupowanie zadań według określonego typu. Gdy proces roboczy rejestruje się w celu odbierania pracy, musi również określić, dla których kanałów mogą obsługiwać pracę, oraz ile z nich może obsługiwać współbieżnie. Rzeczywistym przykładem tego może być voice calls lub chats w centrum telefonicznym.

Oferta

Oferta jest rozszerzona przez jobRouter do procesu roboczego w celu obsługi określonego zadania, gdy określa dopasowanie, to powiadomienie jest zwykle dostarczane za pośrednictwem usługi EventGrid. Proces roboczy może zaakceptować lub odrzucić ofertę przy użyciu interfejsu API JobRouter lub wygaśnie zgodnie z czasem wygaśnięcia skonfigurowanym w zasadach dystrybucji. Rzeczywistym przykładem może być dzwonienie agenta w centrum telefonicznym.

Zasady dystrybucji

Zasady dystrybucji reprezentują zestaw konfiguracji, który określa sposób dystrybucji zadań w kolejce do procesów roboczych zarejestrowanych w tej kolejce. Ta konfiguracja obejmuje, jak długo oferta jest prawidłowa przed wygaśnięciem, oraz tryb dystrybucji, który definiuje kolejność, w której pracownicy są wybierani, gdy istnieje wiele dostępnych.

Tryb dystrybucji

3 typy trybów to

  • Round Robin: Pracownicy są uporządkowane przez Id i następny pracownik po poprzedniej, która dostała ofertę, jest wybierana.
  • Najdłuższa bezczynność: pracownik, który nie pracował nad pracą najdłużej.
  • Najlepszy proces roboczy: możesz określić wyrażenie, aby porównać 2 procesy robocze, aby określić, który z nich chcesz wybrać.

Etykiety

Etykiety można dołączać do procesów roboczych, zadań i kolejek. Są to pary wartości klucza, które mogą być stringtypami danych lub boolean . number Rzeczywistym przykładem może być poziom umiejętności określonego pracownika lub zespołu lub lokalizacji geograficznej.

Selektory etykiet

Selektory etykiet można dołączyć do zadania w celu kierowania podzestawu procesów roboczych obsługujących kolejkę. Rzeczywistym przykładem może być warunek połączenia przychodzącego, który agent musi mieć minimalny poziom wiedzy na temat określonego produktu.

Zasady klasyfikacji

Zasady klasyfikacji mogą służyć do dynamicznego wybierania kolejki, określania priorytetu zadania i dołączania selektorów etykiet procesu roboczego do zadania przy użyciu aparatu reguł.

Zasady wyjątków

Zasady wyjątku steruje zachowaniem zadania na podstawie wyzwalacza i wykonuje żądaną akcję. Zasady wyjątków są dołączane do kolejki, dzięki czemu mogą kontrolować zachowanie zadań w kolejce.

Przykłady

Inicjowanie klienta

Aby zainicjować klienta programu SMS, można użyć parametry połączenia do utworzenia wystąpienia. Alternatywnie można również użyć uwierzytelniania usługi Active Directory przy użyciu opcji 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)

Zasady dystrybucji

Przed utworzeniem kolejki potrzebujemy zasad dystrybucji.

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
)

Kolejka

Następnie możemy utworzyć kolejkę.

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
)

Zadanie

Teraz możemy przesłać zadanie bezpośrednio do tej kolejki, a selektor procesu roboczego wymaga, aby pracownik miał etykietę Some-Skill większą niż 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
)

Pracownik

Teraz rejestrujemy proces roboczy w celu odbierania pracy z tej kolejki z etykietą Some-Skill równą 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
)

Oferta

Powinniśmy uzyskać routerWorkerOfferIssued z subskrypcji EventGrid.

Istnieje kilka różnych usług platformy Azure, które działają jako procedura obsługi zdarzeń. W tym scenariuszu przyjmiemy elementy webhook do dostarczania zdarzeń. Dowiedz się więcej na temat dostarczania zdarzeń elementu webhook

Po dostarczeniu zdarzeń do procedury obsługi zdarzeń możemy deserializacji ładunku JSON do listy zdarzeń.

# 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

Możemy jednak również poczekać kilka sekund, a następnie wysłać zapytanie do procesu roboczego bezpośrednio względem interfejsu API JobRouter, aby sprawdzić, czy oferta została mu wydana.

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

Akceptowanie oferty

Gdy pracownik otrzyma ofertę, może wykonać dwie możliwe akcje: akceptowanie lub odrzucanie. Zaakceptujemy ofertę.

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

Kończenie zadania

Po zakończeniu pracy procesu roboczego proces roboczy musi oznaczyć zadanie jako 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.")

Zamykanie zadania

Po zakończeniu zadania proces roboczy może wykonać czynności podsumowujące zadanie przed zamknięciem zadania, a na koniec zwolnić jego pojemność, aby zaakceptować więcej zadań przychodzących

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

Rozwiązywanie problemów

Występują problemy? Ta sekcja powinna zawierać szczegółowe informacje dotyczące tego, co tam zrobić.

Następne kroki

Więcej przykładów kodu

Zapoznaj się z katalogiem samples , aby zapoznać się ze szczegółowymi przykładami użycia tej biblioteki.

Przekazywanie opinii

Jeśli wystąpią jakiekolwiek usterki lub sugestie, zgłoś problem w sekcji Problemy w projekcie

Współtworzenie

W tym projekcie zachęcamy do współtworzenia i zgłaszania sugestii. Współtworzenie w większości przypadków wymaga zgody na umowę licencyjną dotyczącą współautorów (CLA, Contributor License Agreement), zgodnie z którą współautor ma prawo udzielić i faktycznie udziela nam praw do używania wytworzonej przez siebie zawartości. Aby uzyskać szczegółowe informacje, odwiedź stronę cla.microsoft.com.

W tym projekcie przyjęto Kodeks postępowania oprogramowania Open Source firmy Microsoft. Aby uzyskać więcej informacji, zobacz Często zadawane pytania dotyczące kodeksu postępowania lub skontaktuj się z opencode@microsoft.com dodatkowymi pytaniami lub komentarzami.