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.
Files changed (413) hide show
  1. wxcli/__init__.py +4 -0
  2. wxcli/_playbook/.claude/agents/migration-advisor.md +239 -0
  3. wxcli/_playbook/.claude/agents/wxc-calling-builder.md +946 -0
  4. wxcli/_playbook/.claude/rules/cleanup.md +29 -0
  5. wxcli/_playbook/.claude/rules/cucm-migration.md +58 -0
  6. wxcli/_playbook/.claude/rules/org-health.md +14 -0
  7. wxcli/_playbook/.claude/settings.json +8 -0
  8. wxcli/_playbook/.claude/skills/audit-compliance/SKILL.md +515 -0
  9. wxcli/_playbook/.claude/skills/call-control/SKILL.md +747 -0
  10. wxcli/_playbook/.claude/skills/configure-features/SKILL.md +623 -0
  11. wxcli/_playbook/.claude/skills/configure-routing/SKILL.md +627 -0
  12. wxcli/_playbook/.claude/skills/contact-center/SKILL.md +1181 -0
  13. wxcli/_playbook/.claude/skills/cucm-migrate/SKILL.md +820 -0
  14. wxcli/_playbook/.claude/skills/customer-assist/SKILL.md +443 -0
  15. wxcli/_playbook/.claude/skills/device-platform/SKILL.md +407 -0
  16. wxcli/_playbook/.claude/skills/manage-call-settings/SKILL.md +757 -0
  17. wxcli/_playbook/.claude/skills/manage-devices/SKILL.md +790 -0
  18. wxcli/_playbook/.claude/skills/manage-identity/SKILL.md +638 -0
  19. wxcli/_playbook/.claude/skills/manage-licensing/SKILL.md +528 -0
  20. wxcli/_playbook/.claude/skills/manage-meetings/SKILL.md +708 -0
  21. wxcli/_playbook/.claude/skills/messaging-bots/SKILL.md +365 -0
  22. wxcli/_playbook/.claude/skills/messaging-spaces/SKILL.md +520 -0
  23. wxcli/_playbook/.claude/skills/org-health/SKILL.md +159 -0
  24. wxcli/_playbook/.claude/skills/provision-calling/SKILL.md +421 -0
  25. wxcli/_playbook/.claude/skills/query-live/SKILL.md +183 -0
  26. wxcli/_playbook/.claude/skills/query-live/domains/call-flow-trace.md +223 -0
  27. wxcli/_playbook/.claude/skills/query-live/domains/call-history.md +44 -0
  28. wxcli/_playbook/.claude/skills/query-live/domains/features.md +169 -0
  29. wxcli/_playbook/.claude/skills/query-live/domains/numbers.md +93 -0
  30. wxcli/_playbook/.claude/skills/query-live/domains/people-and-settings.md +146 -0
  31. wxcli/_playbook/.claude/skills/query-live/domains/routing.md +124 -0
  32. wxcli/_playbook/.claude/skills/reporting/SKILL.md +501 -0
  33. wxcli/_playbook/.claude/skills/reporting/references/cdr-recipes.md +1628 -0
  34. wxcli/_playbook/.claude/skills/reporting-cc/SKILL.md +251 -0
  35. wxcli/_playbook/.claude/skills/reporting-meetings/SKILL.md +290 -0
  36. wxcli/_playbook/.claude/skills/teardown/SKILL.md +214 -0
  37. wxcli/_playbook/.claude/skills/video-mesh/SKILL.md +379 -0
  38. wxcli/_playbook/.claude/skills/wxc-calling-debug/SKILL.md +475 -0
  39. wxcli/_playbook/CLAUDE.md +373 -0
  40. wxcli/_playbook/docs/reference/CLAUDE.md +25 -0
  41. wxcli/_playbook/docs/reference/admin-apps-data.md +643 -0
  42. wxcli/_playbook/docs/reference/admin-audit-security.md +322 -0
  43. wxcli/_playbook/docs/reference/admin-hybrid.md +383 -0
  44. wxcli/_playbook/docs/reference/admin-identity-scim.md +1007 -0
  45. wxcli/_playbook/docs/reference/admin-licensing.md +414 -0
  46. wxcli/_playbook/docs/reference/admin-org-management.md +586 -0
  47. wxcli/_playbook/docs/reference/admin-partner.md +357 -0
  48. wxcli/_playbook/docs/reference/archive/wxc-sdk-patterns.md +1229 -0
  49. wxcli/_playbook/docs/reference/archive/wxcadm-advanced.md +835 -0
  50. wxcli/_playbook/docs/reference/archive/wxcadm-core.md +743 -0
  51. wxcli/_playbook/docs/reference/archive/wxcadm-devices-workspaces.md +1305 -0
  52. wxcli/_playbook/docs/reference/archive/wxcadm-features.md +849 -0
  53. wxcli/_playbook/docs/reference/archive/wxcadm-locations.md +938 -0
  54. wxcli/_playbook/docs/reference/archive/wxcadm-person.md +1255 -0
  55. wxcli/_playbook/docs/reference/archive/wxcadm-routing.md +1262 -0
  56. wxcli/_playbook/docs/reference/authentication.md +965 -0
  57. wxcli/_playbook/docs/reference/call-control.md +1205 -0
  58. wxcli/_playbook/docs/reference/call-features-additional.md +2541 -0
  59. wxcli/_playbook/docs/reference/call-features-major.md +1320 -0
  60. wxcli/_playbook/docs/reference/call-routing.md +2304 -0
  61. wxcli/_playbook/docs/reference/contact-center-analytics.md +1049 -0
  62. wxcli/_playbook/docs/reference/contact-center-core.md +1614 -0
  63. wxcli/_playbook/docs/reference/contact-center-journey.md +457 -0
  64. wxcli/_playbook/docs/reference/contact-center-routing.md +1138 -0
  65. wxcli/_playbook/docs/reference/devices-core.md +1869 -0
  66. wxcli/_playbook/docs/reference/devices-dect.md +1150 -0
  67. wxcli/_playbook/docs/reference/devices-platform.md +467 -0
  68. wxcli/_playbook/docs/reference/devices-workspaces.md +1426 -0
  69. wxcli/_playbook/docs/reference/emergency-services.md +1122 -0
  70. wxcli/_playbook/docs/reference/location-calling-core.md +2037 -0
  71. wxcli/_playbook/docs/reference/location-calling-media.md +1334 -0
  72. wxcli/_playbook/docs/reference/location-recording-advanced.md +1482 -0
  73. wxcli/_playbook/docs/reference/meetings-content.md +473 -0
  74. wxcli/_playbook/docs/reference/meetings-core.md +903 -0
  75. wxcli/_playbook/docs/reference/meetings-infrastructure.md +899 -0
  76. wxcli/_playbook/docs/reference/meetings-settings.md +850 -0
  77. wxcli/_playbook/docs/reference/messaging-bots.md +1091 -0
  78. wxcli/_playbook/docs/reference/messaging-spaces.md +695 -0
  79. wxcli/_playbook/docs/reference/person-call-settings-behavior.md +1639 -0
  80. wxcli/_playbook/docs/reference/person-call-settings-handling.md +1394 -0
  81. wxcli/_playbook/docs/reference/person-call-settings-media.md +1898 -0
  82. wxcli/_playbook/docs/reference/person-call-settings-permissions.md +1329 -0
  83. wxcli/_playbook/docs/reference/provisioning.md +1366 -0
  84. wxcli/_playbook/docs/reference/reporting-analytics.md +1318 -0
  85. wxcli/_playbook/docs/reference/self-service-call-settings.md +1020 -0
  86. wxcli/_playbook/docs/reference/virtual-lines.md +1132 -0
  87. wxcli/_playbook/docs/reference/webhooks-events.md +1444 -0
  88. wxcli/_playbook/docs/reference/wxcadm-xsi-realtime.md +953 -0
  89. wxcli/_version.py +24 -0
  90. wxcli/auth.py +137 -0
  91. wxcli/commands/__init__.py +0 -0
  92. wxcli/commands/_registry.py +181 -0
  93. wxcli/commands/activation_email.py +103 -0
  94. wxcli/commands/admin_recordings.py +585 -0
  95. wxcli/commands/analytics.py +105 -0
  96. wxcli/commands/announcement_playlists.py +219 -0
  97. wxcli/commands/announcements.py +519 -0
  98. wxcli/commands/archive_users.py +36 -0
  99. wxcli/commands/attachment_actions.py +60 -0
  100. wxcli/commands/audit_events.py +83 -0
  101. wxcli/commands/authorizations.py +113 -0
  102. wxcli/commands/auto_attendant.py +642 -0
  103. wxcli/commands/broadworks_billing_reports.py +126 -0
  104. wxcli/commands/broadworks_enterprises.py +160 -0
  105. wxcli/commands/broadworks_subscribers.py +319 -0
  106. wxcli/commands/broadworks_workspaces.py +108 -0
  107. wxcli/commands/call_controls.py +1304 -0
  108. wxcli/commands/call_park.py +494 -0
  109. wxcli/commands/call_pickup.py +229 -0
  110. wxcli/commands/call_queue.py +1878 -0
  111. wxcli/commands/call_recording.py +707 -0
  112. wxcli/commands/call_routing.py +1610 -0
  113. wxcli/commands/call_settings_for_me_phase_5.py +212 -0
  114. wxcli/commands/caller_reputation.py +169 -0
  115. wxcli/commands/calling_service.py +305 -0
  116. wxcli/commands/cc_address_book.py +770 -0
  117. wxcli/commands/cc_agent_greetings.py +242 -0
  118. wxcli/commands/cc_agent_summaries.py +39 -0
  119. wxcli/commands/cc_agent_wellbeing.py +216 -0
  120. wxcli/commands/cc_agents.py +425 -0
  121. wxcli/commands/cc_ai_assistant.py +55 -0
  122. wxcli/commands/cc_ai_feature.py +294 -0
  123. wxcli/commands/cc_audio_files.py +149 -0
  124. wxcli/commands/cc_auto_csat.py +311 -0
  125. wxcli/commands/cc_aux_code.py +458 -0
  126. wxcli/commands/cc_business_hour.py +353 -0
  127. wxcli/commands/cc_call_monitoring.py +228 -0
  128. wxcli/commands/cc_callbacks.py +194 -0
  129. wxcli/commands/cc_campaign.py +212 -0
  130. wxcli/commands/cc_captures.py +39 -0
  131. wxcli/commands/cc_contact_list.py +169 -0
  132. wxcli/commands/cc_contact_number.py +295 -0
  133. wxcli/commands/cc_data_sources.py +235 -0
  134. wxcli/commands/cc_desktop_layout.py +380 -0
  135. wxcli/commands/cc_desktop_profile.py +322 -0
  136. wxcli/commands/cc_dial_number.py +511 -0
  137. wxcli/commands/cc_dial_plan.py +347 -0
  138. wxcli/commands/cc_dnc.py +101 -0
  139. wxcli/commands/cc_entry_point.py +545 -0
  140. wxcli/commands/cc_ewt.py +51 -0
  141. wxcli/commands/cc_flow.py +477 -0
  142. wxcli/commands/cc_global_vars.py +430 -0
  143. wxcli/commands/cc_holiday_list.py +335 -0
  144. wxcli/commands/cc_journey.py +1261 -0
  145. wxcli/commands/cc_legacy_flows.py +49 -0
  146. wxcli/commands/cc_multimedia_profile.py +436 -0
  147. wxcli/commands/cc_notification.py +51 -0
  148. wxcli/commands/cc_outdial_ani.py +604 -0
  149. wxcli/commands/cc_overrides.py +341 -0
  150. wxcli/commands/cc_queue.py +1083 -0
  151. wxcli/commands/cc_queue_stats.py +55 -0
  152. wxcli/commands/cc_realtime.py +51 -0
  153. wxcli/commands/cc_resource_collection.py +312 -0
  154. wxcli/commands/cc_search.py +46 -0
  155. wxcli/commands/cc_site.py +400 -0
  156. wxcli/commands/cc_skill.py +350 -0
  157. wxcli/commands/cc_skill_profile.py +289 -0
  158. wxcli/commands/cc_subscriptions.py +426 -0
  159. wxcli/commands/cc_summaries.py +130 -0
  160. wxcli/commands/cc_tasks.py +844 -0
  161. wxcli/commands/cc_team.py +325 -0
  162. wxcli/commands/cc_user_profiles.py +349 -0
  163. wxcli/commands/cc_users.py +701 -0
  164. wxcli/commands/cc_work_types.py +363 -0
  165. wxcli/commands/cdr.py +89 -0
  166. wxcli/commands/classifications.py +38 -0
  167. wxcli/commands/cleanup.py +1427 -0
  168. wxcli/commands/client_settings.py +72 -0
  169. wxcli/commands/conference.py +328 -0
  170. wxcli/commands/configure.py +72 -0
  171. wxcli/commands/converged_recordings.py +347 -0
  172. wxcli/commands/converged_recordings_export.py +310 -0
  173. wxcli/commands/cq_playlists.py +42 -0
  174. wxcli/commands/cucm.py +2794 -0
  175. wxcli/commands/cucm_config.py +129 -0
  176. wxcli/commands/customer_assist.py +373 -0
  177. wxcli/commands/data_sources.py +227 -0
  178. wxcli/commands/dect_devices.py +787 -0
  179. wxcli/commands/device_configurations.py +77 -0
  180. wxcli/commands/device_dynamic_settings.py +320 -0
  181. wxcli/commands/device_settings.py +1489 -0
  182. wxcli/commands/devices.py +280 -0
  183. wxcli/commands/domains.py +142 -0
  184. wxcli/commands/ecm.py +178 -0
  185. wxcli/commands/emergency_services.py +827 -0
  186. wxcli/commands/events.py +83 -0
  187. wxcli/commands/external_voicemail.py +52 -0
  188. wxcli/commands/groups.py +206 -0
  189. wxcli/commands/guest_management.py +76 -0
  190. wxcli/commands/hds.py +340 -0
  191. wxcli/commands/hot_desk.py +67 -0
  192. wxcli/commands/hot_desking_members.py +118 -0
  193. wxcli/commands/hot_desking_portal.py +124 -0
  194. wxcli/commands/hunt_group.py +577 -0
  195. wxcli/commands/hybrid_clusters.py +71 -0
  196. wxcli/commands/hybrid_connectors.py +67 -0
  197. wxcli/commands/identity_org.py +159 -0
  198. wxcli/commands/init_playbook.py +155 -0
  199. wxcli/commands/licenses.py +106 -0
  200. wxcli/commands/live_monitoring.py +40 -0
  201. wxcli/commands/location_call_handling.py +577 -0
  202. wxcli/commands/location_schedules.py +341 -0
  203. wxcli/commands/location_settings.py +1297 -0
  204. wxcli/commands/location_voicemail.py +494 -0
  205. wxcli/commands/locations.py +336 -0
  206. wxcli/commands/meeting_captions.py +110 -0
  207. wxcli/commands/meeting_chats.py +63 -0
  208. wxcli/commands/meeting_invitees.py +234 -0
  209. wxcli/commands/meeting_messages.py +28 -0
  210. wxcli/commands/meeting_participants.py +278 -0
  211. wxcli/commands/meeting_polls.py +111 -0
  212. wxcli/commands/meeting_preferences.py +515 -0
  213. wxcli/commands/meeting_qa.py +78 -0
  214. wxcli/commands/meeting_qualities.py +43 -0
  215. wxcli/commands/meeting_reports.py +101 -0
  216. wxcli/commands/meeting_session_types.py +105 -0
  217. wxcli/commands/meeting_site.py +57 -0
  218. wxcli/commands/meeting_slido.py +44 -0
  219. wxcli/commands/meeting_summaries.py +92 -0
  220. wxcli/commands/meeting_tracking_codes.py +233 -0
  221. wxcli/commands/meeting_transcripts.py +230 -0
  222. wxcli/commands/meetings.py +1997 -0
  223. wxcli/commands/memberships.py +164 -0
  224. wxcli/commands/messages.py +213 -0
  225. wxcli/commands/mode_management.py +244 -0
  226. wxcli/commands/my_call_settings.py +3577 -0
  227. wxcli/commands/numbers.py +405 -0
  228. wxcli/commands/operating_modes.py +410 -0
  229. wxcli/commands/org_contacts.py +284 -0
  230. wxcli/commands/org_health_cli.py +55 -0
  231. wxcli/commands/org_settings.py +71 -0
  232. wxcli/commands/organizations.py +83 -0
  233. wxcli/commands/paging_group.py +257 -0
  234. wxcli/commands/partner_admins.py +141 -0
  235. wxcli/commands/partner_reports.py +188 -0
  236. wxcli/commands/partner_tags.py +216 -0
  237. wxcli/commands/people.py +279 -0
  238. wxcli/commands/person_call_settings.py +71 -0
  239. wxcli/commands/pstn.py +280 -0
  240. wxcli/commands/recording_report.py +154 -0
  241. wxcli/commands/report_templates.py +38 -0
  242. wxcli/commands/reports.py +144 -0
  243. wxcli/commands/resource_group_memberships.py +160 -0
  244. wxcli/commands/resource_groups.py +67 -0
  245. wxcli/commands/roles.py +63 -0
  246. wxcli/commands/room_tabs.py +160 -0
  247. wxcli/commands/rooms.py +225 -0
  248. wxcli/commands/scim_bulk.py +46 -0
  249. wxcli/commands/scim_groups.py +246 -0
  250. wxcli/commands/scim_schemas.py +82 -0
  251. wxcli/commands/scim_users.py +283 -0
  252. wxcli/commands/security_audit.py +54 -0
  253. wxcli/commands/service_apps.py +51 -0
  254. wxcli/commands/single_number_reach.py +209 -0
  255. wxcli/commands/team_memberships.py +155 -0
  256. wxcli/commands/teams.py +153 -0
  257. wxcli/commands/ucm_profile.py +42 -0
  258. wxcli/commands/update.py +219 -0
  259. wxcli/commands/user_settings.py +5116 -0
  260. wxcli/commands/video_mesh.py +1090 -0
  261. wxcli/commands/virtual_extensions.py +502 -0
  262. wxcli/commands/virtual_line_settings.py +2072 -0
  263. wxcli/commands/webhooks.py +176 -0
  264. wxcli/commands/wholesale_billing_reports.py +147 -0
  265. wxcli/commands/wholesale_provisioning.py +523 -0
  266. wxcli/commands/workspace_locations.py +339 -0
  267. wxcli/commands/workspace_metrics.py +103 -0
  268. wxcli/commands/workspace_personalization.py +70 -0
  269. wxcli/commands/workspace_settings.py +3347 -0
  270. wxcli/commands/workspaces.py +279 -0
  271. wxcli/commands/xapi.py +114 -0
  272. wxcli/config.py +139 -0
  273. wxcli/errors.py +77 -0
  274. wxcli/main.py +210 -0
  275. wxcli/migration/CLAUDE.md +106 -0
  276. wxcli/migration/__init__.py +1 -0
  277. wxcli/migration/advisory/CLAUDE.md +196 -0
  278. wxcli/migration/advisory/__init__.py +46 -0
  279. wxcli/migration/advisory/advisor.py +107 -0
  280. wxcli/migration/advisory/advisory_patterns.py +2552 -0
  281. wxcli/migration/advisory/recommendation_rules.py +835 -0
  282. wxcli/migration/cucm/CLAUDE.md +74 -0
  283. wxcli/migration/cucm/__init__.py +5 -0
  284. wxcli/migration/cucm/connection.py +265 -0
  285. wxcli/migration/cucm/discovery.py +225 -0
  286. wxcli/migration/cucm/extractors/__init__.py +1 -0
  287. wxcli/migration/cucm/extractors/announcements.py +92 -0
  288. wxcli/migration/cucm/extractors/base.py +90 -0
  289. wxcli/migration/cucm/extractors/device_profiles.py +98 -0
  290. wxcli/migration/cucm/extractors/devices.py +193 -0
  291. wxcli/migration/cucm/extractors/e911.py +103 -0
  292. wxcli/migration/cucm/extractors/features.py +309 -0
  293. wxcli/migration/cucm/extractors/helpers.py +73 -0
  294. wxcli/migration/cucm/extractors/informational.py +295 -0
  295. wxcli/migration/cucm/extractors/locations.py +221 -0
  296. wxcli/migration/cucm/extractors/moh.py +100 -0
  297. wxcli/migration/cucm/extractors/remote_destinations.py +96 -0
  298. wxcli/migration/cucm/extractors/routing.py +493 -0
  299. wxcli/migration/cucm/extractors/shared_lines.py +146 -0
  300. wxcli/migration/cucm/extractors/templates.py +229 -0
  301. wxcli/migration/cucm/extractors/tier4.py +173 -0
  302. wxcli/migration/cucm/extractors/users.py +240 -0
  303. wxcli/migration/cucm/extractors/voicemail.py +243 -0
  304. wxcli/migration/cucm/extractors/workspaces.py +88 -0
  305. wxcli/migration/cucm/unity_connection.py +304 -0
  306. wxcli/migration/execute/CLAUDE.md +372 -0
  307. wxcli/migration/execute/__init__.py +303 -0
  308. wxcli/migration/execute/batch.py +277 -0
  309. wxcli/migration/execute/dependency.py +483 -0
  310. wxcli/migration/execute/engine.py +964 -0
  311. wxcli/migration/execute/handlers.py +2232 -0
  312. wxcli/migration/execute/planner.py +1939 -0
  313. wxcli/migration/execute/runtime.py +571 -0
  314. wxcli/migration/export/CLAUDE.md +49 -0
  315. wxcli/migration/export/__init__.py +8 -0
  316. wxcli/migration/export/csv_export.py +126 -0
  317. wxcli/migration/export/deployment_plan.py +479 -0
  318. wxcli/migration/export/json_export.py +60 -0
  319. wxcli/migration/models.py +941 -0
  320. wxcli/migration/phone_models.py +50 -0
  321. wxcli/migration/preflight/CLAUDE.md +52 -0
  322. wxcli/migration/preflight/__init__.py +89 -0
  323. wxcli/migration/preflight/checks.py +911 -0
  324. wxcli/migration/preflight/runner.py +293 -0
  325. wxcli/migration/rate_limiter.py +144 -0
  326. wxcli/migration/report/CLAUDE.md +245 -0
  327. wxcli/migration/report/__init__.py +7 -0
  328. wxcli/migration/report/appendix.py +2437 -0
  329. wxcli/migration/report/assembler.py +183 -0
  330. wxcli/migration/report/charts.py +263 -0
  331. wxcli/migration/report/executive.py +776 -0
  332. wxcli/migration/report/explainer.py +704 -0
  333. wxcli/migration/report/helpers.py +74 -0
  334. wxcli/migration/report/ingest.py +152 -0
  335. wxcli/migration/report/notice_templates.py +192 -0
  336. wxcli/migration/report/score.py +375 -0
  337. wxcli/migration/report/styles.py +1052 -0
  338. wxcli/migration/report/user_diff.py +1052 -0
  339. wxcli/migration/report/user_notice.py +425 -0
  340. wxcli/migration/state.py +139 -0
  341. wxcli/migration/store.py +860 -0
  342. wxcli/migration/transform/CLAUDE.md +107 -0
  343. wxcli/migration/transform/__init__.py +12 -0
  344. wxcli/migration/transform/analysis_pipeline.py +453 -0
  345. wxcli/migration/transform/analyzers/__init__.py +142 -0
  346. wxcli/migration/transform/analyzers/css_permission.py +189 -0
  347. wxcli/migration/transform/analyzers/css_routing.py +335 -0
  348. wxcli/migration/transform/analyzers/device_compatibility.py +122 -0
  349. wxcli/migration/transform/analyzers/dn_ambiguity.py +131 -0
  350. wxcli/migration/transform/analyzers/duplicate_user.py +221 -0
  351. wxcli/migration/transform/analyzers/extension_conflict.py +173 -0
  352. wxcli/migration/transform/analyzers/feature_approximation.py +227 -0
  353. wxcli/migration/transform/analyzers/layout_overflow.py +174 -0
  354. wxcli/migration/transform/analyzers/location_ambiguity.py +184 -0
  355. wxcli/migration/transform/analyzers/missing_data.py +300 -0
  356. wxcli/migration/transform/analyzers/selective_call_handling.py +394 -0
  357. wxcli/migration/transform/analyzers/shared_line.py +170 -0
  358. wxcli/migration/transform/analyzers/voicemail_compatibility.py +267 -0
  359. wxcli/migration/transform/analyzers/workspace_license.py +212 -0
  360. wxcli/migration/transform/cross_reference.py +1136 -0
  361. wxcli/migration/transform/cucm_pattern.py +246 -0
  362. wxcli/migration/transform/decisions.py +301 -0
  363. wxcli/migration/transform/e164.py +145 -0
  364. wxcli/migration/transform/engine.py +256 -0
  365. wxcli/migration/transform/mappers/CLAUDE.md +123 -0
  366. wxcli/migration/transform/mappers/__init__.py +76 -0
  367. wxcli/migration/transform/mappers/announcement_mapper.py +122 -0
  368. wxcli/migration/transform/mappers/base.py +190 -0
  369. wxcli/migration/transform/mappers/button_template_mapper.py +186 -0
  370. wxcli/migration/transform/mappers/call_forwarding_mapper.py +228 -0
  371. wxcli/migration/transform/mappers/call_settings_mapper.py +144 -0
  372. wxcli/migration/transform/mappers/css_mapper.py +868 -0
  373. wxcli/migration/transform/mappers/dect_mapper.py +367 -0
  374. wxcli/migration/transform/mappers/device_layout_mapper.py +289 -0
  375. wxcli/migration/transform/mappers/device_mapper.py +227 -0
  376. wxcli/migration/transform/mappers/device_profile_mapper.py +190 -0
  377. wxcli/migration/transform/mappers/device_settings_mapper.py +464 -0
  378. wxcli/migration/transform/mappers/e911_mapper.py +129 -0
  379. wxcli/migration/transform/mappers/ecbn_mapper.py +263 -0
  380. wxcli/migration/transform/mappers/executive_assistant_mapper.py +156 -0
  381. wxcli/migration/transform/mappers/feature_mapper.py +1179 -0
  382. wxcli/migration/transform/mappers/line_mapper.py +310 -0
  383. wxcli/migration/transform/mappers/location_mapper.py +235 -0
  384. wxcli/migration/transform/mappers/moh_mapper.py +114 -0
  385. wxcli/migration/transform/mappers/monitoring_mapper.py +221 -0
  386. wxcli/migration/transform/mappers/receptionist_mapper.py +245 -0
  387. wxcli/migration/transform/mappers/routing_mapper.py +821 -0
  388. wxcli/migration/transform/mappers/snr_mapper.py +201 -0
  389. wxcli/migration/transform/mappers/softkey_mapper.py +205 -0
  390. wxcli/migration/transform/mappers/user_mapper.py +264 -0
  391. wxcli/migration/transform/mappers/voicemail_group_mapper.py +286 -0
  392. wxcli/migration/transform/mappers/voicemail_mapper.py +514 -0
  393. wxcli/migration/transform/mappers/workspace_mapper.py +464 -0
  394. wxcli/migration/transform/normalizers.py +2008 -0
  395. wxcli/migration/transform/pattern_converter.py +106 -0
  396. wxcli/migration/transform/pipeline.py +271 -0
  397. wxcli/migration/transform/rules.py +255 -0
  398. wxcli/org_health/CLAUDE.md +63 -0
  399. wxcli/org_health/__init__.py +7 -0
  400. wxcli/org_health/analyze.py +93 -0
  401. wxcli/org_health/checks.py +458 -0
  402. wxcli/org_health/collector.py +62 -0
  403. wxcli/org_health/models.py +78 -0
  404. wxcli/org_health/report.py +300 -0
  405. wxcli/output.py +101 -0
  406. wxcli-1.2.0.dist-info/METADATA +505 -0
  407. wxcli-1.2.0.dist-info/RECORD +413 -0
  408. wxcli-1.2.0.dist-info/WHEEL +5 -0
  409. wxcli-1.2.0.dist-info/entry_points.txt +2 -0
  410. wxcli-1.2.0.dist-info/licenses/LICENSE +191 -0
  411. wxcli-1.2.0.dist-info/scm_file_list.json +751 -0
  412. wxcli-1.2.0.dist-info/scm_version.json +8 -0
  413. wxcli-1.2.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,425 @@
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-agents.")
10
+
11
+
12
+ @app.command("create")
13
+ def create(
14
+ dial_number: str = typer.Option(None, "--dial-number", help="(required) A dialNumber field contains the number to dial such as a rou"),
15
+ team_id: str = typer.Option(None, "--team-id", help="The unique ID representing a team of users. Leaving this fie"),
16
+ is_extension: bool = typer.Option(None, "--is-extension/--no-is-extension", help="It indicates if the dialNumber field is full number or exten"),
17
+ device_type: str = typer.Option(None, "--device-type", help="It represents the way to differentiate type of login request"),
18
+ device_id: str = typer.Option(None, "--device-id", help="It is equal to dialNumber for AGENT_DN & EXTENSION deviceTyp"),
19
+ json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
20
+ output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
21
+ debug: bool = typer.Option(False, "--debug"),
22
+ ):
23
+ """Login\n\nExample --json-body:\n '{"dialNumber":"...","roles":["..."],"teamId":"...","isExtension":true,"deviceType":"...","deviceId":"..."}'."""
24
+ api = get_api(debug=debug)
25
+ cc_base_url = get_cc_base_url()
26
+ url = f"{cc_base_url}/agents/login"
27
+ if json_body:
28
+ body = json.loads(json_body)
29
+ else:
30
+ body = {}
31
+ if dial_number is not None:
32
+ body["dialNumber"] = dial_number
33
+ if team_id is not None:
34
+ body["teamId"] = team_id
35
+ if is_extension is not None:
36
+ body["isExtension"] = is_extension
37
+ if device_type is not None:
38
+ body["deviceType"] = device_type
39
+ if device_id is not None:
40
+ body["deviceId"] = device_id
41
+ _missing = [f for f in ['dialNumber'] if f not in body or body[f] is None]
42
+ if _missing:
43
+ typer.echo("Error: Missing required fields: " + ", ".join(_missing), err=True)
44
+ raise typer.Exit(1)
45
+ try:
46
+ result = api.session.rest_post(url, json=body)
47
+ except WebexError as e:
48
+ handle_rest_error(e)
49
+ if output == "json":
50
+ print_json(result)
51
+ elif isinstance(result, dict) and "id" in result:
52
+ typer.echo(f"Created: {result['id']}")
53
+ elif not result or result == {}:
54
+ typer.echo("Created.")
55
+ else:
56
+ print_json(result)
57
+
58
+
59
+
60
+ @app.command("update")
61
+ def update(
62
+ logout_reason: str = typer.Option(None, "--logout-reason", help="The reason for performing logout operation, maximum length 1"),
63
+ agent_id: str = typer.Option(None, "--agent-id", help="Unique ID of the user who is being logged out, maximum lengt"),
64
+ json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
65
+ debug: bool = typer.Option(False, "--debug"),
66
+ ):
67
+ """Logout."""
68
+ api = get_api(debug=debug)
69
+ cc_base_url = get_cc_base_url()
70
+ url = f"{cc_base_url}/agents/logout"
71
+ if json_body:
72
+ body = json.loads(json_body)
73
+ else:
74
+ body = {}
75
+ if logout_reason is not None:
76
+ body["logoutReason"] = logout_reason
77
+ if agent_id is not None:
78
+ body["agentId"] = agent_id
79
+ try:
80
+ result = api.session.rest_put(url, json=body)
81
+ except WebexError as e:
82
+ handle_rest_error(e)
83
+ typer.echo(f"Updated.")
84
+
85
+
86
+
87
+ @app.command("update-state-session")
88
+ def update_state_session(
89
+ state: str = typer.Option(None, "--state", help="It represents the current state of the user. Can be set to `"),
90
+ aux_code_id: str = typer.Option(None, "--aux-code-id", help="Auxiliary Codes are status codes which an agent can select i"),
91
+ last_state_change_reason: str = typer.Option(None, "--last-state-change-reason", help="It represents the reason of the last state change request, m"),
92
+ agent_id: str = typer.Option(None, "--agent-id", help="User for which state change is initiated, maximum length 36"),
93
+ json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
94
+ debug: bool = typer.Option(False, "--debug"),
95
+ ):
96
+ """State Change."""
97
+ api = get_api(debug=debug)
98
+ cc_base_url = get_cc_base_url()
99
+ url = f"{cc_base_url}/agents/session/state"
100
+ if json_body:
101
+ body = json.loads(json_body)
102
+ else:
103
+ body = {}
104
+ if state is not None:
105
+ body["state"] = state
106
+ if aux_code_id is not None:
107
+ body["auxCodeId"] = aux_code_id
108
+ if last_state_change_reason is not None:
109
+ body["lastStateChangeReason"] = last_state_change_reason
110
+ if agent_id is not None:
111
+ body["agentId"] = agent_id
112
+ try:
113
+ result = api.session.rest_put(url, json=body)
114
+ except WebexError as e:
115
+ handle_rest_error(e)
116
+ typer.echo(f"Updated.")
117
+
118
+
119
+
120
+ @app.command("create-reload-agents")
121
+ def create_reload_agents(
122
+ json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
123
+ output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
124
+ debug: bool = typer.Option(False, "--debug"),
125
+ ):
126
+ """Reload."""
127
+ api = get_api(debug=debug)
128
+ cc_base_url = get_cc_base_url()
129
+ url = f"{cc_base_url}/agents/reload"
130
+ if json_body:
131
+ body = json.loads(json_body)
132
+ else:
133
+ body = {}
134
+ try:
135
+ result = api.session.rest_post(url, json=body)
136
+ except WebexError as e:
137
+ handle_rest_error(e)
138
+ if output == "json":
139
+ print_json(result)
140
+ elif isinstance(result, dict) and "id" in result:
141
+ typer.echo(f"Created: {result['id']}")
142
+ elif not result or result == {}:
143
+ typer.echo("Created.")
144
+ else:
145
+ print_json(result)
146
+
147
+
148
+
149
+ @app.command("create-buddy-list")
150
+ def create_buddy_list(
151
+ agent_profile_id: str = typer.Option(None, "--agent-profile-id", help="(required) The profile ID of a particular agent. Can be obtained from ["),
152
+ media_type: str = typer.Option(None, "--media-type", help="(required) The media type for the request. The supported values are ```"),
153
+ state: str = typer.Option(None, "--state", help="It represents the current state of the returned agents which"),
154
+ json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
155
+ output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
156
+ debug: bool = typer.Option(False, "--debug"),
157
+ ):
158
+ """Buddy Agents List."""
159
+ api = get_api(debug=debug)
160
+ cc_base_url = get_cc_base_url()
161
+ url = f"{cc_base_url}/agents/buddyList"
162
+ if json_body:
163
+ body = json.loads(json_body)
164
+ else:
165
+ body = {}
166
+ if agent_profile_id is not None:
167
+ body["agentProfileId"] = agent_profile_id
168
+ if media_type is not None:
169
+ body["mediaType"] = media_type
170
+ if state is not None:
171
+ body["state"] = state
172
+ _missing = [f for f in ['agentProfileId', 'mediaType'] if f not in body or body[f] is None]
173
+ if _missing:
174
+ typer.echo("Error: Missing required fields: " + ", ".join(_missing), err=True)
175
+ raise typer.Exit(1)
176
+ try:
177
+ result = api.session.rest_post(url, json=body)
178
+ except WebexError as e:
179
+ handle_rest_error(e)
180
+ if output == "json":
181
+ print_json(result)
182
+ elif isinstance(result, dict) and "id" in result:
183
+ typer.echo(f"Created: {result['id']}")
184
+ elif not result or result == {}:
185
+ typer.echo("Created.")
186
+ else:
187
+ print_json(result)
188
+
189
+
190
+
191
+ @app.command("list")
192
+ def cmd_list(
193
+ agent_ids: str = typer.Option(None, "--agent-ids", help="Filter agent activities by agent ids separated with commas i"),
194
+ team_ids: str = typer.Option(None, "--team-ids", help="Filter agent activities by team ids separated with commas if"),
195
+ channel_types: str = typer.Option(None, "--channel-types", help="Channel type(s) permitted in response. Separate values with"),
196
+ from_param: str = typer.Option(..., "--from", help="Filter agent activities created after given epoch timestamp"),
197
+ to: str = typer.Option(None, "--to", help="Filter agent activities created before given epoch timestamp"),
198
+ page_size: str = typer.Option(None, "--page-size", help="Maximum page size in response. Maximum allowed value is 1000"),
199
+ page: str = typer.Option(None, "--page", help="Page number to be passed. Maximum number of records that can"),
200
+ output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
201
+ limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
202
+ offset: int = typer.Option(0, "--offset", help="Start offset"),
203
+ debug: bool = typer.Option(False, "--debug"),
204
+ ):
205
+ """Get Agent Activities."""
206
+ api = get_api(debug=debug)
207
+ cc_base_url = get_cc_base_url()
208
+ url = f"{cc_base_url}/agents/activities"
209
+ params = {}
210
+ if agent_ids is not None:
211
+ params["agentIds"] = agent_ids
212
+ if team_ids is not None:
213
+ params["teamIds"] = team_ids
214
+ if channel_types is not None:
215
+ params["channelTypes"] = channel_types
216
+ if from_param is not None:
217
+ params["from"] = from_param
218
+ if to is not None:
219
+ params["to"] = to
220
+ if page_size is not None:
221
+ params["pageSize"] = page_size
222
+ if page is not None:
223
+ params["page"] = page
224
+ if limit > 0:
225
+ params["max"] = limit
226
+ if offset > 0:
227
+ params["start"] = offset
228
+ org_id = get_org_id()
229
+ if org_id is not None:
230
+ params["orgId"] = org_id
231
+ result = None
232
+ try:
233
+ result = api.session.rest_get(url, params=params)
234
+ except WebexError as e:
235
+ handle_rest_error(e)
236
+ result = result or []
237
+ items = result.get("data", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
238
+ if output == "json":
239
+ print_json(items)
240
+ else:
241
+ print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
242
+
243
+
244
+
245
+ @app.command("list-statistics")
246
+ def list_statistics(
247
+ from_param: str = typer.Option(..., "--from", help="Start time for the query (in epoch milliseconds). Any epoch"),
248
+ to: str = typer.Option(..., "--to", help="End time for the query (in epoch milliseconds). Any epoch ti"),
249
+ interval: str = typer.Option(None, "--interval", help="Time interval (in minutes) to chunk statistics by i.e. break"),
250
+ agent_ids: str = typer.Option(None, "--agent-ids", help="Comma-separated list of agent IDs. A maximum of 100 values i"),
251
+ output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
252
+ limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
253
+ offset: int = typer.Option(0, "--offset", help="Start offset"),
254
+ debug: bool = typer.Option(False, "--debug"),
255
+ ):
256
+ """Get Agent Statistics."""
257
+ api = get_api(debug=debug)
258
+ cc_base_url = get_cc_base_url()
259
+ url = f"{cc_base_url}/agents/statistics"
260
+ params = {}
261
+ if from_param is not None:
262
+ params["from"] = from_param
263
+ if to is not None:
264
+ params["to"] = to
265
+ if interval is not None:
266
+ params["interval"] = interval
267
+ if agent_ids is not None:
268
+ params["agentIds"] = agent_ids
269
+ if limit > 0:
270
+ params["max"] = limit
271
+ if offset > 0:
272
+ params["start"] = offset
273
+ org_id = get_org_id()
274
+ if org_id is not None:
275
+ params["orgId"] = org_id
276
+ result = None
277
+ try:
278
+ result = api.session.rest_get(url, params=params)
279
+ except WebexError as e:
280
+ handle_rest_error(e)
281
+ result = result or []
282
+ items = result.get("data", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
283
+ if output == "json":
284
+ print_json(items)
285
+ else:
286
+ print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
287
+
288
+
289
+
290
+ @app.command("create-login")
291
+ def create_login(
292
+ dial_number: str = typer.Option(None, "--dial-number", help="(required) A dialNumber field contains the number to dial such as a rou"),
293
+ team_id: str = typer.Option(None, "--team-id", help="The unique ID representing a team of users. Leaving this fie"),
294
+ is_extension: bool = typer.Option(None, "--is-extension/--no-is-extension", help="It indicates if the dialNumber field is full number or exten"),
295
+ device_type: str = typer.Option(None, "--device-type", help="It represents the way to differentiate type of login request"),
296
+ device_id: str = typer.Option(None, "--device-id", help="It is equal to dialNumber for AGENT_DN & EXTENSION deviceTyp"),
297
+ json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
298
+ output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
299
+ debug: bool = typer.Option(False, "--debug"),
300
+ ):
301
+ """Login\n\nExample --json-body:\n '{"dialNumber":"...","roles":["..."],"teamId":"...","isExtension":true,"deviceType":"...","deviceId":"..."}'."""
302
+ api = get_api(debug=debug)
303
+ cc_base_url = get_cc_base_url()
304
+ url = f"{cc_base_url}/v2/agents/login"
305
+ if json_body:
306
+ body = json.loads(json_body)
307
+ else:
308
+ body = {}
309
+ if dial_number is not None:
310
+ body["dialNumber"] = dial_number
311
+ if team_id is not None:
312
+ body["teamId"] = team_id
313
+ if is_extension is not None:
314
+ body["isExtension"] = is_extension
315
+ if device_type is not None:
316
+ body["deviceType"] = device_type
317
+ if device_id is not None:
318
+ body["deviceId"] = device_id
319
+ _missing = [f for f in ['dialNumber'] if f not in body or body[f] is None]
320
+ if _missing:
321
+ typer.echo("Error: Missing required fields: " + ", ".join(_missing), err=True)
322
+ raise typer.Exit(1)
323
+ try:
324
+ result = api.session.rest_post(url, json=body)
325
+ except WebexError as e:
326
+ handle_rest_error(e)
327
+ if output == "json":
328
+ print_json(result)
329
+ elif isinstance(result, dict) and "id" in result:
330
+ typer.echo(f"Created: {result['id']}")
331
+ elif not result or result == {}:
332
+ typer.echo("Created.")
333
+ else:
334
+ print_json(result)
335
+
336
+
337
+
338
+ @app.command("update-logout")
339
+ def update_logout(
340
+ logout_reason: str = typer.Option(None, "--logout-reason", help="The reason for performing logout operation, maximum length 1"),
341
+ agent_id: str = typer.Option(None, "--agent-id", help="Unique ID of the user who is being logged out, maximum lengt"),
342
+ json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
343
+ debug: bool = typer.Option(False, "--debug"),
344
+ ):
345
+ """Logout."""
346
+ api = get_api(debug=debug)
347
+ cc_base_url = get_cc_base_url()
348
+ url = f"{cc_base_url}/v2/agents/logout"
349
+ if json_body:
350
+ body = json.loads(json_body)
351
+ else:
352
+ body = {}
353
+ if logout_reason is not None:
354
+ body["logoutReason"] = logout_reason
355
+ if agent_id is not None:
356
+ body["agentId"] = agent_id
357
+ try:
358
+ result = api.session.rest_put(url, json=body)
359
+ except WebexError as e:
360
+ handle_rest_error(e)
361
+ typer.echo(f"Updated.")
362
+
363
+
364
+
365
+ @app.command("update-state-session-1")
366
+ def update_state_session_1(
367
+ state: str = typer.Option(None, "--state", help="It represents the current state of the user. Can be set to `"),
368
+ aux_code_id: str = typer.Option(None, "--aux-code-id", help="Auxiliary Codes are status codes which an agent can select i"),
369
+ reason: str = typer.Option(None, "--reason", help="It represents the reason of the last agent channel state cha"),
370
+ agent_id: str = typer.Option(None, "--agent-id", help="User for which agent channel state change is initiated, maxi"),
371
+ json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
372
+ debug: bool = typer.Option(False, "--debug"),
373
+ ):
374
+ """State Change\n\nExample --json-body:\n '{"channelType":["..."],"state":"...","auxCodeId":"...","reason":"...","agentId":"..."}'."""
375
+ api = get_api(debug=debug)
376
+ cc_base_url = get_cc_base_url()
377
+ url = f"{cc_base_url}/v2/agents/session/state"
378
+ if json_body:
379
+ body = json.loads(json_body)
380
+ else:
381
+ body = {}
382
+ if state is not None:
383
+ body["state"] = state
384
+ if aux_code_id is not None:
385
+ body["auxCodeId"] = aux_code_id
386
+ if reason is not None:
387
+ body["reason"] = reason
388
+ if agent_id is not None:
389
+ body["agentId"] = agent_id
390
+ try:
391
+ result = api.session.rest_put(url, json=body)
392
+ except WebexError as e:
393
+ handle_rest_error(e)
394
+ typer.echo(f"Updated.")
395
+
396
+
397
+
398
+ @app.command("create-reload-agents-1")
399
+ def create_reload_agents_1(
400
+ json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
401
+ output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
402
+ debug: bool = typer.Option(False, "--debug"),
403
+ ):
404
+ """Reload."""
405
+ api = get_api(debug=debug)
406
+ cc_base_url = get_cc_base_url()
407
+ url = f"{cc_base_url}/v2/agents/reload"
408
+ if json_body:
409
+ body = json.loads(json_body)
410
+ else:
411
+ body = {}
412
+ try:
413
+ result = api.session.rest_post(url, json=body)
414
+ except WebexError as e:
415
+ handle_rest_error(e)
416
+ if output == "json":
417
+ print_json(result)
418
+ elif isinstance(result, dict) and "id" in result:
419
+ typer.echo(f"Created: {result['id']}")
420
+ elif not result or result == {}:
421
+ typer.echo("Created.")
422
+ else:
423
+ print_json(result)
424
+
425
+
@@ -0,0 +1,55 @@
1
+ import json
2
+ import typer
3
+ from wxcli.errors import WebexError, handle_rest_error
4
+ from wxcli.auth import get_api
5
+ from wxcli.output import print_table, print_json
6
+ from wxcli.config import get_cc_base_url
7
+
8
+
9
+ app = typer.Typer(help="Manage Webex Contact Center cc-ai-assistant.")
10
+
11
+
12
+ @app.command("create")
13
+ def create(
14
+ agent_id: str = typer.Option(None, "--agent-id", help="(required) Agent identifier"),
15
+ org_id: str = typer.Option(None, "--org-id", help="(required) Organization identifier"),
16
+ event_type: str = typer.Option(None, "--event-type", help="(required) Choices: CUSTOM_EVENT"),
17
+ event_name: str = typer.Option(None, "--event-name", help="(required) Choices: GET_SUGGESTIONS"),
18
+ json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
19
+ output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
20
+ debug: bool = typer.Option(False, "--debug"),
21
+ ):
22
+ """Get suggestions\n\nExample --json-body:\n '{"agentId":"...","orgId":"...","eventType":"CUSTOM_EVENT","eventName":"GET_SUGGESTIONS","eventDetails":{"data":{"interactionId":"...","actionTimeStamp":"...","trackingId":"...","languageCode":"...","aiAssistantSkillId":"...","source":"..."}}}'."""
23
+ api = get_api(debug=debug)
24
+ cc_base_url = get_cc_base_url()
25
+ url = f"{cc_base_url}/event"
26
+ if json_body:
27
+ body = json.loads(json_body)
28
+ else:
29
+ body = {}
30
+ if agent_id is not None:
31
+ body["agentId"] = agent_id
32
+ if org_id is not None:
33
+ body["orgId"] = org_id
34
+ if event_type is not None:
35
+ body["eventType"] = event_type
36
+ if event_name is not None:
37
+ body["eventName"] = event_name
38
+ _missing = [f for f in ['agentId', 'orgId', 'eventType', 'eventName'] if f not in body or body[f] is None]
39
+ if _missing:
40
+ typer.echo("Error: Missing required fields: " + ", ".join(_missing), err=True)
41
+ raise typer.Exit(1)
42
+ try:
43
+ result = api.session.rest_post(url, json=body)
44
+ except WebexError as e:
45
+ handle_rest_error(e)
46
+ if output == "json":
47
+ print_json(result)
48
+ elif isinstance(result, dict) and "id" in result:
49
+ typer.echo(f"Created: {result['id']}")
50
+ elif not result or result == {}:
51
+ typer.echo("Created.")
52
+ else:
53
+ print_json(result)
54
+
55
+