From ab1a49f6b0891eaea13cb3dcb17cf6b9ad05322f Mon Sep 17 00:00:00 2001 From: Jordan Prescott Date: Wed, 4 Sep 2024 14:25:35 +0100 Subject: [PATCH 01/17] feature set up for dev - Added to scripts folder - Updated __init__ - Write docstring for metho --- odins_spear/scripter.py | 29 +++++++++++++++++++++++++++- odins_spear/scripts/__init__.py | 4 +++- odins_spear/scripts/webex_builder.py | 26 +++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 odins_spear/scripts/webex_builder.py diff --git a/odins_spear/scripter.py b/odins_spear/scripter.py index 20995d1..48fab01 100644 --- a/odins_spear/scripter.py +++ b/odins_spear/scripter.py @@ -185,4 +185,31 @@ def service_provider_trunking_capacity(self, service_provider_id: str): JSON: JSON data of Trunking Call Capacity details of SP/ ENT, Groups, and Trunk Groups. """ return scripts.service_provider_trunking_capacity.main(self.api, service_provider_id) - \ No newline at end of file + + + def webex_builder(self, service_provider_id: str, group_id: str, user_id: str, + device_type: str, email:str, primary_device: bool =True, + webex_feature_pack_name: str =None, enable_integrated_imp: bool =True): + """Builds a Webex device and assigns to user either as the primary device or a + Shared Call Appearance. + + Args: + service_provider_id (str): Service Provider ID where group is hosted. + group_id (str): Group ID where target user is hosted. + user_id (str): Target user to build and add webex device. + device_type (str): Name of the device profile to apply. + email (str): Email of user. This will be used to sign into the webex client. + primary_device (bool, optional): Setting to False will assign as SCA, True is primary. Defaults to True. + webex_feature_pack_name (str, optional): Feature pack to assign for Webex services. Defaults to None. + enable_integrated_imp (bool, optional): Enables Integrated IMP service for the user if True .Defaults to True. + + Returns: + dict: Webex user/ device details. Includes webex client username and password, and if primary device + device type set. + + Raises: + OSLicenseNonExistent: Raised if user does not have correct license which allows for SCA devices. + """ + + return scripts.webex_builder.main(self.api, service_provider_id, group_id, user_id, device_type, + email, primary_device, webex_feature_pack_name) \ No newline at end of file diff --git a/odins_spear/scripts/__init__.py b/odins_spear/scripts/__init__.py index dadde3b..171649d 100644 --- a/odins_spear/scripts/__init__.py +++ b/odins_spear/scripts/__init__.py @@ -9,7 +9,8 @@ "service_pack_audit", "service_provider_trunking_capacity", "user_activity", - "user_association" + "user_association", + "webex_builder" ] from .aa_cc_hg_audit import main @@ -23,3 +24,4 @@ from .service_provider_trunking_capacity import main from .user_activity import main from .user_association import main +from .webex_builder import main diff --git a/odins_spear/scripts/webex_builder.py b/odins_spear/scripts/webex_builder.py new file mode 100644 index 0000000..9c756e8 --- /dev/null +++ b/odins_spear/scripts/webex_builder.py @@ -0,0 +1,26 @@ + +def main(): + + # 1. update the email - KB + + # 2. update alt user id - KB + + # 3. assign feature pack - OC + + # 4. enable IMP in service settings (Micheal Clarke 04.09.24) - MC + + # 5. build device - OC + + # 6. add device to user based on primary flag - JP + + # 7. get webex password - JP + + # 8. return formatted data + ''' + username - webex + password - webex + primary_device + device_type + ''' + + pass \ No newline at end of file From d52bc01802730a48bc5c663d1180574ac3bbe901 Mon Sep 17 00:00:00 2001 From: Jordan Prescott Date: Wed, 4 Sep 2024 14:27:21 +0100 Subject: [PATCH 02/17] missed webex --- odins_spear/scripts/webex_builder.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/odins_spear/scripts/webex_builder.py b/odins_spear/scripts/webex_builder.py index 9c756e8..9ebf4c8 100644 --- a/odins_spear/scripts/webex_builder.py +++ b/odins_spear/scripts/webex_builder.py @@ -1,5 +1,7 @@ -def main(): + +def main(api, service_provider_id, group_id, user_id, device_type, + email, primary_device, webex_feature_pack_name): # 1. update the email - KB From fab66762d610f1873a9bbf5c5e3b2a35f8d190d2 Mon Sep 17 00:00:00 2001 From: Malkin0xb Date: Fri, 6 Sep 2024 12:51:55 +0100 Subject: [PATCH 03/17] Added get user_service_settings() and put user_service_settings() PUT user_service_settings requires a dictionary of changes that's passed through to update settings. For examples: https://doc.odinapi.net/#95bdfa78-9ba1-4c31-b7e8-6b4d5a1d37ff --- odins_spear/methods/get.py | 18 ++++++++++++++++++ odins_spear/methods/put.py | 22 +++++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/odins_spear/methods/get.py b/odins_spear/methods/get.py index 3f9dc29..467d1f3 100644 --- a/odins_spear/methods/get.py +++ b/odins_spear/methods/get.py @@ -1272,6 +1272,24 @@ def user_services(self, user_id: str): return self.requester.get(endpoint, params=params) + def user_service_settings(self, user_id: str): + """Retrieves all service settings for a specific user. + + Args: + user_id (str): ID of the target user + + Returns: + Dict: A dictionary containing all the service settings for the specified user. + """ + + endpoint = f"/users/services/settings" + + params = { + "userId": user_id + } + + return self.requester.get(endpoint, params=params) + def group_services(self, group_id: str, service_provider_id: str): """ Fetch all userServices, groupServices and servicePackServices assigned to a group. diff --git a/odins_spear/methods/put.py b/odins_spear/methods/put.py index f017ef0..4cb8d44 100644 --- a/odins_spear/methods/put.py +++ b/odins_spear/methods/put.py @@ -1032,9 +1032,29 @@ def user_services(self, user_id: str, services: list =None, service_packs: list data["userServices"] = [{'serviceName': service, 'assigned': assigned} for service in services] if service_packs: data["servicePackServices"] = [{'serviceName': service_pack, 'assigned': assigned} for service_pack in service_packs] - + print(data) return self.requester.put(endpoint, data=data) + def user_service_settings(self, user_id: str, settings: dict): + """Updates specific service settings for a given user. + This function allows you to modify one or more service settings associated with a particular user. + + Args: + user_id (str): The ID of the target user + settings (dict): A dictionary containing the new settings to be applied. The structure of this dictionary should mirror the API's expected format for updating service settings. + + Returns: + Dict: A dictionary representing the updated service settings for the specified user. + """ + + endpoint = f"/users/services/settings" + + data = { + "userId": user_id, + **settings + } + + return self.requester.put(endpoint, data=data) #SHARED CALL APPEARANCE #SILENT ALERTING From 74914970e3dcbc4420d1e8b50f68da5097acbdb3 Mon Sep 17 00:00:00 2001 From: Malkin0xb Date: Fri, 6 Sep 2024 12:52:48 +0100 Subject: [PATCH 04/17] Removed left-over testing artifact --- odins_spear/methods/put.py | 1 - 1 file changed, 1 deletion(-) diff --git a/odins_spear/methods/put.py b/odins_spear/methods/put.py index 4cb8d44..d6e5692 100644 --- a/odins_spear/methods/put.py +++ b/odins_spear/methods/put.py @@ -1032,7 +1032,6 @@ def user_services(self, user_id: str, services: list =None, service_packs: list data["userServices"] = [{'serviceName': service, 'assigned': assigned} for service in services] if service_packs: data["servicePackServices"] = [{'serviceName': service_pack, 'assigned': assigned} for service_pack in service_packs] - print(data) return self.requester.put(endpoint, data=data) def user_service_settings(self, user_id: str, settings: dict): From f695a7cdc66bd405f2044800663cd4e128763b65 Mon Sep 17 00:00:00 2001 From: Malkin0xb Date: Mon, 9 Sep 2024 13:41:21 +0100 Subject: [PATCH 05/17] Enable IMP in webex_builder.py --- odins_spear/scripts/webex_builder.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/odins_spear/scripts/webex_builder.py b/odins_spear/scripts/webex_builder.py index 9ebf4c8..786a6f5 100644 --- a/odins_spear/scripts/webex_builder.py +++ b/odins_spear/scripts/webex_builder.py @@ -10,6 +10,8 @@ def main(api, service_provider_id, group_id, user_id, device_type, # 3. assign feature pack - OC # 4. enable IMP in service settings (Micheal Clarke 04.09.24) - MC + enableIMP = {'Integrated IMP': {'isActive': True}} + magic.put.user_service_settings(user_id=user_id, settings=enableIMP) # 5. build device - OC From 49a5575582a5bb88da84c12caa05043de6eeb51e Mon Sep 17 00:00:00 2001 From: Jordan Prescott Date: Mon, 9 Sep 2024 16:08:49 +0100 Subject: [PATCH 06/17] completed section 7 and started 6 --- odins_spear/scripts/webex_builder.py | 41 ++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/odins_spear/scripts/webex_builder.py b/odins_spear/scripts/webex_builder.py index 786a6f5..c77ac50 100644 --- a/odins_spear/scripts/webex_builder.py +++ b/odins_spear/scripts/webex_builder.py @@ -3,6 +3,22 @@ def main(api, service_provider_id, group_id, user_id, device_type, email, primary_device, webex_feature_pack_name): + DEVICE_NAME = f"{user_id.split('@')[0]}_WBX" + WEBEX_DEVICE_CONFIGURATION = { + "endpointType": "accessDeviceEndpoint", +` "accessDeviceEndpoint": { + "accessDevice": { + "deviceType": device_type, + "deviceName": f"{user_id.split('@')[0]}_WBX", + "serviceProviderId": service_provider_id, + "groupId": group_id, + "deviceLevel": "Group", + }, + "linePort": user_id, + } +} +` + # 1. update the email - KB # 2. update alt user id - KB @@ -11,20 +27,27 @@ def main(api, service_provider_id, group_id, user_id, device_type, # 4. enable IMP in service settings (Micheal Clarke 04.09.24) - MC enableIMP = {'Integrated IMP': {'isActive': True}} - magic.put.user_service_settings(user_id=user_id, settings=enableIMP) + api.put.user_service_settings(user_id=user_id, settings=enableIMP) # 5. build device - OC + device_name = f"{user_id.split('@')[0]}_WBX_{device_type.upper()}" # 6. add device to user based on primary flag - JP + # + if primary_device: + pass + # 7. get webex password - JP + password = api.get.passwords_generate(service_provider_id, group_id)["password"] + api.put.user_web_authentication_password(user_id, password) # 8. return formatted data - ''' - username - webex - password - webex - primary_device - device_type - ''' - - pass \ No newline at end of file + webex_user_details = { + "username": email, + "password": password, + "primary_device": primary_device, + "device_type": device_type + } + + return webex_user_details \ No newline at end of file From a6f115d199c552530b3ff4e8d1e9abcddab8b148 Mon Sep 17 00:00:00 2001 From: Jordan Prescott Date: Tue, 10 Sep 2024 09:34:19 +0100 Subject: [PATCH 07/17] sections complete - added post sca method - completed logic for primary for sca --- odins_spear/methods/post.py | 27 ++++++++ odins_spear/scripts/webex_builder.py | 100 ++++++++++++++------------- 2 files changed, 78 insertions(+), 49 deletions(-) diff --git a/odins_spear/methods/post.py b/odins_spear/methods/post.py index 491acac..948bf57 100644 --- a/odins_spear/methods/post.py +++ b/odins_spear/methods/post.py @@ -389,6 +389,33 @@ def group_hunt_groups_remove_user(self, service_provider_id: str, group_id: str, #SERVICE PROVIDERS #SERVICES #SHARED CALL APPEARANCE + + def user_shared_call_appearance_endpoint(self, user_id: str, line_port: str, device_name): + """Creates a new Shared Call Apprance (SCA) on a single user. + + Args: + user_id (str): Target user id of user to create SCA on. + line_port (str): Line port to be assigned to the new SCA. + device_name (_type_): Device to add for SCA from available devices. + + Returns: + dict: New SCA details applied to user. + """ + + endpoint = "/users/shared-call-appearance/endpoints" + + data = { + "userId":user_id, + "linePort":line_port, + "isActive":True, + "allowOrigination":True, + "allowTermination":True, + "deviceName":device_name, + "deviceLevel":"Group" + } + + return self.requester.post(endpoint, data=data) + #SILENT ALERTING #SIMULTANEOUS RING PERSONAL #SMARTY ADDRESS diff --git a/odins_spear/scripts/webex_builder.py b/odins_spear/scripts/webex_builder.py index c77ac50..779a46c 100644 --- a/odins_spear/scripts/webex_builder.py +++ b/odins_spear/scripts/webex_builder.py @@ -2,52 +2,54 @@ def main(api, service_provider_id, group_id, user_id, device_type, email, primary_device, webex_feature_pack_name): - - DEVICE_NAME = f"{user_id.split('@')[0]}_WBX" - WEBEX_DEVICE_CONFIGURATION = { - "endpointType": "accessDeviceEndpoint", -` "accessDeviceEndpoint": { - "accessDevice": { - "deviceType": device_type, - "deviceName": f"{user_id.split('@')[0]}_WBX", - "serviceProviderId": service_provider_id, - "groupId": group_id, - "deviceLevel": "Group", - }, - "linePort": user_id, - } -} -` - - # 1. update the email - KB - - # 2. update alt user id - KB - - # 3. assign feature pack - OC - - # 4. enable IMP in service settings (Micheal Clarke 04.09.24) - MC - enableIMP = {'Integrated IMP': {'isActive': True}} - api.put.user_service_settings(user_id=user_id, settings=enableIMP) - - # 5. build device - OC - device_name = f"{user_id.split('@')[0]}_WBX_{device_type.upper()}" - - # 6. add device to user based on primary flag - JP - # - if primary_device: - pass - - - # 7. get webex password - JP - password = api.get.passwords_generate(service_provider_id, group_id)["password"] - api.put.user_web_authentication_password(user_id, password) - - # 8. return formatted data - webex_user_details = { - "username": email, - "password": password, - "primary_device": primary_device, - "device_type": device_type - } - - return webex_user_details \ No newline at end of file + + DEVICE_NAME = f"{user_id.split('@')[0]}_WBX" + + # 1. update the email - KB + + # 2. update alt user id - KB + + # 3. assign feature pack - OC + + # 4. enable IMP in service settings (Micheal Clarke 04.09.24) - MC + enableIMP = {'Integrated IMP': {'isActive': True}} + api.put.user_service_settings(user_id=user_id, settings=enableIMP) + + # 5. build device - OC + + # 6. add device to user based on primary flag - JP + if primary_device: + primary_device_configuration = { + "endpointType": "accessDeviceEndpoint", + "accessDeviceEndpoint": { + "accessDevice": { + "deviceType": device_type, + "deviceName": f"{user_id.split('@')[0]}_WBX", + "serviceProviderId": service_provider_id, + "groupId": group_id, + "deviceLevel": "Group", + }, + "linePort": user_id, + } + } + api.put.user(service_provider_id, group_id, user_id, primary_device_configuration) + else: + api.post.user_shared_call_appearance_endpoint( + user_id, + user_id.replace("@", "_WBX@"), + DEVICE_NAME + ) + + # 7. get webex password - JP + password = api.get.passwords_generate(service_provider_id, group_id)["password"] + api.put.user_web_authentication_password(user_id, password) + + # 8. return formatted data + webex_user_details = { + "username": email, + "password": password, + "primary_device": primary_device, + "device_type": device_type + } + + return webex_user_details \ No newline at end of file From cff8ad066274adcedb2ff1296226589aec509c4b Mon Sep 17 00:00:00 2001 From: CHOPP3D <64507146+Chopped4Life@users.noreply.github.com> Date: Tue, 10 Sep 2024 13:50:17 +0100 Subject: [PATCH 08/17] Update webex_builder.py --- odins_spear/scripts/webex_builder.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/odins_spear/scripts/webex_builder.py b/odins_spear/scripts/webex_builder.py index 779a46c..460c83d 100644 --- a/odins_spear/scripts/webex_builder.py +++ b/odins_spear/scripts/webex_builder.py @@ -11,6 +11,22 @@ def main(api, service_provider_id, group_id, user_id, device_type, # 3. assign feature pack - OC + + api.put.user( + service_provider_id, + group_id, + user_id, + { + "emailAddress": email, + "alternateUserId": [ + { + "alternateUserId": alternateid, + "description": description + } + ] + } + ) + # 4. enable IMP in service settings (Micheal Clarke 04.09.24) - MC enableIMP = {'Integrated IMP': {'isActive': True}} api.put.user_service_settings(user_id=user_id, settings=enableIMP) From 02233f25bd8c6f8302d875424f6c69759cf0f5e5 Mon Sep 17 00:00:00 2001 From: CHOPP3D <64507146+Chopped4Life@users.noreply.github.com> Date: Tue, 10 Sep 2024 13:53:19 +0100 Subject: [PATCH 09/17] Update webex_builder.py --- odins_spear/scripts/webex_builder.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/odins_spear/scripts/webex_builder.py b/odins_spear/scripts/webex_builder.py index 460c83d..35e01ff 100644 --- a/odins_spear/scripts/webex_builder.py +++ b/odins_spear/scripts/webex_builder.py @@ -5,12 +5,7 @@ def main(api, service_provider_id, group_id, user_id, device_type, DEVICE_NAME = f"{user_id.split('@')[0]}_WBX" - # 1. update the email - KB - - # 2. update alt user id - KB - - # 3. assign feature pack - OC - + # 1 update the email & 2. update alt user id - KB api.put.user( service_provider_id, @@ -26,6 +21,7 @@ def main(api, service_provider_id, group_id, user_id, device_type, ] } ) + # 3. assign feature pack - OC # 4. enable IMP in service settings (Micheal Clarke 04.09.24) - MC enableIMP = {'Integrated IMP': {'isActive': True}} From c6c5ef3e8ae4a9cae5e7cd1265f3c02f982bd505 Mon Sep 17 00:00:00 2001 From: Jordan Prescott Date: Tue, 17 Sep 2024 14:36:20 +0100 Subject: [PATCH 10/17] docs updated --- .../hunt-groups/delete-group-hunt-group.md | 66 ++ .../get-group-hunt-groups-available-users.md | 66 ++ .../post-group-hunt-groups-remove-user.md | 39 ++ .../services/get-user-service-settings.md | 42 ++ .../services/put-user-service-settings.md | 572 ++++++++++++++++++ .../methods/shared-call-appearance/README.md | 3 + .../post-user-shared-call-appearance-endpoint | 33 + odins_spear/scripts/webex_builder.py | 4 +- 8 files changed, 823 insertions(+), 2 deletions(-) create mode 100644 docs/docs/methods/hunt-groups/delete-group-hunt-group.md create mode 100644 docs/docs/methods/hunt-groups/get-group-hunt-groups-available-users.md create mode 100644 docs/docs/methods/hunt-groups/post-group-hunt-groups-remove-user.md create mode 100644 docs/docs/methods/services/get-user-service-settings.md create mode 100644 docs/docs/methods/services/put-user-service-settings.md create mode 100644 docs/docs/methods/shared-call-appearance/README.md create mode 100644 docs/docs/methods/shared-call-appearance/post-user-shared-call-appearance-endpoint diff --git a/docs/docs/methods/hunt-groups/delete-group-hunt-group.md b/docs/docs/methods/hunt-groups/delete-group-hunt-group.md new file mode 100644 index 0000000..8638fb3 --- /dev/null +++ b/docs/docs/methods/hunt-groups/delete-group-hunt-group.md @@ -0,0 +1,66 @@ +--- +description: my_api.delete.group_hunt_group() +--- + +# ๐Ÿ’” DELETE - Group Hunt Group + +Deletes the specified hunt group. + +### Parameters + +* service_user_id (str): The service user ID of the hunt group to be deleted. + +### Returns + +* Dict: Profile of the deleted hunt group. + +### How To Use: + +{% code overflow="wrap" %} +```python +from odins_spear import api + +my_api= api.Api(base_url="https://base_url/api/vx", username="john.smith", password="ODIN_INSTANCE_1") +my_api.authenticate() + +my_api.delete.group_hunt_group( + service_user_id = "test_hunt_groupd@domain.com" +) +``` +{% endcode %} + +### Example Returned Data (Formatted) +```json +{ + "serviceInstanceProfile": { + "name": "test_hunt_group", + "callingLineIdLastName": "Hunt Group", + "callingLineIdFirstName": "Test", + "hiraganaLastName": "Hunt Group", + "hiraganaFirstName": "Test", + "language": "English", + "timeZone": "Europe/London", + "timeZoneDisplayName": "(GMT+01:00) Greenwich Mean Time", + "aliases": [] + }, + "policy": "Regular", + "huntAfterNoAnswer": False, + "noAnswerNumberOfRings": 5, + "forwardAfterTimeout": False, + "forwardTimeoutSeconds": 10, + "allowCallWaitingForAgents": False, + "useSystemHuntGroupCLIDSetting": True, + "includeHuntGroupNameInCLID": True, + "enableNotReachableForwarding": False, + "makeBusyWhenNotReachable": False, + "allowMembersToControlGroupBusy": False, + "enableGroupBusy": False, + "applyGroupBusyWhenTerminatingToAgent": False, + "serviceUserId": "test_hunt_group@domain.com", + "resellerId": None, + "serviceProviderId": "ExampleServiceProvider", + "groupId": "ExampleGroup", + "isEnterprise": True, + "agents": [] +} +``` diff --git a/docs/docs/methods/hunt-groups/get-group-hunt-groups-available-users.md b/docs/docs/methods/hunt-groups/get-group-hunt-groups-available-users.md new file mode 100644 index 0000000..5106061 --- /dev/null +++ b/docs/docs/methods/hunt-groups/get-group-hunt-groups-available-users.md @@ -0,0 +1,66 @@ +--- +description: my_api.get.group_hunt_groups_available_users() +--- + +# ๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง GET - Group Hunt Groups Available Users + +Deletes the specified hunt group. + +### Parameters + +* service_user_id (str): The service user ID of the hunt group to be deleted. + +### Returns + +* Dict: Profile of the deleted hunt group. + +### How To Use: + +{% code overflow="wrap" %} +```python +from odins_spear import api + +my_api= api.Api(base_url="https://base_url/api/vx", username="john.smith", password="ODIN_INSTANCE_1") +my_api.authenticate() + +my_api.get.group_hunt_groups_available_users( + service_user_id="test_hgd@domain.com" +) +``` +{% endcode %} + +### Example Returned Data (Formatted) +```json +{ + "serviceInstanceProfile": { + "name": "test_hg", + "callingLineIdLastName": "hg", + "callingLineIdFirstName": "test", + "hiraganaLastName": "test_hg", + "hiraganaFirstName": "Hunt Group", + "language": "English", + "timeZone": "Europe/London", + "timeZoneDisplayName": "(GMT+01:00) Greenwich Mean Time", + "aliases": [] + }, + "policy": "Regular", + "huntAfterNoAnswer": false, + "noAnswerNumberOfRings": 5, + "forwardAfterTimeout": false, + "forwardTimeoutSeconds": 10, + "allowCallWaitingForAgents": false, + "useSystemHuntGroupCLIDSetting": true, + "includeHuntGroupNameInCLID": true, + "enableNotReachableForwarding": false, + "makeBusyWhenNotReachable": false, + "allowMembersToControlGroupBusy": false, + "enableGroupBusy": false, + "applyGroupBusyWhenTerminatingToAgent": false, + "serviceUserId": "test_hg@domain.com", + "resellerId": null, + "serviceProviderId": "Example Service Provider ID", + "groupId": "Example Group ID", + "isEnterprise": true, + "agents": [] +} +``` diff --git a/docs/docs/methods/hunt-groups/post-group-hunt-groups-remove-user.md b/docs/docs/methods/hunt-groups/post-group-hunt-groups-remove-user.md new file mode 100644 index 0000000..8f5e100 --- /dev/null +++ b/docs/docs/methods/hunt-groups/post-group-hunt-groups-remove-user.md @@ -0,0 +1,39 @@ +--- +description: my_api.post.group_hunt_groups_remove_user() +--- + +# ๐Ÿ‘‹ POST - Group Hunt Groups Remove User + +Removes the specified user from all hunt groups in which it currently exists. + +### Parameters + +* service_provider_id (str): The service provider ID in which the target user exists. +* group_id (str): The group ID where the user exists. +* user_id (str): The User ID of the user that is to be removed from the hunt group(s). + +### Returns + +* List: Service user ID's (str) of the hunt groups from which the specified user has been removed. + +### How To Use: + +{% code overflow="wrap" %} +```python +from odins_spear import api + +my_api= api.Api(base_url="https://base_url/api/vx", username="john.smith", password="ODIN_INSTANCE_1") +my_api.authenticate() + +my_api.post.group_hunt_groups_remove_user( + service_provider_id = "Test Service Provider ID", + group_id = "Test Group ID", + user_id = "test_user@domain.com" +) +``` +{% endcode %} + +### Example Returned Data (Formatted) +```json +["test_hunt_group_1@domain.com", "test_hunt_group2@domain.com"] +``` diff --git a/docs/docs/methods/services/get-user-service-settings.md b/docs/docs/methods/services/get-user-service-settings.md new file mode 100644 index 0000000..f667090 --- /dev/null +++ b/docs/docs/methods/services/get-user-service-settings.md @@ -0,0 +1,42 @@ +--- +description: my_api.get.user_service_settings() +--- + +# โš™๏ธ GET - User Service Settings + +This method grabs all of a Broadwork entity's service settings. + +### Parameters + +* user\_id (str): User ID of the target Broadworks entity. + +### Returns + +* Dict: Broadworks entity and all service settings. + +### How To Use: + +```python +from odins_spear import api + +my_api= api.Api(base_url="https://base_url/api/vx", username="john.smith", password="ODIN_INSTANCE_1") +my_api.authenticate() + +# updating a users service pack +my_api.get.user_service_settings( + "userId@domain.com" +) +``` +{% endcode %} + +### Example Data Returned (Formatted) +```json +{ + "userId": "user@odinapi.net", + "Advice Of Charge": { + "isActive": false, + "aocType": "During Call" + } +} +``` +``` \ No newline at end of file diff --git a/docs/docs/methods/services/put-user-service-settings.md b/docs/docs/methods/services/put-user-service-settings.md new file mode 100644 index 0000000..bab9551 --- /dev/null +++ b/docs/docs/methods/services/put-user-service-settings.md @@ -0,0 +1,572 @@ +--- +description: my_api.put.user_service_settings() +--- + +# โš™๏ธ PUT - User Service Settings + +This method updates a Broadwork entity's service settings. This uses a dicitonary as an input to apply changes, the structure of this dictionary should mirror the API's expected format for updating service settings. + +For more information and other examples please visit [here](https://doc.odinapi.net/#95bdfa78-9ba1-4c31-b7e8-6b4d5a1d37ff) + +Most broadworks User Service Settings have varying options and choices that can be made: + +```JSON +"Call Forwarding Busy": {"isActive": false, "forwardToPhoneNumber": 12314} +``` + +```JSON +"Call Forwarding Selective": {"isActive": false,"playRingReminder": false,"criteria": []} +``` + +Here you can see the differences between two similar services. To update settings using this function you must follow this structure. + +You can either follow the link above for examples, or see the exmaple responses below to copy and paste the format. Otherwise, you can also use the output of get.user_service_settings(). + +### Parameters + +* user\_id (str): User ID of the target Broadworks entity. +* settings (dict): A dictionary containing the new settings to be applied. + +### Returns + +* Dict: A dictionary representing the updated service settings for the specified user. + +### How To Use: + +```python +from odins_spear import api + +my_api= api.Api(base_url="https://base_url/api/vx", username="john.smith", password="ODIN_INSTANCE_1") +my_api.authenticate() + +# Enabling Call Forward Always to ext 1509 + +settings = {"Call Forwarding Always": {"isActive": false, "forwardToPhoneNumber": 1509}} + +# Enabling Call Forward Not Reachable to 1509 after 20 rings + +settings = {'Call Forwarding No Answer': {'isActive': True, 'numberOfRings': 20, 'forwardToPhoneNumber': 1509}} + +my_api.put.user_service_settings( + "userId@domain.com", + settings +) +``` +{% endcode %} + +### Example Data Returned (Formatted) +```json +{ + "userId": "9871515000@odinapi.net", + "Advice Of Charge": { + "isActive": false, + "aocType": "During Call" + }, + "Alternate Numbers": { + "distinctiveRing": true, + "alternateEntries": [ + { + "phoneNumber": null, + "extension": null, + "ringPattern": null, + "alternateEntryId": 1 + }, + { + "phoneNumber": null, + "extension": null, + "ringPattern": null, + "alternateEntryId": 2 + }, + { + "phoneNumber": null, + "extension": null, + "ringPattern": null, + "alternateEntryId": 3 + }, + { + "phoneNumber": null, + "extension": null, + "ringPattern": null, + "alternateEntryId": 4 + }, + { + "phoneNumber": null, + "extension": null, + "ringPattern": null, + "alternateEntryId": 5 + }, + { + "phoneNumber": null, + "extension": null, + "ringPattern": null, + "alternateEntryId": 6 + }, + { + "phoneNumber": null, + "extension": null, + "ringPattern": null, + "alternateEntryId": 7 + }, + { + "phoneNumber": null, + "extension": null, + "ringPattern": null, + "alternateEntryId": 8 + }, + { + "phoneNumber": null, + "extension": null, + "ringPattern": null, + "alternateEntryId": 9 + }, + { + "phoneNumber": null, + "extension": null, + "ringPattern": null, + "alternateEntryId": 10 + } + ] + }, + "Anonymous Call Rejection": { + "isActive": false + }, + "Authentication": { + "userName": 9871515000, + "serviceProviderId": "ent.odin", + "groupId": "grp.odin" + }, + "Automatic Callback": { + "isActive": false + }, + "Automatic Hold/Retrieve": { + "isActive": false, + "recallTimerSeconds": 120 + }, + "Barge-in Exempt": { + "isActive": true + }, + "BroadWorks Anywhere": { + "alertAllLocationsForClickToDialCalls": false, + "alertAllLocationsForGroupPagingCalls": false, + "phoneNumbers": [] + }, + "BroadWorks Mobility": { + "isActive": false, + "phonesToRing": "Fixed", + "alertClickToDialCalls": false, + "alertGroupPagingCalls": false, + "enableDiversionInhibitor": false, + "requireAnswerConfirmation": false, + "broadworksCallControl": false, + "useSettingLevel": "Group", + "denyCallOriginations": false, + "denyCallTerminations": false + }, + "Busy Lamp Field": { + "enableCallParkNotification": false, + "users": [] + }, + "Call Forwarding Always": { + "isActive": false, + "forwardToPhoneNumber": 1234, + "isRingSplashActive": false + }, + "Call Forwarding Always Secondary": { + "isActive": false, + "isRingSplashActive": false + }, + "Call Forwarding Busy": { + "isActive": false + }, + "Call Forwarding No Answer": { + "isActive": false, + "forwardToPhoneNumber": 12314, + "numberOfRings": 2 + }, + "Call Forwarding Not Reachable": { + "isActive": false + }, + "Call Forwarding Selective": { + "isActive": false, + "playRingReminder": false, + "criteria": [] + }, + "Call Notify": { + "criteria": [] + }, + "Call Recording": { + "recordingOption": "Never", + "pauseResumeNotification": "None", + "enableCallRecordingAnnouncement": false, + "enableRecordCallRepeatWarningTone": false, + "recordCallRepeatWarningToneTimerSeconds": 15, + "enableVoiceMailRecording": false + }, + "Call Transfer": { + "isRecallActive": false, + "recallNumberOfRings": 4, + "useDiversionInhibitorForBlindTransfer": false, + "useDiversionInhibitorForConsultativeCalls": false, + "enableBusyCampOn": false, + "busyCampOnSeconds": 120 + }, + "Call Waiting": { + "isActive": true, + "disableCallingLineIdDelivery": false + }, + "Calling Line ID Blocking Override": { + "isActive": false + }, + "Calling Line ID Delivery Blocking": { + "isActive": false + }, + "Calling Name Delivery": { + "isActiveForExternalCalls": true, + "isActiveForInternalCalls": true + }, + "Calling Name Retrieval": { + "isActive": false + }, + "Calling Number Delivery": { + "isActiveForExternalCalls": true, + "isActiveForInternalCalls": true + }, + "Calling Party Category": { + "category": "Ordinary" + }, + "Charge Number": { + "useChargeNumberForEnhancedTranslations": false, + "sendChargeNumberToNetwork": true + }, + "Classmark": [], + "CommPilot Express": { + "availableInOffice": { + "busySetting": { + "action": "Transfer To Voice Mail" + }, + "noAnswerSetting": { + "action": "Transfer To Voice Mail" + } + }, + "availableOutOfOffice": { + "incomingCalls": { + "action": "Transfer To Voice Mail" + }, + "incomingCallNotify": { + "sendEmail": "false" + } + }, + "busy": { + "incomingCalls": { + "sendCallsToVoiceMailExceptExcludedNumbers": "false" + }, + "voiceMailNotify": { + "sendEmail": "false" + } + }, + "unavailable": { + "incomingCalls": { + "sendCallsToVoiceMailExceptExcludedNumbers": "false" + }, + "voiceMailGreeting": "No Answer" + } + }, + "Communication Barring User-Control": { + "lockoutStatus": false, + "profileTable": [] + }, + "Connected Line Identification Restriction": { + "isActive": false + }, + "Direct Route": { + "outgoingDTGPolicy": "Direct Route DTG", + "outgoingTrunkIdentityPolicy": "Direct Route Trunk Identity", + "routes": [] + }, + "Directed Call Pickup with Barge-in": { + "enableBargeInWarningTone": true, + "enableAutomaticTargetSelection": false + }, + "Do Not Disturb": { + "isActive": false, + "ringSplash": false + }, + "Executive-Assistant": { + "enableDivert": false, + "executives": [] + }, + "External Calling Line ID Delivery": { + "isActive": true + }, + "External Custom Ringback": { + "isActive": false, + "useSettingLevel": "Service Provider" + }, + "Fax Messaging": { + "isActive": false, + "aliases": [] + }, + "Group Night Forwarding": { + "nightForwarding": "Use Group", + "groupNightForwarding": "On" + }, + "Hoteling Guest": { + "isActive": false, + "enableAssociationLimit": true, + "associationLimitHours": 12 + }, + "Hoteling Host": { + "isActive": false, + "enforceAssociationLimit": true, + "associationLimitHours": 24, + "accessLevel": "Group" + }, + "In-Call Service Activation": { + "isActive": false + }, + "Integrated IMP": { + "isActive": false + }, + "Intercept User": { + "isActive": false, + "announcementSelection": "Default", + "inboundCallMode": "Intercept All", + "alternateBlockingAnnouncement": false, + "exemptInboundMobilityCalls": false, + "disableParallelRingingToNetworkLocations": false, + "routeToVoiceMail": false, + "playNewPhoneNumber": false, + "transferOnZeroToPhoneNumber": false, + "outboundCallMode": "Block All", + "exemptOutboundMobilityCalls": false, + "rerouteOutboundCalls": false + }, + "Internal Calling Line ID Delivery": { + "isActive": true + }, + "MWI Delivery to Mobile Endpoint": { + "isActive": false + }, + "Malicious Call Trace": { + "isActive": false, + "traceTypeSelection": "Answered Incoming", + "traceForTimePeriod": false + }, + "Number Portability Announcement": { + "enable": false + }, + "Physical Location": { + "isActive": false + }, + "Pre-alerting Announcement": { + "isActive": false, + "audioSelection": "Default", + "videoSelection": "Default", + "criteria": [] + }, + "Preferred Carrier User": { + "intraLataCarrier": { + "useGroupPreferredCarrier": "false" + }, + "interLataCarrier": { + "useGroupPreferredCarrier": "false" + }, + "internationalCarrier": { + "useGroupPreferredCarrier": "false" + } + }, + "Prepaid": { + "isActive": false + }, + "Priority Alert": { + "isActive": false, + "criteria": [] + }, + "Privacy": { + "enableDirectoryPrivacy": false, + "enableAutoAttendantExtensionDialingPrivacy": false, + "enableAutoAttendantNameDialingPrivacy": false, + "enablePhoneStatusPrivacy": false, + "permittedMonitors": [] + }, + "Push to Talk": { + "allowAutoAnswer": true, + "outgoingConnectionSelection": "Two Way", + "accessListSelection": "Allow Calls From Selected Users", + "users": [] + }, + "Remote Office": { + "isActive": false + }, + "Route List": { + "treatOriginationsAndPBXRedirectionsAsScreened": true, + "useRouteListIdentityForNonEmergencyCalls": true, + "useRouteListIdentityForEmergencyCalls": true, + "assignedNumberPrefixTable": [], + "dns": [] + }, + "Security Classification": [], + "Selective Call Acceptance": [], + "Selective Call Rejection": [], + "Sequential Ring": { + "ringBaseLocationFirst": true, + "baseLocationNumberOfRings": 2, + "continueIfBaseLocationIsBusy": true, + "callerMayStopSearch": true, + "locations": [ + { + "phoneNumber": "", + "numberOfRings": 3, + "answerConfirmationRequired": false + }, + { + "phoneNumber": "", + "numberOfRings": 3, + "answerConfirmationRequired": false + }, + { + "phoneNumber": "", + "numberOfRings": 3, + "answerConfirmationRequired": false + }, + { + "phoneNumber": "", + "numberOfRings": 3, + "answerConfirmationRequired": false + }, + { + "phoneNumber": "", + "numberOfRings": 3, + "answerConfirmationRequired": false + } + ], + "criteria": [] + }, + "Shared Call Appearance": { + "alertAllAppearancesForClickToDialCalls": false, + "alertAllAppearancesForGroupPagingCalls": false, + "maxAppearances": 35, + "allowSCACallRetrieve": false, + "enableMultipleCallArrangement": true, + "multipleCallArrangementIsActive": true, + "allowBridgingBetweenLocations": false, + "bridgeWarningTone": "None", + "enableCallParkNotification": false, + "endpoints": [] + }, + "Silent Alerting": { + "isActive": false + }, + "Simultaneous Ring Personal": { + "isActive": false, + "doNotRingIfOnCall": true, + "criteria": [], + "locations": [] + }, + "Speed Dial 100": { + "speedCodes": [] + }, + "Speed Dial 8": { + "speedCodes": [ + { + "speedCode": "2" + }, + { + "speedCode": "3" + }, + { + "speedCode": "4" + }, + { + "speedCode": "5" + }, + { + "speedCode": "6" + }, + { + "speedCode": "7" + }, + { + "speedCode": "8" + }, + { + "speedCode": "9" + } + ] + }, + "Terminating Alternate Trunk Identity": [], + "Third-Party Voice Mail Support": { + "isActive": false, + "busyRedirectToVoiceMail": true, + "noAnswerRedirectToVoiceMail": true, + "serverSelection": "Group Mail Server", + "mailboxIdType": "User Or Group Phone Number", + "noAnswerNumberOfRings": 2, + "alwaysRedirectToVoiceMail": false, + "outOfPrimaryZoneRedirectToVoiceMail": false + }, + "Two-Stage Dialing": { + "isActive": true, + "allowActivationWithUserAddresses": false + }, + "Video Add-On": { + "isActive": false, + "maxOriginatingCallDelaySeconds": 2 + }, + "Voice Messaging User": { + "Voice Messaging User": { + "isActive": false, + "processing": "Unified Voice and Email Messaging", + "voiceMessageDeliveryEmailAddress": "mreverman@parkbenchsolutions.com", + "usePhoneMessageWaitingIndicator": true, + "sendVoiceMessageNotifyEmail": false, + "sendCarbonCopyVoiceMessage": false, + "transferOnZeroToPhoneNumber": false, + "alwaysRedirectToVoiceMail": false, + "busyRedirectToVoiceMail": true, + "noAnswerRedirectToVoiceMail": true, + "outOfPrimaryZoneRedirectToVoiceMail": false, + "serviceProviderId": "ent.odin", + "groupId": "grp.odin", + "userId": "9871515000@odinapi.net" + }, + "Voice Messaging User Advanced": { + "mailServerSelection": "Group Mail Server", + "groupMailServerEmailAddress": "mreverman@parkbenchsolutions.com", + "groupMailServerUserId": "vm9871515000", + "useGroupDefaultMailServerFullMailboxLimit": true, + "personalMailServerProtocol": "POP3", + "personalMailServerRealDeleteForImap": false, + "serviceProviderId": "ent.odin", + "groupId": "grp.odin", + "userId": "9871515000@odinapi.net" + }, + "Voice Messaging User Greeting": { + "busyAnnouncementSelection": "Default", + "noAnswerAnnouncementSelection": "Default", + "extendedAwayEnabled": false, + "extendedAwayDisableMessageDeposit": true, + "noAnswerNumberOfRings": 2, + "disableMessageDeposit": false, + "disableMessageDepositAction": "Disconnect", + "userId": "9871515000@odinapi.net" + }, + "Voice Messaging User Voice Portal": { + "usePersonalizedName": true, + "voicePortalAutoLogin": true, + "serviceProviderId": "ent.odin", + "groupId": "grp.odin", + "userId": "9871515000@odinapi.net", + "audioFile": { + "description": "aa1 copy is a copy of the Let's go song", + "mediaType": "WAV" + } + } + }, + "Voice Portal Calling": { + "isActive": false + }, + "Zone Calling Restrictions": [] +} +``` +``` \ No newline at end of file diff --git a/docs/docs/methods/shared-call-appearance/README.md b/docs/docs/methods/shared-call-appearance/README.md new file mode 100644 index 0000000..f2f6d45 --- /dev/null +++ b/docs/docs/methods/shared-call-appearance/README.md @@ -0,0 +1,3 @@ +# ๐ŸŽญ Shared Call Appearance + +All things shared call appearance. diff --git a/docs/docs/methods/shared-call-appearance/post-user-shared-call-appearance-endpoint b/docs/docs/methods/shared-call-appearance/post-user-shared-call-appearance-endpoint new file mode 100644 index 0000000..48fadb2 --- /dev/null +++ b/docs/docs/methods/shared-call-appearance/post-user-shared-call-appearance-endpoint @@ -0,0 +1,33 @@ +--- +description: my_api.put.user_shared_call_appearance_endpoint() +--- + +# ๐ŸŽญ POST - User Shared Call Appearance Endpoint + +Creates a new Shared Call Apprance (SCA) on a single user. + +### Parameters + +* user_id (str): Target user id of user to create SCA on. +* line_port (str): Line port to be assigned to the new SCA. +* device_name (str): Device to add for SCA from available devices. + +### Returns + +* Dict: New SCA details applied to user. + +### How To Use: + +```python +from odins_spear import api + +my_api= api.Api(base_url="https://base_url/api/vx", username="john.smith", password="ODIN_INSTANCE_1") +my_api.authenticate() + +# updating a users service pack +my_api.post.user_shared_call_appearance_endpoint( + "userId@domain.com", + "userId_webex_mobile@domain.com", + "webex mobile user x" +) +``` diff --git a/odins_spear/scripts/webex_builder.py b/odins_spear/scripts/webex_builder.py index 35e01ff..6e40772 100644 --- a/odins_spear/scripts/webex_builder.py +++ b/odins_spear/scripts/webex_builder.py @@ -15,8 +15,8 @@ def main(api, service_provider_id, group_id, user_id, device_type, "emailAddress": email, "alternateUserId": [ { - "alternateUserId": alternateid, - "description": description + "alternateUserId": email, + "description": "Webex" } ] } From 2640e36c21dbff6f25663888bd888f357a6cfaa7 Mon Sep 17 00:00:00 2001 From: LivCurtis <133100222+LivCurtis@users.noreply.github.com> Date: Wed, 18 Sep 2024 09:51:10 +0100 Subject: [PATCH 11/17] Updated webex_builder.py Added step 3 to assign the webex feature pack to the user --- odins_spear/scripts/webex_builder.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/odins_spear/scripts/webex_builder.py b/odins_spear/scripts/webex_builder.py index 6e40772..a647f08 100644 --- a/odins_spear/scripts/webex_builder.py +++ b/odins_spear/scripts/webex_builder.py @@ -23,6 +23,11 @@ def main(api, service_provider_id, group_id, user_id, device_type, ) # 3. assign feature pack - OC + api.put.user_services( + user_id = user_id, + service_packs = [webex_feature_pack_name] + ) + # 4. enable IMP in service settings (Micheal Clarke 04.09.24) - MC enableIMP = {'Integrated IMP': {'isActive': True}} api.put.user_service_settings(user_id=user_id, settings=enableIMP) From 3c996cd3b2a0270e389d23e1545037a2e5252c46 Mon Sep 17 00:00:00 2001 From: LivCurtis <133100222+LivCurtis@users.noreply.github.com> Date: Wed, 18 Sep 2024 10:06:35 +0100 Subject: [PATCH 12/17] Update webex_builder.py Added if statement to assigning webex feature pack step to make this universal. Changed DEVICE_NAME to be lowercase --- odins_spear/scripts/webex_builder.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/odins_spear/scripts/webex_builder.py b/odins_spear/scripts/webex_builder.py index a647f08..1b62869 100644 --- a/odins_spear/scripts/webex_builder.py +++ b/odins_spear/scripts/webex_builder.py @@ -3,7 +3,7 @@ def main(api, service_provider_id, group_id, user_id, device_type, email, primary_device, webex_feature_pack_name): - DEVICE_NAME = f"{user_id.split('@')[0]}_WBX" + device_name = f"{user_id.split('@')[0]}_WBX" # 1 update the email & 2. update alt user id - KB @@ -23,10 +23,12 @@ def main(api, service_provider_id, group_id, user_id, device_type, ) # 3. assign feature pack - OC - api.put.user_services( - user_id = user_id, - service_packs = [webex_feature_pack_name] - ) + if webex_feature_pack_name: + + api.put.user_services( + user_id = user_id, + service_packs = [webex_feature_pack_name] + ) # 4. enable IMP in service settings (Micheal Clarke 04.09.24) - MC enableIMP = {'Integrated IMP': {'isActive': True}} @@ -54,7 +56,7 @@ def main(api, service_provider_id, group_id, user_id, device_type, api.post.user_shared_call_appearance_endpoint( user_id, user_id.replace("@", "_WBX@"), - DEVICE_NAME + device_name ) # 7. get webex password - JP From 5807f89ba6c2011547fe6fec153784176be75f0c Mon Sep 17 00:00:00 2001 From: LivCurtis <133100222+LivCurtis@users.noreply.github.com> Date: Wed, 18 Sep 2024 10:52:08 +0100 Subject: [PATCH 13/17] Update webex_builder.py Added step 5 to build a the device --- odins_spear/scripts/webex_builder.py | 47 +++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/odins_spear/scripts/webex_builder.py b/odins_spear/scripts/webex_builder.py index 1b62869..a1538ac 100644 --- a/odins_spear/scripts/webex_builder.py +++ b/odins_spear/scripts/webex_builder.py @@ -36,6 +36,51 @@ def main(api, service_provider_id, group_id, user_id, device_type, # 5. build device - OC + device_password = api.get.password_generate(service_provider_id, group_id)["password"] + + device_payload = { + "deviceLevel": "Group", + "useCustomUserNamePassword": "true", + "accessDeviceCredentials": { + "userName": device_name, + "password": device_password + }, + "netAddress": "", + "port": "", + "outboundProxyServerNetAddress": "", + "stunServerNetAddress": "", + "macAddress": "", + "serialNumber": "", + "description": "", + "physicalLocation": "", + "transportProtocol": "UDP", + "profile": "Intelligent Proxy Addressing", + "staticRegistrationCapable": "false", + "configType": "2 File Configuration", + "protocolChoice": [ + "SIP 2.0" + ], + "isIpAddressOptional": "true", + "useDomain": "true", + "isMobilityManagerDevice": "false", + "deviceConfigurationOption": "Device Management", + "staticLineOrdering": "false", + "deviceTypeLevel": "System", + "tags": ["US-One"], + "relatedServices": ["Client License 18"], + "protocol": "SIP 2.0", + "userName": device_name + } + + api.post.group_device( + service_provider_id = service_provider_id, + group_id = group_id, + device_name = device_name, + device_type = device_type, + payload = device_payload + ) + + # 6. add device to user based on primary flag - JP if primary_device: primary_device_configuration = { @@ -60,7 +105,7 @@ def main(api, service_provider_id, group_id, user_id, device_type, ) # 7. get webex password - JP - password = api.get.passwords_generate(service_provider_id, group_id)["password"] + password = api.get.password_generate(service_provider_id, group_id)["password"] api.put.user_web_authentication_password(user_id, password) # 8. return formatted data From 8ce02a8b202005e582009f6c258f882a6435e56a Mon Sep 17 00:00:00 2001 From: Jordan Prescott Date: Wed, 18 Sep 2024 13:45:36 +0100 Subject: [PATCH 14/17] tidy up after all sections completed --- odins_spear/scripts/webex_builder.py | 75 +++++++++------------------- 1 file changed, 23 insertions(+), 52 deletions(-) diff --git a/odins_spear/scripts/webex_builder.py b/odins_spear/scripts/webex_builder.py index a1538ac..7f06127 100644 --- a/odins_spear/scripts/webex_builder.py +++ b/odins_spear/scripts/webex_builder.py @@ -3,15 +3,8 @@ def main(api, service_provider_id, group_id, user_id, device_type, email, primary_device, webex_feature_pack_name): - device_name = f"{user_id.split('@')[0]}_WBX" - - # 1 update the email & 2. update alt user id - KB - - api.put.user( - service_provider_id, - group_id, - user_id, - { + # Update the email & alt user id + email_alt_userid = { "emailAddress": email, "alternateUserId": [ { @@ -19,69 +12,47 @@ def main(api, service_provider_id, group_id, user_id, device_type, "description": "Webex" } ] - } + } + api.put.user( + service_provider_id, + group_id, + user_id, + updates=email_alt_userid ) - # 3. assign feature pack - OC - - if webex_feature_pack_name: + # Assign feature pack + if webex_feature_pack_name: api.put.user_services( - user_id = user_id, - service_packs = [webex_feature_pack_name] + user_id=user_id, + service_packs=[webex_feature_pack_name] ) - # 4. enable IMP in service settings (Micheal Clarke 04.09.24) - MC + # 4. enable IMP in service settings enableIMP = {'Integrated IMP': {'isActive': True}} api.put.user_service_settings(user_id=user_id, settings=enableIMP) - # 5. build device - OC - + # 5. build device + device_name = f"{user_id.split('@')[0]}_WBX" device_password = api.get.password_generate(service_provider_id, group_id)["password"] device_payload = { - "deviceLevel": "Group", "useCustomUserNamePassword": "true", "accessDeviceCredentials": { "userName": device_name, "password": device_password }, - "netAddress": "", - "port": "", - "outboundProxyServerNetAddress": "", - "stunServerNetAddress": "", - "macAddress": "", - "serialNumber": "", - "description": "", - "physicalLocation": "", - "transportProtocol": "UDP", - "profile": "Intelligent Proxy Addressing", - "staticRegistrationCapable": "false", - "configType": "2 File Configuration", - "protocolChoice": [ - "SIP 2.0" - ], - "isIpAddressOptional": "true", - "useDomain": "true", - "isMobilityManagerDevice": "false", - "deviceConfigurationOption": "Device Management", - "staticLineOrdering": "false", - "deviceTypeLevel": "System", - "tags": ["US-One"], - "relatedServices": ["Client License 18"], - "protocol": "SIP 2.0", "userName": device_name } api.post.group_device( - service_provider_id = service_provider_id, - group_id = group_id, - device_name = device_name, - device_type = device_type, - payload = device_payload + service_provider_id=service_provider_id, + group_id=group_id, + device_name=device_name, + device_type=device_type, + payload=device_payload ) - - # 6. add device to user based on primary flag - JP + # Add device to user based on primary flag - JP if primary_device: primary_device_configuration = { "endpointType": "accessDeviceEndpoint", @@ -104,11 +75,11 @@ def main(api, service_provider_id, group_id, user_id, device_type, device_name ) - # 7. get webex password - JP + # Get webex password password = api.get.password_generate(service_provider_id, group_id)["password"] api.put.user_web_authentication_password(user_id, password) - # 8. return formatted data + # Return formatted data webex_user_details = { "username": email, "password": password, From b654f1ec11914e35e2447579fe6b10e745e78cd7 Mon Sep 17 00:00:00 2001 From: Jordan Prescott Date: Wed, 18 Sep 2024 15:36:16 +0100 Subject: [PATCH 15/17] feature complete --- odins_spear/methods/put.py | 6 +++--- odins_spear/scripts/webex_builder.py | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/odins_spear/methods/put.py b/odins_spear/methods/put.py index d6e5692..1272d69 100644 --- a/odins_spear/methods/put.py +++ b/odins_spear/methods/put.py @@ -1185,10 +1185,10 @@ def user(self, service_provider_id: str, group_id: str, user_id: str, updates: d Note: Available options to change can be seen through: get.user_by_id() Args: - service_provider_id (str): Target Service Provider where group is located + service_provider_id (str): + updates (dict): The updates to be applied Target Service Provider where group is located group_id (str): Target Group ID where user is located - user_id (str): Target User ID - updates (dict): The updates to be applied to the list of Users e.g {"extension":"9999"} + user_id (str): Target User IDto the list of Users e.g {"extension":"9999"} Returns: Dict: Returns the changes made including User ID and updates. diff --git a/odins_spear/scripts/webex_builder.py b/odins_spear/scripts/webex_builder.py index 7f06127..9d50857 100644 --- a/odins_spear/scripts/webex_builder.py +++ b/odins_spear/scripts/webex_builder.py @@ -13,6 +13,7 @@ def main(api, service_provider_id, group_id, user_id, device_type, } ] } + api.put.user( service_provider_id, group_id, @@ -27,11 +28,11 @@ def main(api, service_provider_id, group_id, user_id, device_type, service_packs=[webex_feature_pack_name] ) - # 4. enable IMP in service settings + # enable IMP in service settings enableIMP = {'Integrated IMP': {'isActive': True}} api.put.user_service_settings(user_id=user_id, settings=enableIMP) - # 5. build device + # build device device_name = f"{user_id.split('@')[0]}_WBX" device_password = api.get.password_generate(service_provider_id, group_id)["password"] @@ -59,7 +60,7 @@ def main(api, service_provider_id, group_id, user_id, device_type, "accessDeviceEndpoint": { "accessDevice": { "deviceType": device_type, - "deviceName": f"{user_id.split('@')[0]}_WBX", + "deviceName": device_name, "serviceProviderId": service_provider_id, "groupId": group_id, "deviceLevel": "Group", From eedd045f0a06eaf701ba7f5aadada2936901d539 Mon Sep 17 00:00:00 2001 From: Jordan Prescott Date: Wed, 18 Sep 2024 16:01:29 +0100 Subject: [PATCH 16/17] docs complete --- docs/SUMMARY.md | 1 + docs/docs/features/scripter/webex-builder.md | 67 ++++++++++++++++++++ odins_spear/scripts/webex_builder.py | 4 +- 3 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 docs/docs/features/scripter/webex-builder.md diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index fa3d359..a768a0d 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -159,6 +159,7 @@ * [๐Ÿ”ข Remove Numbers](docs/features/scripter/remove-numbers.md) * [๐Ÿ”‘ Bulk Password Reset](docs/features/scripter/bulk-password-reset.md) * [๐Ÿ“œ Service Provider Trunking Capacity](docs/features/scripter/service-provider-trunking-capacity.md) + * [๐Ÿ’ป Webex Builder](docs/features/scripter/webex-builder.md) * [๐Ÿ“ˆ Reporter](docs/features/reporter/README.md) * [๐Ÿค™ Call Flow](docs/features/reporter/call-flow/README.md) * [๐Ÿ”‘ Node Key](docs/features/reporter/call-flow/node-key.md) diff --git a/docs/docs/features/scripter/webex-builder.md b/docs/docs/features/scripter/webex-builder.md new file mode 100644 index 0000000..bd2bdc7 --- /dev/null +++ b/docs/docs/features/scripter/webex-builder.md @@ -0,0 +1,67 @@ +--- +description: api.scripter.webex_builder() +--- + +# ๐Ÿ’ป Webex Builder + +This script will build a webex device for a user either as a primary device or as a Shared Call Appearance. + +An email and alternate user id is set, then an optional feature pack can be assigned for billing. + +Next, Integrated IMP is enabled in the user services (This is needed for the integration with Cisco). Furthermore, the device is built to the device profile you set using `device_type` parameter and then added to the user either as a primary device or SCA. + +{% hint style="warning" %} +``` +Before running ensure your user has correct licensing for Shared Call Appearance if secondary device. Furthermore, make sure all prerequisites for the group to have webex users have been taken. +``` +{% endhint %} + +### Parameters + +* service\_provider\_id (str): Service Provider ID where group is hosted. +* group\_id (str): Group ID where target user is hosted. +* user\_id (str): Target user to build and add webex device. +* device\_type (str): Name of the device profile to apply. +* email (str): Email of user. This will be used to sign into the webex client. +* primary\_device (bool, optional): Setting to False will assign as SCA, True is primary. Defaults to True. +* webex\_feature\_pack\_name (str, optional): Feature pack to assign for Webex services. Defaults to None. +* enable\_integrated\_imp (bool, optional): Enables Integrated IMP service for the user if True .Defaults to True. + +### Return + +* dict: Webex user/ device details. Includes webex client username and password, and if primary device, device type set. + +### How To Use: + +{% code overflow="wrap" %} +```python +from odins_spear import api + +my_api = api.Api(base_url="https://base_url/api/vx", username="john.smith", password="ODIN_INSTANCE_1") +my_api.authenticate() + +my_api.scripter.webex_builder( + service_provider_id="serviceProviderId", + group_id="groupId", + user_id="userId", + device_type="Businness Communicator - Mobile", + email="test@test.com", + primary_device=True, + webex_feature_pack_name="Webex Mobile", + enable_integrated_imp=True +) +``` +{% endcode %} + +### Terminal Output + +{% code overflow="wrap" fullWidth="false" %} +``` + { + 'username': 'Jordan.Prescott4401@jrdneva.ev.wbx.com', + 'password': '{YdQb8', + 'primary_device': True, + 'device_type': 'Business Communicator - PC' + } +``` +{% endcode %} diff --git a/odins_spear/scripts/webex_builder.py b/odins_spear/scripts/webex_builder.py index 9d50857..7eb3572 100644 --- a/odins_spear/scripts/webex_builder.py +++ b/odins_spear/scripts/webex_builder.py @@ -29,8 +29,8 @@ def main(api, service_provider_id, group_id, user_id, device_type, ) # enable IMP in service settings - enableIMP = {'Integrated IMP': {'isActive': True}} - api.put.user_service_settings(user_id=user_id, settings=enableIMP) + enable_IMP = {'Integrated IMP': {'isActive': True}} + api.put.user_service_settings(user_id=user_id, settings=enable_IMP) # build device device_name = f"{user_id.split('@')[0]}_WBX" From bf2d65204ab036ab41bfcafee47acf4afd8e3f6e Mon Sep 17 00:00:00 2001 From: Jordan Prescott Date: Wed, 18 Sep 2024 16:03:01 +0100 Subject: [PATCH 17/17] Update webex-builder.md --- docs/docs/features/scripter/webex-builder.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/features/scripter/webex-builder.md b/docs/docs/features/scripter/webex-builder.md index bd2bdc7..b50b8ce 100644 --- a/docs/docs/features/scripter/webex-builder.md +++ b/docs/docs/features/scripter/webex-builder.md @@ -53,7 +53,7 @@ my_api.scripter.webex_builder( ``` {% endcode %} -### Terminal Output +### Retuned Data (Formatted) {% code overflow="wrap" fullWidth="false" %} ```