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,545 @@
|
|
|
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 resolve_org_id, get_cc_base_url, get_cc_org_id
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
app = typer.Typer(help="Manage Webex Contact Center cc-entry-point.")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@app.command("list")
|
|
13
|
+
def cmd_list(
|
|
14
|
+
filter_param: str = typer.Option(None, "--filter", help="Specify a filter based on which the results will be fetched."),
|
|
15
|
+
channel_types: str = typer.Option(None, "--channel-types", help="[DEPRECATED] Channel type(s) allowed by the system.Separate"),
|
|
16
|
+
attributes: str = typer.Option(None, "--attributes", help="Specify the attributes to be returned.Default all attributes"),
|
|
17
|
+
page: str = typer.Option(None, "--page", help="Defines the number of displayed page. The page number starts"),
|
|
18
|
+
page_size: str = typer.Option(None, "--page-size", help="Defines the number of items to be displayed on a page. If th"),
|
|
19
|
+
single_object_response: str = typer.Option(None, "--single-object-response", help="Specifiy whether to include array fields in the response, Th"),
|
|
20
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
21
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
22
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
23
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
24
|
+
):
|
|
25
|
+
"""List Entry Point(s)."""
|
|
26
|
+
api = get_api(debug=debug)
|
|
27
|
+
cc_base_url = get_cc_base_url()
|
|
28
|
+
orgid = get_cc_org_id(api.session)
|
|
29
|
+
url = f"{cc_base_url}/organization/{orgid}/entry-point"
|
|
30
|
+
params = {}
|
|
31
|
+
if filter_param is not None:
|
|
32
|
+
params["filter"] = filter_param
|
|
33
|
+
if channel_types is not None:
|
|
34
|
+
params["channelTypes"] = channel_types
|
|
35
|
+
if attributes is not None:
|
|
36
|
+
params["attributes"] = attributes
|
|
37
|
+
if page is not None:
|
|
38
|
+
params["page"] = page
|
|
39
|
+
if page_size is not None:
|
|
40
|
+
params["pageSize"] = page_size
|
|
41
|
+
if single_object_response is not None:
|
|
42
|
+
params["singleObjectResponse"] = single_object_response
|
|
43
|
+
if limit > 0:
|
|
44
|
+
params["max"] = limit
|
|
45
|
+
if offset > 0:
|
|
46
|
+
params["start"] = offset
|
|
47
|
+
result = None
|
|
48
|
+
try:
|
|
49
|
+
result = api.session.rest_get(url, params=params)
|
|
50
|
+
except WebexError as e:
|
|
51
|
+
handle_rest_error(e)
|
|
52
|
+
result = result or []
|
|
53
|
+
items = result.get("items", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
54
|
+
if output == "json":
|
|
55
|
+
print_json(items)
|
|
56
|
+
else:
|
|
57
|
+
print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@app.command("create")
|
|
62
|
+
def create(
|
|
63
|
+
organization_id: str = typer.Option(None, "--organization-id", help="ID of the contact center organization. It is required to def"),
|
|
64
|
+
id_param: str = typer.Option(None, "--id", help="ID of this contact center resource. It should not be specifi"),
|
|
65
|
+
version: str = typer.Option(None, "--version", help="The version of this resource. For a newly created resource,"),
|
|
66
|
+
name: str = typer.Option(None, "--name", help="(required) A unique name for the entry point within the organization. I"),
|
|
67
|
+
description: str = typer.Option(None, "--description", help="A short description of the entry point."),
|
|
68
|
+
entry_point_type: str = typer.Option(None, "--entry-point-type", help="(required) Choices: INBOUND, OUTBOUND"),
|
|
69
|
+
channel_type: str = typer.Option(None, "--channel-type", help="(required) Choices: TELEPHONY, EMAIL, FAX, CHAT, VIDEO, OTHERS, SOCIAL_CHANNEL"),
|
|
70
|
+
social_channel_type: str = typer.Option(None, "--social-channel-type", help="(required) Choices: MESSAGEBIRD, MESSENGER, WHATSAPP, APPLE_BUSINESS_CHAT, GOOGLE_BUSINESS_MESSAGES"),
|
|
71
|
+
active: bool = typer.Option(None, "--active/--no-active", help="(required) Used to toggle the state of the entrypoint from active to in"),
|
|
72
|
+
service_level_threshold: str = typer.Option(None, "--service-level-threshold", help="(required) Allows to set the time that a customer request can be in a q"),
|
|
73
|
+
maximum_active_contacts: str = typer.Option(None, "--maximum-active-contacts", help="(required) Caps the maximum number of simultaneous calls for this entry"),
|
|
74
|
+
control_flow_script_url: str = typer.Option(None, "--control-flow-script-url", help="(required) The system automatically populates this field with the URL f"),
|
|
75
|
+
overflow_number: str = typer.Option(None, "--overflow-number", help="(required) Allows to set the destination phone number to which the syst"),
|
|
76
|
+
timezone: str = typer.Option(None, "--timezone", help="(Optional) Any routing strategy for this entry point uses th"),
|
|
77
|
+
imi_org_type: str = typer.Option(None, "--imi-org-type", help="(required) Choices: MIXED_MODE, IMI"),
|
|
78
|
+
asset_id: str = typer.Option(None, "--asset-id", help="(required) ID of the asset in IMI that corresponds to this entrypoint."),
|
|
79
|
+
xsp_version: str = typer.Option(None, "--xsp-version", help="(Optional) Used to subscribe for recording events."),
|
|
80
|
+
subscription_id: str = typer.Option(None, "--subscription-id", help="(Optional) Used to subscribe for recording events."),
|
|
81
|
+
route_point_id: str = typer.Option(None, "--route-point-id", help="The identifier of a route point of WxC which is similar to e"),
|
|
82
|
+
flow_id: str = typer.Option(None, "--flow-id", help=""),
|
|
83
|
+
flow_tag_id: str = typer.Option(None, "--flow-tag-id", help=""),
|
|
84
|
+
music_on_hold_id: str = typer.Option(None, "--music-on-hold-id", help=""),
|
|
85
|
+
outdial_queue_id: str = typer.Option(None, "--outdial-queue-id", help=""),
|
|
86
|
+
system_default: bool = typer.Option(None, "--system-default/--no-system-default", help="Indicates whether the created resource is system created or"),
|
|
87
|
+
callback_enabled: bool = typer.Option(None, "--callback-enabled/--no-callback-enabled", help="Indicates whether the created resource is call back enabled"),
|
|
88
|
+
outdial_transfer_to_queue_enabled: bool = typer.Option(None, "--outdial-transfer-to-queue-enabled/--no-outdial-transfer-to-queue-enabled", help="Indicates whether the resource is Default Outdial Transfer t"),
|
|
89
|
+
dn_ep_mapping_count: str = typer.Option(None, "--dn-ep-mapping-count", help=""),
|
|
90
|
+
created_time: str = typer.Option(None, "--created-time", help="Creation time(in epoch millis) of this resource."),
|
|
91
|
+
last_updated_time: str = typer.Option(None, "--last-updated-time", help="Time(in epoch millis) when this resource was last updated."),
|
|
92
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
93
|
+
output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
|
|
94
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
95
|
+
):
|
|
96
|
+
"""Create a new Entry Point\n\nExample --json-body:\n '{"name":"...","entryPointType":"INBOUND","channelType":"TELEPHONY","socialChannelType":"MESSAGEBIRD","active":true,"serviceLevelThreshold":0,"maximumActiveContacts":0,"controlFlowScriptUrl":"..."}'."""
|
|
97
|
+
api = get_api(debug=debug)
|
|
98
|
+
cc_base_url = get_cc_base_url()
|
|
99
|
+
orgid = get_cc_org_id(api.session)
|
|
100
|
+
url = f"{cc_base_url}/organization/{orgid}/entry-point"
|
|
101
|
+
if json_body:
|
|
102
|
+
body = json.loads(json_body)
|
|
103
|
+
else:
|
|
104
|
+
body = {}
|
|
105
|
+
if organization_id is not None:
|
|
106
|
+
body["organizationId"] = organization_id
|
|
107
|
+
if id_param is not None:
|
|
108
|
+
body["id"] = id_param
|
|
109
|
+
if version is not None:
|
|
110
|
+
body["version"] = version
|
|
111
|
+
if name is not None:
|
|
112
|
+
body["name"] = name
|
|
113
|
+
if description is not None:
|
|
114
|
+
body["description"] = description
|
|
115
|
+
if entry_point_type is not None:
|
|
116
|
+
body["entryPointType"] = entry_point_type
|
|
117
|
+
if channel_type is not None:
|
|
118
|
+
body["channelType"] = channel_type
|
|
119
|
+
if social_channel_type is not None:
|
|
120
|
+
body["socialChannelType"] = social_channel_type
|
|
121
|
+
if active is not None:
|
|
122
|
+
body["active"] = active
|
|
123
|
+
if service_level_threshold is not None:
|
|
124
|
+
body["serviceLevelThreshold"] = service_level_threshold
|
|
125
|
+
if maximum_active_contacts is not None:
|
|
126
|
+
body["maximumActiveContacts"] = maximum_active_contacts
|
|
127
|
+
if control_flow_script_url is not None:
|
|
128
|
+
body["controlFlowScriptUrl"] = control_flow_script_url
|
|
129
|
+
if overflow_number is not None:
|
|
130
|
+
body["overflowNumber"] = overflow_number
|
|
131
|
+
if timezone is not None:
|
|
132
|
+
body["timezone"] = timezone
|
|
133
|
+
if imi_org_type is not None:
|
|
134
|
+
body["imiOrgType"] = imi_org_type
|
|
135
|
+
if asset_id is not None:
|
|
136
|
+
body["assetId"] = asset_id
|
|
137
|
+
if xsp_version is not None:
|
|
138
|
+
body["xspVersion"] = xsp_version
|
|
139
|
+
if subscription_id is not None:
|
|
140
|
+
body["subscriptionId"] = subscription_id
|
|
141
|
+
if route_point_id is not None:
|
|
142
|
+
body["routePointId"] = route_point_id
|
|
143
|
+
if flow_id is not None:
|
|
144
|
+
body["flowId"] = flow_id
|
|
145
|
+
if flow_tag_id is not None:
|
|
146
|
+
body["flowTagId"] = flow_tag_id
|
|
147
|
+
if music_on_hold_id is not None:
|
|
148
|
+
body["musicOnHoldId"] = music_on_hold_id
|
|
149
|
+
if outdial_queue_id is not None:
|
|
150
|
+
body["outdialQueueId"] = outdial_queue_id
|
|
151
|
+
if system_default is not None:
|
|
152
|
+
body["systemDefault"] = system_default
|
|
153
|
+
if callback_enabled is not None:
|
|
154
|
+
body["callbackEnabled"] = callback_enabled
|
|
155
|
+
if outdial_transfer_to_queue_enabled is not None:
|
|
156
|
+
body["outdialTransferToQueueEnabled"] = outdial_transfer_to_queue_enabled
|
|
157
|
+
if dn_ep_mapping_count is not None:
|
|
158
|
+
body["dnEpMappingCount"] = dn_ep_mapping_count
|
|
159
|
+
if created_time is not None:
|
|
160
|
+
body["createdTime"] = created_time
|
|
161
|
+
if last_updated_time is not None:
|
|
162
|
+
body["lastUpdatedTime"] = last_updated_time
|
|
163
|
+
_missing = [f for f in ['name', 'entryPointType', 'channelType', 'socialChannelType', 'active', 'serviceLevelThreshold', 'maximumActiveContacts', 'controlFlowScriptUrl', 'overflowNumber', 'imiOrgType', 'assetId'] if f not in body or body[f] is None]
|
|
164
|
+
if _missing:
|
|
165
|
+
typer.echo("Error: Missing required fields: " + ", ".join(_missing), err=True)
|
|
166
|
+
raise typer.Exit(1)
|
|
167
|
+
try:
|
|
168
|
+
result = api.session.rest_post(url, json=body)
|
|
169
|
+
except WebexError as e:
|
|
170
|
+
handle_rest_error(e)
|
|
171
|
+
if output == "json":
|
|
172
|
+
print_json(result)
|
|
173
|
+
elif isinstance(result, dict) and "id" in result:
|
|
174
|
+
typer.echo(f"Created: {result['id']}")
|
|
175
|
+
elif not result or result == {}:
|
|
176
|
+
typer.echo("Created.")
|
|
177
|
+
else:
|
|
178
|
+
print_json(result)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
@app.command("create-bulk")
|
|
183
|
+
def create_bulk(
|
|
184
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
185
|
+
output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
|
|
186
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
187
|
+
):
|
|
188
|
+
"""Bulk save Entry Point(s)\n\nExample --json-body:\n '{"items":[{"itemIdentifier":"...","item":"...","requestAction":"..."}]}'."""
|
|
189
|
+
api = get_api(debug=debug)
|
|
190
|
+
cc_base_url = get_cc_base_url()
|
|
191
|
+
orgid = get_cc_org_id(api.session)
|
|
192
|
+
url = f"{cc_base_url}/organization/{orgid}/entry-point/bulk"
|
|
193
|
+
if json_body:
|
|
194
|
+
body = json.loads(json_body)
|
|
195
|
+
else:
|
|
196
|
+
body = {}
|
|
197
|
+
try:
|
|
198
|
+
result = api.session.rest_post(url, json=body)
|
|
199
|
+
except WebexError as e:
|
|
200
|
+
handle_rest_error(e)
|
|
201
|
+
if output == "json":
|
|
202
|
+
print_json(result)
|
|
203
|
+
elif isinstance(result, dict) and "id" in result:
|
|
204
|
+
typer.echo(f"Created: {result['id']}")
|
|
205
|
+
elif not result or result == {}:
|
|
206
|
+
typer.echo("Created.")
|
|
207
|
+
else:
|
|
208
|
+
print_json(result)
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
@app.command("list-bulk-export")
|
|
213
|
+
def list_bulk_export(
|
|
214
|
+
type_param: str = typer.Option(..., "--type", help="Choices: INBOUND, OUTBOUND"),
|
|
215
|
+
page: str = typer.Option(None, "--page", help="Defines the number of displayed page. The page number starts"),
|
|
216
|
+
page_size: str = typer.Option(None, "--page-size", help="Defines the number of items to be displayed on a page. If th"),
|
|
217
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
218
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
219
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
220
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
221
|
+
):
|
|
222
|
+
"""Bulk export Entry Point(s)."""
|
|
223
|
+
api = get_api(debug=debug)
|
|
224
|
+
cc_base_url = get_cc_base_url()
|
|
225
|
+
orgid = get_cc_org_id(api.session)
|
|
226
|
+
url = f"{cc_base_url}/organization/{orgid}/entry-point/bulk-export"
|
|
227
|
+
params = {}
|
|
228
|
+
if type_param is not None:
|
|
229
|
+
params["type"] = type_param
|
|
230
|
+
if page is not None:
|
|
231
|
+
params["page"] = page
|
|
232
|
+
if page_size is not None:
|
|
233
|
+
params["pageSize"] = page_size
|
|
234
|
+
if limit > 0:
|
|
235
|
+
params["max"] = limit
|
|
236
|
+
if offset > 0:
|
|
237
|
+
params["start"] = offset
|
|
238
|
+
result = None
|
|
239
|
+
try:
|
|
240
|
+
result = api.session.rest_get(url, params=params)
|
|
241
|
+
except WebexError as e:
|
|
242
|
+
handle_rest_error(e)
|
|
243
|
+
result = result or []
|
|
244
|
+
items = result.get("items", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
245
|
+
if output == "json":
|
|
246
|
+
print_json(items)
|
|
247
|
+
else:
|
|
248
|
+
print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
@app.command("create-purge-inactive-entities")
|
|
253
|
+
def create_purge_inactive_entities(
|
|
254
|
+
next_start_id: str = typer.Option(None, "--next-start-id", help="This is the entity ID from which items for the next purge ba"),
|
|
255
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
256
|
+
output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
|
|
257
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
258
|
+
):
|
|
259
|
+
"""Purge inactive Entry Point(s)."""
|
|
260
|
+
api = get_api(debug=debug)
|
|
261
|
+
cc_base_url = get_cc_base_url()
|
|
262
|
+
orgid = get_cc_org_id(api.session)
|
|
263
|
+
url = f"{cc_base_url}/organization/{orgid}/entry-point/purge-inactive-entities"
|
|
264
|
+
params = {}
|
|
265
|
+
if next_start_id is not None:
|
|
266
|
+
params["nextStartId"] = next_start_id
|
|
267
|
+
if json_body:
|
|
268
|
+
body = json.loads(json_body)
|
|
269
|
+
else:
|
|
270
|
+
body = {}
|
|
271
|
+
try:
|
|
272
|
+
result = api.session.rest_post(url, json=body, params=params)
|
|
273
|
+
except WebexError as e:
|
|
274
|
+
handle_rest_error(e)
|
|
275
|
+
if output == "json":
|
|
276
|
+
print_json(result)
|
|
277
|
+
elif isinstance(result, dict) and "id" in result:
|
|
278
|
+
typer.echo(f"Created: {result['id']}")
|
|
279
|
+
elif not result or result == {}:
|
|
280
|
+
typer.echo("Created.")
|
|
281
|
+
else:
|
|
282
|
+
print_json(result)
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
@app.command("show")
|
|
287
|
+
def show(
|
|
288
|
+
id: str = typer.Argument(help="id"),
|
|
289
|
+
include_names: str = typer.Option(None, "--include-names", help="Specifiy whether to include flow override settings reference"),
|
|
290
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
291
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
292
|
+
):
|
|
293
|
+
"""Get specific Entry Point by ID."""
|
|
294
|
+
api = get_api(debug=debug)
|
|
295
|
+
cc_base_url = get_cc_base_url()
|
|
296
|
+
orgid = get_cc_org_id(api.session)
|
|
297
|
+
url = f"{cc_base_url}/organization/{orgid}/entry-point/{id}"
|
|
298
|
+
params = {}
|
|
299
|
+
if include_names is not None:
|
|
300
|
+
params["includeNames"] = include_names
|
|
301
|
+
try:
|
|
302
|
+
result = api.session.rest_get(url, params=params)
|
|
303
|
+
except WebexError as e:
|
|
304
|
+
handle_rest_error(e)
|
|
305
|
+
if output == "json":
|
|
306
|
+
print_json(result)
|
|
307
|
+
else:
|
|
308
|
+
if isinstance(result, dict):
|
|
309
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
310
|
+
elif isinstance(result, list):
|
|
311
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
312
|
+
else:
|
|
313
|
+
print_json(result)
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
@app.command("update")
|
|
318
|
+
def update(
|
|
319
|
+
id: str = typer.Argument(help="id"),
|
|
320
|
+
organization_id: str = typer.Option(None, "--organization-id", help="ID of the contact center organization. It is required to def"),
|
|
321
|
+
id_param: str = typer.Option(None, "--id", help="ID of this contact center resource. It should not be specifi"),
|
|
322
|
+
version: str = typer.Option(None, "--version", help="The version of this resource. For a newly created resource,"),
|
|
323
|
+
name: str = typer.Option(None, "--name", help="A unique name for the entry point within the organization. I"),
|
|
324
|
+
description: str = typer.Option(None, "--description", help="A short description of the entry point."),
|
|
325
|
+
entry_point_type: str = typer.Option(None, "--entry-point-type", help="Choices: INBOUND, OUTBOUND"),
|
|
326
|
+
channel_type: str = typer.Option(None, "--channel-type", help="Choices: TELEPHONY, EMAIL, FAX, CHAT, VIDEO, OTHERS, SOCIAL_CHANNEL"),
|
|
327
|
+
social_channel_type: str = typer.Option(None, "--social-channel-type", help="Choices: MESSAGEBIRD, MESSENGER, WHATSAPP, APPLE_BUSINESS_CHAT, GOOGLE_BUSINESS_MESSAGES"),
|
|
328
|
+
active: bool = typer.Option(None, "--active/--no-active", help="Used to toggle the state of the entrypoint from active to in"),
|
|
329
|
+
service_level_threshold: str = typer.Option(None, "--service-level-threshold", help="Allows to set the time that a customer request can be in a q"),
|
|
330
|
+
maximum_active_contacts: str = typer.Option(None, "--maximum-active-contacts", help="Caps the maximum number of simultaneous calls for this entry"),
|
|
331
|
+
control_flow_script_url: str = typer.Option(None, "--control-flow-script-url", help="The system automatically populates this field with the URL f"),
|
|
332
|
+
overflow_number: str = typer.Option(None, "--overflow-number", help="Allows to set the destination phone number to which the syst"),
|
|
333
|
+
timezone: str = typer.Option(None, "--timezone", help="(Optional) Any routing strategy for this entry point uses th"),
|
|
334
|
+
imi_org_type: str = typer.Option(None, "--imi-org-type", help="Choices: MIXED_MODE, IMI"),
|
|
335
|
+
asset_id: str = typer.Option(None, "--asset-id", help="ID of the asset in IMI that corresponds to this entrypoint."),
|
|
336
|
+
xsp_version: str = typer.Option(None, "--xsp-version", help="(Optional) Used to subscribe for recording events."),
|
|
337
|
+
subscription_id: str = typer.Option(None, "--subscription-id", help="(Optional) Used to subscribe for recording events."),
|
|
338
|
+
route_point_id: str = typer.Option(None, "--route-point-id", help="The identifier of a route point of WxC which is similar to e"),
|
|
339
|
+
flow_id: str = typer.Option(None, "--flow-id", help=""),
|
|
340
|
+
flow_tag_id: str = typer.Option(None, "--flow-tag-id", help=""),
|
|
341
|
+
music_on_hold_id: str = typer.Option(None, "--music-on-hold-id", help=""),
|
|
342
|
+
outdial_queue_id: str = typer.Option(None, "--outdial-queue-id", help=""),
|
|
343
|
+
system_default: bool = typer.Option(None, "--system-default/--no-system-default", help="Indicates whether the created resource is system created or"),
|
|
344
|
+
callback_enabled: bool = typer.Option(None, "--callback-enabled/--no-callback-enabled", help="Indicates whether the created resource is call back enabled"),
|
|
345
|
+
outdial_transfer_to_queue_enabled: bool = typer.Option(None, "--outdial-transfer-to-queue-enabled/--no-outdial-transfer-to-queue-enabled", help="Indicates whether the resource is Default Outdial Transfer t"),
|
|
346
|
+
dn_ep_mapping_count: str = typer.Option(None, "--dn-ep-mapping-count", help=""),
|
|
347
|
+
created_time: str = typer.Option(None, "--created-time", help="Creation time(in epoch millis) of this resource."),
|
|
348
|
+
last_updated_time: str = typer.Option(None, "--last-updated-time", help="Time(in epoch millis) when this resource was last updated."),
|
|
349
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
350
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
351
|
+
):
|
|
352
|
+
"""Update specific Entry Point by ID\n\nExample --json-body:\n '{"name":"...","entryPointType":"INBOUND","channelType":"TELEPHONY","socialChannelType":"MESSAGEBIRD","active":true,"serviceLevelThreshold":0,"maximumActiveContacts":0,"controlFlowScriptUrl":"..."}'."""
|
|
353
|
+
api = get_api(debug=debug)
|
|
354
|
+
cc_base_url = get_cc_base_url()
|
|
355
|
+
orgid = get_cc_org_id(api.session)
|
|
356
|
+
url = f"{cc_base_url}/organization/{orgid}/entry-point/{id}"
|
|
357
|
+
if json_body:
|
|
358
|
+
body = json.loads(json_body)
|
|
359
|
+
else:
|
|
360
|
+
body = {}
|
|
361
|
+
if organization_id is not None:
|
|
362
|
+
body["organizationId"] = organization_id
|
|
363
|
+
if id_param is not None:
|
|
364
|
+
body["id"] = id_param
|
|
365
|
+
if version is not None:
|
|
366
|
+
body["version"] = version
|
|
367
|
+
if name is not None:
|
|
368
|
+
body["name"] = name
|
|
369
|
+
if description is not None:
|
|
370
|
+
body["description"] = description
|
|
371
|
+
if entry_point_type is not None:
|
|
372
|
+
body["entryPointType"] = entry_point_type
|
|
373
|
+
if channel_type is not None:
|
|
374
|
+
body["channelType"] = channel_type
|
|
375
|
+
if social_channel_type is not None:
|
|
376
|
+
body["socialChannelType"] = social_channel_type
|
|
377
|
+
if active is not None:
|
|
378
|
+
body["active"] = active
|
|
379
|
+
if service_level_threshold is not None:
|
|
380
|
+
body["serviceLevelThreshold"] = service_level_threshold
|
|
381
|
+
if maximum_active_contacts is not None:
|
|
382
|
+
body["maximumActiveContacts"] = maximum_active_contacts
|
|
383
|
+
if control_flow_script_url is not None:
|
|
384
|
+
body["controlFlowScriptUrl"] = control_flow_script_url
|
|
385
|
+
if overflow_number is not None:
|
|
386
|
+
body["overflowNumber"] = overflow_number
|
|
387
|
+
if timezone is not None:
|
|
388
|
+
body["timezone"] = timezone
|
|
389
|
+
if imi_org_type is not None:
|
|
390
|
+
body["imiOrgType"] = imi_org_type
|
|
391
|
+
if asset_id is not None:
|
|
392
|
+
body["assetId"] = asset_id
|
|
393
|
+
if xsp_version is not None:
|
|
394
|
+
body["xspVersion"] = xsp_version
|
|
395
|
+
if subscription_id is not None:
|
|
396
|
+
body["subscriptionId"] = subscription_id
|
|
397
|
+
if route_point_id is not None:
|
|
398
|
+
body["routePointId"] = route_point_id
|
|
399
|
+
if flow_id is not None:
|
|
400
|
+
body["flowId"] = flow_id
|
|
401
|
+
if flow_tag_id is not None:
|
|
402
|
+
body["flowTagId"] = flow_tag_id
|
|
403
|
+
if music_on_hold_id is not None:
|
|
404
|
+
body["musicOnHoldId"] = music_on_hold_id
|
|
405
|
+
if outdial_queue_id is not None:
|
|
406
|
+
body["outdialQueueId"] = outdial_queue_id
|
|
407
|
+
if system_default is not None:
|
|
408
|
+
body["systemDefault"] = system_default
|
|
409
|
+
if callback_enabled is not None:
|
|
410
|
+
body["callbackEnabled"] = callback_enabled
|
|
411
|
+
if outdial_transfer_to_queue_enabled is not None:
|
|
412
|
+
body["outdialTransferToQueueEnabled"] = outdial_transfer_to_queue_enabled
|
|
413
|
+
if dn_ep_mapping_count is not None:
|
|
414
|
+
body["dnEpMappingCount"] = dn_ep_mapping_count
|
|
415
|
+
if created_time is not None:
|
|
416
|
+
body["createdTime"] = created_time
|
|
417
|
+
if last_updated_time is not None:
|
|
418
|
+
body["lastUpdatedTime"] = last_updated_time
|
|
419
|
+
try:
|
|
420
|
+
result = api.session.rest_put(url, json=body)
|
|
421
|
+
except WebexError as e:
|
|
422
|
+
handle_rest_error(e)
|
|
423
|
+
typer.echo(f"Updated.")
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
@app.command("delete")
|
|
428
|
+
def delete(
|
|
429
|
+
id: str = typer.Argument(help="id"),
|
|
430
|
+
force: bool = typer.Option(False, "--force", help="Skip confirmation"),
|
|
431
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
432
|
+
):
|
|
433
|
+
"""Delete specific Entry Point by ID."""
|
|
434
|
+
if not force:
|
|
435
|
+
typer.confirm(f"Delete {id}?", abort=True)
|
|
436
|
+
api = get_api(debug=debug)
|
|
437
|
+
cc_base_url = get_cc_base_url()
|
|
438
|
+
orgid = get_cc_org_id(api.session)
|
|
439
|
+
url = f"{cc_base_url}/organization/{orgid}/entry-point/{id}"
|
|
440
|
+
try:
|
|
441
|
+
api.session.rest_delete(url)
|
|
442
|
+
except WebexError as e:
|
|
443
|
+
handle_rest_error(e)
|
|
444
|
+
typer.echo(f"Deleted: {id}")
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
@app.command("list-incoming-references")
|
|
449
|
+
def list_incoming_references(
|
|
450
|
+
id: str = typer.Argument(help="id"),
|
|
451
|
+
type_param: str = typer.Option(None, "--type", help="Entity type of the other entity that has a reference to this"),
|
|
452
|
+
page: str = typer.Option(None, "--page", help="Defines the number of displayed page. The page number starts"),
|
|
453
|
+
page_size: str = typer.Option(None, "--page-size", help="Defines the number of items to be displayed on a page. If th"),
|
|
454
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
455
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
456
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
457
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
458
|
+
):
|
|
459
|
+
"""List references for a specific Entry Point."""
|
|
460
|
+
api = get_api(debug=debug)
|
|
461
|
+
cc_base_url = get_cc_base_url()
|
|
462
|
+
orgid = get_cc_org_id(api.session)
|
|
463
|
+
url = f"{cc_base_url}/organization/{orgid}/entry-point/{id}/incoming-references"
|
|
464
|
+
params = {}
|
|
465
|
+
if type_param is not None:
|
|
466
|
+
params["type"] = type_param
|
|
467
|
+
if page is not None:
|
|
468
|
+
params["page"] = page
|
|
469
|
+
if page_size is not None:
|
|
470
|
+
params["pageSize"] = page_size
|
|
471
|
+
if limit > 0:
|
|
472
|
+
params["max"] = limit
|
|
473
|
+
if offset > 0:
|
|
474
|
+
params["start"] = offset
|
|
475
|
+
result = None
|
|
476
|
+
try:
|
|
477
|
+
result = api.session.rest_get(url, params=params)
|
|
478
|
+
except WebexError as e:
|
|
479
|
+
handle_rest_error(e)
|
|
480
|
+
result = result or []
|
|
481
|
+
items = result.get("items", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
482
|
+
if output == "json":
|
|
483
|
+
print_json(items)
|
|
484
|
+
else:
|
|
485
|
+
print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
|
|
486
|
+
|
|
487
|
+
|
|
488
|
+
|
|
489
|
+
@app.command("list-entry-point")
|
|
490
|
+
def list_entry_point(
|
|
491
|
+
filter_param: str = typer.Option(None, "--filter", help="Specify a filter based on which the results will be fetched."),
|
|
492
|
+
attributes: str = typer.Option(None, "--attributes", help="Specify the attributes to be returned.Default all attributes"),
|
|
493
|
+
search: str = typer.Option(None, "--search", help="Filter data based on the search keyword.Supported search col"),
|
|
494
|
+
page: str = typer.Option(None, "--page", help="Defines the number of displayed page. The page number starts"),
|
|
495
|
+
page_size: str = typer.Option(None, "--page-size", help="Defines the number of items to be displayed on a page. If th"),
|
|
496
|
+
desktop_profile_filter: str = typer.Option(None, "--desktop-profile-filter", help="If set to true, the API will return only the data that the u"),
|
|
497
|
+
provisioning_view: str = typer.Option(None, "--provisioning-view", help="If set to true, the API will only return data that user has"),
|
|
498
|
+
include_count: str = typer.Option(None, "--include-count", help="Enable the flag to get the count of DN-EP Mapping"),
|
|
499
|
+
single_object_response: str = typer.Option(None, "--single-object-response", help="Specifiy whether to include array fields in the response, Th"),
|
|
500
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
501
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
502
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
503
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
504
|
+
):
|
|
505
|
+
"""List Entry Point(s)."""
|
|
506
|
+
api = get_api(debug=debug)
|
|
507
|
+
cc_base_url = get_cc_base_url()
|
|
508
|
+
orgid = get_cc_org_id(api.session)
|
|
509
|
+
url = f"{cc_base_url}/organization/{orgid}/v2/entry-point"
|
|
510
|
+
params = {}
|
|
511
|
+
if filter_param is not None:
|
|
512
|
+
params["filter"] = filter_param
|
|
513
|
+
if attributes is not None:
|
|
514
|
+
params["attributes"] = attributes
|
|
515
|
+
if search is not None:
|
|
516
|
+
params["search"] = search
|
|
517
|
+
if page is not None:
|
|
518
|
+
params["page"] = page
|
|
519
|
+
if page_size is not None:
|
|
520
|
+
params["pageSize"] = page_size
|
|
521
|
+
if desktop_profile_filter is not None:
|
|
522
|
+
params["desktopProfileFilter"] = desktop_profile_filter
|
|
523
|
+
if provisioning_view is not None:
|
|
524
|
+
params["provisioningView"] = provisioning_view
|
|
525
|
+
if include_count is not None:
|
|
526
|
+
params["includeCount"] = include_count
|
|
527
|
+
if single_object_response is not None:
|
|
528
|
+
params["singleObjectResponse"] = single_object_response
|
|
529
|
+
if limit > 0:
|
|
530
|
+
params["max"] = limit
|
|
531
|
+
if offset > 0:
|
|
532
|
+
params["start"] = offset
|
|
533
|
+
result = None
|
|
534
|
+
try:
|
|
535
|
+
result = api.session.rest_get(url, params=params)
|
|
536
|
+
except WebexError as e:
|
|
537
|
+
handle_rest_error(e)
|
|
538
|
+
result = result or []
|
|
539
|
+
items = result.get("items", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
540
|
+
if output == "json":
|
|
541
|
+
print_json(items)
|
|
542
|
+
else:
|
|
543
|
+
print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
|
|
544
|
+
|
|
545
|
+
|
wxcli/commands/cc_ewt.py
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
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, get_cc_base_url, get_cc_org_id
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
app = typer.Typer(help="Manage Webex Contact Center cc-ewt.")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@app.command("show")
|
|
13
|
+
def show(
|
|
14
|
+
queue_id: str = typer.Option(..., "--queue-id", help="Id of the queue for which the EWT is to be returned"),
|
|
15
|
+
lookback_minutes: str = typer.Option(..., "--lookback-minutes", help="Integer between 5 and 240 (4 hours) signifying how long back"),
|
|
16
|
+
max_cv: str = typer.Option(None, "--max-cv", help="This an optional parameter. Maximum value of Coefficient of"),
|
|
17
|
+
min_valid_samples: str = typer.Option(None, "--min-valid-samples", help="This an optional parameter. Minimum value of percentage of v"),
|
|
18
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
19
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
20
|
+
):
|
|
21
|
+
"""Get Estimated Wait Time."""
|
|
22
|
+
api = get_api(debug=debug)
|
|
23
|
+
cc_base_url = get_cc_base_url()
|
|
24
|
+
url = f"{cc_base_url}/ewt"
|
|
25
|
+
params = {}
|
|
26
|
+
if queue_id is not None:
|
|
27
|
+
params["queueId"] = queue_id
|
|
28
|
+
if lookback_minutes is not None:
|
|
29
|
+
params["lookbackMinutes"] = lookback_minutes
|
|
30
|
+
if max_cv is not None:
|
|
31
|
+
params["maxCV"] = max_cv
|
|
32
|
+
if min_valid_samples is not None:
|
|
33
|
+
params["minValidSamples"] = min_valid_samples
|
|
34
|
+
org_id = get_org_id()
|
|
35
|
+
if org_id is not None:
|
|
36
|
+
params["orgId"] = org_id
|
|
37
|
+
try:
|
|
38
|
+
result = api.session.rest_get(url, params=params)
|
|
39
|
+
except WebexError as e:
|
|
40
|
+
handle_rest_error(e)
|
|
41
|
+
if output == "json":
|
|
42
|
+
print_json(result)
|
|
43
|
+
else:
|
|
44
|
+
if isinstance(result, dict):
|
|
45
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
46
|
+
elif isinstance(result, list):
|
|
47
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
48
|
+
else:
|
|
49
|
+
print_json(result)
|
|
50
|
+
|
|
51
|
+
|