Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions libzapi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from libzapi.application import AgentAvailability
from libzapi.application import AssetManagement
from libzapi.application import ZendeskStatus
from libzapi.application import Voice

__all__ = [
"HelpCenter",
Expand All @@ -12,4 +13,5 @@
"AgentAvailability",
"AssetManagement",
"ZendeskStatus",
"Voice",
]
2 changes: 2 additions & 0 deletions libzapi/application/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from libzapi.application.services.agent_availability import AgentAvailability
from libzapi.application.services.asset_management import AssetManagement
from libzapi.application.services.status import ZendeskStatus
from libzapi.application.services.voice import Voice

__all__ = [
"HelpCenter",
Expand All @@ -12,4 +13,5 @@
"AgentAvailability",
"AssetManagement",
"ZendeskStatus",
"Voice",
]
Empty file.
24 changes: 24 additions & 0 deletions libzapi/application/commands/voice/address_cmds.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from dataclasses import dataclass


@dataclass(frozen=True, slots=True)
class CreateAddressCmd:
city: str
country_code: str
name: str
province: str
street: str
zip: str
state: str = ""
provider_reference: str = ""


@dataclass(frozen=True, slots=True)
class UpdateAddressCmd:
city: str | None = None
country_code: str | None = None
name: str | None = None
province: str | None = None
street: str | None = None
zip: str | None = None
state: str | None = None
8 changes: 8 additions & 0 deletions libzapi/application/commands/voice/availability_cmds.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from dataclasses import dataclass


@dataclass(frozen=True, slots=True)
class UpdateAvailabilityCmd:
agent_state: str | None = None
call_status: str | None = None
via: str | None = None
10 changes: 10 additions & 0 deletions libzapi/application/commands/voice/callback_request_cmds.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from __future__ import annotations

from dataclasses import dataclass, field


@dataclass(frozen=True, slots=True)
class CreateCallbackRequestCmd:
phone_number_id: int
requester_phone_number: str
group_ids: list[int] = field(default_factory=list)
23 changes: 23 additions & 0 deletions libzapi/application/commands/voice/digital_line_cmds.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from __future__ import annotations

from dataclasses import dataclass


@dataclass(frozen=True, slots=True)
class CreateDigitalLineCmd:
nickname: str = ""
line_type: str = ""
brand_id: int | None = None
default_group_id: int | None = None
group_ids: list[int] | None = None


@dataclass(frozen=True, slots=True)
class UpdateDigitalLineCmd:
nickname: str | None = None
default_group_id: int | None = None
group_ids: list[int] | None = None
recorded: bool | None = None
transcription: bool | None = None
schedule_id: int | None = None
priority: int | None = None
13 changes: 13 additions & 0 deletions libzapi/application/commands/voice/greeting_cmds.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from dataclasses import dataclass


@dataclass(frozen=True, slots=True)
class CreateGreetingCmd:
category_id: int
name: str
audio_name: str = ""


@dataclass(frozen=True, slots=True)
class UpdateGreetingCmd:
name: str | None = None
45 changes: 45 additions & 0 deletions libzapi/application/commands/voice/ivr_cmds.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from __future__ import annotations

from dataclasses import dataclass, field


@dataclass(frozen=True, slots=True)
class CreateIvrCmd:
name: str
phone_number_ids: list[int] = field(default_factory=list)


@dataclass(frozen=True, slots=True)
class UpdateIvrCmd:
name: str | None = None
phone_number_ids: list[int] | None = None


@dataclass(frozen=True, slots=True)
class CreateIvrMenuCmd:
name: str
default: bool = False
greeting_id: int | None = None


@dataclass(frozen=True, slots=True)
class UpdateIvrMenuCmd:
name: str | None = None
default: bool | None = None
greeting_id: int | None = None


@dataclass(frozen=True, slots=True)
class CreateIvrRouteCmd:
action: str
keypress: str
options: dict = field(default_factory=dict)
tags: list[str] = field(default_factory=list)


@dataclass(frozen=True, slots=True)
class UpdateIvrRouteCmd:
action: str | None = None
keypress: str | None = None
options: dict | None = None
tags: list[str] | None = None
28 changes: 28 additions & 0 deletions libzapi/application/commands/voice/phone_number_cmds.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from __future__ import annotations

from dataclasses import dataclass


@dataclass(frozen=True, slots=True)
class CreatePhoneNumberCmd:
token: str
nickname: str = ""
address_sid: str | None = None


@dataclass(frozen=True, slots=True)
class UpdatePhoneNumberCmd:
nickname: str | None = None
default_group_id: int | None = None
group_ids: list[int] | None = None
priority: int | None = None
outbound_enabled: bool | None = None
voice_enabled: bool | None = None
sms_enabled: bool | None = None
recorded: bool | None = None
transcription: bool | None = None
greeting_ids: list[int] | None = None
schedule_id: int | None = None
ivr_id: int | None = None
call_recording_consent: str | None = None
failover_number: str | None = None
13 changes: 13 additions & 0 deletions libzapi/application/commands/voice/voice_settings_cmds.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from __future__ import annotations

from dataclasses import dataclass


@dataclass(frozen=True, slots=True)
class UpdateVoiceSettingsCmd:
agent_confirmation_when_forwarding: bool | None = None
agent_wrap_up_after_calls: bool | None = None
maximum_queue_size: int | None = None
maximum_queue_wait_time: int | None = None
only_during_business_hours: bool | None = None
recordings_public: bool | None = None
47 changes: 47 additions & 0 deletions libzapi/application/services/voice/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import libzapi.infrastructure.api_clients.voice as api
from libzapi.application.services.voice.addresses_service import AddressesService
from libzapi.application.services.voice.availabilities_service import AvailabilitiesService
from libzapi.application.services.voice.callback_requests_service import CallbackRequestsService
from libzapi.application.services.voice.digital_lines_service import DigitalLinesService
from libzapi.application.services.voice.greetings_service import GreetingsService
from libzapi.application.services.voice.incremental_exports_service import IncrementalExportsService
from libzapi.application.services.voice.ivr_menus_service import IvrMenusService
from libzapi.application.services.voice.ivr_routes_service import IvrRoutesService
from libzapi.application.services.voice.ivrs_service import IvrsService
from libzapi.application.services.voice.lines_service import LinesService
from libzapi.application.services.voice.phone_numbers_service import PhoneNumbersService
from libzapi.application.services.voice.recordings_service import RecordingsService
from libzapi.application.services.voice.stats_service import StatsService
from libzapi.application.services.voice.voice_settings_service import VoiceSettingsService
from libzapi.infrastructure.http.auth import api_token_headers, oauth_headers
from libzapi.infrastructure.http.client import HttpClient


class Voice:
def __init__(
self, base_url: str, oauth_token: str | None = None, email: str | None = None, api_token: str | None = None
):
if oauth_token:
headers = oauth_headers(oauth_token)
elif email and api_token:
headers = api_token_headers(email, api_token)
else:
raise ValueError("Provide oauth_token or email+api_token")

http = HttpClient(base_url, headers=headers)

# Initialize services
self.phone_numbers = PhoneNumbersService(api.PhoneNumberApiClient(http))
self.digital_lines = DigitalLinesService(api.DigitalLineApiClient(http))
self.lines = LinesService(api.LineApiClient(http))
self.availabilities = AvailabilitiesService(api.AvailabilityApiClient(http))
self.greetings = GreetingsService(api.GreetingApiClient(http))
self.callback_requests = CallbackRequestsService(api.CallbackRequestApiClient(http))
self.stats = StatsService(api.StatsApiClient(http))
self.incremental_exports = IncrementalExportsService(api.IncrementalExportApiClient(http))
self.recordings = RecordingsService(api.RecordingApiClient(http))
self.addresses = AddressesService(api.AddressApiClient(http))
self.voice_settings = VoiceSettingsService(api.VoiceSettingsApiClient(http))
self.ivrs = IvrsService(api.IvrApiClient(http))
self.ivr_menus = IvrMenusService(api.IvrMenuApiClient(http))
self.ivr_routes = IvrRoutesService(api.IvrRouteApiClient(http))
33 changes: 33 additions & 0 deletions libzapi/application/services/voice/addresses_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from __future__ import annotations

from typing import Iterator

from libzapi.application.commands.voice.address_cmds import CreateAddressCmd, UpdateAddressCmd
from libzapi.domain.models.voice.address import Address
from libzapi.infrastructure.api_clients.voice.address_api_client import AddressApiClient


class AddressesService:
def __init__(self, client: AddressApiClient) -> None:
self._client = client

def list_all(self) -> Iterator[Address]:
return self._client.list_all()

def get(self, address_id: int) -> Address:
return self._client.get(address_id=address_id)

def create(
self, city: str, country_code: str, name: str, province: str, street: str, zip: str, **kwargs
) -> Address:
cmd = CreateAddressCmd(
city=city, country_code=country_code, name=name, province=province, street=street, zip=zip, **kwargs
)
return self._client.create(cmd=cmd)

def update(self, address_id: int, **kwargs) -> Address:
cmd = UpdateAddressCmd(**kwargs)
return self._client.update(address_id=address_id, cmd=cmd)

def delete(self, address_id: int) -> None:
self._client.delete(address_id=address_id)
17 changes: 17 additions & 0 deletions libzapi/application/services/voice/availabilities_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from __future__ import annotations

from libzapi.application.commands.voice.availability_cmds import UpdateAvailabilityCmd
from libzapi.domain.models.voice.availability import Availability
from libzapi.infrastructure.api_clients.voice.availability_api_client import AvailabilityApiClient


class AvailabilitiesService:
def __init__(self, client: AvailabilityApiClient) -> None:
self._client = client

def get(self, agent_id: int) -> Availability:
return self._client.get(agent_id=agent_id)

def update(self, agent_id: int, **kwargs) -> Availability:
cmd = UpdateAvailabilityCmd(**kwargs)
return self._client.update(agent_id=agent_id, cmd=cmd)
17 changes: 17 additions & 0 deletions libzapi/application/services/voice/callback_requests_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from __future__ import annotations

from libzapi.application.commands.voice.callback_request_cmds import CreateCallbackRequestCmd
from libzapi.infrastructure.api_clients.voice.callback_request_api_client import CallbackRequestApiClient


class CallbackRequestsService:
def __init__(self, client: CallbackRequestApiClient) -> None:
self._client = client

def create(self, phone_number_id: int, requester_phone_number: str, group_ids: list[int] | None = None) -> dict:
cmd = CreateCallbackRequestCmd(
phone_number_id=phone_number_id,
requester_phone_number=requester_phone_number,
group_ids=group_ids or [],
)
return self._client.create(cmd=cmd)
24 changes: 24 additions & 0 deletions libzapi/application/services/voice/digital_lines_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from __future__ import annotations

from libzapi.application.commands.voice.digital_line_cmds import CreateDigitalLineCmd, UpdateDigitalLineCmd
from libzapi.domain.models.voice.digital_line import DigitalLine
from libzapi.infrastructure.api_clients.voice.digital_line_api_client import DigitalLineApiClient


class DigitalLinesService:
def __init__(self, client: DigitalLineApiClient) -> None:
self._client = client

def get(self, digital_line_id: int) -> DigitalLine:
return self._client.get(digital_line_id=digital_line_id)

def create(self, **kwargs) -> DigitalLine:
cmd = CreateDigitalLineCmd(**kwargs)
return self._client.create(cmd=cmd)

def update(self, digital_line_id: int, **kwargs) -> DigitalLine:
cmd = UpdateDigitalLineCmd(**kwargs)
return self._client.update(digital_line_id=digital_line_id, cmd=cmd)

def delete(self, digital_line_id: int) -> None:
self._client.delete(digital_line_id=digital_line_id)
35 changes: 35 additions & 0 deletions libzapi/application/services/voice/greetings_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from __future__ import annotations

from typing import Iterator

from libzapi.application.commands.voice.greeting_cmds import CreateGreetingCmd, UpdateGreetingCmd
from libzapi.domain.models.voice.greeting import Greeting, GreetingCategory
from libzapi.infrastructure.api_clients.voice.greeting_api_client import GreetingApiClient


class GreetingsService:
def __init__(self, client: GreetingApiClient) -> None:
self._client = client

def list_all(self) -> Iterator[Greeting]:
return self._client.list_all()

def get(self, greeting_id: int) -> Greeting:
return self._client.get(greeting_id=greeting_id)

def create(self, category_id: int, name: str, audio_name: str = "") -> Greeting:
cmd = CreateGreetingCmd(category_id=category_id, name=name, audio_name=audio_name)
return self._client.create(cmd=cmd)

def update(self, greeting_id: int, **kwargs) -> Greeting:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lmeilibr Pessoalmente, não sou muito fã do uso do kwargs para esse tipo de método, seria ideal criar um dataclass com os args de update e um mini parser para validar esses argumentos, assim fica explícito para que usar esse método, quais argumentos e modificações ele suporta sem ter que olhar a doc da zendesk.
(pode ser feito para todos os métodos de update)
(não é algo que quebra ou inibe o merge, apenas uma marcação para uma possível feature).

cmd = UpdateGreetingCmd(**kwargs)
return self._client.update(greeting_id=greeting_id, cmd=cmd)

def delete(self, greeting_id: int) -> None:
self._client.delete(greeting_id=greeting_id)

def list_categories(self) -> Iterator[GreetingCategory]:
return self._client.list_categories()

def get_category(self, category_id: int) -> GreetingCategory:
return self._client.get_category(category_id=category_id)
17 changes: 17 additions & 0 deletions libzapi/application/services/voice/incremental_exports_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from __future__ import annotations

from typing import Iterator

from libzapi.domain.models.voice.call import Call, CallLeg
from libzapi.infrastructure.api_clients.voice.incremental_export_api_client import IncrementalExportApiClient


class IncrementalExportsService:
def __init__(self, client: IncrementalExportApiClient) -> None:
self._client = client

def calls(self, start_time: int) -> Iterator[Call]:
return self._client.calls(start_time=start_time)

def legs(self, start_time: int) -> Iterator[CallLeg]:
return self._client.legs(start_time=start_time)
Loading
Loading