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,701 @@
|
|
|
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-users.")
|
|
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
|
+
attributes: str = typer.Option(None, "--attributes", help="Specify the attributes to be returned. By default, all attri"),
|
|
16
|
+
page: str = typer.Option(None, "--page", help="Defines the number of displayed page. The page number starts"),
|
|
17
|
+
page_size: str = typer.Option(None, "--page-size", help="Defines the number of items to be displayed on a page. If th"),
|
|
18
|
+
single_object_response: str = typer.Option(None, "--single-object-response", help="Specify whether to include array fields in the response. Thi"),
|
|
19
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
20
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
21
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
22
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
23
|
+
):
|
|
24
|
+
"""List Users."""
|
|
25
|
+
api = get_api(debug=debug)
|
|
26
|
+
cc_base_url = get_cc_base_url()
|
|
27
|
+
orgid = get_cc_org_id(api.session)
|
|
28
|
+
url = f"{cc_base_url}/organization/{orgid}/user"
|
|
29
|
+
params = {}
|
|
30
|
+
if filter_param is not None:
|
|
31
|
+
params["filter"] = filter_param
|
|
32
|
+
if attributes is not None:
|
|
33
|
+
params["attributes"] = attributes
|
|
34
|
+
if page is not None:
|
|
35
|
+
params["page"] = page
|
|
36
|
+
if page_size is not None:
|
|
37
|
+
params["pageSize"] = page_size
|
|
38
|
+
if single_object_response is not None:
|
|
39
|
+
params["singleObjectResponse"] = single_object_response
|
|
40
|
+
if limit > 0:
|
|
41
|
+
params["max"] = limit
|
|
42
|
+
if offset > 0:
|
|
43
|
+
params["start"] = offset
|
|
44
|
+
result = None
|
|
45
|
+
try:
|
|
46
|
+
result = api.session.rest_get(url, params=params)
|
|
47
|
+
except WebexError as e:
|
|
48
|
+
handle_rest_error(e)
|
|
49
|
+
result = result or []
|
|
50
|
+
items = result.get("items", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
51
|
+
if output == "json":
|
|
52
|
+
print_json(items)
|
|
53
|
+
else:
|
|
54
|
+
print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@app.command("update")
|
|
59
|
+
def update(
|
|
60
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
61
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
62
|
+
):
|
|
63
|
+
"""Bulk partial update Users\n\nExample --json-body:\n '{"items":[{"itemIdentifier":"...","item":"...","requestAction":"..."}]}'."""
|
|
64
|
+
api = get_api(debug=debug)
|
|
65
|
+
cc_base_url = get_cc_base_url()
|
|
66
|
+
orgid = get_cc_org_id(api.session)
|
|
67
|
+
url = f"{cc_base_url}/organization/{orgid}/user/bulk"
|
|
68
|
+
if json_body:
|
|
69
|
+
body = json.loads(json_body)
|
|
70
|
+
else:
|
|
71
|
+
body = {}
|
|
72
|
+
try:
|
|
73
|
+
result = api.session.rest_patch(url, json=body)
|
|
74
|
+
except WebexError as e:
|
|
75
|
+
handle_rest_error(e)
|
|
76
|
+
typer.echo(f"Updated.")
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
@app.command("update-dynamic-skill")
|
|
81
|
+
def update_dynamic_skill(
|
|
82
|
+
skill_id: str = typer.Argument(help="skillId"),
|
|
83
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
84
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
85
|
+
):
|
|
86
|
+
"""Bulk partial update Users with dynamic skills\n\nExample --json-body:\n '{"items":[{"itemIdentifier":"...","item":"...","requestAction":"..."}]}'."""
|
|
87
|
+
api = get_api(debug=debug)
|
|
88
|
+
cc_base_url = get_cc_base_url()
|
|
89
|
+
orgid = get_cc_org_id(api.session)
|
|
90
|
+
url = f"{cc_base_url}/organization/{orgid}/user/bulk/update-dynamic-skill/{skill_id}"
|
|
91
|
+
if json_body:
|
|
92
|
+
body = json.loads(json_body)
|
|
93
|
+
else:
|
|
94
|
+
body = {}
|
|
95
|
+
try:
|
|
96
|
+
result = api.session.rest_patch(url, json=body)
|
|
97
|
+
except WebexError as e:
|
|
98
|
+
handle_rest_error(e)
|
|
99
|
+
typer.echo(f"Updated.")
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
@app.command("show")
|
|
104
|
+
def show(
|
|
105
|
+
id: str = typer.Argument(help="id"),
|
|
106
|
+
page: str = typer.Option(None, "--page", help="Defines the number of displayed page. The page number starts"),
|
|
107
|
+
page_size: str = typer.Option(None, "--page-size", help="Defines the number of items to be displayed on a page. If th"),
|
|
108
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
109
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
110
|
+
):
|
|
111
|
+
"""List users by call monitoring id."""
|
|
112
|
+
api = get_api(debug=debug)
|
|
113
|
+
cc_base_url = get_cc_base_url()
|
|
114
|
+
orgid = get_cc_org_id(api.session)
|
|
115
|
+
url = f"{cc_base_url}/organization/{orgid}/user/by-call-monitoring-id/{id}"
|
|
116
|
+
params = {}
|
|
117
|
+
if page is not None:
|
|
118
|
+
params["page"] = page
|
|
119
|
+
if page_size is not None:
|
|
120
|
+
params["pageSize"] = page_size
|
|
121
|
+
try:
|
|
122
|
+
result = api.session.rest_get(url, params=params)
|
|
123
|
+
except WebexError as e:
|
|
124
|
+
handle_rest_error(e)
|
|
125
|
+
if output == "json":
|
|
126
|
+
print_json(result)
|
|
127
|
+
else:
|
|
128
|
+
if isinstance(result, dict):
|
|
129
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
130
|
+
elif isinstance(result, list):
|
|
131
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
132
|
+
else:
|
|
133
|
+
print_json(result)
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
@app.command("show-by-ci-user-id-organization")
|
|
138
|
+
def show_by_ci_user_id_organization(
|
|
139
|
+
id: str = typer.Argument(help="id"),
|
|
140
|
+
include_user_profile: str = typer.Option(None, "--include-user-profile", help="Specifiy whether to include user profile data"),
|
|
141
|
+
include_skill_details: str = typer.Option(None, "--include-skill-details", help="If set to true, the response includes skill information for"),
|
|
142
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
143
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
144
|
+
):
|
|
145
|
+
"""Get specific User by CI User ID."""
|
|
146
|
+
api = get_api(debug=debug)
|
|
147
|
+
cc_base_url = get_cc_base_url()
|
|
148
|
+
orgid = get_cc_org_id(api.session)
|
|
149
|
+
url = f"{cc_base_url}/organization/{orgid}/user/by-ci-user-id/{id}"
|
|
150
|
+
params = {}
|
|
151
|
+
if include_user_profile is not None:
|
|
152
|
+
params["includeUserProfile"] = include_user_profile
|
|
153
|
+
if include_skill_details is not None:
|
|
154
|
+
params["includeSkillDetails"] = include_skill_details
|
|
155
|
+
try:
|
|
156
|
+
result = api.session.rest_get(url, params=params)
|
|
157
|
+
except WebexError as e:
|
|
158
|
+
handle_rest_error(e)
|
|
159
|
+
if output == "json":
|
|
160
|
+
print_json(result)
|
|
161
|
+
else:
|
|
162
|
+
if isinstance(result, dict):
|
|
163
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
164
|
+
elif isinstance(result, list):
|
|
165
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
166
|
+
else:
|
|
167
|
+
print_json(result)
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
@app.command("show-by-dynamic-skill-id")
|
|
172
|
+
def show_by_dynamic_skill_id(
|
|
173
|
+
skill_id: str = typer.Argument(help="skillId"),
|
|
174
|
+
search: str = typer.Option(None, "--search", help="Filter data based on the search keyword.Supported search col"),
|
|
175
|
+
page: str = typer.Option(None, "--page", help="Defines the number of displayed page. The page number starts"),
|
|
176
|
+
page_size: str = typer.Option(None, "--page-size", help="Defines the number of items to be displayed on a page. If th"),
|
|
177
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
178
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
179
|
+
):
|
|
180
|
+
"""Get users by dynamic skill ID."""
|
|
181
|
+
api = get_api(debug=debug)
|
|
182
|
+
cc_base_url = get_cc_base_url()
|
|
183
|
+
orgid = get_cc_org_id(api.session)
|
|
184
|
+
url = f"{cc_base_url}/organization/{orgid}/user/by-dynamic-skill-id/{skill_id}"
|
|
185
|
+
params = {}
|
|
186
|
+
if search is not None:
|
|
187
|
+
params["search"] = search
|
|
188
|
+
if page is not None:
|
|
189
|
+
params["page"] = page
|
|
190
|
+
if page_size is not None:
|
|
191
|
+
params["pageSize"] = page_size
|
|
192
|
+
try:
|
|
193
|
+
result = api.session.rest_get(url, params=params)
|
|
194
|
+
except WebexError as e:
|
|
195
|
+
handle_rest_error(e)
|
|
196
|
+
if output == "json":
|
|
197
|
+
print_json(result)
|
|
198
|
+
else:
|
|
199
|
+
if isinstance(result, dict):
|
|
200
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
201
|
+
elif isinstance(result, list):
|
|
202
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
203
|
+
else:
|
|
204
|
+
print_json(result)
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
@app.command("create")
|
|
209
|
+
def create(
|
|
210
|
+
search: str = typer.Option(None, "--search", help="Filter data based on the search keyword.Supported search col"),
|
|
211
|
+
page: str = typer.Option(None, "--page", help="Defines the number of displayed page. The page number starts"),
|
|
212
|
+
page_size: str = typer.Option(None, "--page-size", help="Defines the number of items to be displayed on a page. If th"),
|
|
213
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
214
|
+
output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
|
|
215
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
216
|
+
):
|
|
217
|
+
"""Get the agents matching skill requirements criteria\n\nExample --json-body:\n '{"skillRequirements":[{"skillId":"...","condition":"...","skillValue":"...","organizationId":"...","id":"...","version":"...","skillName":"...","skillType":"..."}]}'."""
|
|
218
|
+
api = get_api(debug=debug)
|
|
219
|
+
cc_base_url = get_cc_base_url()
|
|
220
|
+
orgid = get_cc_org_id(api.session)
|
|
221
|
+
url = f"{cc_base_url}/organization/{orgid}/user/fetch-by-skill-requirements"
|
|
222
|
+
params = {}
|
|
223
|
+
if search is not None:
|
|
224
|
+
params["search"] = search
|
|
225
|
+
if page is not None:
|
|
226
|
+
params["page"] = page
|
|
227
|
+
if page_size is not None:
|
|
228
|
+
params["pageSize"] = page_size
|
|
229
|
+
if json_body:
|
|
230
|
+
body = json.loads(json_body)
|
|
231
|
+
else:
|
|
232
|
+
body = {}
|
|
233
|
+
try:
|
|
234
|
+
result = api.session.rest_post(url, json=body, params=params)
|
|
235
|
+
except WebexError as e:
|
|
236
|
+
handle_rest_error(e)
|
|
237
|
+
if output == "json":
|
|
238
|
+
print_json(result)
|
|
239
|
+
elif isinstance(result, dict) and "id" in result:
|
|
240
|
+
typer.echo(f"Created: {result['id']}")
|
|
241
|
+
elif not result or result == {}:
|
|
242
|
+
typer.echo("Created.")
|
|
243
|
+
else:
|
|
244
|
+
print_json(result)
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
@app.command("create-fetch-user-details-by-ids")
|
|
249
|
+
def create_fetch_user_details_by_ids(
|
|
250
|
+
page: str = typer.Option(None, "--page", help="Defines the number of displayed page. The page number starts"),
|
|
251
|
+
page_size: str = typer.Option(None, "--page-size", help="Defines the number of items to be displayed on a page. If th"),
|
|
252
|
+
search: str = typer.Option(None, "--search", help="Text used to search for users (e.g., by firstName, lastName"),
|
|
253
|
+
queue_id: str = typer.Option(None, "--queue-id", help="Agent Based Queue ID to filter users . Required if `search`"),
|
|
254
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
255
|
+
output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
|
|
256
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
257
|
+
):
|
|
258
|
+
"""List Users with details\n\nExample --json-body:\n '{"userIds":[{}],"search":"...","queueId":"..."}'."""
|
|
259
|
+
api = get_api(debug=debug)
|
|
260
|
+
cc_base_url = get_cc_base_url()
|
|
261
|
+
orgid = get_cc_org_id(api.session)
|
|
262
|
+
url = f"{cc_base_url}/organization/{orgid}/user/fetch-user-details-by-ids"
|
|
263
|
+
params = {}
|
|
264
|
+
if page is not None:
|
|
265
|
+
params["page"] = page
|
|
266
|
+
if page_size is not None:
|
|
267
|
+
params["pageSize"] = page_size
|
|
268
|
+
if json_body:
|
|
269
|
+
body = json.loads(json_body)
|
|
270
|
+
else:
|
|
271
|
+
body = {}
|
|
272
|
+
if search is not None:
|
|
273
|
+
body["search"] = search
|
|
274
|
+
if queue_id is not None:
|
|
275
|
+
body["queueId"] = queue_id
|
|
276
|
+
try:
|
|
277
|
+
result = api.session.rest_post(url, json=body, params=params)
|
|
278
|
+
except WebexError as e:
|
|
279
|
+
handle_rest_error(e)
|
|
280
|
+
if output == "json":
|
|
281
|
+
print_json(result)
|
|
282
|
+
elif isinstance(result, dict) and "id" in result:
|
|
283
|
+
typer.echo(f"Created: {result['id']}")
|
|
284
|
+
elif not result or result == {}:
|
|
285
|
+
typer.echo("Created.")
|
|
286
|
+
else:
|
|
287
|
+
print_json(result)
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
@app.command("list-with-user-profile")
|
|
292
|
+
def list_with_user_profile(
|
|
293
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
294
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
295
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
296
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
297
|
+
):
|
|
298
|
+
"""List Users along with profile."""
|
|
299
|
+
api = get_api(debug=debug)
|
|
300
|
+
cc_base_url = get_cc_base_url()
|
|
301
|
+
orgid = get_cc_org_id(api.session)
|
|
302
|
+
url = f"{cc_base_url}/organization/{orgid}/user/with-user-profile"
|
|
303
|
+
params = {}
|
|
304
|
+
if limit > 0:
|
|
305
|
+
params["max"] = limit
|
|
306
|
+
if offset > 0:
|
|
307
|
+
params["start"] = offset
|
|
308
|
+
result = None
|
|
309
|
+
try:
|
|
310
|
+
result = api.session.rest_get(url, params=params)
|
|
311
|
+
except WebexError as e:
|
|
312
|
+
handle_rest_error(e)
|
|
313
|
+
result = result or []
|
|
314
|
+
items = result.get("items", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
315
|
+
if output == "json":
|
|
316
|
+
print_json(items)
|
|
317
|
+
else:
|
|
318
|
+
print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
@app.command("show-with-user-profile")
|
|
323
|
+
def show_with_user_profile(
|
|
324
|
+
id: str = typer.Argument(help="id"),
|
|
325
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
326
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
327
|
+
):
|
|
328
|
+
"""Get specific User along with profile by ID."""
|
|
329
|
+
api = get_api(debug=debug)
|
|
330
|
+
cc_base_url = get_cc_base_url()
|
|
331
|
+
orgid = get_cc_org_id(api.session)
|
|
332
|
+
url = f"{cc_base_url}/organization/{orgid}/user/with-user-profile/{id}"
|
|
333
|
+
try:
|
|
334
|
+
result = api.session.rest_get(url)
|
|
335
|
+
except WebexError as e:
|
|
336
|
+
handle_rest_error(e)
|
|
337
|
+
if output == "json":
|
|
338
|
+
print_json(result)
|
|
339
|
+
else:
|
|
340
|
+
if isinstance(result, dict):
|
|
341
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
342
|
+
elif isinstance(result, list):
|
|
343
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
344
|
+
else:
|
|
345
|
+
print_json(result)
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
@app.command("show-user")
|
|
350
|
+
def show_user(
|
|
351
|
+
id: str = typer.Argument(help="id"),
|
|
352
|
+
include_count: str = typer.Option(None, "--include-count", help="If set to true, the API response will include the count of e"),
|
|
353
|
+
include_user_profile_type: str = typer.Option(None, "--include-user-profile-type", help="If set to true, the API response includes the User Profile."),
|
|
354
|
+
include_skill_profile_audit: str = typer.Option(None, "--include-skill-profile-audit", help="If set to true gives skill profile modification info."),
|
|
355
|
+
include_reskill_audit_info: str = typer.Option(None, "--include-reskill-audit-info", help="If set to true gives skill profile and dynamic skill modific"),
|
|
356
|
+
include_skill_details: str = typer.Option(None, "--include-skill-details", help="If set to true, the response includes skill information for"),
|
|
357
|
+
check_if_user_has_dynamic_skill: str = typer.Option(None, "--check-if-user-has-dynamic-skill", help="If set to true, checks if user has the specified dynamic ski"),
|
|
358
|
+
dynamic_skill_id: str = typer.Option(None, "--dynamic-skill-id", help="Dynamic skill ID to check if user has it assigned (required"),
|
|
359
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
360
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
361
|
+
):
|
|
362
|
+
"""Get specific User by ID."""
|
|
363
|
+
api = get_api(debug=debug)
|
|
364
|
+
cc_base_url = get_cc_base_url()
|
|
365
|
+
orgid = get_cc_org_id(api.session)
|
|
366
|
+
url = f"{cc_base_url}/organization/{orgid}/user/{id}"
|
|
367
|
+
params = {}
|
|
368
|
+
if include_count is not None:
|
|
369
|
+
params["includeCount"] = include_count
|
|
370
|
+
if include_user_profile_type is not None:
|
|
371
|
+
params["includeUserProfileType"] = include_user_profile_type
|
|
372
|
+
if include_skill_profile_audit is not None:
|
|
373
|
+
params["includeSkillProfileAudit"] = include_skill_profile_audit
|
|
374
|
+
if include_reskill_audit_info is not None:
|
|
375
|
+
params["includeReskillAuditInfo"] = include_reskill_audit_info
|
|
376
|
+
if include_skill_details is not None:
|
|
377
|
+
params["includeSkillDetails"] = include_skill_details
|
|
378
|
+
if check_if_user_has_dynamic_skill is not None:
|
|
379
|
+
params["checkIfUserHasDynamicSkill"] = check_if_user_has_dynamic_skill
|
|
380
|
+
if dynamic_skill_id is not None:
|
|
381
|
+
params["dynamicSkillId"] = dynamic_skill_id
|
|
382
|
+
try:
|
|
383
|
+
result = api.session.rest_get(url, params=params)
|
|
384
|
+
except WebexError as e:
|
|
385
|
+
handle_rest_error(e)
|
|
386
|
+
if output == "json":
|
|
387
|
+
print_json(result)
|
|
388
|
+
else:
|
|
389
|
+
if isinstance(result, dict):
|
|
390
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
391
|
+
elif isinstance(result, list):
|
|
392
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
393
|
+
else:
|
|
394
|
+
print_json(result)
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
@app.command("update-user")
|
|
399
|
+
def update_user(
|
|
400
|
+
id: str = typer.Argument(help="id"),
|
|
401
|
+
organization_id: str = typer.Option(None, "--organization-id", help="ID of the contact center organization. This field is require"),
|
|
402
|
+
id_param: str = typer.Option(None, "--id", help="ID of this contact center resource. It should not be specifi"),
|
|
403
|
+
version: str = typer.Option(None, "--version", help="The version of this resource. For a newly created resource,"),
|
|
404
|
+
first_name: str = typer.Option(None, "--first-name", help="The first name of the user. Can be changed using Users Manag"),
|
|
405
|
+
last_name: str = typer.Option(None, "--last-name", help="The last name of the user. Can be changed using Users Manage"),
|
|
406
|
+
email: str = typer.Option(None, "--email", help="The email address of the user. Can be changed using Users Ma"),
|
|
407
|
+
work_phone: str = typer.Option(None, "--work-phone", help="The work phone number of the user."),
|
|
408
|
+
mobile: str = typer.Option(None, "--mobile", help="The mobile phone number of the user."),
|
|
409
|
+
ci_user_id: str = typer.Option(None, "--ci-user-id", help="Cisco Common Identity user Id. Existence of a CI user is a p"),
|
|
410
|
+
broad_cloud_user_id: str = typer.Option(None, "--broad-cloud-user-id", help="Broadcloud user Id. This field cannot be modified."),
|
|
411
|
+
user_profile_id: str = typer.Option(None, "--user-profile-id", help="Identifier for an user profile which a Contact Center admini"),
|
|
412
|
+
contact_center_enabled: bool = typer.Option(None, "--contact-center-enabled/--no-contact-center-enabled", help="The setting is for accessing the Agent Desktop to handle cus"),
|
|
413
|
+
timezone: str = typer.Option(None, "--timezone", help="(Optional) The time zone that you provision for your enterpr"),
|
|
414
|
+
xsp_version: str = typer.Option(None, "--xsp-version", help="(Optional) Used to subscribe for recording events. This fiel"),
|
|
415
|
+
subscription_id: str = typer.Option(None, "--subscription-id", help="(Optional) Used to subscribe for recording events. This fiel"),
|
|
416
|
+
site_id: str = typer.Option(None, "--site-id", help="(Optional) Identifier for a site which is a physical contact"),
|
|
417
|
+
skill_profile_id: str = typer.Option(None, "--skill-profile-id", help="(Optional) If your enterprise uses the optional Skills-Based"),
|
|
418
|
+
agent_profile_id: str = typer.Option(None, "--agent-profile-id", help="Identifier for a Desktop Profile which is a group of permiss"),
|
|
419
|
+
multimedia_profile_id: str = typer.Option(None, "--multimedia-profile-id", help="(Optional) If your organization administrator enables Multim"),
|
|
420
|
+
deafult_dialled_number: str = typer.Option(None, "--deafult-dialled-number", help="(Optional) The dial number of the agent. This field is appli"),
|
|
421
|
+
external_identifier: str = typer.Option(None, "--external-identifier", help="(Optional) Agent identification details, such as the employe"),
|
|
422
|
+
active: bool = typer.Option(None, "--active/--no-active", help="Indicates whether the user is active or not active. Can be c"),
|
|
423
|
+
imi_user_created: bool = typer.Option(None, "--imi-user-created/--no-imi-user-created", help="(Optional) Indicates whether this user has a corresponding u"),
|
|
424
|
+
preferred_supervisor_team_id: str = typer.Option(None, "--preferred-supervisor-team-id", help="(Optional) Indicates the id of a preferred supervisor."),
|
|
425
|
+
user_level_burnout_inclusion: str = typer.Option(None, "--user-level-burnout-inclusion", help="Choices: INCLUDED, EXCLUDED"),
|
|
426
|
+
user_level_auto_csat_inclusion: str = typer.Option(None, "--user-level-auto-csat-inclusion", help="Choices: INCLUDED, EXCLUDED"),
|
|
427
|
+
user_level_wellness_break_reminders: str = typer.Option(None, "--user-level-wellness-break-reminders", help="Choices: DISABLED, ENABLED"),
|
|
428
|
+
user_level_summaries_inclusion: str = typer.Option(None, "--user-level-summaries-inclusion", help="Choices: INCLUDED, EXCLUDED"),
|
|
429
|
+
supervisor_capabilities_enabled: bool = typer.Option(None, "--supervisor-capabilities-enabled/--no-supervisor-capabilities-enabled", help="Indicates whether supervisor capabilities are enabled for th"),
|
|
430
|
+
agent_capabilities_enabled: bool = typer.Option(None, "--agent-capabilities-enabled/--no-agent-capabilities-enabled", help="Indicates whether agent capabilities are enabled for the use"),
|
|
431
|
+
created_time: str = typer.Option(None, "--created-time", help="This is the created time of the entity."),
|
|
432
|
+
last_updated_time: str = typer.Option(None, "--last-updated-time", help="This is the updated time of the entity."),
|
|
433
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
434
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
435
|
+
):
|
|
436
|
+
"""Update specific User by ID\n\nExample --json-body:\n '{"firstName":"...","lastName":"...","email":"...","ciUserId":"...","userProfileId":"...","contactCenterEnabled":true,"active":true,"organizationId":"..."}'."""
|
|
437
|
+
api = get_api(debug=debug)
|
|
438
|
+
cc_base_url = get_cc_base_url()
|
|
439
|
+
orgid = get_cc_org_id(api.session)
|
|
440
|
+
url = f"{cc_base_url}/organization/{orgid}/user/{id}"
|
|
441
|
+
if json_body:
|
|
442
|
+
body = json.loads(json_body)
|
|
443
|
+
else:
|
|
444
|
+
body = {}
|
|
445
|
+
if organization_id is not None:
|
|
446
|
+
body["organizationId"] = organization_id
|
|
447
|
+
if id_param is not None:
|
|
448
|
+
body["id"] = id_param
|
|
449
|
+
if version is not None:
|
|
450
|
+
body["version"] = version
|
|
451
|
+
if first_name is not None:
|
|
452
|
+
body["firstName"] = first_name
|
|
453
|
+
if last_name is not None:
|
|
454
|
+
body["lastName"] = last_name
|
|
455
|
+
if email is not None:
|
|
456
|
+
body["email"] = email
|
|
457
|
+
if work_phone is not None:
|
|
458
|
+
body["workPhone"] = work_phone
|
|
459
|
+
if mobile is not None:
|
|
460
|
+
body["mobile"] = mobile
|
|
461
|
+
if ci_user_id is not None:
|
|
462
|
+
body["ciUserId"] = ci_user_id
|
|
463
|
+
if broad_cloud_user_id is not None:
|
|
464
|
+
body["broadCloudUserId"] = broad_cloud_user_id
|
|
465
|
+
if user_profile_id is not None:
|
|
466
|
+
body["userProfileId"] = user_profile_id
|
|
467
|
+
if contact_center_enabled is not None:
|
|
468
|
+
body["contactCenterEnabled"] = contact_center_enabled
|
|
469
|
+
if timezone is not None:
|
|
470
|
+
body["timezone"] = timezone
|
|
471
|
+
if xsp_version is not None:
|
|
472
|
+
body["xspVersion"] = xsp_version
|
|
473
|
+
if subscription_id is not None:
|
|
474
|
+
body["subscriptionId"] = subscription_id
|
|
475
|
+
if site_id is not None:
|
|
476
|
+
body["siteId"] = site_id
|
|
477
|
+
if skill_profile_id is not None:
|
|
478
|
+
body["skillProfileId"] = skill_profile_id
|
|
479
|
+
if agent_profile_id is not None:
|
|
480
|
+
body["agentProfileId"] = agent_profile_id
|
|
481
|
+
if multimedia_profile_id is not None:
|
|
482
|
+
body["multimediaProfileId"] = multimedia_profile_id
|
|
483
|
+
if deafult_dialled_number is not None:
|
|
484
|
+
body["deafultDialledNumber"] = deafult_dialled_number
|
|
485
|
+
if external_identifier is not None:
|
|
486
|
+
body["externalIdentifier"] = external_identifier
|
|
487
|
+
if active is not None:
|
|
488
|
+
body["active"] = active
|
|
489
|
+
if imi_user_created is not None:
|
|
490
|
+
body["imiUserCreated"] = imi_user_created
|
|
491
|
+
if preferred_supervisor_team_id is not None:
|
|
492
|
+
body["preferredSupervisorTeamId"] = preferred_supervisor_team_id
|
|
493
|
+
if user_level_burnout_inclusion is not None:
|
|
494
|
+
body["userLevelBurnoutInclusion"] = user_level_burnout_inclusion
|
|
495
|
+
if user_level_auto_csat_inclusion is not None:
|
|
496
|
+
body["userLevelAutoCSATInclusion"] = user_level_auto_csat_inclusion
|
|
497
|
+
if user_level_wellness_break_reminders is not None:
|
|
498
|
+
body["userLevelWellnessBreakReminders"] = user_level_wellness_break_reminders
|
|
499
|
+
if user_level_summaries_inclusion is not None:
|
|
500
|
+
body["userLevelSummariesInclusion"] = user_level_summaries_inclusion
|
|
501
|
+
if supervisor_capabilities_enabled is not None:
|
|
502
|
+
body["supervisorCapabilitiesEnabled"] = supervisor_capabilities_enabled
|
|
503
|
+
if agent_capabilities_enabled is not None:
|
|
504
|
+
body["agentCapabilitiesEnabled"] = agent_capabilities_enabled
|
|
505
|
+
if created_time is not None:
|
|
506
|
+
body["createdTime"] = created_time
|
|
507
|
+
if last_updated_time is not None:
|
|
508
|
+
body["lastUpdatedTime"] = last_updated_time
|
|
509
|
+
try:
|
|
510
|
+
result = api.session.rest_put(url, json=body)
|
|
511
|
+
except WebexError as e:
|
|
512
|
+
handle_rest_error(e)
|
|
513
|
+
typer.echo(f"Updated.")
|
|
514
|
+
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+
@app.command("list-incoming-references")
|
|
518
|
+
def list_incoming_references(
|
|
519
|
+
id: str = typer.Argument(help="id"),
|
|
520
|
+
type_param: str = typer.Option(None, "--type", help="Entity type of the other entity that has a reference to this"),
|
|
521
|
+
page: str = typer.Option(None, "--page", help="Defines the number of displayed page. The page number starts"),
|
|
522
|
+
page_size: str = typer.Option(None, "--page-size", help="Defines the number of items to be displayed on a page. If th"),
|
|
523
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
524
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
525
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
526
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
527
|
+
):
|
|
528
|
+
"""List references for a specific User."""
|
|
529
|
+
api = get_api(debug=debug)
|
|
530
|
+
cc_base_url = get_cc_base_url()
|
|
531
|
+
orgid = get_cc_org_id(api.session)
|
|
532
|
+
url = f"{cc_base_url}/organization/{orgid}/user/{id}/incoming-references"
|
|
533
|
+
params = {}
|
|
534
|
+
if type_param is not None:
|
|
535
|
+
params["type"] = type_param
|
|
536
|
+
if page is not None:
|
|
537
|
+
params["page"] = page
|
|
538
|
+
if page_size is not None:
|
|
539
|
+
params["pageSize"] = page_size
|
|
540
|
+
if limit > 0:
|
|
541
|
+
params["max"] = limit
|
|
542
|
+
if offset > 0:
|
|
543
|
+
params["start"] = offset
|
|
544
|
+
result = None
|
|
545
|
+
try:
|
|
546
|
+
result = api.session.rest_get(url, params=params)
|
|
547
|
+
except WebexError as e:
|
|
548
|
+
handle_rest_error(e)
|
|
549
|
+
result = result or []
|
|
550
|
+
items = result.get("data", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
551
|
+
if output == "json":
|
|
552
|
+
print_json(items)
|
|
553
|
+
else:
|
|
554
|
+
print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
|
|
555
|
+
|
|
556
|
+
|
|
557
|
+
|
|
558
|
+
@app.command("update-reskill")
|
|
559
|
+
def update_reskill(
|
|
560
|
+
id: str = typer.Argument(help="id"),
|
|
561
|
+
organization_id: str = typer.Option(None, "--organization-id", help="ID of the contact center organization. This field is require"),
|
|
562
|
+
id_param: str = typer.Option(None, "--id", help="ID of this contact center resource. It should not be specifi"),
|
|
563
|
+
version: str = typer.Option(None, "--version", help="The version of this resource. For a newly created resource,"),
|
|
564
|
+
skill_profile_id: str = typer.Option(None, "--skill-profile-id", help="The unique identifier of the skill profile to assign to the"),
|
|
565
|
+
created_time: str = typer.Option(None, "--created-time", help="This is the created time of the entity."),
|
|
566
|
+
last_updated_time: str = typer.Option(None, "--last-updated-time", help="This is the updated time of the entity."),
|
|
567
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
568
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
569
|
+
):
|
|
570
|
+
"""Reskill Agents\n\nExample --json-body:\n '{"organizationId":"...","id":"...","version":0,"skillProfileId":"...","dynamicSkills":{"add":["..."],"remove":["..."]},"createdTime":0,"lastUpdatedTime":0}'."""
|
|
571
|
+
api = get_api(debug=debug)
|
|
572
|
+
cc_base_url = get_cc_base_url()
|
|
573
|
+
orgid = get_cc_org_id(api.session)
|
|
574
|
+
url = f"{cc_base_url}/organization/{orgid}/user/{id}/reskill"
|
|
575
|
+
if json_body:
|
|
576
|
+
body = json.loads(json_body)
|
|
577
|
+
else:
|
|
578
|
+
body = {}
|
|
579
|
+
if organization_id is not None:
|
|
580
|
+
body["organizationId"] = organization_id
|
|
581
|
+
if id_param is not None:
|
|
582
|
+
body["id"] = id_param
|
|
583
|
+
if version is not None:
|
|
584
|
+
body["version"] = version
|
|
585
|
+
if skill_profile_id is not None:
|
|
586
|
+
body["skillProfileId"] = skill_profile_id
|
|
587
|
+
if created_time is not None:
|
|
588
|
+
body["createdTime"] = created_time
|
|
589
|
+
if last_updated_time is not None:
|
|
590
|
+
body["lastUpdatedTime"] = last_updated_time
|
|
591
|
+
try:
|
|
592
|
+
result = api.session.rest_patch(url, json=body)
|
|
593
|
+
except WebexError as e:
|
|
594
|
+
handle_rest_error(e)
|
|
595
|
+
typer.echo(f"Updated.")
|
|
596
|
+
|
|
597
|
+
|
|
598
|
+
|
|
599
|
+
@app.command("list-user")
|
|
600
|
+
def list_user(
|
|
601
|
+
filter_param: str = typer.Option(None, "--filter", help="Specify a filter based on which the results will be fetched."),
|
|
602
|
+
attributes: str = typer.Option(None, "--attributes", help="Specify the attributes to be returned. By default, all attri"),
|
|
603
|
+
search: str = typer.Option(None, "--search", help="Filter data based on the search keyword.Supported search col"),
|
|
604
|
+
page: str = typer.Option(None, "--page", help="Defines the number of displayed page. The page number starts"),
|
|
605
|
+
page_size: str = typer.Option(None, "--page-size", help="Defines the number of items to be displayed on a page. If th"),
|
|
606
|
+
supervisor_managed_agents_only: str = typer.Option(None, "--supervisor-managed-agents-only", help="If set to true, the API will return contact center enabled u"),
|
|
607
|
+
single_object_response: str = typer.Option(None, "--single-object-response", help="Specify whether to include array fields in the response. Thi"),
|
|
608
|
+
buddy_team_agents_only: str = typer.Option(None, "--buddy-team-agents-only", help="If set to true, returns only users who are part of buddy tea"),
|
|
609
|
+
user_in_queue: str = typer.Option(None, "--user-in-queue", help="Can be either assigned or unassigned. If passed, returns the"),
|
|
610
|
+
queue_id: str = typer.Option(None, "--queue-id", help="Contact Service Queue ID for which the list of assigned or u"),
|
|
611
|
+
include_ai_mapping_count: str = typer.Option(None, "--include-ai-mapping-count", help="If set to true, the API response will include the count of e"),
|
|
612
|
+
include_dynamic_skills_limit_reached: str = typer.Option(None, "--include-dynamic-skills-limit-reached", help="If true, includes whether each user has reached the dynamic"),
|
|
613
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
614
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
615
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
616
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
617
|
+
):
|
|
618
|
+
"""List Users."""
|
|
619
|
+
api = get_api(debug=debug)
|
|
620
|
+
cc_base_url = get_cc_base_url()
|
|
621
|
+
orgid = get_cc_org_id(api.session)
|
|
622
|
+
url = f"{cc_base_url}/organization/{orgid}/v2/user"
|
|
623
|
+
params = {}
|
|
624
|
+
if filter_param is not None:
|
|
625
|
+
params["filter"] = filter_param
|
|
626
|
+
if attributes is not None:
|
|
627
|
+
params["attributes"] = attributes
|
|
628
|
+
if search is not None:
|
|
629
|
+
params["search"] = search
|
|
630
|
+
if page is not None:
|
|
631
|
+
params["page"] = page
|
|
632
|
+
if page_size is not None:
|
|
633
|
+
params["pageSize"] = page_size
|
|
634
|
+
if supervisor_managed_agents_only is not None:
|
|
635
|
+
params["supervisorManagedAgentsOnly"] = supervisor_managed_agents_only
|
|
636
|
+
if single_object_response is not None:
|
|
637
|
+
params["singleObjectResponse"] = single_object_response
|
|
638
|
+
if buddy_team_agents_only is not None:
|
|
639
|
+
params["buddyTeamAgentsOnly"] = buddy_team_agents_only
|
|
640
|
+
if user_in_queue is not None:
|
|
641
|
+
params["userInQueue"] = user_in_queue
|
|
642
|
+
if queue_id is not None:
|
|
643
|
+
params["queueId"] = queue_id
|
|
644
|
+
if include_ai_mapping_count is not None:
|
|
645
|
+
params["includeAIMappingCount"] = include_ai_mapping_count
|
|
646
|
+
if include_dynamic_skills_limit_reached is not None:
|
|
647
|
+
params["includeDynamicSkillsLimitReached"] = include_dynamic_skills_limit_reached
|
|
648
|
+
if limit > 0:
|
|
649
|
+
params["max"] = limit
|
|
650
|
+
if offset > 0:
|
|
651
|
+
params["start"] = offset
|
|
652
|
+
result = None
|
|
653
|
+
try:
|
|
654
|
+
result = api.session.rest_get(url, params=params)
|
|
655
|
+
except WebexError as e:
|
|
656
|
+
handle_rest_error(e)
|
|
657
|
+
result = result or []
|
|
658
|
+
items = result.get("data", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
659
|
+
if output == "json":
|
|
660
|
+
print_json(items)
|
|
661
|
+
else:
|
|
662
|
+
print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
|
|
663
|
+
|
|
664
|
+
|
|
665
|
+
|
|
666
|
+
@app.command("show-by-ci-user-id-v2")
|
|
667
|
+
def show_by_ci_user_id_v2(
|
|
668
|
+
id: str = typer.Argument(help="id"),
|
|
669
|
+
include_user_profile: str = typer.Option(None, "--include-user-profile", help="Specifiy whether to include user profile data"),
|
|
670
|
+
include_names: str = typer.Option(None, "--include-names", help="Specifiy whether to include resource collection names"),
|
|
671
|
+
include_skill_details: str = typer.Option(None, "--include-skill-details", help="If set to true, the response includes skill information for"),
|
|
672
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
673
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
674
|
+
):
|
|
675
|
+
"""Get specific User by CI User ID."""
|
|
676
|
+
api = get_api(debug=debug)
|
|
677
|
+
cc_base_url = get_cc_base_url()
|
|
678
|
+
orgid = get_cc_org_id(api.session)
|
|
679
|
+
url = f"{cc_base_url}/organization/{orgid}/v2/user/by-ci-user-id/{id}"
|
|
680
|
+
params = {}
|
|
681
|
+
if include_user_profile is not None:
|
|
682
|
+
params["includeUserProfile"] = include_user_profile
|
|
683
|
+
if include_names is not None:
|
|
684
|
+
params["includeNames"] = include_names
|
|
685
|
+
if include_skill_details is not None:
|
|
686
|
+
params["includeSkillDetails"] = include_skill_details
|
|
687
|
+
try:
|
|
688
|
+
result = api.session.rest_get(url, params=params)
|
|
689
|
+
except WebexError as e:
|
|
690
|
+
handle_rest_error(e)
|
|
691
|
+
if output == "json":
|
|
692
|
+
print_json(result)
|
|
693
|
+
else:
|
|
694
|
+
if isinstance(result, dict):
|
|
695
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
696
|
+
elif isinstance(result, list):
|
|
697
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
698
|
+
else:
|
|
699
|
+
print_json(result)
|
|
700
|
+
|
|
701
|
+
|