Source code for wxc_sdk.telephony.huntgroup

from collections.abc import Generator
from dataclasses import dataclass
from typing import Optional, Any

from .forwarding import ForwardingApi, FeatureSelector
from .hg_and_cq import HGandCQ, Policy
from ..api_child import ApiChild
from ..base import ApiModel, to_camel
from ..common import AlternateNumber
from ..rest import RestSession

__all__ = ['NoAnswer', 'BusinessContinuity', 'HGCallPolicies', 'HuntGroup', 'HuntGroupApi']


[docs] class NoAnswer(ApiModel): """ Settings for when the call into the hunt group is not answered. """ #: If enabled, advance to next agent after the next_agent_rings has occurred. next_agent_enabled: Optional[bool] = None #: Number of rings before call will be forwarded if unanswered and nextAgentEnabled is true. next_agent_rings: Optional[int] = None #: If true, forwards unanswered calls to the destination after the number of rings occurs. forward_enabled: Optional[bool] = None #: Destination if forward_enabled is True. destination: Optional[str] = None #: Number of rings before forwarding calls if forward_enabled is true. number_of_rings: Optional[int] = None #: System-wide maximum number of rings allowed for number_of_rings setting. system_max_number_of_rings: Optional[int] = None #: If destination_voicemail_enabled is true, enables and disables sending incoming to destination number's #: voicemail if the destination is an internal phone number and that number has the voicemail service enabled. destination_voicemail_enabled: Optional[bool] = None
[docs] @staticmethod def default() -> 'NoAnswer': return NoAnswer(destination_voicemail_enabled=False, forward_enabled=False, next_agent_enabled=False, next_agent_rings=5, number_of_rings=15, system_max_number_of_rings=20)
[docs] class BusinessContinuity(ApiModel): """ Settings for sending calls to a destination of your choice if your phone is not connected to the network for any reason, such as power outage, failed Internet connection, or wiring problem """ #: Divert calls when unreachable, unanswered calls divert to a defined phone number. This could apply to phone #: calls that aren't answered due to a network outage, or all agents of the hunt group are busy and the Advance #: when the busy option is also enabled. For persons only using a mobile device, calls won't be diverted, if there #: is a network outage. enabled: Optional[bool] = None #: Destination for Business Continuity. destination: Optional[str] = None #: Indicates enabled or disabled state of sending diverted incoming calls to the destination number's voicemail if #: the destination is an internal phone number and that number has the voicemail service enabled. destination_voicemail_enabled: Optional[bool] = None
[docs] @staticmethod def default() -> 'BusinessContinuity': return BusinessContinuity(enabled=False, destination_voicemail_enabled=False)
[docs] class HGCallPolicies(ApiModel): """ Policy controlling how calls are routed to agents. """ #: Call routing policy to use to dispatch calls to agents. policy: Optional[Policy] = None #: If false, then the option is treated as "Advance when busy": the hunt group won’t ring agents when they’re on #: a call and will advance to the next agent. If a hunt group agent has call waiting enabled and the call is #: advanced to them, then the call will wait until that hunt group agent isn’t busy. waiting_enabled: Optional[bool] = None #: Settings for when the call into the hunt group is not answered. no_answer: Optional[NoAnswer] = None #: Settings for sending calls to a destination of your choice if your phone is not connected to the network for #: any reason, such as power outage, failed Internet connection, or wiring problem. business_continuity: Optional[BusinessContinuity] = None
[docs] @staticmethod def default() -> 'HGCallPolicies': return HGCallPolicies(policy=Policy.circular, waiting_enabled=False, no_answer=NoAnswer.default(), business_continuity=BusinessContinuity.default())
[docs] class HuntGroup(HGandCQ): """ The huntgroup object """ #: The alternate numbers feature allows you to assign multiple phone numbers or extensions to a hunt group. Each #: number will reach the same greeting and each menu will function identically to the main number. The alternate #: numbers option enables you to have up to ten (10) phone numbers ring into the hunt group. alternate_numbers: Optional[list[AlternateNumber]] = None #: Policy controlling how calls are routed to agents. call_policies: Optional[HGCallPolicies] = None # TODO: undocumented address_agents: Optional[Any] = None #: Whether or not the hunt group can be used as the caller ID when the agent places outgoing calls. hunt_group_caller_id_for_outgoing_calls_enabled: Optional[bool] = None @staticmethod def exclude_update_or_create() -> dict: """ Exclude dict for update or create calls :meta private: :return: dict """ base_exclude = HGandCQ.exclude_update_or_create() base_exclude.update({'call_policies': {'no_answer': {'system_max_number_of_rings': True}}, 'alternate_numbers': {'__all__': {'toll_free_number': True}}, 'address_agents': True}) return base_exclude
[docs] @staticmethod def create(name: str, extension: str = None, phone_number: str = None) -> 'HuntGroup': """ Get minimal hunt group settings that can be used to create a hunt group by calling :meth:`HuntGroupApi.create` with these settings. The hunt group will not have any agents. :param name: Unique name :type name: str :param extension: Extension :type extension: str :param phone_number: Primary phone number :type phone_number: str :return: :class:`HuntGroup` instance """ if not any((extension, phone_number)): raise ValueError('at least one of phone_number or extension has to be set') return HuntGroup(name=name, phone_number=phone_number, extension=extension)
[docs] @dataclass(init=False) class HuntGroupApi(ApiChild, base='telephony/config/huntGroups'): """ Hunt Group API """ forwarding: ForwardingApi def __init__(self, session: RestSession): super().__init__(session=session) self.forwarding = ForwardingApi(session=session, feature_selector=FeatureSelector.huntgroups) def _endpoint(self, *, location_id: str = None, huntgroup_id: str = None) -> str: """ hunt group specific feature endpoint like /v1/telephony/config/locations/{locationId}/huntGroups/{huntGroupId} :meta private: :param location_id: Unique identifier for the location. :type location_id: str :param huntgroup_id: schedule id :type huntgroup_id: str :return: full endpoint :rtype: str """ if location_id is None: return self.session.ep('telephony/config/huntGroups') else: ep = self.session.ep(f'telephony/config/locations/{location_id}/huntGroups') if huntgroup_id: ep = f'{ep}/{huntgroup_id}' return ep
[docs] def list(self, org_id: str = None, location_id: str = None, name: str = None, phone_number: str = None, **params) -> Generator[HuntGroup, None, None]: """ Read the List of Hunt Groups List all calling Hunt Groups for the organization. Hunt groups can route incoming calls to a group of people or workspaces. You can even configure a pattern to route to a whole group. Retrieving this list requires a full or read-only administrator auth token with a scope of spark-admin:telephony_config_read. :param org_id: List hunt groups for this organization. :param location_id: Only return hunt groups with matching location ID. :param name: Only return hunt groups with the matching name. :param phone_number: Only return hunt groups with the matching primary phone number or extension. :return: yields :class:`HuntGroup` instances """ params.update((to_camel(k), v) for i, (k, v) in enumerate(locals().items()) if i and v is not None and k != 'params') url = self._endpoint() # noinspection PyTypeChecker return self.session.follow_pagination(url=url, model=HuntGroup, params=params)
[docs] def by_name(self, name: str, location_id: str = None, org_id: str = None) -> Optional[HuntGroup]: """ Get hunt group info by name :param location_id: :param name: :param org_id: :return: """ return next((hg for hg in self.list(name=name, location_id=location_id, org_id=org_id) if hg.name == name), None)
[docs] def create(self, location_id: str, settings: HuntGroup, org_id: str = None) -> str: """ Create a Hunt Group Create new Hunt Groups for the given location. Hunt groups can route incoming calls to a group of people or workspaces. You can even configure a pattern to route to a whole group. Creating a hunt group requires a full administrator auth token with a scope of spark-admin:telephony_config_write. :param location_id: Create the hunt group for the given location. :type location_id: str :param settings: hunt group details :type settings: :class:`HuntGroup` :param org_id: Create the hunt group for this organization. :type org_id: str :return: ID of the newly created hunt group. :rtype: str """ params = org_id and {'orgId': org_id} or {} settings.call_policies = settings.call_policies or HGCallPolicies().default() data = settings.create_or_update() url = self._endpoint(location_id=location_id) data = self.post(url, data=data, params=params) return data['id']
[docs] def delete_huntgroup(self, location_id: str, huntgroup_id: str, org_id: str = None): """ Delete a Hunt Group Delete the designated Hunt Group. Hunt groups can route incoming calls to a group of people or workspaces. You can even configure a pattern to route to a whole group. Deleting a hunt group requires a full administrator auth token with a scope of spark-admin:telephony_config_write. :param location_id: Location from which to delete a hunt group. :type location_id: str :param huntgroup_id: Delete the hunt group with the matching ID. :type huntgroup_id: str :param org_id: Delete the hunt group with the matching ID. :type org_id: str """ params = org_id and {'orgId': org_id} or None url = self._endpoint(location_id=location_id, huntgroup_id=huntgroup_id) self.delete(url, params=params)
[docs] def details(self, location_id: str, huntgroup_id: str, org_id: str = None) -> HuntGroup: """ Get Details for a Hunt Group Retrieve Hunt Group details. Hunt groups can route incoming calls to a group of people or workspaces. You can even configure a pattern to route to a whole group. Retrieving hunt group details requires a full or read-only administrator auth token with a scope of spark-admin:telephony_config_read. :param location_id: Retrieve settings for a hunt group in this location. :type location_id: str :param huntgroup_id: Retrieve settings for the hunt group with this identifier. :type huntgroup_id: str :param org_id: Retrieve hunt group settings from this organization. :type org_id: str :return: hunt group details """ url = self._endpoint(location_id=location_id, huntgroup_id=huntgroup_id) params = org_id and {'orgId': org_id} or {} data = self.get(url, params=params) result = HuntGroup.model_validate(data) return result
[docs] def update(self, location_id: str, huntgroup_id: str, update: HuntGroup, org_id: str = None): """ Update a Hunt Group Update the designated Hunt Group. Hunt groups can route incoming calls to a group of people or workspaces. You can even configure a pattern to route to a whole group. Updating a hunt group requires a full administrator auth token with a scope of spark-admin:telephony_config_write. :param location_id: Update the hunt group for this location. :type location_id: str :param huntgroup_id: Update setting for the hunt group with the matching ID. :type huntgroup_id: str :param update: hunt group settings :type update: :class:`HuntGroup` :param org_id: Update hunt group settings from this organization. """ params = org_id and {'orgId': org_id} or None data = update.create_or_update() url = self._endpoint(location_id=location_id, huntgroup_id=huntgroup_id) self.put(url, data=data, params=params)