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,212 @@
|
|
|
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
|
+
|
|
7
|
+
|
|
8
|
+
app = typer.Typer(help="Manage Webex Calling call-settings-for-me-phase-5.")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@app.command("show")
|
|
12
|
+
def show(
|
|
13
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
14
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
15
|
+
):
|
|
16
|
+
"""Get Personal Assistant Settings."""
|
|
17
|
+
api = get_api(debug=debug)
|
|
18
|
+
url = f"https://webexapis.com/v1/telephony/config/people/me/settings/personalAssistant"
|
|
19
|
+
try:
|
|
20
|
+
result = api.session.rest_get(url)
|
|
21
|
+
except WebexError as e:
|
|
22
|
+
handle_rest_error(e)
|
|
23
|
+
if output == "json":
|
|
24
|
+
print_json(result)
|
|
25
|
+
else:
|
|
26
|
+
if isinstance(result, dict):
|
|
27
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
28
|
+
elif isinstance(result, list):
|
|
29
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
30
|
+
else:
|
|
31
|
+
print_json(result)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@app.command("update")
|
|
36
|
+
def update(
|
|
37
|
+
enabled: bool = typer.Option(None, "--enabled/--no-enabled", help="Enable/Disable the personal assistant feature."),
|
|
38
|
+
presence: str = typer.Option(None, "--presence", help="Choices: BUSINESS_TRIP, GONE_FOR_THE_DAY, LUNCH, MEETING, OUT_OF_OFFICE, TEMPORARILY_OUT, TRAINING, UNAVAILABLE, VACATION"),
|
|
39
|
+
until_date_time: str = typer.Option(None, "--until-date-time", help="Date and time until which the personal assistant is active ("),
|
|
40
|
+
transfer_enabled: bool = typer.Option(None, "--transfer-enabled/--no-transfer-enabled", help="Enable/Disable call transfer when personal assistant is acti"),
|
|
41
|
+
transfer_number: str = typer.Option(None, "--transfer-number", help="Phone number to transfer calls to when transfer is enabled."),
|
|
42
|
+
alerting: str = typer.Option(None, "--alerting", help="Choices: ALERT_ME_FIRST, PLAY_RING_REMINDER, NONE"),
|
|
43
|
+
alert_me_first_number_of_rings: str = typer.Option(None, "--alert-me-first-number-of-rings", help="Number of rings before transferring the call when alerting i"),
|
|
44
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
45
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
46
|
+
):
|
|
47
|
+
"""Update Personal Assistant Settings."""
|
|
48
|
+
api = get_api(debug=debug)
|
|
49
|
+
url = f"https://webexapis.com/v1/telephony/config/people/me/settings/personalAssistant"
|
|
50
|
+
if json_body:
|
|
51
|
+
body = json.loads(json_body)
|
|
52
|
+
else:
|
|
53
|
+
body = {}
|
|
54
|
+
if enabled is not None:
|
|
55
|
+
body["enabled"] = enabled
|
|
56
|
+
if presence is not None:
|
|
57
|
+
body["presence"] = presence
|
|
58
|
+
if until_date_time is not None:
|
|
59
|
+
body["untilDateTime"] = until_date_time
|
|
60
|
+
if transfer_enabled is not None:
|
|
61
|
+
body["transferEnabled"] = transfer_enabled
|
|
62
|
+
if transfer_number is not None:
|
|
63
|
+
body["transferNumber"] = transfer_number
|
|
64
|
+
if alerting is not None:
|
|
65
|
+
body["alerting"] = alerting
|
|
66
|
+
if alert_me_first_number_of_rings is not None:
|
|
67
|
+
body["alertMeFirstNumberOfRings"] = alert_me_first_number_of_rings
|
|
68
|
+
try:
|
|
69
|
+
result = api.session.rest_put(url, json=body)
|
|
70
|
+
except WebexError as e:
|
|
71
|
+
handle_rest_error(e)
|
|
72
|
+
typer.echo(f"Updated.")
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@app.command("show-rules")
|
|
77
|
+
def show_rules(
|
|
78
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
79
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
80
|
+
):
|
|
81
|
+
"""Get Person's Voicemail Rules."""
|
|
82
|
+
api = get_api(debug=debug)
|
|
83
|
+
url = f"https://webexapis.com/v1/telephony/config/people/me/voicemail/rules"
|
|
84
|
+
try:
|
|
85
|
+
result = api.session.rest_get(url)
|
|
86
|
+
except WebexError as e:
|
|
87
|
+
handle_rest_error(e)
|
|
88
|
+
if output == "json":
|
|
89
|
+
print_json(result)
|
|
90
|
+
else:
|
|
91
|
+
if isinstance(result, dict):
|
|
92
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
93
|
+
elif isinstance(result, list):
|
|
94
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
95
|
+
else:
|
|
96
|
+
print_json(result)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
@app.command("update-pin")
|
|
101
|
+
def update_pin(
|
|
102
|
+
passcode: str = typer.Option(None, "--passcode", help="Person voicemail PIN. The PIN must comply with the passcode"),
|
|
103
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
104
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
105
|
+
):
|
|
106
|
+
"""Update Voicemail PIN."""
|
|
107
|
+
api = get_api(debug=debug)
|
|
108
|
+
url = f"https://webexapis.com/v1/telephony/config/people/me/voicemail/pin"
|
|
109
|
+
if json_body:
|
|
110
|
+
body = json.loads(json_body)
|
|
111
|
+
else:
|
|
112
|
+
body = {}
|
|
113
|
+
if passcode is not None:
|
|
114
|
+
body["passcode"] = passcode
|
|
115
|
+
try:
|
|
116
|
+
result = api.session.rest_put(url, json=body)
|
|
117
|
+
except WebexError as e:
|
|
118
|
+
handle_rest_error(e)
|
|
119
|
+
typer.echo(f"Updated.")
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
@app.command("show-guest")
|
|
124
|
+
def show_guest(
|
|
125
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
126
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
127
|
+
):
|
|
128
|
+
"""Get Hoteling Guest Settings."""
|
|
129
|
+
api = get_api(debug=debug)
|
|
130
|
+
url = f"https://webexapis.com/v1/telephony/config/people/me/settings/hoteling/guest"
|
|
131
|
+
try:
|
|
132
|
+
result = api.session.rest_get(url)
|
|
133
|
+
except WebexError as e:
|
|
134
|
+
handle_rest_error(e)
|
|
135
|
+
if output == "json":
|
|
136
|
+
print_json(result)
|
|
137
|
+
else:
|
|
138
|
+
if isinstance(result, dict):
|
|
139
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
140
|
+
elif isinstance(result, list):
|
|
141
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
142
|
+
else:
|
|
143
|
+
print_json(result)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
@app.command("update-guest")
|
|
148
|
+
def update_guest(
|
|
149
|
+
enabled: bool = typer.Option(None, "--enabled/--no-enabled", help="Enable/Disable hoteling guest functionality for the person."),
|
|
150
|
+
association_limit_enabled: bool = typer.Option(None, "--association-limit-enabled/--no-association-limit-enabled", help="When enabled, the person's hoteling guest association will b"),
|
|
151
|
+
association_limit_hours: str = typer.Option(None, "--association-limit-hours", help="Time limit in hours for the hoteling guest association (1-99"),
|
|
152
|
+
host_id: str = typer.Option(None, "--host-id", help="Unique identifier of the hoteling host person or workspace t"),
|
|
153
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
154
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
155
|
+
):
|
|
156
|
+
"""Update Hoteling Guest Settings."""
|
|
157
|
+
api = get_api(debug=debug)
|
|
158
|
+
url = f"https://webexapis.com/v1/telephony/config/people/me/settings/hoteling/guest"
|
|
159
|
+
if json_body:
|
|
160
|
+
body = json.loads(json_body)
|
|
161
|
+
else:
|
|
162
|
+
body = {}
|
|
163
|
+
if enabled is not None:
|
|
164
|
+
body["enabled"] = enabled
|
|
165
|
+
if association_limit_enabled is not None:
|
|
166
|
+
body["associationLimitEnabled"] = association_limit_enabled
|
|
167
|
+
if association_limit_hours is not None:
|
|
168
|
+
body["associationLimitHours"] = association_limit_hours
|
|
169
|
+
if host_id is not None:
|
|
170
|
+
body["hostId"] = host_id
|
|
171
|
+
try:
|
|
172
|
+
result = api.session.rest_put(url, json=body)
|
|
173
|
+
except WebexError as e:
|
|
174
|
+
handle_rest_error(e)
|
|
175
|
+
typer.echo(f"Updated.")
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
@app.command("list")
|
|
180
|
+
def cmd_list(
|
|
181
|
+
name: str = typer.Option(None, "--name", help="Filter hosts by name (first name or last name). Partial matc"),
|
|
182
|
+
phone_number: str = typer.Option(None, "--phone-number", help="Filter hosts by phone number. Partial match is supported."),
|
|
183
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
184
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
185
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
186
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
187
|
+
):
|
|
188
|
+
"""Get Available Hoteling Hosts."""
|
|
189
|
+
api = get_api(debug=debug)
|
|
190
|
+
url = f"https://webexapis.com/v1/telephony/config/people/me/settings/hoteling/availableHosts"
|
|
191
|
+
params = {}
|
|
192
|
+
if name is not None:
|
|
193
|
+
params["name"] = name
|
|
194
|
+
if phone_number is not None:
|
|
195
|
+
params["phoneNumber"] = phone_number
|
|
196
|
+
if limit > 0:
|
|
197
|
+
params["max"] = limit
|
|
198
|
+
if offset > 0:
|
|
199
|
+
params["start"] = offset
|
|
200
|
+
result = None
|
|
201
|
+
try:
|
|
202
|
+
result = api.session.rest_get(url, params=params)
|
|
203
|
+
except WebexError as e:
|
|
204
|
+
handle_rest_error(e)
|
|
205
|
+
result = result or []
|
|
206
|
+
items = result.get("hosts", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
207
|
+
if output == "json":
|
|
208
|
+
print_json(items)
|
|
209
|
+
else:
|
|
210
|
+
print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
|
|
211
|
+
|
|
212
|
+
|
|
@@ -0,0 +1,169 @@
|
|
|
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
|
+
|
|
7
|
+
|
|
8
|
+
app = typer.Typer(help="Manage Webex Calling caller-reputation.")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@app.command("show")
|
|
12
|
+
def show(
|
|
13
|
+
organization_id: str = typer.Option(None, "--organization-id", help="Unique identifier for the organization."),
|
|
14
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
15
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
16
|
+
):
|
|
17
|
+
"""Get Caller Reputation Provider Service Settings."""
|
|
18
|
+
api = get_api(debug=debug)
|
|
19
|
+
url = f"https://webexapis.com/v1/telephony/config/serviceSettings/callerReputationProvider"
|
|
20
|
+
params = {}
|
|
21
|
+
if organization_id is not None:
|
|
22
|
+
params["organizationId"] = organization_id
|
|
23
|
+
try:
|
|
24
|
+
result = api.session.rest_get(url, params=params)
|
|
25
|
+
except WebexError as e:
|
|
26
|
+
handle_rest_error(e)
|
|
27
|
+
if output == "json":
|
|
28
|
+
print_json(result)
|
|
29
|
+
else:
|
|
30
|
+
if isinstance(result, dict):
|
|
31
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
32
|
+
elif isinstance(result, list):
|
|
33
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
34
|
+
else:
|
|
35
|
+
print_json(result)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@app.command("update")
|
|
40
|
+
def update(
|
|
41
|
+
organization_id: str = typer.Option(None, "--organization-id", help="Unique identifier for the organization."),
|
|
42
|
+
enabled: bool = typer.Option(None, "--enabled/--no-enabled", help="Indicates if the caller reputation provider service is enabl"),
|
|
43
|
+
id_param: str = typer.Option(None, "--id", help="Unique identifier for the reputation provider."),
|
|
44
|
+
name: str = typer.Option(None, "--name", help="Name of the reputation provider."),
|
|
45
|
+
client_id: str = typer.Option(None, "--client-id", help="Client ID used for integration with the reputation provider."),
|
|
46
|
+
client_secret: str = typer.Option(None, "--client-secret", help="Client secret used for integration with the reputation provi"),
|
|
47
|
+
call_block_score_threshold: str = typer.Option(None, "--call-block-score-threshold", help="Score threshold for blocking calls."),
|
|
48
|
+
call_allow_score_threshold: str = typer.Option(None, "--call-allow-score-threshold", help="Score threshold for allowing calls."),
|
|
49
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
50
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
51
|
+
):
|
|
52
|
+
"""Update Caller Reputation Provider Service Settings."""
|
|
53
|
+
api = get_api(debug=debug)
|
|
54
|
+
url = f"https://webexapis.com/v1/telephony/config/serviceSettings/callerReputationProvider"
|
|
55
|
+
params = {}
|
|
56
|
+
if organization_id is not None:
|
|
57
|
+
params["organizationId"] = organization_id
|
|
58
|
+
if json_body:
|
|
59
|
+
body = json.loads(json_body)
|
|
60
|
+
else:
|
|
61
|
+
body = {}
|
|
62
|
+
if enabled is not None:
|
|
63
|
+
body["enabled"] = enabled
|
|
64
|
+
if id_param is not None:
|
|
65
|
+
body["id"] = id_param
|
|
66
|
+
if name is not None:
|
|
67
|
+
body["name"] = name
|
|
68
|
+
if client_id is not None:
|
|
69
|
+
body["clientId"] = client_id
|
|
70
|
+
if client_secret is not None:
|
|
71
|
+
body["clientSecret"] = client_secret
|
|
72
|
+
if call_block_score_threshold is not None:
|
|
73
|
+
body["callBlockScoreThreshold"] = call_block_score_threshold
|
|
74
|
+
if call_allow_score_threshold is not None:
|
|
75
|
+
body["callAllowScoreThreshold"] = call_allow_score_threshold
|
|
76
|
+
try:
|
|
77
|
+
result = api.session.rest_put(url, json=body, params=params)
|
|
78
|
+
except WebexError as e:
|
|
79
|
+
handle_rest_error(e)
|
|
80
|
+
typer.echo(f"Updated.")
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
@app.command("show-status")
|
|
85
|
+
def show_status(
|
|
86
|
+
organization_id: str = typer.Option(None, "--organization-id", help="Unique identifier for the organization."),
|
|
87
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
88
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
89
|
+
):
|
|
90
|
+
"""Get Caller Reputation Provider Status."""
|
|
91
|
+
api = get_api(debug=debug)
|
|
92
|
+
url = f"https://webexapis.com/v1/telephony/config/serviceSettings/callerReputationProvider/status"
|
|
93
|
+
params = {}
|
|
94
|
+
if organization_id is not None:
|
|
95
|
+
params["organizationId"] = organization_id
|
|
96
|
+
try:
|
|
97
|
+
result = api.session.rest_get(url, params=params)
|
|
98
|
+
except WebexError as e:
|
|
99
|
+
handle_rest_error(e)
|
|
100
|
+
if output == "json":
|
|
101
|
+
print_json(result)
|
|
102
|
+
else:
|
|
103
|
+
if isinstance(result, dict):
|
|
104
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
105
|
+
elif isinstance(result, list):
|
|
106
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
107
|
+
else:
|
|
108
|
+
print_json(result)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
@app.command("unlock-caller-reputation")
|
|
113
|
+
def unlock_caller_reputation(
|
|
114
|
+
organization_id: str = typer.Option(None, "--organization-id", help="Unique identifier for the organization."),
|
|
115
|
+
id_param: str = typer.Option(None, "--id", help="Unique identifier for the reputation provider."),
|
|
116
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body"),
|
|
117
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
118
|
+
):
|
|
119
|
+
"""Unlock Caller Reputation Provider."""
|
|
120
|
+
api = get_api(debug=debug)
|
|
121
|
+
url = f"https://webexapis.com/v1/telephony/config/serviceSettings/callerReputationProvider/actions/unlock/invoke"
|
|
122
|
+
params = {}
|
|
123
|
+
if organization_id is not None:
|
|
124
|
+
params["organizationId"] = organization_id
|
|
125
|
+
if json_body:
|
|
126
|
+
body = json.loads(json_body)
|
|
127
|
+
else:
|
|
128
|
+
body = {}
|
|
129
|
+
if id_param is not None:
|
|
130
|
+
body["id"] = id_param
|
|
131
|
+
try:
|
|
132
|
+
result = api.session.rest_post(url, json=body, params=params)
|
|
133
|
+
except WebexError as e:
|
|
134
|
+
handle_rest_error(e)
|
|
135
|
+
print_json(result)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
@app.command("list")
|
|
140
|
+
def cmd_list(
|
|
141
|
+
organization_id: str = typer.Option(None, "--organization-id", help="Unique identifier for the organization."),
|
|
142
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
143
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
144
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
145
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
146
|
+
):
|
|
147
|
+
"""Get Caller Reputation Provider Providers."""
|
|
148
|
+
api = get_api(debug=debug)
|
|
149
|
+
url = f"https://webexapis.com/v1/telephony/config/serviceSettings/callerReputationProvider/providers"
|
|
150
|
+
params = {}
|
|
151
|
+
if organization_id is not None:
|
|
152
|
+
params["organizationId"] = organization_id
|
|
153
|
+
if limit > 0:
|
|
154
|
+
params["max"] = limit
|
|
155
|
+
if offset > 0:
|
|
156
|
+
params["start"] = offset
|
|
157
|
+
result = None
|
|
158
|
+
try:
|
|
159
|
+
result = api.session.rest_get(url, params=params)
|
|
160
|
+
except WebexError as e:
|
|
161
|
+
handle_rest_error(e)
|
|
162
|
+
result = result or []
|
|
163
|
+
items = result.get("providers", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
164
|
+
if output == "json":
|
|
165
|
+
print_json(items)
|
|
166
|
+
else:
|
|
167
|
+
print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
|
|
168
|
+
|
|
169
|
+
|
|
@@ -0,0 +1,305 @@
|
|
|
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 calling-service.")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@app.command("list")
|
|
13
|
+
def cmd_list(
|
|
14
|
+
tts_language: str = typer.Option(None, "--tts-language", help="Filter languages by TTS support."),
|
|
15
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
16
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
17
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
18
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
19
|
+
):
|
|
20
|
+
"""Read the List of Announcement Languages."""
|
|
21
|
+
api = get_api(debug=debug)
|
|
22
|
+
url = f"https://webexapis.com/v1/telephony/config/announcementLanguages"
|
|
23
|
+
params = {}
|
|
24
|
+
if tts_language is not None:
|
|
25
|
+
params["ttsLanguage"] = tts_language
|
|
26
|
+
if limit > 0:
|
|
27
|
+
params["max"] = limit
|
|
28
|
+
if offset > 0:
|
|
29
|
+
params["start"] = offset
|
|
30
|
+
result = None
|
|
31
|
+
try:
|
|
32
|
+
result = api.session.rest_get(url, params=params)
|
|
33
|
+
except WebexError as e:
|
|
34
|
+
handle_rest_error(e)
|
|
35
|
+
result = result or []
|
|
36
|
+
items = result.get("languages", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
37
|
+
if output == "json":
|
|
38
|
+
print_json(items)
|
|
39
|
+
else:
|
|
40
|
+
print_table(items, columns=[('Name', 'name'), ('Code', 'code')], limit=limit)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@app.command("show")
|
|
45
|
+
def show(
|
|
46
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
47
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
48
|
+
):
|
|
49
|
+
"""Get Voicemail Settings."""
|
|
50
|
+
api = get_api(debug=debug)
|
|
51
|
+
url = f"https://webexapis.com/v1/telephony/config/voicemail/settings"
|
|
52
|
+
params = {}
|
|
53
|
+
org_id = get_org_id()
|
|
54
|
+
if org_id is not None:
|
|
55
|
+
params["orgId"] = org_id
|
|
56
|
+
try:
|
|
57
|
+
result = api.session.rest_get(url, params=params)
|
|
58
|
+
except WebexError as e:
|
|
59
|
+
handle_rest_error(e)
|
|
60
|
+
if output == "json":
|
|
61
|
+
print_json(result)
|
|
62
|
+
else:
|
|
63
|
+
if isinstance(result, dict):
|
|
64
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
65
|
+
elif isinstance(result, list):
|
|
66
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
67
|
+
else:
|
|
68
|
+
print_json(result)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
@app.command("update")
|
|
73
|
+
def update(
|
|
74
|
+
message_expiry_enabled: bool = typer.Option(None, "--message-expiry-enabled/--no-message-expiry-enabled", help="Set to `true` to enable voicemail deletion and set the delet"),
|
|
75
|
+
number_of_days_for_message_expiry: str = typer.Option(None, "--number-of-days-for-message-expiry", help="Number of days after which messages expire."),
|
|
76
|
+
strict_deletion_enabled: bool = typer.Option(None, "--strict-deletion-enabled/--no-strict-deletion-enabled", help="Set to `true` to delete all read and unread voicemail messag"),
|
|
77
|
+
voice_message_forwarding_enabled: bool = typer.Option(None, "--voice-message-forwarding-enabled/--no-voice-message-forwarding-enabled", help="Set to `true` to allow people to configure the email forward"),
|
|
78
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
79
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
80
|
+
):
|
|
81
|
+
"""Update Voicemail Settings."""
|
|
82
|
+
api = get_api(debug=debug)
|
|
83
|
+
url = f"https://webexapis.com/v1/telephony/config/voicemail/settings"
|
|
84
|
+
params = {}
|
|
85
|
+
org_id = get_org_id()
|
|
86
|
+
if org_id is not None:
|
|
87
|
+
params["orgId"] = org_id
|
|
88
|
+
if json_body:
|
|
89
|
+
body = json.loads(json_body)
|
|
90
|
+
else:
|
|
91
|
+
body = {}
|
|
92
|
+
if message_expiry_enabled is not None:
|
|
93
|
+
body["messageExpiryEnabled"] = message_expiry_enabled
|
|
94
|
+
if number_of_days_for_message_expiry is not None:
|
|
95
|
+
body["numberOfDaysForMessageExpiry"] = number_of_days_for_message_expiry
|
|
96
|
+
if strict_deletion_enabled is not None:
|
|
97
|
+
body["strictDeletionEnabled"] = strict_deletion_enabled
|
|
98
|
+
if voice_message_forwarding_enabled is not None:
|
|
99
|
+
body["voiceMessageForwardingEnabled"] = voice_message_forwarding_enabled
|
|
100
|
+
try:
|
|
101
|
+
result = api.session.rest_put(url, json=body, params=params)
|
|
102
|
+
except WebexError as e:
|
|
103
|
+
handle_rest_error(e)
|
|
104
|
+
typer.echo(f"Updated.")
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
@app.command("show-rules")
|
|
109
|
+
def show_rules(
|
|
110
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
111
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
112
|
+
):
|
|
113
|
+
"""Get Voicemail Rules."""
|
|
114
|
+
api = get_api(debug=debug)
|
|
115
|
+
url = f"https://webexapis.com/v1/telephony/config/voicemail/rules"
|
|
116
|
+
params = {}
|
|
117
|
+
org_id = get_org_id()
|
|
118
|
+
if org_id is not None:
|
|
119
|
+
params["orgId"] = org_id
|
|
120
|
+
try:
|
|
121
|
+
result = api.session.rest_get(url, params=params)
|
|
122
|
+
except WebexError as e:
|
|
123
|
+
handle_rest_error(e)
|
|
124
|
+
if output == "json":
|
|
125
|
+
print_json(result)
|
|
126
|
+
else:
|
|
127
|
+
if isinstance(result, dict):
|
|
128
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
129
|
+
elif isinstance(result, list):
|
|
130
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
131
|
+
else:
|
|
132
|
+
print_json(result)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
@app.command("update-rules")
|
|
137
|
+
def update_rules(
|
|
138
|
+
default_voicemail_pin_enabled: bool = typer.Option(None, "--default-voicemail-pin-enabled/--no-default-voicemail-pin-enabled", help="Set to `true` to enable the default voicemail passcode."),
|
|
139
|
+
default_voicemail_pin: str = typer.Option(None, "--default-voicemail-pin", help="Default voicemail passcode."),
|
|
140
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
141
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
142
|
+
):
|
|
143
|
+
"""Update Voicemail Rules\n\nExample --json-body:\n '{"defaultVoicemailPinEnabled":true,"defaultVoicemailPin":"...","expirePasscode":{"enabled":true,"numberOfDays":0},"changePasscode":{"enabled":true,"numberOfDays":0},"blockPreviousPasscodes":{"enabled":true,"numberOfPasscodes":0}}'."""
|
|
144
|
+
api = get_api(debug=debug)
|
|
145
|
+
url = f"https://webexapis.com/v1/telephony/config/voicemail/rules"
|
|
146
|
+
params = {}
|
|
147
|
+
org_id = get_org_id()
|
|
148
|
+
if org_id is not None:
|
|
149
|
+
params["orgId"] = org_id
|
|
150
|
+
if json_body:
|
|
151
|
+
body = json.loads(json_body)
|
|
152
|
+
else:
|
|
153
|
+
body = {}
|
|
154
|
+
if default_voicemail_pin_enabled is not None:
|
|
155
|
+
body["defaultVoicemailPinEnabled"] = default_voicemail_pin_enabled
|
|
156
|
+
if default_voicemail_pin is not None:
|
|
157
|
+
body["defaultVoicemailPin"] = default_voicemail_pin
|
|
158
|
+
try:
|
|
159
|
+
result = api.session.rest_put(url, json=body, params=params)
|
|
160
|
+
except WebexError as e:
|
|
161
|
+
handle_rest_error(e)
|
|
162
|
+
typer.echo(f"Updated.")
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
@app.command("show-settings")
|
|
167
|
+
def show_settings(
|
|
168
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
169
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
170
|
+
):
|
|
171
|
+
"""Get the organization Music on Hold configuration."""
|
|
172
|
+
api = get_api(debug=debug)
|
|
173
|
+
url = f"https://webexapis.com/v1/telephony/config/moh/settings"
|
|
174
|
+
params = {}
|
|
175
|
+
org_id = get_org_id()
|
|
176
|
+
if org_id is not None:
|
|
177
|
+
params["orgId"] = org_id
|
|
178
|
+
try:
|
|
179
|
+
result = api.session.rest_get(url, params=params)
|
|
180
|
+
except WebexError as e:
|
|
181
|
+
handle_rest_error(e)
|
|
182
|
+
if output == "json":
|
|
183
|
+
print_json(result)
|
|
184
|
+
else:
|
|
185
|
+
if isinstance(result, dict):
|
|
186
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
187
|
+
elif isinstance(result, list):
|
|
188
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
189
|
+
else:
|
|
190
|
+
print_json(result)
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
@app.command("update-settings")
|
|
195
|
+
def update_settings(
|
|
196
|
+
default_org_moh: str = typer.Option(None, "--default-org-moh", help="Default org level Music on Hold option, can be one of two op"),
|
|
197
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
198
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
199
|
+
):
|
|
200
|
+
"""Update the organization Music on Hold configuration."""
|
|
201
|
+
api = get_api(debug=debug)
|
|
202
|
+
url = f"https://webexapis.com/v1/telephony/config/moh/settings"
|
|
203
|
+
params = {}
|
|
204
|
+
org_id = get_org_id()
|
|
205
|
+
if org_id is not None:
|
|
206
|
+
params["orgId"] = org_id
|
|
207
|
+
if json_body:
|
|
208
|
+
body = json.loads(json_body)
|
|
209
|
+
else:
|
|
210
|
+
body = {}
|
|
211
|
+
if default_org_moh is not None:
|
|
212
|
+
body["defaultOrgMoh"] = default_org_moh
|
|
213
|
+
try:
|
|
214
|
+
result = api.session.rest_put(url, json=body, params=params)
|
|
215
|
+
except WebexError as e:
|
|
216
|
+
handle_rest_error(e)
|
|
217
|
+
typer.echo(f"Updated.")
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
@app.command("show-large-org-status")
|
|
222
|
+
def show_large_org_status(
|
|
223
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
224
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
225
|
+
):
|
|
226
|
+
"""Get Large Organization Status."""
|
|
227
|
+
api = get_api(debug=debug)
|
|
228
|
+
url = f"https://webexapis.com/v1/telephony/config/largeOrgStatus"
|
|
229
|
+
params = {}
|
|
230
|
+
org_id = get_org_id()
|
|
231
|
+
if org_id is not None:
|
|
232
|
+
params["orgId"] = org_id
|
|
233
|
+
try:
|
|
234
|
+
result = api.session.rest_get(url, params=params)
|
|
235
|
+
except WebexError as e:
|
|
236
|
+
handle_rest_error(e)
|
|
237
|
+
if output == "json":
|
|
238
|
+
print_json(result)
|
|
239
|
+
else:
|
|
240
|
+
if isinstance(result, dict):
|
|
241
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
242
|
+
elif isinstance(result, list):
|
|
243
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
244
|
+
else:
|
|
245
|
+
print_json(result)
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
@app.command("show-call-captions")
|
|
250
|
+
def show_call_captions(
|
|
251
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
252
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
253
|
+
):
|
|
254
|
+
"""Get the organization call captions settings."""
|
|
255
|
+
api = get_api(debug=debug)
|
|
256
|
+
url = f"https://webexapis.com/v1/telephony/config/callCaptions"
|
|
257
|
+
params = {}
|
|
258
|
+
org_id = get_org_id()
|
|
259
|
+
if org_id is not None:
|
|
260
|
+
params["orgId"] = org_id
|
|
261
|
+
try:
|
|
262
|
+
result = api.session.rest_get(url, params=params)
|
|
263
|
+
except WebexError as e:
|
|
264
|
+
handle_rest_error(e)
|
|
265
|
+
if output == "json":
|
|
266
|
+
print_json(result)
|
|
267
|
+
else:
|
|
268
|
+
if isinstance(result, dict):
|
|
269
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
270
|
+
elif isinstance(result, list):
|
|
271
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
272
|
+
else:
|
|
273
|
+
print_json(result)
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
@app.command("update-call-captions")
|
|
278
|
+
def update_call_captions(
|
|
279
|
+
org_closed_captions_enabled: bool = typer.Option(None, "--org-closed-captions-enabled/--no-org-closed-captions-enabled", help="Enable or disable organization-level closed captions."),
|
|
280
|
+
org_transcripts_enabled: bool = typer.Option(None, "--org-transcripts-enabled/--no-org-transcripts-enabled", help="Enable or disable organization-level transcripts."),
|
|
281
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
282
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
283
|
+
):
|
|
284
|
+
"""Update the organization call captions settings."""
|
|
285
|
+
api = get_api(debug=debug)
|
|
286
|
+
url = f"https://webexapis.com/v1/telephony/config/callCaptions"
|
|
287
|
+
params = {}
|
|
288
|
+
org_id = get_org_id()
|
|
289
|
+
if org_id is not None:
|
|
290
|
+
params["orgId"] = org_id
|
|
291
|
+
if json_body:
|
|
292
|
+
body = json.loads(json_body)
|
|
293
|
+
else:
|
|
294
|
+
body = {}
|
|
295
|
+
if org_closed_captions_enabled is not None:
|
|
296
|
+
body["orgClosedCaptionsEnabled"] = org_closed_captions_enabled
|
|
297
|
+
if org_transcripts_enabled is not None:
|
|
298
|
+
body["orgTranscriptsEnabled"] = org_transcripts_enabled
|
|
299
|
+
try:
|
|
300
|
+
result = api.session.rest_put(url, json=body, params=params)
|
|
301
|
+
except WebexError as e:
|
|
302
|
+
handle_rest_error(e)
|
|
303
|
+
typer.echo(f"Updated.")
|
|
304
|
+
|
|
305
|
+
|