wxcli 1.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wxcli/__init__.py +4 -0
- wxcli/_playbook/.claude/agents/migration-advisor.md +239 -0
- wxcli/_playbook/.claude/agents/wxc-calling-builder.md +946 -0
- wxcli/_playbook/.claude/rules/cleanup.md +29 -0
- wxcli/_playbook/.claude/rules/cucm-migration.md +58 -0
- wxcli/_playbook/.claude/rules/org-health.md +14 -0
- wxcli/_playbook/.claude/settings.json +8 -0
- wxcli/_playbook/.claude/skills/audit-compliance/SKILL.md +515 -0
- wxcli/_playbook/.claude/skills/call-control/SKILL.md +747 -0
- wxcli/_playbook/.claude/skills/configure-features/SKILL.md +623 -0
- wxcli/_playbook/.claude/skills/configure-routing/SKILL.md +627 -0
- wxcli/_playbook/.claude/skills/contact-center/SKILL.md +1181 -0
- wxcli/_playbook/.claude/skills/cucm-migrate/SKILL.md +820 -0
- wxcli/_playbook/.claude/skills/customer-assist/SKILL.md +443 -0
- wxcli/_playbook/.claude/skills/device-platform/SKILL.md +407 -0
- wxcli/_playbook/.claude/skills/manage-call-settings/SKILL.md +757 -0
- wxcli/_playbook/.claude/skills/manage-devices/SKILL.md +790 -0
- wxcli/_playbook/.claude/skills/manage-identity/SKILL.md +638 -0
- wxcli/_playbook/.claude/skills/manage-licensing/SKILL.md +528 -0
- wxcli/_playbook/.claude/skills/manage-meetings/SKILL.md +708 -0
- wxcli/_playbook/.claude/skills/messaging-bots/SKILL.md +365 -0
- wxcli/_playbook/.claude/skills/messaging-spaces/SKILL.md +520 -0
- wxcli/_playbook/.claude/skills/org-health/SKILL.md +159 -0
- wxcli/_playbook/.claude/skills/provision-calling/SKILL.md +421 -0
- wxcli/_playbook/.claude/skills/query-live/SKILL.md +183 -0
- wxcli/_playbook/.claude/skills/query-live/domains/call-flow-trace.md +223 -0
- wxcli/_playbook/.claude/skills/query-live/domains/call-history.md +44 -0
- wxcli/_playbook/.claude/skills/query-live/domains/features.md +169 -0
- wxcli/_playbook/.claude/skills/query-live/domains/numbers.md +93 -0
- wxcli/_playbook/.claude/skills/query-live/domains/people-and-settings.md +146 -0
- wxcli/_playbook/.claude/skills/query-live/domains/routing.md +124 -0
- wxcli/_playbook/.claude/skills/reporting/SKILL.md +501 -0
- wxcli/_playbook/.claude/skills/reporting/references/cdr-recipes.md +1628 -0
- wxcli/_playbook/.claude/skills/reporting-cc/SKILL.md +251 -0
- wxcli/_playbook/.claude/skills/reporting-meetings/SKILL.md +290 -0
- wxcli/_playbook/.claude/skills/teardown/SKILL.md +214 -0
- wxcli/_playbook/.claude/skills/video-mesh/SKILL.md +379 -0
- wxcli/_playbook/.claude/skills/wxc-calling-debug/SKILL.md +475 -0
- wxcli/_playbook/CLAUDE.md +373 -0
- wxcli/_playbook/docs/reference/CLAUDE.md +25 -0
- wxcli/_playbook/docs/reference/admin-apps-data.md +643 -0
- wxcli/_playbook/docs/reference/admin-audit-security.md +322 -0
- wxcli/_playbook/docs/reference/admin-hybrid.md +383 -0
- wxcli/_playbook/docs/reference/admin-identity-scim.md +1007 -0
- wxcli/_playbook/docs/reference/admin-licensing.md +414 -0
- wxcli/_playbook/docs/reference/admin-org-management.md +586 -0
- wxcli/_playbook/docs/reference/admin-partner.md +357 -0
- wxcli/_playbook/docs/reference/archive/wxc-sdk-patterns.md +1229 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-advanced.md +835 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-core.md +743 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-devices-workspaces.md +1305 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-features.md +849 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-locations.md +938 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-person.md +1255 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-routing.md +1262 -0
- wxcli/_playbook/docs/reference/authentication.md +965 -0
- wxcli/_playbook/docs/reference/call-control.md +1205 -0
- wxcli/_playbook/docs/reference/call-features-additional.md +2541 -0
- wxcli/_playbook/docs/reference/call-features-major.md +1320 -0
- wxcli/_playbook/docs/reference/call-routing.md +2304 -0
- wxcli/_playbook/docs/reference/contact-center-analytics.md +1049 -0
- wxcli/_playbook/docs/reference/contact-center-core.md +1614 -0
- wxcli/_playbook/docs/reference/contact-center-journey.md +457 -0
- wxcli/_playbook/docs/reference/contact-center-routing.md +1138 -0
- wxcli/_playbook/docs/reference/devices-core.md +1869 -0
- wxcli/_playbook/docs/reference/devices-dect.md +1150 -0
- wxcli/_playbook/docs/reference/devices-platform.md +467 -0
- wxcli/_playbook/docs/reference/devices-workspaces.md +1426 -0
- wxcli/_playbook/docs/reference/emergency-services.md +1122 -0
- wxcli/_playbook/docs/reference/location-calling-core.md +2037 -0
- wxcli/_playbook/docs/reference/location-calling-media.md +1334 -0
- wxcli/_playbook/docs/reference/location-recording-advanced.md +1482 -0
- wxcli/_playbook/docs/reference/meetings-content.md +473 -0
- wxcli/_playbook/docs/reference/meetings-core.md +903 -0
- wxcli/_playbook/docs/reference/meetings-infrastructure.md +899 -0
- wxcli/_playbook/docs/reference/meetings-settings.md +850 -0
- wxcli/_playbook/docs/reference/messaging-bots.md +1091 -0
- wxcli/_playbook/docs/reference/messaging-spaces.md +695 -0
- wxcli/_playbook/docs/reference/person-call-settings-behavior.md +1639 -0
- wxcli/_playbook/docs/reference/person-call-settings-handling.md +1394 -0
- wxcli/_playbook/docs/reference/person-call-settings-media.md +1898 -0
- wxcli/_playbook/docs/reference/person-call-settings-permissions.md +1329 -0
- wxcli/_playbook/docs/reference/provisioning.md +1366 -0
- wxcli/_playbook/docs/reference/reporting-analytics.md +1318 -0
- wxcli/_playbook/docs/reference/self-service-call-settings.md +1020 -0
- wxcli/_playbook/docs/reference/virtual-lines.md +1132 -0
- wxcli/_playbook/docs/reference/webhooks-events.md +1444 -0
- wxcli/_playbook/docs/reference/wxcadm-xsi-realtime.md +953 -0
- wxcli/_version.py +24 -0
- wxcli/auth.py +137 -0
- wxcli/commands/__init__.py +0 -0
- wxcli/commands/_registry.py +181 -0
- wxcli/commands/activation_email.py +103 -0
- wxcli/commands/admin_recordings.py +585 -0
- wxcli/commands/analytics.py +105 -0
- wxcli/commands/announcement_playlists.py +219 -0
- wxcli/commands/announcements.py +519 -0
- wxcli/commands/archive_users.py +36 -0
- wxcli/commands/attachment_actions.py +60 -0
- wxcli/commands/audit_events.py +83 -0
- wxcli/commands/authorizations.py +113 -0
- wxcli/commands/auto_attendant.py +642 -0
- wxcli/commands/broadworks_billing_reports.py +126 -0
- wxcli/commands/broadworks_enterprises.py +160 -0
- wxcli/commands/broadworks_subscribers.py +319 -0
- wxcli/commands/broadworks_workspaces.py +108 -0
- wxcli/commands/call_controls.py +1304 -0
- wxcli/commands/call_park.py +494 -0
- wxcli/commands/call_pickup.py +229 -0
- wxcli/commands/call_queue.py +1878 -0
- wxcli/commands/call_recording.py +707 -0
- wxcli/commands/call_routing.py +1610 -0
- wxcli/commands/call_settings_for_me_phase_5.py +212 -0
- wxcli/commands/caller_reputation.py +169 -0
- wxcli/commands/calling_service.py +305 -0
- wxcli/commands/cc_address_book.py +770 -0
- wxcli/commands/cc_agent_greetings.py +242 -0
- wxcli/commands/cc_agent_summaries.py +39 -0
- wxcli/commands/cc_agent_wellbeing.py +216 -0
- wxcli/commands/cc_agents.py +425 -0
- wxcli/commands/cc_ai_assistant.py +55 -0
- wxcli/commands/cc_ai_feature.py +294 -0
- wxcli/commands/cc_audio_files.py +149 -0
- wxcli/commands/cc_auto_csat.py +311 -0
- wxcli/commands/cc_aux_code.py +458 -0
- wxcli/commands/cc_business_hour.py +353 -0
- wxcli/commands/cc_call_monitoring.py +228 -0
- wxcli/commands/cc_callbacks.py +194 -0
- wxcli/commands/cc_campaign.py +212 -0
- wxcli/commands/cc_captures.py +39 -0
- wxcli/commands/cc_contact_list.py +169 -0
- wxcli/commands/cc_contact_number.py +295 -0
- wxcli/commands/cc_data_sources.py +235 -0
- wxcli/commands/cc_desktop_layout.py +380 -0
- wxcli/commands/cc_desktop_profile.py +322 -0
- wxcli/commands/cc_dial_number.py +511 -0
- wxcli/commands/cc_dial_plan.py +347 -0
- wxcli/commands/cc_dnc.py +101 -0
- wxcli/commands/cc_entry_point.py +545 -0
- wxcli/commands/cc_ewt.py +51 -0
- wxcli/commands/cc_flow.py +477 -0
- wxcli/commands/cc_global_vars.py +430 -0
- wxcli/commands/cc_holiday_list.py +335 -0
- wxcli/commands/cc_journey.py +1261 -0
- wxcli/commands/cc_legacy_flows.py +49 -0
- wxcli/commands/cc_multimedia_profile.py +436 -0
- wxcli/commands/cc_notification.py +51 -0
- wxcli/commands/cc_outdial_ani.py +604 -0
- wxcli/commands/cc_overrides.py +341 -0
- wxcli/commands/cc_queue.py +1083 -0
- wxcli/commands/cc_queue_stats.py +55 -0
- wxcli/commands/cc_realtime.py +51 -0
- wxcli/commands/cc_resource_collection.py +312 -0
- wxcli/commands/cc_search.py +46 -0
- wxcli/commands/cc_site.py +400 -0
- wxcli/commands/cc_skill.py +350 -0
- wxcli/commands/cc_skill_profile.py +289 -0
- wxcli/commands/cc_subscriptions.py +426 -0
- wxcli/commands/cc_summaries.py +130 -0
- wxcli/commands/cc_tasks.py +844 -0
- wxcli/commands/cc_team.py +325 -0
- wxcli/commands/cc_user_profiles.py +349 -0
- wxcli/commands/cc_users.py +701 -0
- wxcli/commands/cc_work_types.py +363 -0
- wxcli/commands/cdr.py +89 -0
- wxcli/commands/classifications.py +38 -0
- wxcli/commands/cleanup.py +1427 -0
- wxcli/commands/client_settings.py +72 -0
- wxcli/commands/conference.py +328 -0
- wxcli/commands/configure.py +72 -0
- wxcli/commands/converged_recordings.py +347 -0
- wxcli/commands/converged_recordings_export.py +310 -0
- wxcli/commands/cq_playlists.py +42 -0
- wxcli/commands/cucm.py +2794 -0
- wxcli/commands/cucm_config.py +129 -0
- wxcli/commands/customer_assist.py +373 -0
- wxcli/commands/data_sources.py +227 -0
- wxcli/commands/dect_devices.py +787 -0
- wxcli/commands/device_configurations.py +77 -0
- wxcli/commands/device_dynamic_settings.py +320 -0
- wxcli/commands/device_settings.py +1489 -0
- wxcli/commands/devices.py +280 -0
- wxcli/commands/domains.py +142 -0
- wxcli/commands/ecm.py +178 -0
- wxcli/commands/emergency_services.py +827 -0
- wxcli/commands/events.py +83 -0
- wxcli/commands/external_voicemail.py +52 -0
- wxcli/commands/groups.py +206 -0
- wxcli/commands/guest_management.py +76 -0
- wxcli/commands/hds.py +340 -0
- wxcli/commands/hot_desk.py +67 -0
- wxcli/commands/hot_desking_members.py +118 -0
- wxcli/commands/hot_desking_portal.py +124 -0
- wxcli/commands/hunt_group.py +577 -0
- wxcli/commands/hybrid_clusters.py +71 -0
- wxcli/commands/hybrid_connectors.py +67 -0
- wxcli/commands/identity_org.py +159 -0
- wxcli/commands/init_playbook.py +155 -0
- wxcli/commands/licenses.py +106 -0
- wxcli/commands/live_monitoring.py +40 -0
- wxcli/commands/location_call_handling.py +577 -0
- wxcli/commands/location_schedules.py +341 -0
- wxcli/commands/location_settings.py +1297 -0
- wxcli/commands/location_voicemail.py +494 -0
- wxcli/commands/locations.py +336 -0
- wxcli/commands/meeting_captions.py +110 -0
- wxcli/commands/meeting_chats.py +63 -0
- wxcli/commands/meeting_invitees.py +234 -0
- wxcli/commands/meeting_messages.py +28 -0
- wxcli/commands/meeting_participants.py +278 -0
- wxcli/commands/meeting_polls.py +111 -0
- wxcli/commands/meeting_preferences.py +515 -0
- wxcli/commands/meeting_qa.py +78 -0
- wxcli/commands/meeting_qualities.py +43 -0
- wxcli/commands/meeting_reports.py +101 -0
- wxcli/commands/meeting_session_types.py +105 -0
- wxcli/commands/meeting_site.py +57 -0
- wxcli/commands/meeting_slido.py +44 -0
- wxcli/commands/meeting_summaries.py +92 -0
- wxcli/commands/meeting_tracking_codes.py +233 -0
- wxcli/commands/meeting_transcripts.py +230 -0
- wxcli/commands/meetings.py +1997 -0
- wxcli/commands/memberships.py +164 -0
- wxcli/commands/messages.py +213 -0
- wxcli/commands/mode_management.py +244 -0
- wxcli/commands/my_call_settings.py +3577 -0
- wxcli/commands/numbers.py +405 -0
- wxcli/commands/operating_modes.py +410 -0
- wxcli/commands/org_contacts.py +284 -0
- wxcli/commands/org_health_cli.py +55 -0
- wxcli/commands/org_settings.py +71 -0
- wxcli/commands/organizations.py +83 -0
- wxcli/commands/paging_group.py +257 -0
- wxcli/commands/partner_admins.py +141 -0
- wxcli/commands/partner_reports.py +188 -0
- wxcli/commands/partner_tags.py +216 -0
- wxcli/commands/people.py +279 -0
- wxcli/commands/person_call_settings.py +71 -0
- wxcli/commands/pstn.py +280 -0
- wxcli/commands/recording_report.py +154 -0
- wxcli/commands/report_templates.py +38 -0
- wxcli/commands/reports.py +144 -0
- wxcli/commands/resource_group_memberships.py +160 -0
- wxcli/commands/resource_groups.py +67 -0
- wxcli/commands/roles.py +63 -0
- wxcli/commands/room_tabs.py +160 -0
- wxcli/commands/rooms.py +225 -0
- wxcli/commands/scim_bulk.py +46 -0
- wxcli/commands/scim_groups.py +246 -0
- wxcli/commands/scim_schemas.py +82 -0
- wxcli/commands/scim_users.py +283 -0
- wxcli/commands/security_audit.py +54 -0
- wxcli/commands/service_apps.py +51 -0
- wxcli/commands/single_number_reach.py +209 -0
- wxcli/commands/team_memberships.py +155 -0
- wxcli/commands/teams.py +153 -0
- wxcli/commands/ucm_profile.py +42 -0
- wxcli/commands/update.py +219 -0
- wxcli/commands/user_settings.py +5116 -0
- wxcli/commands/video_mesh.py +1090 -0
- wxcli/commands/virtual_extensions.py +502 -0
- wxcli/commands/virtual_line_settings.py +2072 -0
- wxcli/commands/webhooks.py +176 -0
- wxcli/commands/wholesale_billing_reports.py +147 -0
- wxcli/commands/wholesale_provisioning.py +523 -0
- wxcli/commands/workspace_locations.py +339 -0
- wxcli/commands/workspace_metrics.py +103 -0
- wxcli/commands/workspace_personalization.py +70 -0
- wxcli/commands/workspace_settings.py +3347 -0
- wxcli/commands/workspaces.py +279 -0
- wxcli/commands/xapi.py +114 -0
- wxcli/config.py +139 -0
- wxcli/errors.py +77 -0
- wxcli/main.py +210 -0
- wxcli/migration/CLAUDE.md +106 -0
- wxcli/migration/__init__.py +1 -0
- wxcli/migration/advisory/CLAUDE.md +196 -0
- wxcli/migration/advisory/__init__.py +46 -0
- wxcli/migration/advisory/advisor.py +107 -0
- wxcli/migration/advisory/advisory_patterns.py +2552 -0
- wxcli/migration/advisory/recommendation_rules.py +835 -0
- wxcli/migration/cucm/CLAUDE.md +74 -0
- wxcli/migration/cucm/__init__.py +5 -0
- wxcli/migration/cucm/connection.py +265 -0
- wxcli/migration/cucm/discovery.py +225 -0
- wxcli/migration/cucm/extractors/__init__.py +1 -0
- wxcli/migration/cucm/extractors/announcements.py +92 -0
- wxcli/migration/cucm/extractors/base.py +90 -0
- wxcli/migration/cucm/extractors/device_profiles.py +98 -0
- wxcli/migration/cucm/extractors/devices.py +193 -0
- wxcli/migration/cucm/extractors/e911.py +103 -0
- wxcli/migration/cucm/extractors/features.py +309 -0
- wxcli/migration/cucm/extractors/helpers.py +73 -0
- wxcli/migration/cucm/extractors/informational.py +295 -0
- wxcli/migration/cucm/extractors/locations.py +221 -0
- wxcli/migration/cucm/extractors/moh.py +100 -0
- wxcli/migration/cucm/extractors/remote_destinations.py +96 -0
- wxcli/migration/cucm/extractors/routing.py +493 -0
- wxcli/migration/cucm/extractors/shared_lines.py +146 -0
- wxcli/migration/cucm/extractors/templates.py +229 -0
- wxcli/migration/cucm/extractors/tier4.py +173 -0
- wxcli/migration/cucm/extractors/users.py +240 -0
- wxcli/migration/cucm/extractors/voicemail.py +243 -0
- wxcli/migration/cucm/extractors/workspaces.py +88 -0
- wxcli/migration/cucm/unity_connection.py +304 -0
- wxcli/migration/execute/CLAUDE.md +372 -0
- wxcli/migration/execute/__init__.py +303 -0
- wxcli/migration/execute/batch.py +277 -0
- wxcli/migration/execute/dependency.py +483 -0
- wxcli/migration/execute/engine.py +964 -0
- wxcli/migration/execute/handlers.py +2232 -0
- wxcli/migration/execute/planner.py +1939 -0
- wxcli/migration/execute/runtime.py +571 -0
- wxcli/migration/export/CLAUDE.md +49 -0
- wxcli/migration/export/__init__.py +8 -0
- wxcli/migration/export/csv_export.py +126 -0
- wxcli/migration/export/deployment_plan.py +479 -0
- wxcli/migration/export/json_export.py +60 -0
- wxcli/migration/models.py +941 -0
- wxcli/migration/phone_models.py +50 -0
- wxcli/migration/preflight/CLAUDE.md +52 -0
- wxcli/migration/preflight/__init__.py +89 -0
- wxcli/migration/preflight/checks.py +911 -0
- wxcli/migration/preflight/runner.py +293 -0
- wxcli/migration/rate_limiter.py +144 -0
- wxcli/migration/report/CLAUDE.md +245 -0
- wxcli/migration/report/__init__.py +7 -0
- wxcli/migration/report/appendix.py +2437 -0
- wxcli/migration/report/assembler.py +183 -0
- wxcli/migration/report/charts.py +263 -0
- wxcli/migration/report/executive.py +776 -0
- wxcli/migration/report/explainer.py +704 -0
- wxcli/migration/report/helpers.py +74 -0
- wxcli/migration/report/ingest.py +152 -0
- wxcli/migration/report/notice_templates.py +192 -0
- wxcli/migration/report/score.py +375 -0
- wxcli/migration/report/styles.py +1052 -0
- wxcli/migration/report/user_diff.py +1052 -0
- wxcli/migration/report/user_notice.py +425 -0
- wxcli/migration/state.py +139 -0
- wxcli/migration/store.py +860 -0
- wxcli/migration/transform/CLAUDE.md +107 -0
- wxcli/migration/transform/__init__.py +12 -0
- wxcli/migration/transform/analysis_pipeline.py +453 -0
- wxcli/migration/transform/analyzers/__init__.py +142 -0
- wxcli/migration/transform/analyzers/css_permission.py +189 -0
- wxcli/migration/transform/analyzers/css_routing.py +335 -0
- wxcli/migration/transform/analyzers/device_compatibility.py +122 -0
- wxcli/migration/transform/analyzers/dn_ambiguity.py +131 -0
- wxcli/migration/transform/analyzers/duplicate_user.py +221 -0
- wxcli/migration/transform/analyzers/extension_conflict.py +173 -0
- wxcli/migration/transform/analyzers/feature_approximation.py +227 -0
- wxcli/migration/transform/analyzers/layout_overflow.py +174 -0
- wxcli/migration/transform/analyzers/location_ambiguity.py +184 -0
- wxcli/migration/transform/analyzers/missing_data.py +300 -0
- wxcli/migration/transform/analyzers/selective_call_handling.py +394 -0
- wxcli/migration/transform/analyzers/shared_line.py +170 -0
- wxcli/migration/transform/analyzers/voicemail_compatibility.py +267 -0
- wxcli/migration/transform/analyzers/workspace_license.py +212 -0
- wxcli/migration/transform/cross_reference.py +1136 -0
- wxcli/migration/transform/cucm_pattern.py +246 -0
- wxcli/migration/transform/decisions.py +301 -0
- wxcli/migration/transform/e164.py +145 -0
- wxcli/migration/transform/engine.py +256 -0
- wxcli/migration/transform/mappers/CLAUDE.md +123 -0
- wxcli/migration/transform/mappers/__init__.py +76 -0
- wxcli/migration/transform/mappers/announcement_mapper.py +122 -0
- wxcli/migration/transform/mappers/base.py +190 -0
- wxcli/migration/transform/mappers/button_template_mapper.py +186 -0
- wxcli/migration/transform/mappers/call_forwarding_mapper.py +228 -0
- wxcli/migration/transform/mappers/call_settings_mapper.py +144 -0
- wxcli/migration/transform/mappers/css_mapper.py +868 -0
- wxcli/migration/transform/mappers/dect_mapper.py +367 -0
- wxcli/migration/transform/mappers/device_layout_mapper.py +289 -0
- wxcli/migration/transform/mappers/device_mapper.py +227 -0
- wxcli/migration/transform/mappers/device_profile_mapper.py +190 -0
- wxcli/migration/transform/mappers/device_settings_mapper.py +464 -0
- wxcli/migration/transform/mappers/e911_mapper.py +129 -0
- wxcli/migration/transform/mappers/ecbn_mapper.py +263 -0
- wxcli/migration/transform/mappers/executive_assistant_mapper.py +156 -0
- wxcli/migration/transform/mappers/feature_mapper.py +1179 -0
- wxcli/migration/transform/mappers/line_mapper.py +310 -0
- wxcli/migration/transform/mappers/location_mapper.py +235 -0
- wxcli/migration/transform/mappers/moh_mapper.py +114 -0
- wxcli/migration/transform/mappers/monitoring_mapper.py +221 -0
- wxcli/migration/transform/mappers/receptionist_mapper.py +245 -0
- wxcli/migration/transform/mappers/routing_mapper.py +821 -0
- wxcli/migration/transform/mappers/snr_mapper.py +201 -0
- wxcli/migration/transform/mappers/softkey_mapper.py +205 -0
- wxcli/migration/transform/mappers/user_mapper.py +264 -0
- wxcli/migration/transform/mappers/voicemail_group_mapper.py +286 -0
- wxcli/migration/transform/mappers/voicemail_mapper.py +514 -0
- wxcli/migration/transform/mappers/workspace_mapper.py +464 -0
- wxcli/migration/transform/normalizers.py +2008 -0
- wxcli/migration/transform/pattern_converter.py +106 -0
- wxcli/migration/transform/pipeline.py +271 -0
- wxcli/migration/transform/rules.py +255 -0
- wxcli/org_health/CLAUDE.md +63 -0
- wxcli/org_health/__init__.py +7 -0
- wxcli/org_health/analyze.py +93 -0
- wxcli/org_health/checks.py +458 -0
- wxcli/org_health/collector.py +62 -0
- wxcli/org_health/models.py +78 -0
- wxcli/org_health/report.py +300 -0
- wxcli/output.py +101 -0
- wxcli-1.2.0.dist-info/METADATA +505 -0
- wxcli-1.2.0.dist-info/RECORD +413 -0
- wxcli-1.2.0.dist-info/WHEEL +5 -0
- wxcli-1.2.0.dist-info/entry_points.txt +2 -0
- wxcli-1.2.0.dist-info/licenses/LICENSE +191 -0
- wxcli-1.2.0.dist-info/scm_file_list.json +751 -0
- wxcli-1.2.0.dist-info/scm_version.json +8 -0
- wxcli-1.2.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,1297 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import typer
|
|
3
|
+
from wxcli.auth import get_api
|
|
4
|
+
from wxcli.errors import WebexError, handle_rest_error
|
|
5
|
+
from wxcli.output import print_table, print_json
|
|
6
|
+
from wxcli.config import get_org_id
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
app = typer.Typer(help="Manage Webex Calling location-settings.")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@app.command("list")
|
|
13
|
+
def cmd_list(
|
|
14
|
+
dial_plan_id: str = typer.Argument(help="dialPlanId"),
|
|
15
|
+
dial_pattern: str = typer.Option(None, "--dial-pattern", help="An enterprise dial pattern is represented by a sequence of d"),
|
|
16
|
+
order: str = typer.Option(None, "--order", help="Order the dial patterns according to the designated fields."),
|
|
17
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
18
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
19
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
20
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
21
|
+
):
|
|
22
|
+
"""Read the List of Dial Patterns."""
|
|
23
|
+
api = get_api(debug=debug)
|
|
24
|
+
url = f"https://webexapis.com/v1/telephony/config/premisePstn/dialPlans/{dial_plan_id}/dialPatterns"
|
|
25
|
+
params = {}
|
|
26
|
+
if dial_pattern is not None:
|
|
27
|
+
params["dialPattern"] = dial_pattern
|
|
28
|
+
if order is not None:
|
|
29
|
+
params["order"] = order
|
|
30
|
+
if limit > 0:
|
|
31
|
+
params["max"] = limit
|
|
32
|
+
if offset > 0:
|
|
33
|
+
params["start"] = offset
|
|
34
|
+
org_id = get_org_id()
|
|
35
|
+
if org_id is not None:
|
|
36
|
+
params["orgId"] = org_id
|
|
37
|
+
result = None
|
|
38
|
+
try:
|
|
39
|
+
result = api.session.rest_get(url, params=params)
|
|
40
|
+
except WebexError as e:
|
|
41
|
+
handle_rest_error(e)
|
|
42
|
+
result = result or []
|
|
43
|
+
items = result.get("dialPatterns", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
44
|
+
if output == "json":
|
|
45
|
+
print_json(items)
|
|
46
|
+
else:
|
|
47
|
+
print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@app.command("list-1")
|
|
52
|
+
def list_1(
|
|
53
|
+
name: str = typer.Option(None, "--name", help="List locations whose name contains this string."),
|
|
54
|
+
order: str = typer.Option(None, "--order", help="Sort the list of locations based on `name`, either asc or de"),
|
|
55
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
56
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
57
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
58
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
59
|
+
):
|
|
60
|
+
"""List Locations Webex Calling Details."""
|
|
61
|
+
api = get_api(debug=debug)
|
|
62
|
+
url = f"https://webexapis.com/v1/telephony/config/locations"
|
|
63
|
+
params = {}
|
|
64
|
+
if name is not None:
|
|
65
|
+
params["name"] = name
|
|
66
|
+
if order is not None:
|
|
67
|
+
params["order"] = order
|
|
68
|
+
if limit > 0:
|
|
69
|
+
params["max"] = limit
|
|
70
|
+
if offset > 0:
|
|
71
|
+
params["start"] = offset
|
|
72
|
+
org_id = get_org_id()
|
|
73
|
+
if org_id is not None:
|
|
74
|
+
params["orgId"] = org_id
|
|
75
|
+
try:
|
|
76
|
+
if limit > 0:
|
|
77
|
+
result = api.session.rest_get(url, params=params)
|
|
78
|
+
result = result or {}
|
|
79
|
+
items = result.get("locations", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
80
|
+
else:
|
|
81
|
+
items = list(api.session.follow_pagination(url=url, params=params, item_key="locations"))
|
|
82
|
+
except WebexError as e:
|
|
83
|
+
handle_rest_error(e)
|
|
84
|
+
if output == "json":
|
|
85
|
+
print_json(items)
|
|
86
|
+
else:
|
|
87
|
+
print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
@app.command("create")
|
|
92
|
+
def create(
|
|
93
|
+
id_param: str = typer.Option(None, "--id", help="(required) A unique identifier for the location."),
|
|
94
|
+
name: str = typer.Option(None, "--name", help="(required) The name of the location."),
|
|
95
|
+
time_zone: str = typer.Option(None, "--time-zone", help="(required) Time zone associated with this location. Refer to this link"),
|
|
96
|
+
preferred_language: str = typer.Option(None, "--preferred-language", help="(required) Default email language."),
|
|
97
|
+
announcement_language: str = typer.Option(None, "--announcement-language", help="(required) Location's phone announcement language."),
|
|
98
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
99
|
+
output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
|
|
100
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
101
|
+
):
|
|
102
|
+
"""Enable a Location for Webex Calling\n\nExample --json-body:\n '{"id":"...","name":"...","timeZone":"...","preferredLanguage":"...","announcementLanguage":"...","address":{"address1":"...","city":"...","state":"...","postalCode":"...","country":"...","address2":"..."}}'."""
|
|
103
|
+
api = get_api(debug=debug)
|
|
104
|
+
url = f"https://webexapis.com/v1/telephony/config/locations"
|
|
105
|
+
params = {}
|
|
106
|
+
org_id = get_org_id()
|
|
107
|
+
if org_id is not None:
|
|
108
|
+
params["orgId"] = org_id
|
|
109
|
+
if json_body:
|
|
110
|
+
body = json.loads(json_body)
|
|
111
|
+
else:
|
|
112
|
+
body = {}
|
|
113
|
+
if id_param is not None:
|
|
114
|
+
body["id"] = id_param
|
|
115
|
+
if name is not None:
|
|
116
|
+
body["name"] = name
|
|
117
|
+
if time_zone is not None:
|
|
118
|
+
body["timeZone"] = time_zone
|
|
119
|
+
if preferred_language is not None:
|
|
120
|
+
body["preferredLanguage"] = preferred_language
|
|
121
|
+
if announcement_language is not None:
|
|
122
|
+
body["announcementLanguage"] = announcement_language
|
|
123
|
+
_missing = [f for f in ['id', 'name', 'timeZone', 'preferredLanguage', 'announcementLanguage'] if f not in body or body[f] is None]
|
|
124
|
+
if _missing:
|
|
125
|
+
typer.echo("Error: Missing required fields: " + ", ".join(_missing), err=True)
|
|
126
|
+
raise typer.Exit(1)
|
|
127
|
+
try:
|
|
128
|
+
result = api.session.rest_post(url, json=body, params=params)
|
|
129
|
+
except WebexError as e:
|
|
130
|
+
handle_rest_error(e)
|
|
131
|
+
if output == "json":
|
|
132
|
+
print_json(result)
|
|
133
|
+
elif isinstance(result, dict) and "id" in result:
|
|
134
|
+
typer.echo(f"Created: {result['id']}")
|
|
135
|
+
elif not result or result == {}:
|
|
136
|
+
typer.echo("Created.")
|
|
137
|
+
else:
|
|
138
|
+
print_json(result)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
@app.command("show")
|
|
143
|
+
def show(
|
|
144
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
145
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
146
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
147
|
+
):
|
|
148
|
+
"""Get Location Webex Calling Details."""
|
|
149
|
+
api = get_api(debug=debug)
|
|
150
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}"
|
|
151
|
+
params = {}
|
|
152
|
+
org_id = get_org_id()
|
|
153
|
+
if org_id is not None:
|
|
154
|
+
params["orgId"] = org_id
|
|
155
|
+
try:
|
|
156
|
+
result = api.session.rest_get(url, params=params)
|
|
157
|
+
except WebexError as e:
|
|
158
|
+
handle_rest_error(e)
|
|
159
|
+
if output == "json":
|
|
160
|
+
print_json(result)
|
|
161
|
+
else:
|
|
162
|
+
if isinstance(result, dict):
|
|
163
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
164
|
+
elif isinstance(result, list):
|
|
165
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
166
|
+
else:
|
|
167
|
+
print_json(result)
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
@app.command("update")
|
|
172
|
+
def update(
|
|
173
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
174
|
+
announcement_language: str = typer.Option(None, "--announcement-language", help="Location's phone announcement language."),
|
|
175
|
+
external_caller_id_name: str = typer.Option(None, "--external-caller-id-name", help="External caller ID name value. Unicode characters."),
|
|
176
|
+
p_access_network_info: str = typer.Option(None, "--p-access-network-info", help="Emergency Location Identifier for a location. The `pAccessNe"),
|
|
177
|
+
outside_dial_digit: str = typer.Option(None, "--outside-dial-digit", help="Must dial to reach an outside line. Default is none."),
|
|
178
|
+
enforce_outside_dial_digit: bool = typer.Option(None, "--enforce-outside-dial-digit/--no-enforce-outside-dial-digit", help="True when enforcing outside dial digit at location level to"),
|
|
179
|
+
routing_prefix: str = typer.Option(None, "--routing-prefix", help="Must dial a prefix when calling between locations having sam"),
|
|
180
|
+
charge_number: str = typer.Option(None, "--charge-number", help="Set the chargeable number for the line placing the call. Wh"),
|
|
181
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
182
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
183
|
+
):
|
|
184
|
+
"""Update Location Webex Calling Details\n\nExample --json-body:\n '{"announcementLanguage":"...","callingLineId":{"name":"...","phoneNumber":"..."},"connection":{"type":"ROUTE_GROUP","id":"..."},"externalCallerIdName":"...","pAccessNetworkInfo":"...","outsideDialDigit":"...","enforceOutsideDialDigit":true,"routingPrefix":"..."}'."""
|
|
185
|
+
api = get_api(debug=debug)
|
|
186
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}"
|
|
187
|
+
params = {}
|
|
188
|
+
org_id = get_org_id()
|
|
189
|
+
if org_id is not None:
|
|
190
|
+
params["orgId"] = org_id
|
|
191
|
+
if json_body:
|
|
192
|
+
body = json.loads(json_body)
|
|
193
|
+
else:
|
|
194
|
+
body = {}
|
|
195
|
+
if announcement_language is not None:
|
|
196
|
+
body["announcementLanguage"] = announcement_language
|
|
197
|
+
if external_caller_id_name is not None:
|
|
198
|
+
body["externalCallerIdName"] = external_caller_id_name
|
|
199
|
+
if p_access_network_info is not None:
|
|
200
|
+
body["pAccessNetworkInfo"] = p_access_network_info
|
|
201
|
+
if outside_dial_digit is not None:
|
|
202
|
+
body["outsideDialDigit"] = outside_dial_digit
|
|
203
|
+
if enforce_outside_dial_digit is not None:
|
|
204
|
+
body["enforceOutsideDialDigit"] = enforce_outside_dial_digit
|
|
205
|
+
if routing_prefix is not None:
|
|
206
|
+
body["routingPrefix"] = routing_prefix
|
|
207
|
+
if charge_number is not None:
|
|
208
|
+
body["chargeNumber"] = charge_number
|
|
209
|
+
try:
|
|
210
|
+
result = api.session.rest_put(url, json=body, params=params)
|
|
211
|
+
except WebexError as e:
|
|
212
|
+
handle_rest_error(e)
|
|
213
|
+
typer.echo(f"Updated.")
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
@app.command("list-update-routing-prefix")
|
|
218
|
+
def list_update_routing_prefix(
|
|
219
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
220
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
221
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
222
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
223
|
+
):
|
|
224
|
+
"""Get a List of Update Routing Prefix jobs."""
|
|
225
|
+
api = get_api(debug=debug)
|
|
226
|
+
url = f"https://webexapis.com/v1/telephony/config/jobs/updateRoutingPrefix"
|
|
227
|
+
params = {}
|
|
228
|
+
if limit > 0:
|
|
229
|
+
params["max"] = limit
|
|
230
|
+
if offset > 0:
|
|
231
|
+
params["start"] = offset
|
|
232
|
+
org_id = get_org_id()
|
|
233
|
+
if org_id is not None:
|
|
234
|
+
params["orgId"] = org_id
|
|
235
|
+
result = None
|
|
236
|
+
try:
|
|
237
|
+
result = api.session.rest_get(url, params=params)
|
|
238
|
+
except WebexError as e:
|
|
239
|
+
handle_rest_error(e)
|
|
240
|
+
result = result or []
|
|
241
|
+
items = result.get("items", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
242
|
+
if output == "json":
|
|
243
|
+
print_json(items)
|
|
244
|
+
else:
|
|
245
|
+
print_table(items, columns=[('ID', 'id'), ('Status', 'latestExecutionStatus')], limit=limit)
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
@app.command("show-update-routing-prefix")
|
|
250
|
+
def show_update_routing_prefix(
|
|
251
|
+
job_id: str = typer.Argument(help="jobId"),
|
|
252
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
253
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
254
|
+
):
|
|
255
|
+
"""Get the job status of Update Routing Prefix job."""
|
|
256
|
+
api = get_api(debug=debug)
|
|
257
|
+
url = f"https://webexapis.com/v1/telephony/config/jobs/updateRoutingPrefix/{job_id}"
|
|
258
|
+
params = {}
|
|
259
|
+
org_id = get_org_id()
|
|
260
|
+
if org_id is not None:
|
|
261
|
+
params["orgId"] = org_id
|
|
262
|
+
try:
|
|
263
|
+
result = api.session.rest_get(url, params=params)
|
|
264
|
+
except WebexError as e:
|
|
265
|
+
handle_rest_error(e)
|
|
266
|
+
if output == "json":
|
|
267
|
+
print_json(result)
|
|
268
|
+
else:
|
|
269
|
+
if isinstance(result, dict):
|
|
270
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
271
|
+
elif isinstance(result, list):
|
|
272
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
273
|
+
else:
|
|
274
|
+
print_json(result)
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
@app.command("show-errors")
|
|
279
|
+
def show_errors(
|
|
280
|
+
job_id: str = typer.Argument(help="jobId"),
|
|
281
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
282
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
283
|
+
):
|
|
284
|
+
"""Get job errors for update routing prefix job."""
|
|
285
|
+
api = get_api(debug=debug)
|
|
286
|
+
url = f"https://webexapis.com/v1/telephony/config/jobs/updateRoutingPrefix/{job_id}/errors"
|
|
287
|
+
params = {}
|
|
288
|
+
org_id = get_org_id()
|
|
289
|
+
if org_id is not None:
|
|
290
|
+
params["orgId"] = org_id
|
|
291
|
+
try:
|
|
292
|
+
result = api.session.rest_get(url, params=params)
|
|
293
|
+
except WebexError as e:
|
|
294
|
+
handle_rest_error(e)
|
|
295
|
+
if output == "json":
|
|
296
|
+
print_json(result)
|
|
297
|
+
else:
|
|
298
|
+
if isinstance(result, dict):
|
|
299
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
300
|
+
elif isinstance(result, list):
|
|
301
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
302
|
+
else:
|
|
303
|
+
print_json(result)
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
@app.command("change-announcement-language")
|
|
308
|
+
def change_announcement_language(
|
|
309
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
310
|
+
agent_enabled: str = typer.Option(None, "--agent-enabled", help="Set to `true` to change announcement language for existing p"),
|
|
311
|
+
service_enabled: str = typer.Option(None, "--service-enabled", help="Set to `true` to change announcement language for existing f"),
|
|
312
|
+
announcement_language_code: str = typer.Option(None, "--announcement-language-code", help="Language code."),
|
|
313
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body"),
|
|
314
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
315
|
+
):
|
|
316
|
+
"""Change Announcement Language."""
|
|
317
|
+
api = get_api(debug=debug)
|
|
318
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/actions/modifyAnnouncementLanguage/invoke"
|
|
319
|
+
params = {}
|
|
320
|
+
org_id = get_org_id()
|
|
321
|
+
if org_id is not None:
|
|
322
|
+
params["orgId"] = org_id
|
|
323
|
+
if json_body:
|
|
324
|
+
body = json.loads(json_body)
|
|
325
|
+
else:
|
|
326
|
+
body = {}
|
|
327
|
+
if agent_enabled is not None:
|
|
328
|
+
body["agentEnabled"] = agent_enabled
|
|
329
|
+
if service_enabled is not None:
|
|
330
|
+
body["serviceEnabled"] = service_enabled
|
|
331
|
+
if announcement_language_code is not None:
|
|
332
|
+
body["announcementLanguageCode"] = announcement_language_code
|
|
333
|
+
try:
|
|
334
|
+
result = api.session.rest_post(url, json=body, params=params)
|
|
335
|
+
except WebexError as e:
|
|
336
|
+
handle_rest_error(e)
|
|
337
|
+
print_json(result)
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
@app.command("show-emergency-callback-number")
|
|
342
|
+
def show_emergency_callback_number(
|
|
343
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
344
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
345
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
346
|
+
):
|
|
347
|
+
"""Get a Location Emergency callback number."""
|
|
348
|
+
api = get_api(debug=debug)
|
|
349
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/features/emergencyCallbackNumber"
|
|
350
|
+
params = {}
|
|
351
|
+
org_id = get_org_id()
|
|
352
|
+
if org_id is not None:
|
|
353
|
+
params["orgId"] = org_id
|
|
354
|
+
try:
|
|
355
|
+
result = api.session.rest_get(url, params=params)
|
|
356
|
+
except WebexError as e:
|
|
357
|
+
handle_rest_error(e)
|
|
358
|
+
if output == "json":
|
|
359
|
+
print_json(result)
|
|
360
|
+
else:
|
|
361
|
+
if isinstance(result, dict):
|
|
362
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
363
|
+
elif isinstance(result, list):
|
|
364
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
365
|
+
else:
|
|
366
|
+
print_json(result)
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
@app.command("update-emergency-callback-number")
|
|
371
|
+
def update_emergency_callback_number(
|
|
372
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
373
|
+
selected: str = typer.Option(None, "--selected", help="Choices: LOCATION_NUMBER, LOCATION_MEMBER_NUMBER"),
|
|
374
|
+
location_member_id: str = typer.Option(None, "--location-member-id", help="Member ID of user/place/virtual line/hunt group within the l"),
|
|
375
|
+
elin_expiry_time_minutes: str = typer.Option(None, "--elin-expiry-time-minutes", help="ELIN (Emergency Location Identification Number) provides loc"),
|
|
376
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
377
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
378
|
+
):
|
|
379
|
+
"""Update a Location Emergency callback number\n\nExample --json-body:\n '{"selected":"LOCATION_NUMBER","locationMemberId":"...","elinExpiryTimeMinutes":0}'."""
|
|
380
|
+
api = get_api(debug=debug)
|
|
381
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/features/emergencyCallbackNumber"
|
|
382
|
+
params = {}
|
|
383
|
+
org_id = get_org_id()
|
|
384
|
+
if org_id is not None:
|
|
385
|
+
params["orgId"] = org_id
|
|
386
|
+
if json_body:
|
|
387
|
+
body = json.loads(json_body)
|
|
388
|
+
else:
|
|
389
|
+
body = {}
|
|
390
|
+
if selected is not None:
|
|
391
|
+
body["selected"] = selected
|
|
392
|
+
if location_member_id is not None:
|
|
393
|
+
body["locationMemberId"] = location_member_id
|
|
394
|
+
if elin_expiry_time_minutes is not None:
|
|
395
|
+
body["elinExpiryTimeMinutes"] = elin_expiry_time_minutes
|
|
396
|
+
try:
|
|
397
|
+
result = api.session.rest_put(url, json=body, params=params)
|
|
398
|
+
except WebexError as e:
|
|
399
|
+
handle_rest_error(e)
|
|
400
|
+
typer.echo(f"Updated.")
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
@app.command("validate-the-list")
|
|
405
|
+
def validate_the_list(
|
|
406
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body"),
|
|
407
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
408
|
+
):
|
|
409
|
+
"""Validate the List of Extensions\n\nExample --json-body:\n '{"extensions":["..."]}'."""
|
|
410
|
+
api = get_api(debug=debug)
|
|
411
|
+
url = f"https://webexapis.com/v1/telephony/config/actions/validateExtensions/invoke"
|
|
412
|
+
params = {}
|
|
413
|
+
org_id = get_org_id()
|
|
414
|
+
if org_id is not None:
|
|
415
|
+
params["orgId"] = org_id
|
|
416
|
+
if json_body:
|
|
417
|
+
body = json.loads(json_body)
|
|
418
|
+
else:
|
|
419
|
+
body = {}
|
|
420
|
+
try:
|
|
421
|
+
result = api.session.rest_post(url, json=body, params=params)
|
|
422
|
+
except WebexError as e:
|
|
423
|
+
handle_rest_error(e)
|
|
424
|
+
print_json(result)
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
@app.command("validate-extensions")
|
|
429
|
+
def validate_extensions(
|
|
430
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
431
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body"),
|
|
432
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
433
|
+
):
|
|
434
|
+
"""Validate Extensions\n\nExample --json-body:\n '{"extensions":["..."]}'."""
|
|
435
|
+
api = get_api(debug=debug)
|
|
436
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/actions/validateExtensions/invoke"
|
|
437
|
+
params = {}
|
|
438
|
+
org_id = get_org_id()
|
|
439
|
+
if org_id is not None:
|
|
440
|
+
params["orgId"] = org_id
|
|
441
|
+
if json_body:
|
|
442
|
+
body = json.loads(json_body)
|
|
443
|
+
else:
|
|
444
|
+
body = {}
|
|
445
|
+
try:
|
|
446
|
+
result = api.session.rest_post(url, json=body, params=params)
|
|
447
|
+
except WebexError as e:
|
|
448
|
+
handle_rest_error(e)
|
|
449
|
+
print_json(result)
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
@app.command("show-music-on-hold")
|
|
454
|
+
def show_music_on_hold(
|
|
455
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
456
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
457
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
458
|
+
):
|
|
459
|
+
"""Get Music On Hold."""
|
|
460
|
+
api = get_api(debug=debug)
|
|
461
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/musicOnHold"
|
|
462
|
+
params = {}
|
|
463
|
+
org_id = get_org_id()
|
|
464
|
+
if org_id is not None:
|
|
465
|
+
params["orgId"] = org_id
|
|
466
|
+
try:
|
|
467
|
+
result = api.session.rest_get(url, params=params)
|
|
468
|
+
except WebexError as e:
|
|
469
|
+
handle_rest_error(e)
|
|
470
|
+
if output == "json":
|
|
471
|
+
print_json(result)
|
|
472
|
+
else:
|
|
473
|
+
if isinstance(result, dict):
|
|
474
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
475
|
+
elif isinstance(result, list):
|
|
476
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
477
|
+
else:
|
|
478
|
+
print_json(result)
|
|
479
|
+
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
@app.command("update-music-on-hold")
|
|
483
|
+
def update_music_on_hold(
|
|
484
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
485
|
+
moh_enabled: bool = typer.Option(None, "--moh-enabled/--no-moh-enabled", help="Music on hold is enabled or disabled for the workspace."),
|
|
486
|
+
greeting: str = typer.Option(None, "--greeting", help="Choices: DEFAULT, CUSTOM"),
|
|
487
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
488
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
489
|
+
):
|
|
490
|
+
"""Update Music On Hold\n\nExample --json-body:\n '{"mohEnabled":true,"greeting":"DEFAULT","audioAnnouncementFile":{"id":"...","fileName":"...","mediaFileType":"WAV","level":"ORGANIZATION"}}'."""
|
|
491
|
+
api = get_api(debug=debug)
|
|
492
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/musicOnHold"
|
|
493
|
+
params = {}
|
|
494
|
+
org_id = get_org_id()
|
|
495
|
+
if org_id is not None:
|
|
496
|
+
params["orgId"] = org_id
|
|
497
|
+
if json_body:
|
|
498
|
+
body = json.loads(json_body)
|
|
499
|
+
else:
|
|
500
|
+
body = {}
|
|
501
|
+
if moh_enabled is not None:
|
|
502
|
+
body["mohEnabled"] = moh_enabled
|
|
503
|
+
if greeting is not None:
|
|
504
|
+
body["greeting"] = greeting
|
|
505
|
+
try:
|
|
506
|
+
result = api.session.rest_put(url, json=body, params=params)
|
|
507
|
+
except WebexError as e:
|
|
508
|
+
handle_rest_error(e)
|
|
509
|
+
typer.echo(f"Updated.")
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
|
|
513
|
+
@app.command("show-private-network-connect")
|
|
514
|
+
def show_private_network_connect(
|
|
515
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
516
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
517
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
518
|
+
):
|
|
519
|
+
"""Get Private Network Connect."""
|
|
520
|
+
api = get_api(debug=debug)
|
|
521
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/privateNetworkConnect"
|
|
522
|
+
params = {}
|
|
523
|
+
org_id = get_org_id()
|
|
524
|
+
if org_id is not None:
|
|
525
|
+
params["orgId"] = org_id
|
|
526
|
+
try:
|
|
527
|
+
result = api.session.rest_get(url, params=params)
|
|
528
|
+
except WebexError as e:
|
|
529
|
+
handle_rest_error(e)
|
|
530
|
+
if output == "json":
|
|
531
|
+
print_json(result)
|
|
532
|
+
else:
|
|
533
|
+
if isinstance(result, dict):
|
|
534
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
535
|
+
elif isinstance(result, list):
|
|
536
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
537
|
+
else:
|
|
538
|
+
print_json(result)
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
|
|
542
|
+
@app.command("update-private-network-connect")
|
|
543
|
+
def update_private_network_connect(
|
|
544
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
545
|
+
network_connection_type: str = typer.Option(None, "--network-connection-type", help="Choices: PUBLIC_INTERNET, PRIVATE_NETWORK"),
|
|
546
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
547
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
548
|
+
):
|
|
549
|
+
"""Update Private Network Connect."""
|
|
550
|
+
api = get_api(debug=debug)
|
|
551
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/privateNetworkConnect"
|
|
552
|
+
params = {}
|
|
553
|
+
org_id = get_org_id()
|
|
554
|
+
if org_id is not None:
|
|
555
|
+
params["orgId"] = org_id
|
|
556
|
+
if json_body:
|
|
557
|
+
body = json.loads(json_body)
|
|
558
|
+
else:
|
|
559
|
+
body = {}
|
|
560
|
+
if network_connection_type is not None:
|
|
561
|
+
body["networkConnectionType"] = network_connection_type
|
|
562
|
+
try:
|
|
563
|
+
result = api.session.rest_put(url, json=body, params=params)
|
|
564
|
+
except WebexError as e:
|
|
565
|
+
handle_rest_error(e)
|
|
566
|
+
typer.echo(f"Updated.")
|
|
567
|
+
|
|
568
|
+
|
|
569
|
+
|
|
570
|
+
@app.command("list-route-choices")
|
|
571
|
+
def list_route_choices(
|
|
572
|
+
route_group_name: str = typer.Option(None, "--route-group-name", help="Return the list of route identities matching the Route group"),
|
|
573
|
+
trunk_name: str = typer.Option(None, "--trunk-name", help="Return the list of route identities matching the Trunk name."),
|
|
574
|
+
order: str = typer.Option(None, "--order", help="Order the route identities according to the designated field"),
|
|
575
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
576
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
577
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
578
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
579
|
+
):
|
|
580
|
+
"""Read the List of Routing Choices."""
|
|
581
|
+
api = get_api(debug=debug)
|
|
582
|
+
url = f"https://webexapis.com/v1/telephony/config/routeChoices"
|
|
583
|
+
params = {}
|
|
584
|
+
if route_group_name is not None:
|
|
585
|
+
params["routeGroupName"] = route_group_name
|
|
586
|
+
if trunk_name is not None:
|
|
587
|
+
params["trunkName"] = trunk_name
|
|
588
|
+
if order is not None:
|
|
589
|
+
params["order"] = order
|
|
590
|
+
if limit > 0:
|
|
591
|
+
params["max"] = limit
|
|
592
|
+
if offset > 0:
|
|
593
|
+
params["start"] = offset
|
|
594
|
+
org_id = get_org_id()
|
|
595
|
+
if org_id is not None:
|
|
596
|
+
params["orgId"] = org_id
|
|
597
|
+
result = None
|
|
598
|
+
try:
|
|
599
|
+
result = api.session.rest_get(url, params=params)
|
|
600
|
+
except WebexError as e:
|
|
601
|
+
handle_rest_error(e)
|
|
602
|
+
result = result or []
|
|
603
|
+
items = result.get("routeIdentities", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
604
|
+
if output == "json":
|
|
605
|
+
print_json(items)
|
|
606
|
+
else:
|
|
607
|
+
print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
|
|
608
|
+
|
|
609
|
+
|
|
610
|
+
|
|
611
|
+
@app.command("list-available-numbers-external-caller-id")
|
|
612
|
+
def list_available_numbers_external_caller_id(
|
|
613
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
614
|
+
phone_number: str = typer.Option(None, "--phone-number", help="Filter phone numbers based on the provided list in the `phon"),
|
|
615
|
+
owner_name: str = typer.Option(None, "--owner-name", help="Return the list of phone numbers that are owned by the given"),
|
|
616
|
+
person_id: str = typer.Option(None, "--person-id", help="Retrieve available external caller ID numbers for this perso"),
|
|
617
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
618
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
619
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
620
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
621
|
+
):
|
|
622
|
+
"""Get the List of Phone Numbers Available for External Caller ID."""
|
|
623
|
+
api = get_api(debug=debug)
|
|
624
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/externalCallerId/availableNumbers"
|
|
625
|
+
params = {}
|
|
626
|
+
if phone_number is not None:
|
|
627
|
+
params["phoneNumber"] = phone_number
|
|
628
|
+
if owner_name is not None:
|
|
629
|
+
params["ownerName"] = owner_name
|
|
630
|
+
if person_id is not None:
|
|
631
|
+
params["personId"] = person_id
|
|
632
|
+
if limit > 0:
|
|
633
|
+
params["max"] = limit
|
|
634
|
+
if offset > 0:
|
|
635
|
+
params["start"] = offset
|
|
636
|
+
org_id = get_org_id()
|
|
637
|
+
if org_id is not None:
|
|
638
|
+
params["orgId"] = org_id
|
|
639
|
+
result = None
|
|
640
|
+
try:
|
|
641
|
+
result = api.session.rest_get(url, params=params)
|
|
642
|
+
except WebexError as e:
|
|
643
|
+
handle_rest_error(e)
|
|
644
|
+
result = result or []
|
|
645
|
+
items = result.get("phoneNumbers", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
646
|
+
if output == "json":
|
|
647
|
+
print_json(items)
|
|
648
|
+
else:
|
|
649
|
+
print_table(items, columns=[('Phone Number', 'phoneNumber'), ('State', 'state')], limit=limit)
|
|
650
|
+
|
|
651
|
+
|
|
652
|
+
|
|
653
|
+
@app.command("list-available-numbers-locations")
|
|
654
|
+
def list_available_numbers_locations(
|
|
655
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
656
|
+
phone_number: str = typer.Option(None, "--phone-number", help="Filter phone numbers based on the comma-separated list provi"),
|
|
657
|
+
owner_name: str = typer.Option(None, "--owner-name", help="Return the list of phone numbers that are owned by the given"),
|
|
658
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
659
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
660
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
661
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
662
|
+
):
|
|
663
|
+
"""Get Available Phone Numbers for a Location with Given Criteria."""
|
|
664
|
+
api = get_api(debug=debug)
|
|
665
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/availableNumbers"
|
|
666
|
+
params = {}
|
|
667
|
+
if phone_number is not None:
|
|
668
|
+
params["phoneNumber"] = phone_number
|
|
669
|
+
if owner_name is not None:
|
|
670
|
+
params["ownerName"] = owner_name
|
|
671
|
+
if limit > 0:
|
|
672
|
+
params["max"] = limit
|
|
673
|
+
if offset > 0:
|
|
674
|
+
params["start"] = offset
|
|
675
|
+
org_id = get_org_id()
|
|
676
|
+
if org_id is not None:
|
|
677
|
+
params["orgId"] = org_id
|
|
678
|
+
result = None
|
|
679
|
+
try:
|
|
680
|
+
result = api.session.rest_get(url, params=params)
|
|
681
|
+
except WebexError as e:
|
|
682
|
+
handle_rest_error(e)
|
|
683
|
+
result = result or []
|
|
684
|
+
items = result.get("phoneNumbers", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
685
|
+
if output == "json":
|
|
686
|
+
print_json(items)
|
|
687
|
+
else:
|
|
688
|
+
print_table(items, columns=[('Phone Number', 'phoneNumber'), ('State', 'state')], limit=limit)
|
|
689
|
+
|
|
690
|
+
|
|
691
|
+
|
|
692
|
+
@app.command("list-available-numbers-webex-go")
|
|
693
|
+
def list_available_numbers_webex_go(
|
|
694
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
695
|
+
phone_number: str = typer.Option(None, "--phone-number", help="Filter phone numbers based on the comma-separated list provi"),
|
|
696
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
697
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
698
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
699
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
700
|
+
):
|
|
701
|
+
"""Get Webex Go Available Phone Numbers."""
|
|
702
|
+
api = get_api(debug=debug)
|
|
703
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/webexGo/availableNumbers"
|
|
704
|
+
params = {}
|
|
705
|
+
if phone_number is not None:
|
|
706
|
+
params["phoneNumber"] = phone_number
|
|
707
|
+
if limit > 0:
|
|
708
|
+
params["max"] = limit
|
|
709
|
+
if offset > 0:
|
|
710
|
+
params["start"] = offset
|
|
711
|
+
org_id = get_org_id()
|
|
712
|
+
if org_id is not None:
|
|
713
|
+
params["orgId"] = org_id
|
|
714
|
+
result = None
|
|
715
|
+
try:
|
|
716
|
+
result = api.session.rest_get(url, params=params)
|
|
717
|
+
except WebexError as e:
|
|
718
|
+
handle_rest_error(e)
|
|
719
|
+
result = result or []
|
|
720
|
+
items = result.get("phoneNumbers", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
721
|
+
if output == "json":
|
|
722
|
+
print_json(items)
|
|
723
|
+
else:
|
|
724
|
+
print_table(items, columns=[('Phone Number', 'phoneNumber'), ('State', 'state')], limit=limit)
|
|
725
|
+
|
|
726
|
+
|
|
727
|
+
|
|
728
|
+
@app.command("list-available-numbers-emergency-callback-number")
|
|
729
|
+
def list_available_numbers_emergency_callback_number(
|
|
730
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
731
|
+
phone_number: str = typer.Option(None, "--phone-number", help="Filter phone numbers based on the comma-separated list provi"),
|
|
732
|
+
owner_name: str = typer.Option(None, "--owner-name", help="Return the list of phone numbers that are owned by the given"),
|
|
733
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
734
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
735
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
736
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
737
|
+
):
|
|
738
|
+
"""Get Location ECBN Available Phone Numbers."""
|
|
739
|
+
api = get_api(debug=debug)
|
|
740
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/emergencyCallbackNumber/availableNumbers"
|
|
741
|
+
params = {}
|
|
742
|
+
if phone_number is not None:
|
|
743
|
+
params["phoneNumber"] = phone_number
|
|
744
|
+
if owner_name is not None:
|
|
745
|
+
params["ownerName"] = owner_name
|
|
746
|
+
if limit > 0:
|
|
747
|
+
params["max"] = limit
|
|
748
|
+
if offset > 0:
|
|
749
|
+
params["start"] = offset
|
|
750
|
+
org_id = get_org_id()
|
|
751
|
+
if org_id is not None:
|
|
752
|
+
params["orgId"] = org_id
|
|
753
|
+
result = None
|
|
754
|
+
try:
|
|
755
|
+
result = api.session.rest_get(url, params=params)
|
|
756
|
+
except WebexError as e:
|
|
757
|
+
handle_rest_error(e)
|
|
758
|
+
result = result or []
|
|
759
|
+
items = result.get("phoneNumbers", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
760
|
+
if output == "json":
|
|
761
|
+
print_json(items)
|
|
762
|
+
else:
|
|
763
|
+
print_table(items, columns=[('Phone Number', 'phoneNumber'), ('State', 'state')], limit=limit)
|
|
764
|
+
|
|
765
|
+
|
|
766
|
+
|
|
767
|
+
@app.command("list-available-numbers-call-intercept")
|
|
768
|
+
def list_available_numbers_call_intercept(
|
|
769
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
770
|
+
phone_number: str = typer.Option(None, "--phone-number", help="Filter phone numbers based on the comma-separated list provi"),
|
|
771
|
+
owner_name: str = typer.Option(None, "--owner-name", help="Return the list of phone numbers that are owned by the given"),
|
|
772
|
+
extension: str = typer.Option(None, "--extension", help="Returns the list of phone numbers with the given `extension`"),
|
|
773
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
774
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
775
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
776
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
777
|
+
):
|
|
778
|
+
"""Get Location Call Intercept Available Phone Numbers."""
|
|
779
|
+
api = get_api(debug=debug)
|
|
780
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/callIntercept/availableNumbers"
|
|
781
|
+
params = {}
|
|
782
|
+
if phone_number is not None:
|
|
783
|
+
params["phoneNumber"] = phone_number
|
|
784
|
+
if owner_name is not None:
|
|
785
|
+
params["ownerName"] = owner_name
|
|
786
|
+
if extension is not None:
|
|
787
|
+
params["extension"] = extension
|
|
788
|
+
if limit > 0:
|
|
789
|
+
params["max"] = limit
|
|
790
|
+
if offset > 0:
|
|
791
|
+
params["start"] = offset
|
|
792
|
+
org_id = get_org_id()
|
|
793
|
+
if org_id is not None:
|
|
794
|
+
params["orgId"] = org_id
|
|
795
|
+
result = None
|
|
796
|
+
try:
|
|
797
|
+
result = api.session.rest_get(url, params=params)
|
|
798
|
+
except WebexError as e:
|
|
799
|
+
handle_rest_error(e)
|
|
800
|
+
result = result or []
|
|
801
|
+
items = result.get("phoneNumbers", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
802
|
+
if output == "json":
|
|
803
|
+
print_json(items)
|
|
804
|
+
else:
|
|
805
|
+
print_table(items, columns=[('Phone Number', 'phoneNumber'), ('State', 'state')], limit=limit)
|
|
806
|
+
|
|
807
|
+
|
|
808
|
+
|
|
809
|
+
@app.command("list-directories")
|
|
810
|
+
def list_directories(
|
|
811
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
812
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
813
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
814
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
815
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
816
|
+
):
|
|
817
|
+
"""Read list of Receptionist Contact Directories."""
|
|
818
|
+
api = get_api(debug=debug)
|
|
819
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/receptionistContacts/directories"
|
|
820
|
+
params = {}
|
|
821
|
+
if limit > 0:
|
|
822
|
+
params["max"] = limit
|
|
823
|
+
if offset > 0:
|
|
824
|
+
params["start"] = offset
|
|
825
|
+
org_id = get_org_id()
|
|
826
|
+
if org_id is not None:
|
|
827
|
+
params["orgId"] = org_id
|
|
828
|
+
result = None
|
|
829
|
+
try:
|
|
830
|
+
result = api.session.rest_get(url, params=params)
|
|
831
|
+
except WebexError as e:
|
|
832
|
+
handle_rest_error(e)
|
|
833
|
+
result = result or []
|
|
834
|
+
items = result.get("directories", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
835
|
+
if output == "json":
|
|
836
|
+
print_json(items)
|
|
837
|
+
else:
|
|
838
|
+
print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
|
|
839
|
+
|
|
840
|
+
|
|
841
|
+
|
|
842
|
+
@app.command("create-directories")
|
|
843
|
+
def create_directories(
|
|
844
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
845
|
+
name: str = typer.Option(None, "--name", help="(required) Receptionist Contact Directory name. The directory name shou"),
|
|
846
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
847
|
+
output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
|
|
848
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
849
|
+
):
|
|
850
|
+
"""Create a Receptionist Contact Directory\n\nExample --json-body:\n '{"name":"...","contacts":[{"personId":"...","featureId":"...","type":"..."}]}'."""
|
|
851
|
+
api = get_api(debug=debug)
|
|
852
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/receptionistContacts/directories"
|
|
853
|
+
params = {}
|
|
854
|
+
org_id = get_org_id()
|
|
855
|
+
if org_id is not None:
|
|
856
|
+
params["orgId"] = org_id
|
|
857
|
+
if json_body:
|
|
858
|
+
body = json.loads(json_body)
|
|
859
|
+
else:
|
|
860
|
+
body = {}
|
|
861
|
+
if name is not None:
|
|
862
|
+
body["name"] = name
|
|
863
|
+
_missing = [f for f in ['name'] if f not in body or body[f] is None]
|
|
864
|
+
if _missing:
|
|
865
|
+
typer.echo("Error: Missing required fields: " + ", ".join(_missing), err=True)
|
|
866
|
+
raise typer.Exit(1)
|
|
867
|
+
try:
|
|
868
|
+
result = api.session.rest_post(url, json=body, params=params)
|
|
869
|
+
except WebexError as e:
|
|
870
|
+
handle_rest_error(e)
|
|
871
|
+
if output == "json":
|
|
872
|
+
print_json(result)
|
|
873
|
+
elif isinstance(result, dict) and "id" in result:
|
|
874
|
+
typer.echo(f"Created: {result['id']}")
|
|
875
|
+
elif not result or result == {}:
|
|
876
|
+
typer.echo("Created.")
|
|
877
|
+
else:
|
|
878
|
+
print_json(result)
|
|
879
|
+
|
|
880
|
+
|
|
881
|
+
|
|
882
|
+
@app.command("show-directories")
|
|
883
|
+
def show_directories(
|
|
884
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
885
|
+
directory_id: str = typer.Argument(help="directoryId"),
|
|
886
|
+
search_criteria_mode_or: str = typer.Option(None, "--search-criteria-mode-or", help="When `true`, results matching any one of the search criteria"),
|
|
887
|
+
first_name: str = typer.Option(None, "--first-name", help="Search for directories that contain people with the indicate"),
|
|
888
|
+
last_name: str = typer.Option(None, "--last-name", help="Search for directories that contain people with the indicate"),
|
|
889
|
+
phone_number: str = typer.Option(None, "--phone-number", help="Search for directories that contain people with the indicate"),
|
|
890
|
+
extension: str = typer.Option(None, "--extension", help="Search for directories that contain people with the indicate"),
|
|
891
|
+
person_id: str = typer.Option(None, "--person-id", help="Search for directories that contain people with the indicate"),
|
|
892
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
893
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
894
|
+
):
|
|
895
|
+
"""Get details for a Receptionist Contact Directory."""
|
|
896
|
+
api = get_api(debug=debug)
|
|
897
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/receptionistContacts/directories/{directory_id}"
|
|
898
|
+
params = {}
|
|
899
|
+
if search_criteria_mode_or is not None:
|
|
900
|
+
params["searchCriteriaModeOr"] = search_criteria_mode_or
|
|
901
|
+
if first_name is not None:
|
|
902
|
+
params["firstName"] = first_name
|
|
903
|
+
if last_name is not None:
|
|
904
|
+
params["lastName"] = last_name
|
|
905
|
+
if phone_number is not None:
|
|
906
|
+
params["phoneNumber"] = phone_number
|
|
907
|
+
if extension is not None:
|
|
908
|
+
params["extension"] = extension
|
|
909
|
+
if person_id is not None:
|
|
910
|
+
params["personId"] = person_id
|
|
911
|
+
org_id = get_org_id()
|
|
912
|
+
if org_id is not None:
|
|
913
|
+
params["orgId"] = org_id
|
|
914
|
+
try:
|
|
915
|
+
result = api.session.rest_get(url, params=params)
|
|
916
|
+
except WebexError as e:
|
|
917
|
+
handle_rest_error(e)
|
|
918
|
+
if output == "json":
|
|
919
|
+
print_json(result)
|
|
920
|
+
else:
|
|
921
|
+
if isinstance(result, dict):
|
|
922
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
923
|
+
elif isinstance(result, list):
|
|
924
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
925
|
+
else:
|
|
926
|
+
print_json(result)
|
|
927
|
+
|
|
928
|
+
|
|
929
|
+
|
|
930
|
+
@app.command("update-directories")
|
|
931
|
+
def update_directories(
|
|
932
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
933
|
+
directory_id: str = typer.Argument(help="directoryId"),
|
|
934
|
+
name: str = typer.Option(None, "--name", help="Receptionist Contact Directory name. The directory name shou"),
|
|
935
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
936
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
937
|
+
):
|
|
938
|
+
"""Modify a Receptionist Contact Directory\n\nExample --json-body:\n '{"name":"...","contacts":["..."]}'."""
|
|
939
|
+
api = get_api(debug=debug)
|
|
940
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/receptionistContacts/directories/{directory_id}"
|
|
941
|
+
params = {}
|
|
942
|
+
org_id = get_org_id()
|
|
943
|
+
if org_id is not None:
|
|
944
|
+
params["orgId"] = org_id
|
|
945
|
+
if json_body:
|
|
946
|
+
body = json.loads(json_body)
|
|
947
|
+
else:
|
|
948
|
+
body = {}
|
|
949
|
+
if name is not None:
|
|
950
|
+
body["name"] = name
|
|
951
|
+
try:
|
|
952
|
+
result = api.session.rest_put(url, json=body, params=params)
|
|
953
|
+
except WebexError as e:
|
|
954
|
+
handle_rest_error(e)
|
|
955
|
+
typer.echo(f"Updated.")
|
|
956
|
+
|
|
957
|
+
|
|
958
|
+
|
|
959
|
+
@app.command("delete")
|
|
960
|
+
def delete(
|
|
961
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
962
|
+
directory_id: str = typer.Argument(help="directoryId"),
|
|
963
|
+
force: bool = typer.Option(False, "--force", help="Skip confirmation"),
|
|
964
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
965
|
+
):
|
|
966
|
+
"""Delete a Receptionist Contact Directory."""
|
|
967
|
+
if not force:
|
|
968
|
+
typer.confirm(f"Delete {directory_id}?", abort=True)
|
|
969
|
+
api = get_api(debug=debug)
|
|
970
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/receptionistContacts/directories/{directory_id}"
|
|
971
|
+
params = {}
|
|
972
|
+
org_id = get_org_id()
|
|
973
|
+
if org_id is not None:
|
|
974
|
+
params["orgId"] = org_id
|
|
975
|
+
try:
|
|
976
|
+
api.session.rest_delete(url, params=params)
|
|
977
|
+
except WebexError as e:
|
|
978
|
+
handle_rest_error(e)
|
|
979
|
+
typer.echo(f"Deleted: {directory_id}")
|
|
980
|
+
|
|
981
|
+
|
|
982
|
+
|
|
983
|
+
@app.command("list-available-numbers-charge-number")
|
|
984
|
+
def list_available_numbers_charge_number(
|
|
985
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
986
|
+
phone_number: str = typer.Option(None, "--phone-number", help="Filter phone numbers based on the comma-separated list provi"),
|
|
987
|
+
owner_name: str = typer.Option(None, "--owner-name", help="Return the list of phone numbers that are owned by the given"),
|
|
988
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
989
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
990
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
991
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
992
|
+
):
|
|
993
|
+
"""Get Available Charge Numbers for a Location with Given Criteria."""
|
|
994
|
+
api = get_api(debug=debug)
|
|
995
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/chargeNumber/availableNumbers"
|
|
996
|
+
params = {}
|
|
997
|
+
if phone_number is not None:
|
|
998
|
+
params["phoneNumber"] = phone_number
|
|
999
|
+
if owner_name is not None:
|
|
1000
|
+
params["ownerName"] = owner_name
|
|
1001
|
+
if limit > 0:
|
|
1002
|
+
params["max"] = limit
|
|
1003
|
+
if offset > 0:
|
|
1004
|
+
params["start"] = offset
|
|
1005
|
+
org_id = get_org_id()
|
|
1006
|
+
if org_id is not None:
|
|
1007
|
+
params["orgId"] = org_id
|
|
1008
|
+
result = None
|
|
1009
|
+
try:
|
|
1010
|
+
result = api.session.rest_get(url, params=params)
|
|
1011
|
+
except WebexError as e:
|
|
1012
|
+
handle_rest_error(e)
|
|
1013
|
+
result = result or []
|
|
1014
|
+
items = result.get("phoneNumbers", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
1015
|
+
if output == "json":
|
|
1016
|
+
print_json(items)
|
|
1017
|
+
else:
|
|
1018
|
+
print_table(items, columns=[('Phone Number', 'phoneNumber'), ('State', 'state')], limit=limit)
|
|
1019
|
+
|
|
1020
|
+
|
|
1021
|
+
|
|
1022
|
+
@app.command("list-delete-calling-location")
|
|
1023
|
+
def list_delete_calling_location(
|
|
1024
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
1025
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
1026
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
1027
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1028
|
+
):
|
|
1029
|
+
"""Get a List of Disable Calling Location Jobs."""
|
|
1030
|
+
api = get_api(debug=debug)
|
|
1031
|
+
url = f"https://webexapis.com/v1/telephony/config/jobs/locations/deleteCallingLocation"
|
|
1032
|
+
params = {}
|
|
1033
|
+
if limit > 0:
|
|
1034
|
+
params["max"] = limit
|
|
1035
|
+
if offset > 0:
|
|
1036
|
+
params["start"] = offset
|
|
1037
|
+
org_id = get_org_id()
|
|
1038
|
+
if org_id is not None:
|
|
1039
|
+
params["orgId"] = org_id
|
|
1040
|
+
result = None
|
|
1041
|
+
try:
|
|
1042
|
+
result = api.session.rest_get(url, params=params)
|
|
1043
|
+
except WebexError as e:
|
|
1044
|
+
handle_rest_error(e)
|
|
1045
|
+
result = result or []
|
|
1046
|
+
items = result.get("items", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
1047
|
+
if output == "json":
|
|
1048
|
+
print_json(items)
|
|
1049
|
+
else:
|
|
1050
|
+
print_table(items, columns=[('ID', 'id'), ('Status', 'latestExecutionStatus')], limit=limit)
|
|
1051
|
+
|
|
1052
|
+
|
|
1053
|
+
|
|
1054
|
+
@app.command("create-delete-calling-location")
|
|
1055
|
+
def create_delete_calling_location(
|
|
1056
|
+
location_id: str = typer.Option(None, "--location-id", help="(required) Unique identifier for the calling location to disable."),
|
|
1057
|
+
location_name: str = typer.Option(None, "--location-name", help="Name of the calling location to disable."),
|
|
1058
|
+
force_delete: bool = typer.Option(None, "--force-delete/--no-force-delete", help="Force delete is only applicable when calling features like c"),
|
|
1059
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
1060
|
+
output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
|
|
1061
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1062
|
+
):
|
|
1063
|
+
"""Disable a Location for Webex Calling."""
|
|
1064
|
+
api = get_api(debug=debug)
|
|
1065
|
+
url = f"https://webexapis.com/v1/telephony/config/jobs/locations/deleteCallingLocation"
|
|
1066
|
+
params = {}
|
|
1067
|
+
org_id = get_org_id()
|
|
1068
|
+
if org_id is not None:
|
|
1069
|
+
params["orgId"] = org_id
|
|
1070
|
+
if json_body:
|
|
1071
|
+
body = json.loads(json_body)
|
|
1072
|
+
else:
|
|
1073
|
+
body = {}
|
|
1074
|
+
if location_id is not None:
|
|
1075
|
+
body["locationId"] = location_id
|
|
1076
|
+
if location_name is not None:
|
|
1077
|
+
body["locationName"] = location_name
|
|
1078
|
+
if force_delete is not None:
|
|
1079
|
+
body["forceDelete"] = force_delete
|
|
1080
|
+
_missing = [f for f in ['locationId'] if f not in body or body[f] is None]
|
|
1081
|
+
if _missing:
|
|
1082
|
+
typer.echo("Error: Missing required fields: " + ", ".join(_missing), err=True)
|
|
1083
|
+
raise typer.Exit(1)
|
|
1084
|
+
try:
|
|
1085
|
+
result = api.session.rest_post(url, json=body, params=params)
|
|
1086
|
+
except WebexError as e:
|
|
1087
|
+
handle_rest_error(e)
|
|
1088
|
+
if output == "json":
|
|
1089
|
+
print_json(result)
|
|
1090
|
+
elif isinstance(result, dict) and "id" in result:
|
|
1091
|
+
typer.echo(f"Created: {result['id']}")
|
|
1092
|
+
elif not result or result == {}:
|
|
1093
|
+
typer.echo("Created.")
|
|
1094
|
+
else:
|
|
1095
|
+
print_json(result)
|
|
1096
|
+
|
|
1097
|
+
|
|
1098
|
+
|
|
1099
|
+
@app.command("safe-delete-check")
|
|
1100
|
+
def safe_delete_check(
|
|
1101
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
1102
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body"),
|
|
1103
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1104
|
+
):
|
|
1105
|
+
"""Safe Delete Check Before Disabling a Location for Webex Calling."""
|
|
1106
|
+
api = get_api(debug=debug)
|
|
1107
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/actions/precheckForDeletion/invoke"
|
|
1108
|
+
params = {}
|
|
1109
|
+
org_id = get_org_id()
|
|
1110
|
+
if org_id is not None:
|
|
1111
|
+
params["orgId"] = org_id
|
|
1112
|
+
if json_body:
|
|
1113
|
+
body = json.loads(json_body)
|
|
1114
|
+
else:
|
|
1115
|
+
body = {}
|
|
1116
|
+
try:
|
|
1117
|
+
result = api.session.rest_post(url, json=body, params=params)
|
|
1118
|
+
except WebexError as e:
|
|
1119
|
+
handle_rest_error(e)
|
|
1120
|
+
print_json(result)
|
|
1121
|
+
|
|
1122
|
+
|
|
1123
|
+
|
|
1124
|
+
@app.command("pause-a-disable")
|
|
1125
|
+
def pause_a_disable(
|
|
1126
|
+
job_id: str = typer.Argument(help="jobId"),
|
|
1127
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body"),
|
|
1128
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1129
|
+
):
|
|
1130
|
+
"""Pause a Disable Calling Location Job."""
|
|
1131
|
+
api = get_api(debug=debug)
|
|
1132
|
+
url = f"https://webexapis.com/v1/telephony/config/jobs/locations/deleteCallingLocation/{job_id}/actions/pause/invoke"
|
|
1133
|
+
params = {}
|
|
1134
|
+
org_id = get_org_id()
|
|
1135
|
+
if org_id is not None:
|
|
1136
|
+
params["orgId"] = org_id
|
|
1137
|
+
if json_body:
|
|
1138
|
+
body = json.loads(json_body)
|
|
1139
|
+
else:
|
|
1140
|
+
body = {}
|
|
1141
|
+
try:
|
|
1142
|
+
result = api.session.rest_post(url, json=body, params=params)
|
|
1143
|
+
except WebexError as e:
|
|
1144
|
+
handle_rest_error(e)
|
|
1145
|
+
print_json(result)
|
|
1146
|
+
|
|
1147
|
+
|
|
1148
|
+
|
|
1149
|
+
@app.command("resume-a-paused")
|
|
1150
|
+
def resume_a_paused(
|
|
1151
|
+
job_id: str = typer.Argument(help="jobId"),
|
|
1152
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body"),
|
|
1153
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1154
|
+
):
|
|
1155
|
+
"""Resume a Paused Disable Calling Location Job."""
|
|
1156
|
+
api = get_api(debug=debug)
|
|
1157
|
+
url = f"https://webexapis.com/v1/telephony/config/jobs/locations/deleteCallingLocation/{job_id}/actions/resume/invoke"
|
|
1158
|
+
params = {}
|
|
1159
|
+
org_id = get_org_id()
|
|
1160
|
+
if org_id is not None:
|
|
1161
|
+
params["orgId"] = org_id
|
|
1162
|
+
if json_body:
|
|
1163
|
+
body = json.loads(json_body)
|
|
1164
|
+
else:
|
|
1165
|
+
body = {}
|
|
1166
|
+
try:
|
|
1167
|
+
result = api.session.rest_post(url, json=body, params=params)
|
|
1168
|
+
except WebexError as e:
|
|
1169
|
+
handle_rest_error(e)
|
|
1170
|
+
print_json(result)
|
|
1171
|
+
|
|
1172
|
+
|
|
1173
|
+
|
|
1174
|
+
@app.command("list-errors")
|
|
1175
|
+
def list_errors(
|
|
1176
|
+
job_id: str = typer.Argument(help="jobId"),
|
|
1177
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
1178
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
1179
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
1180
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1181
|
+
):
|
|
1182
|
+
"""Retrieve Errors for a Disable Calling Location Job."""
|
|
1183
|
+
api = get_api(debug=debug)
|
|
1184
|
+
url = f"https://webexapis.com/v1/telephony/config/jobs/locations/deleteCallingLocation/{job_id}/errors"
|
|
1185
|
+
params = {}
|
|
1186
|
+
if limit > 0:
|
|
1187
|
+
params["max"] = limit
|
|
1188
|
+
if offset > 0:
|
|
1189
|
+
params["start"] = offset
|
|
1190
|
+
org_id = get_org_id()
|
|
1191
|
+
if org_id is not None:
|
|
1192
|
+
params["orgId"] = org_id
|
|
1193
|
+
result = None
|
|
1194
|
+
try:
|
|
1195
|
+
result = api.session.rest_get(url, params=params)
|
|
1196
|
+
except WebexError as e:
|
|
1197
|
+
handle_rest_error(e)
|
|
1198
|
+
result = result or []
|
|
1199
|
+
items = result.get("items", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
1200
|
+
if output == "json":
|
|
1201
|
+
print_json(items)
|
|
1202
|
+
else:
|
|
1203
|
+
print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
|
|
1204
|
+
|
|
1205
|
+
|
|
1206
|
+
|
|
1207
|
+
@app.command("show-delete-calling-location")
|
|
1208
|
+
def show_delete_calling_location(
|
|
1209
|
+
job_id: str = typer.Argument(help="jobId"),
|
|
1210
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
1211
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1212
|
+
):
|
|
1213
|
+
"""Get Disable Calling Location Job Status."""
|
|
1214
|
+
api = get_api(debug=debug)
|
|
1215
|
+
url = f"https://webexapis.com/v1/telephony/config/jobs/locations/deleteCallingLocation/{job_id}"
|
|
1216
|
+
params = {}
|
|
1217
|
+
org_id = get_org_id()
|
|
1218
|
+
if org_id is not None:
|
|
1219
|
+
params["orgId"] = org_id
|
|
1220
|
+
try:
|
|
1221
|
+
result = api.session.rest_get(url, params=params)
|
|
1222
|
+
except WebexError as e:
|
|
1223
|
+
handle_rest_error(e)
|
|
1224
|
+
if output == "json":
|
|
1225
|
+
print_json(result)
|
|
1226
|
+
else:
|
|
1227
|
+
if isinstance(result, dict):
|
|
1228
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
1229
|
+
elif isinstance(result, list):
|
|
1230
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
1231
|
+
else:
|
|
1232
|
+
print_json(result)
|
|
1233
|
+
|
|
1234
|
+
|
|
1235
|
+
|
|
1236
|
+
@app.command("show-call-captions")
|
|
1237
|
+
def show_call_captions(
|
|
1238
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
1239
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
1240
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1241
|
+
):
|
|
1242
|
+
"""Get the location call captions settings."""
|
|
1243
|
+
api = get_api(debug=debug)
|
|
1244
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/callCaptions"
|
|
1245
|
+
params = {}
|
|
1246
|
+
org_id = get_org_id()
|
|
1247
|
+
if org_id is not None:
|
|
1248
|
+
params["orgId"] = org_id
|
|
1249
|
+
try:
|
|
1250
|
+
result = api.session.rest_get(url, params=params)
|
|
1251
|
+
except WebexError as e:
|
|
1252
|
+
handle_rest_error(e)
|
|
1253
|
+
if output == "json":
|
|
1254
|
+
print_json(result)
|
|
1255
|
+
else:
|
|
1256
|
+
if isinstance(result, dict):
|
|
1257
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
1258
|
+
elif isinstance(result, list):
|
|
1259
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
1260
|
+
else:
|
|
1261
|
+
print_json(result)
|
|
1262
|
+
|
|
1263
|
+
|
|
1264
|
+
|
|
1265
|
+
@app.command("update-call-captions")
|
|
1266
|
+
def update_call_captions(
|
|
1267
|
+
location_id: str = typer.Argument(help="locationId"),
|
|
1268
|
+
location_closed_captions_enabled: bool = typer.Option(None, "--location-closed-captions-enabled/--no-location-closed-captions-enabled", help="Enable or disable location-level closed captions."),
|
|
1269
|
+
location_transcripts_enabled: bool = typer.Option(None, "--location-transcripts-enabled/--no-location-transcripts-enabled", help="Enable or disable location-level transcripts."),
|
|
1270
|
+
use_org_settings_enabled: bool = typer.Option(None, "--use-org-settings-enabled/--no-use-org-settings-enabled", help="If `useOrgSettingsEnabled` is `true`, organization-level set"),
|
|
1271
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
1272
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1273
|
+
):
|
|
1274
|
+
"""Update the location call captions settings."""
|
|
1275
|
+
api = get_api(debug=debug)
|
|
1276
|
+
url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/callCaptions"
|
|
1277
|
+
params = {}
|
|
1278
|
+
org_id = get_org_id()
|
|
1279
|
+
if org_id is not None:
|
|
1280
|
+
params["orgId"] = org_id
|
|
1281
|
+
if json_body:
|
|
1282
|
+
body = json.loads(json_body)
|
|
1283
|
+
else:
|
|
1284
|
+
body = {}
|
|
1285
|
+
if location_closed_captions_enabled is not None:
|
|
1286
|
+
body["locationClosedCaptionsEnabled"] = location_closed_captions_enabled
|
|
1287
|
+
if location_transcripts_enabled is not None:
|
|
1288
|
+
body["locationTranscriptsEnabled"] = location_transcripts_enabled
|
|
1289
|
+
if use_org_settings_enabled is not None:
|
|
1290
|
+
body["useOrgSettingsEnabled"] = use_org_settings_enabled
|
|
1291
|
+
try:
|
|
1292
|
+
result = api.session.rest_put(url, json=body, params=params)
|
|
1293
|
+
except WebexError as e:
|
|
1294
|
+
handle_rest_error(e)
|
|
1295
|
+
typer.echo(f"Updated.")
|
|
1296
|
+
|
|
1297
|
+
|