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,747 @@
1
+ ---
2
+ name: call-control
3
+ description: |
4
+ Real-time Webex Calling call control, telephony webhook/event monitoring, conference controls,
5
+ and XSI real-time event streaming. Covers the Call Control API (user-level and Service App),
6
+ telephony webhook subscriptions and event parsing, conference controls, and wxcadm XSI for
7
+ real-time call monitoring and programmatic call control via BroadWorks.
8
+ NOT for: messaging webhooks/bot events (use messaging-bots skill), call settings/forwarding
9
+ configuration (use manage-call-settings skill), or CDR/call history queries (use reporting skill).
10
+ allowed-tools: Read, Grep, Glob, Bash
11
+ argument-hint: [call-control | webhooks | xsi-events | conference]
12
+ ---
13
+
14
+ <!-- Created 2026-03-19 -->
15
+
16
+ # Call Control & Real-time Events Workflow
17
+
18
+ > **CRITICAL WARNING: USER-LEVEL OAUTH TOKEN REQUIRED**
19
+ >
20
+ > The Call Control API (`/v1/telephony/calls/*`) requires a **user-level OAuth token** with `spark:calls_read` / `spark:calls_write` scopes. Admin tokens get **400 "Target user not authorized"**. This is the #1 gotcha.
21
+ >
22
+ > **Service Apps** (with `spark-admin:calls_read` / `spark-admin:calls_write`) must use the **Members API** (`/v1/telephony/calls/members/{memberId}/*`) instead of the user-level endpoints.
23
+ >
24
+ > `wxcli call-controls` commands use user-level endpoints by default. Do NOT use them with admin/service-app tokens.
25
+
26
+ ---
27
+
28
+ **Checkpoint — do NOT proceed until you can answer these:**
29
+ 1. What token type does the Call Control API require, and what error do admin tokens get? (Answer: User-level OAuth with `spark:calls_read`/`spark:calls_write`. Admin tokens get 400 "Target user not authorized".)
30
+ 2. What API path must Service Apps use instead of user-level endpoints? (Answer: Members API — `/v1/telephony/calls/members/{memberId}/*` with `spark-admin:calls_read`/`spark-admin:calls_write`.)
31
+
32
+ If you cannot answer both, you skipped reading this skill. Go back and read it.
33
+
34
+ ## Step 1: Load references
35
+
36
+ Load the reference docs needed for the requested operation. Load all three if the user hasn't specified which approach they need yet; otherwise load only the relevant one(s).
37
+
38
+ | Reference doc | When to load |
39
+ |---------------|-------------|
40
+ | `docs/reference/call-control.md` | Call Control API operations, conference controls |
41
+ | `docs/reference/webhooks-events.md` | Webhook setup, telephony event subscriptions |
42
+ | `docs/reference/wxcadm-xsi-realtime.md` | XSI real-time event streaming (wxcadm only) |
43
+
44
+ **Mandatory --help verification:** Before constructing any wxcli command, run `wxcli <group> --help` to verify the subcommand exists, then `wxcli <group> <subcommand> --help` to verify the exact flags. Do NOT rely on examples in this skill or reference docs — the CLI is auto-generated and flag names may differ from what documentation suggests.
45
+
46
+ ---
47
+
48
+ ## Step 2: Verify authentication
49
+
50
+ Before any call control or webhook operations, confirm the user has a working token:
51
+
52
+ ```bash
53
+ wxcli whoami
54
+ ```
55
+
56
+ If this fails, resolve authentication first (`wxcli configure`).
57
+
58
+ ### Scope verification
59
+
60
+ After confirming a valid token, verify the token has the scopes required for the user's intended approach:
61
+
62
+ | Approach | Required Scopes | Token Type |
63
+ |----------|----------------|------------|
64
+ | **Call Control (user)** | `spark:calls_read`, `spark:calls_write` | User-level OAuth (Integration flow) |
65
+ | **Call Control (Service App)** | `spark-admin:calls_read`, `spark-admin:calls_write` | Service App token |
66
+ | **Webhooks** | `spark:calls_read` (to create telephony_calls webhook) | User-level OAuth |
67
+ | **XSI Events (wxcadm)** | `spark:xsi` (user) or `spark-admin:xsi` (admin) | User or admin |
68
+ | **WebRTC Calling** | `spark:webrtc_calling` | User-level OAuth |
69
+ | **Firehose webhook** | `spark:all` | User-level OAuth |
70
+
71
+ **Scope-checking logic:**
72
+
73
+ 1. Run `wxcli whoami` — confirm the token is valid and note whether it is a user token, admin token, or Service App token.
74
+ 2. Match the token type against the table above:
75
+ - If **user-level token** → proceed with user-level Call Control, Webhooks, or XSI.
76
+ - If **Service App token** → MUST use Members API endpoints (`/calls/members/{memberId}/*`). Standard call-control commands will fail with 400.
77
+ - If **admin token only** → call control will fail. Advise the user to obtain a user-level token or use a Service App with the correct scopes.
78
+ 3. If scope is unclear, warn the user: *"Call Control requires a user-level token with `spark:calls_read` + `spark:calls_write`. Admin tokens get 400 'Target user not authorized'."*
79
+ 4. The 12-hour developer token from developer.webex.com works for testing if it was generated with the correct scopes.
80
+
81
+ ---
82
+
83
+ ## Step 3: Identify the operation
84
+
85
+ Present this decision matrix if the user is unsure which approach fits their need:
86
+
87
+ | Need | Approach | Tool |
88
+ |------|----------|------|
89
+ | Control calls from an external app (click-to-dial, hold, transfer) | **Call Control API** | `wxcli call-controls` or raw HTTP via `WebexSession` |
90
+ | Control calls on behalf of users (admin/service app) | **Members API** | `wxcli call-controls create-dial-members`, `create-answer-members`, etc. |
91
+ | Get notified when calls start/end/change state (push model) | **Webhooks** | `wxcli webhooks` or raw HTTP |
92
+ | Real-time event streaming for dashboards, CRM screen pops | **XSI Events** | wxcadm `XSIEvents` (ONLY option) |
93
+ | Programmatic call control via BroadWorks back-end | **XSI Actions** | wxcadm `XSI` / `Call` class |
94
+ | Multi-party conference management | **Conference Controls** | `wxcli conference` |
95
+ | Poll for active calls or call history | **Call Control API (GET)** | `wxcli call-controls list` / `list-history` |
96
+
97
+ **Key distinctions:**
98
+ - **Call Control API** = REST API on `api.webex.com`, requires user token, works for 3rd-party call control apps
99
+ - **Webhooks** = push notifications to your HTTPS endpoint when call events occur
100
+ - **XSI Events** = persistent streaming connection to BroadWorks XSP, org-wide or per-user, wxcadm only
101
+ - **Conference Controls** = separate API for multi-party conference management
102
+
103
+ ---
104
+
105
+ ## Step 4: Check prerequisites
106
+
107
+ Based on the approach identified in Step 3, verify the prerequisites below.
108
+
109
+ ### 4a. Call Control prerequisites
110
+
111
+ - Token is **user-level** with `spark:calls_read` + `spark:calls_write` (verified in Step 2).
112
+ - For Service App usage, token has `spark-admin:calls_read` + `spark-admin:calls_write` and you will use the Members API.
113
+ - The target user has a **Webex Calling license** assigned. Users without a calling license return 404 (error 4008).
114
+ - Confirm CLI access: `wxcli call-controls --help`
115
+
116
+ ### 4b. Webhook prerequisites
117
+
118
+ - Token has `spark:calls_read` scope.
119
+ - The webhook target URL is **publicly accessible over HTTPS**. For local development, use ngrok or a similar tunnel.
120
+ - No duplicate webhooks exist for the same resource/event combo (duplicates cause duplicate event delivery). Check with: `wxcli webhooks list -o json`
121
+
122
+ ### 4c. XSI prerequisites
123
+
124
+ - **XSI must be enabled on the Webex Org.** Contact Cisco TAC to request activation -- there is no self-service toggle.
125
+ - Token includes `spark:xsi` (user) or `spark-admin:xsi` (admin) scope.
126
+ - wxcadm is installed and available.
127
+ - Verify XSI is enabled:
128
+ ```python
129
+ webex = wxcadm.Webex(access_token, get_xsi=True)
130
+ print(webex.org.xsi) # Should show 4 XSI endpoint URLs (not None)
131
+ ```
132
+ If `webex.org.xsi` is `None`, XSI is not enabled on the org.
133
+
134
+ ---
135
+
136
+ ## Step 5: Build and present deployment plan [SHOW BEFORE EXECUTING]
137
+
138
+ Before executing any call control, webhook, or XSI operations, present the deployment plan to the user for approval. Include:
139
+
140
+ 1. **Approach selected** — which approach from Step 3 (Call Control, Webhooks, XSI, Conference)
141
+ 2. **Token type confirmed** — user-level, Service App, or admin (from Step 2)
142
+ 3. **Operations to perform** — list of specific commands/API calls that will be executed
143
+ 4. **Prerequisites verified** — confirm all Step 4 checks passed
144
+ 5. **Risks or warnings** — any relevant Critical Rules that apply (e.g., "webhook auto-deactivation if target URL is unreachable", "XSI recording pause has known bug")
145
+
146
+ Example plan format:
147
+
148
+ ```
149
+ ## Call Control Deployment Plan
150
+
151
+ **Approach:** Call Control API (user-level)
152
+ **Token:** User OAuth (verified via wxcli whoami)
153
+
154
+ ### Operations
155
+ 1. Initiate click-to-dial to +12223334444
156
+ 2. Monitor call state via list-active
157
+ 3. Transfer to +15551234567 when connected
158
+
159
+ ### Prerequisites
160
+ - [x] User-level token with spark:calls_read + spark:calls_write
161
+ - [x] Target user has Webex Calling license
162
+ - [x] wxcli call-controls accessible
163
+
164
+ ### Warnings
165
+ - Transfer requires the call to be answered first (unanswered = use divert instead)
166
+ ```
167
+
168
+ Wait for user approval before proceeding to Step 6.
169
+
170
+ ---
171
+
172
+ ## Step 6: Execute via wxcli
173
+
174
+ ### 6a. Call control operations
175
+
176
+ #### Call state machine
177
+
178
+ Understanding the call state machine is essential for correct call control:
179
+
180
+ ```
181
+ ┌──────────────┐
182
+ dial ──────>│ connecting │
183
+ └──────┬───────┘
184
+ │ remote rings
185
+ v
186
+ incoming ────>┌──────────────┐
187
+ │ alerting │──── reject ────> disconnected
188
+ └──────┬───────┘
189
+ │ answer
190
+ v
191
+ ┌──────────────┐
192
+ ┌────>│ connected │──── hangup ────> disconnected
193
+ │ └──┬────┬──────┘
194
+ │ │ │
195
+ resume │ hold │ │ remote hold
196
+ │ v v
197
+ │ ┌──────┐ ┌────────────┐
198
+ └──│ held │ │ remoteHeld │
199
+ └──────┘ └────────────┘
200
+ ```
201
+
202
+ **CallState values:** `connecting`, `alerting`, `connected`, `held`, `remoteHeld`, `disconnected`
203
+
204
+ **Personality values:** `originator` (outgoing), `terminator` (incoming), `clickToDial` (alerting for click-to-dial, becomes `originator` on answer)
205
+
206
+ #### Core call operations via wxcli
207
+
208
+ ##### Initiate a call (click-to-dial)
209
+
210
+ ```bash
211
+ wxcli call-controls create --destination "+12223334444"
212
+ ```
213
+
214
+ Optional: `--endpoint-id DEVICE_ID` to target a specific device.
215
+
216
+ ##### Answer an incoming call
217
+
218
+ ```bash
219
+ wxcli call-controls create-answer-calls --call-id CALL_ID
220
+ ```
221
+
222
+ ##### Hold and resume
223
+
224
+ ```bash
225
+ wxcli call-controls create-hold --call-id CALL_ID
226
+ wxcli call-controls create-resume --call-id CALL_ID
227
+ ```
228
+
229
+ ##### Transfer
230
+
231
+ Three transfer modes:
232
+
233
+ | Mode | CLI flags | Description |
234
+ |------|-----------|-------------|
235
+ | Auto (2 calls) | (no call IDs) | User has exactly 2 calls, auto-selected |
236
+ | Consultative | `--call-id1 X --call-id2 Y` | Transfer two specific calls together |
237
+ | Mute transfer | `--call-id1 X --destination NUM` | Transfer to new destination, waits for answer |
238
+
239
+ ```bash
240
+ # Consultative transfer
241
+ wxcli call-controls create-transfer --call-id1 CALL_ID_1 --call-id2 CALL_ID_2
242
+
243
+ # Mute transfer to a number
244
+ wxcli call-controls create-transfer --call-id1 CALL_ID --destination "+15551234567"
245
+ ```
246
+
247
+ **Important:** Unanswered incoming calls cannot be transferred. Use `create-divert` instead.
248
+
249
+ ##### Park and retrieve
250
+
251
+ ```bash
252
+ # Park a call (returns the park extension)
253
+ wxcli call-controls create-park --call-id CALL_ID
254
+
255
+ # Retrieve a parked call
256
+ wxcli call-controls create-retrieve --destination PARK_EXTENSION
257
+ ```
258
+
259
+ ##### Recording control
260
+
261
+ ```bash
262
+ wxcli call-controls create-start-recording --call-id CALL_ID
263
+ wxcli call-controls create-stop-recording --call-id CALL_ID
264
+ wxcli call-controls create-pause-recording --call-id CALL_ID
265
+ wxcli call-controls create-resume-recording --call-id CALL_ID
266
+ ```
267
+
268
+ Recording mode determines which actions are available:
269
+ - **On Demand**: start, stop, pause, resume
270
+ - **Always with Pause/Resume**: pause, resume only
271
+ - **Always**: no manual control
272
+
273
+ ##### Other actions
274
+
275
+ ```bash
276
+ # Reject incoming call
277
+ wxcli call-controls create-reject --call-id CALL_ID
278
+
279
+ # Hangup
280
+ wxcli call-controls create-hangup-calls --call-id CALL_ID
281
+
282
+ # Mute/unmute
283
+ wxcli call-controls create-mute --call-id CALL_ID
284
+ wxcli call-controls create-unmute --call-id CALL_ID
285
+
286
+ # Divert (blind transfer or send to voicemail)
287
+ wxcli call-controls create-divert --call-id CALL_ID --destination "+12223334444"
288
+ wxcli call-controls create-divert --call-id CALL_ID --to-voicemail
289
+
290
+ # Send DTMF tones
291
+ wxcli call-controls create-transmit-dtmf --call-id CALL_ID --dtmf "1,234"
292
+
293
+ # Pick up another user's ringing call
294
+ wxcli call-controls create-pickup --target "+12223334444"
295
+
296
+ # Pull call to another device
297
+ wxcli call-controls create-pull --endpoint-id DEVICE_ID
298
+
299
+ # Push call to executive (assistant only)
300
+ wxcli call-controls create-push --call-id CALL_ID
301
+
302
+ # Barge into another user's call
303
+ wxcli call-controls create-barge-in --target "+12223334444"
304
+ ```
305
+
306
+ #### Query active calls and history
307
+
308
+ ```bash
309
+ # List all active calls for the user
310
+ wxcli call-controls list -o json
311
+
312
+ # Get details of a specific call (--line-owner-id required for Service App tokens)
313
+ wxcli call-controls show CALL_ID -o json
314
+ wxcli call-controls show CALL_ID --line-owner-id USER_ID -o json
315
+
316
+ # List call history (max 20 per type, 60 total)
317
+ wxcli call-controls list-history -o json
318
+ ```
319
+
320
+ #### Service App / Members API commands
321
+
322
+ For Service Apps that control calls on behalf of users:
323
+
324
+ ```bash
325
+ # Dial on behalf of a member
326
+ wxcli call-controls create-dial-members MEMBER_ID --destination "+12223334444"
327
+
328
+ # Answer on behalf of a member
329
+ wxcli call-controls create-answer-members MEMBER_ID --call-id CALL_ID
330
+
331
+ # Hangup on behalf of a member
332
+ wxcli call-controls create-hangup-members MEMBER_ID --call-id CALL_ID
333
+
334
+ # List calls for a member
335
+ wxcli call-controls list-calls-members MEMBER_ID -o json
336
+
337
+ # Get call details for a member
338
+ wxcli call-controls show-calls-members MEMBER_ID CALL_ID -o json
339
+ ```
340
+
341
+ ### 6b. Webhook setup for telephony events
342
+
343
+ #### Creating a telephony call webhook
344
+
345
+ Webhooks deliver push notifications to your HTTPS endpoint when call events occur. The webhook target URL must be publicly accessible over HTTPS (use ngrok for local development).
346
+
347
+ ##### Via wxcli (preferred)
348
+
349
+ ```bash
350
+ # List existing webhooks to check for duplicates
351
+ wxcli webhooks list --output json
352
+
353
+ # Delete old webhook if it exists (avoid duplicate delivery)
354
+ wxcli webhooks delete WEBHOOK_ID
355
+
356
+ # Create webhook for all telephony call events
357
+ wxcli webhooks create \
358
+ --name "My Call Monitor" \
359
+ --target-url "https://your-server.com/webhooks/calls" \
360
+ --resource "telephony_calls" \
361
+ --event "all" \
362
+ --secret "your-hmac-secret"
363
+
364
+ # Verify it was created
365
+ wxcli webhooks list --output json
366
+ ```
367
+
368
+ ##### Via raw HTTP (for programmatic HMAC verification or complex webhook management)
369
+
370
+ ```python
371
+ from wxcli.auth import get_api
372
+
373
+ api = get_api()
374
+ BASE = "https://webexapis.com/v1/webhooks"
375
+
376
+ # Clean up old webhooks first (avoid duplicate delivery)
377
+ existing = list(api.session.follow_pagination(BASE))
378
+ for wh in existing:
379
+ if wh["name"] == "My Call Monitor":
380
+ api.session.rest_delete(f"{BASE}/{wh['id']}")
381
+
382
+ # Create webhook for all telephony call events
383
+ webhook = api.session.rest_post(BASE, json={
384
+ "name": "My Call Monitor",
385
+ "targetUrl": "https://your-server.com/webhooks/calls",
386
+ "resource": "telephony_calls",
387
+ "event": "all",
388
+ "secret": "your-hmac-secret"
389
+ })
390
+ ```
391
+
392
+ #### Webhook event types
393
+
394
+ The `event` field (top-level) maps to telephony-specific `data.eventType` values:
395
+
396
+ | Webhook `event` | `data.eventType` | When it fires |
397
+ |-----------------|-------------------|---------------|
398
+ | `created` | `alerting` | Call is ringing |
399
+ | `created` | `answered` | Call was answered |
400
+ | `updated` | `connected` | Call transitioned to connected |
401
+ | `updated` | `held` | User placed call on hold |
402
+ | `updated` | `remoteHeld` | Remote party placed call on hold |
403
+ | `updated` | `resumed` | Held call was resumed |
404
+ | `updated` | `recording` | Recording state changed |
405
+ | `deleted` | `disconnected` | Call ended |
406
+ | `deleted` | `forwarded` | Call was forwarded away |
407
+
408
+ #### Filtering webhooks
409
+
410
+ Narrow which events are delivered using the `filter` parameter:
411
+
412
+ ```bash
413
+ # Incoming calls only (filter on personality=terminator)
414
+ wxcli webhooks create \
415
+ --name "Incoming Calls" \
416
+ --target-url "https://example.com/incoming" \
417
+ --resource "telephony_calls" \
418
+ --event "all" \
419
+ --filter "personality=terminator"
420
+ ```
421
+
422
+ Available filters: `personality`, `state`, `callType`, `personId`.
423
+
424
+ #### Parsing webhook event payloads
425
+
426
+ ```python
427
+ def handle_webhook(request_json: dict):
428
+ data = request_json["data"]
429
+
430
+ print(f"Event: {data['eventType']}")
431
+ print(f"Call ID: {data['callId']}")
432
+ print(f"State: {data['state']}")
433
+ print(f"Remote: {data.remote_party.name} ({data.remote_party.number})")
434
+ ```
435
+
436
+ The `TelephonyEventData` class inherits from both `WebhookEventData` and `TelephonyCall`, so all call fields are directly accessible.
437
+
438
+ #### HMAC signature verification
439
+
440
+ When a `secret` is provided, verify the `X-Spark-Signature` header:
441
+
442
+ ```python
443
+ import hmac, hashlib
444
+
445
+ def verify_signature(body: bytes, signature: str, secret: str) -> bool:
446
+ expected = hmac.new(secret.encode('utf-8'), body, hashlib.sha1).hexdigest()
447
+ return hmac.compare_digest(expected, signature)
448
+ ```
449
+
450
+ #### Webhook management
451
+
452
+ ```bash
453
+ # List all webhooks
454
+ wxcli webhooks list --output json
455
+
456
+ # Reactivate an auto-deactivated webhook
457
+ wxcli webhooks update WEBHOOK_ID --json-body '{"name": "Reactivated", "targetUrl": "https://...", "status": "active"}'
458
+
459
+ # Delete a webhook
460
+ wxcli webhooks delete WEBHOOK_ID
461
+ ```
462
+
463
+ #### Other telephony webhook resources
464
+
465
+ | Resource | Description |
466
+ |----------|-------------|
467
+ | `telephony_calls` | Call events (alerting, connected, held, disconnected, etc.) |
468
+ | `telephony_conference` | Conference control events |
469
+ | `telephony_mwi` | Voicemail message waiting indicator |
470
+ | `convergedRecordings` | Call recording events |
471
+
472
+ ### 6c. XSI real-time events (wxcadm only)
473
+
474
+ > **XSI is wxcadm's unique capability.** It is NOT available via wxcli or the standard Webex REST APIs. XSI connects directly to the BroadWorks call control back-end that powers Webex Calling.
475
+
476
+ #### When to use XSI vs webhooks
477
+
478
+ | Requirement | Use XSI Events | Use Webhooks |
479
+ |-------------|:-:|:-:|
480
+ | Real-time streaming (sub-second latency) | Yes | No (HTTP delivery delay) |
481
+ | Org-wide call monitoring | Yes | Yes (with org-level webhook) |
482
+ | CRM screen pops | Yes | Possible but higher latency |
483
+ | Real-time agent dashboards | Yes | Possible but less reliable |
484
+ | Simple event notifications (email, Slack) | Overkill | Yes |
485
+ | No server infrastructure needed | No (needs long-running process) | Yes (just an HTTPS endpoint) |
486
+ | Call control from events | Yes (XSI Actions) | Requires separate Call Control API call |
487
+ | Works without Cisco TAC enablement | No | Yes |
488
+
489
+ #### Setting up XSI event monitoring
490
+
491
+ ```python
492
+ import queue
493
+ import wxcadm
494
+
495
+ # Initialize with XSI endpoints
496
+ webex = wxcadm.Webex(access_token, get_xsi=True)
497
+
498
+ # Create XSIEvents instance (org-level)
499
+ events = wxcadm.XSIEvents(webex.org)
500
+
501
+ # Create a queue for events (size to handle bursts)
502
+ events_queue = queue.Queue(maxsize=1000)
503
+
504
+ # Open channel set (auto-discovers XSPs via DNS SRV, opens streaming connections)
505
+ channel = events.open_channel(events_queue)
506
+
507
+ # Subscribe to call events
508
+ subscription = channel.subscribe(["Advanced Call"])
509
+
510
+ # Process events
511
+ while True:
512
+ event = events_queue.get()
513
+ event_data = event['xsi:Event']
514
+ event_type = event_data['xsi:eventData']['@xsi1:type']
515
+ user_id = event_data.get('xsi:userId', '')
516
+ print(f"[{user_id}] {event_type}")
517
+ ```
518
+
519
+ #### Per-user subscription
520
+
521
+ ```python
522
+ person = webex.org.get_person_by_email("user@domain.com")
523
+ subscription = channel.subscribe(["Advanced Call"], person=person)
524
+ ```
525
+
526
+ #### XSI event types
527
+
528
+ A single outbound call generates 6 events:
529
+
530
+ | Event Type | When |
531
+ |------------|------|
532
+ | `xsi:HookStatusEvent` | Phone goes off-hook |
533
+ | `xsi:CallOriginatedEvent` | Call initiated (dialing) |
534
+ | `xsi:CallUpdatedEvent` | Call state changes |
535
+ | `xsi:CallAnsweredEvent` | Remote party answers |
536
+ | `xsi:CallReleasedEvent` | Call ends |
537
+ | `xsi:HookStatusEvent` | Phone goes on-hook |
538
+
539
+ Additional event types: `xsi:CallReceivedEvent` (incoming), `xsi:CallHeldEvent`, `xsi:CallRetrievedEvent`, `xsi:CallTransferredEvent`, `xsi:CallSubscriptionEvent`.
540
+
541
+ #### XSI call control (XSI-Actions)
542
+
543
+ wxcadm also provides direct call control via XSI-Actions (separate from the Webex REST API):
544
+
545
+ ```python
546
+ person = webex.org.get_person_by_email("user@domain.com")
547
+ person.start_xsi()
548
+
549
+ # Originate a call
550
+ call = person.xsi.new_call(address="17192662837")
551
+
552
+ # Mid-call actions
553
+ call.hold()
554
+ call.resume()
555
+ call.transfer("2345")
556
+ call.transfer("2345", type="attended") # Attended transfer
557
+ call.finish_transfer() # Complete attended transfer
558
+ call.conference(address="5678") # Conference with new party
559
+ call.park() # Group call park
560
+ call.park(extension="8001") # Park at specific extension
561
+ call.recording("start") # Start recording
562
+ call.send_dtmf("12345#") # Send DTMF
563
+ call.hangup()
564
+ ```
565
+
566
+ #### XSI channel management
567
+
568
+ ```python
569
+ # Check active channels
570
+ active = channel.active_channels
571
+
572
+ # Close everything (channels + subscriptions)
573
+ channel.close()
574
+ ```
575
+
576
+ Channels auto-refresh hourly (7200-second expiry). Failed channels auto-recover after 60 seconds.
577
+
578
+ ### 6d. Conference control operations
579
+
580
+ #### CLI commands
581
+
582
+ ```bash
583
+ wxcli conference --help
584
+ ```
585
+
586
+ #### Available conference commands
587
+
588
+ | Command | Key Options | Description |
589
+ |---------|-------------|-------------|
590
+ | `wxcli conference list` | `--line-owner-id` | Get conference details |
591
+ | `wxcli conference create` | `--json-body` | Start a conference |
592
+ | `wxcli conference delete` | `--line-owner-id` | Release (end) a conference |
593
+ | `wxcli conference create-add-participant` | `--call-id` (required), `--line-owner-id` | Add a participant |
594
+ | `wxcli conference create-mute` | `--call-id` | Mute a participant |
595
+ | `wxcli conference create-unmute` | `--call-id` | Unmute a participant |
596
+ | `wxcli conference create-deafen` | `--call-id` (required) | Deafen a participant (can't hear) |
597
+ | `wxcli conference create-undeafen` | `--call-id` (required) | Undeafen a participant |
598
+ | `wxcli conference create-hold` | `--line-owner-id` | Hold the conference |
599
+ | `wxcli conference create-resume` | `--line-owner-id` | Resume the conference |
600
+
601
+ **Note:** Conference commands do NOT take a positional conference ID. Use `--line-owner-id` to specify whose conference to operate on (required for Service App tokens).
602
+
603
+ #### 3-way merge via Call Control API
604
+
605
+ The Call Control API also supports merging two active calls into a conference:
606
+
607
+ ```bash
608
+ # Merge two calls (user must have one active, one held)
609
+ wxcli call-controls create-transfer --call-id1 CALL_ID_1 --call-id2 CALL_ID_2
610
+ ```
611
+
612
+ Or via raw HTTP:
613
+
614
+ ```python
615
+ from wxcli.auth import get_api
616
+ api = get_api()
617
+ api.session.rest_post("https://webexapis.com/v1/telephony/calls/conference",
618
+ json={"callId1": call_id_1, "callId2": call_id_2})
619
+ ```
620
+
621
+ #### Conference via XSI (wxcadm)
622
+
623
+ ```python
624
+ # From an attended transfer, bridge all parties
625
+ call.transfer("2345", type="attended")
626
+ call.conference() # Bridges all parties
627
+ call.finish_transfer() # Drop initiator, leave others
628
+
629
+ # Conference with a new party
630
+ conference = call.conference(address="5678")
631
+ conference.mute(call_id) # Mute a participant
632
+ conference.deaf(call_id) # Deafen a participant
633
+ ```
634
+
635
+ ---
636
+
637
+ ## Step 7: Verification
638
+
639
+ ### Verify call control is working
640
+
641
+ ```bash
642
+ # List active calls (should return empty list if no calls)
643
+ wxcli call-controls list -o json
644
+
645
+ # Check call history (confirms API access)
646
+ wxcli call-controls list-history -o json
647
+ ```
648
+
649
+ ### Verify webhook is receiving events
650
+
651
+ ```bash
652
+ # List webhooks and check status — look for status: "active"
653
+ wxcli webhooks list --output json
654
+ ```
655
+
656
+ If a webhook shows `inactive`, it was auto-deactivated due to delivery failures. Fix the target URL and reactivate:
657
+
658
+ ```bash
659
+ wxcli webhooks update WEBHOOK_ID --json-body '{"name": "My Call Monitor", "targetUrl": "https://fixed-url.com/webhooks", "status": "active"}'
660
+ ```
661
+
662
+ ### Verify XSI connectivity
663
+
664
+ ```python
665
+ webex = wxcadm.Webex(access_token, get_xsi=True)
666
+ print(webex.org.xsi) # Should show 4 XSI endpoint URLs (not None)
667
+
668
+ person = webex.org.get_person_by_email("user@domain.com")
669
+ person.start_xsi(get_profile=True)
670
+ print(person.xsi.profile) # Should show user profile from BroadWorks
671
+ ```
672
+
673
+ If `webex.org.xsi` is `None`, XSI is not enabled on the org -- contact Cisco TAC.
674
+
675
+ ---
676
+
677
+ ## Step 8: Report results
678
+
679
+ Summarize the completed operations and their outcomes:
680
+
681
+ 1. **What was configured** — which approach (Call Control, Webhooks, XSI, Conference) and what specific operations were performed
682
+ 2. **Verification results** — confirmation that the configuration is working (API responses, webhook status, XSI connectivity)
683
+ 3. **Active resources** — list any persistent resources created (webhooks, XSI subscriptions, etc.) that the user should be aware of
684
+ 4. **Next steps** — any follow-up actions the user may want to take (e.g., "webhook is active — test by placing a call", "XSI channel is open — events will stream until the process is stopped")
685
+ 5. **Cleanup reminders** — resources that should be cleaned up when no longer needed (e.g., "delete the webhook when done testing", "call `channel.close()` to tear down XSI subscriptions")
686
+
687
+ ---
688
+
689
+ ## Critical Rules
690
+
691
+ 1. **User-level token required for call control.** Admin tokens get 400 "Target user not authorized". Service Apps must use the Members API (`/calls/members/{memberId}/*`). This is the most common failure.
692
+
693
+ 2. **Webhook auto-deactivation.** Webhooks that fail to deliver events (target URL returns errors repeatedly) are automatically set to `inactive`. You must explicitly reactivate them via the update API. You cannot deactivate a webhook via API -- only delete it.
694
+
695
+ 3. **Webhook resource/event/filter are immutable.** You cannot change these after creation. Delete and recreate instead. Only `name`, `targetUrl`, `secret`, and `status` can be updated.
696
+
697
+ 4. **Webhook URL must be HTTPS.** For local development, use ngrok or a similar tunnel.
698
+
699
+ 5. **`callId` vs `id` aliasing.** API responses use `id`, webhook events use `callId`. The SDK handles both transparently via the `call_id` property.
700
+
701
+ 6. **Transfer restrictions.** Unanswered incoming calls cannot be transferred. Use `divert` (blind transfer / send to voicemail) for unanswered calls.
702
+
703
+ 7. **Recording mode dependency.** `start/stop` only work with "On Demand" mode. `pause/resume` work with both "On Demand" and "Always with Pause/Resume". Check the user's recording configuration first.
704
+
705
+ 8. **Call history limit.** `list-history` returns max 20 records per type (placed/missed/received), max 60 total.
706
+
707
+ 9. **XSI requires Cisco TAC enablement.** There is no self-service toggle. If `webex.org.xsi` returns `None`, XSI is not enabled.
708
+
709
+ 10. **XSI events are XML, not JSON.** wxcadm parses them with `xmltodict` into OrderedDicts. The `$` key holds text content, `@` prefix denotes attributes.
710
+
711
+ 11. **XSI event volume is high.** A single call generates 6 events. A busy org can produce hundreds of events per second. Size your queue appropriately (start with 500-1000).
712
+
713
+ 12. **XSI channel auto-recovery has a 60-second gap.** Failed channels wait 60 seconds before restarting. Events for that XSP are lost during the gap.
714
+
715
+ 13. **XSI `recording("pause")` has a known bug (verified 2026-03-18).** Duplicate `elif` in wxcadm source causes `ValueError`. Workaround: call the XSI `PauseRecording` endpoint directly via `requests.put()`.
716
+
717
+ 14. **Conference via Call Control API requires two calls.** The user must have one active and one held call to merge. Use `hold` first, then `dial` the second party, then `conference`.
718
+
719
+ 15. **Webhook event delivery is not guaranteed to be ordered.** Use `data.eventTimestamp` and `data.callSessionId` to correlate and order events.
720
+
721
+ 16. **One webhook per resource/event combo.** Creating duplicates results in duplicate event delivery. Always clean up old webhooks before creating new ones.
722
+
723
+ ---
724
+
725
+ ## Scope Quick Reference
726
+
727
+ | Scope | Purpose |
728
+ |-------|---------|
729
+ | `spark:calls_read` | List calls, call details, call history, create telephony webhooks (user) |
730
+ | `spark:calls_write` | All call control actions: dial, answer, hold, transfer, park, record (user) |
731
+ | `spark-admin:calls_read` | List/get calls for any member (Service App) |
732
+ | `spark-admin:calls_write` | Call control actions for any member (Service App) |
733
+ | `spark:xsi` | XSI access (user-level) |
734
+ | `spark-admin:xsi` | XSI access (admin-level) |
735
+ | `spark:webrtc_calling` | WebRTC calling |
736
+ | `spark:all` | Firehose webhook (all resources, all events) |
737
+
738
+ ---
739
+
740
+ ## Context Compaction Recovery
741
+
742
+ If context compacts mid-execution, recover by:
743
+ 1. Re-read `docs/reference/call-control.md` for call control API details
744
+ 2. Re-read `docs/reference/webhooks-events.md` for webhook setup
745
+ 3. Re-read `docs/reference/wxcadm-xsi-realtime.md` for XSI events
746
+ 4. Run `wxcli call-controls --help` and `wxcli conference --help` to rediscover CLI commands
747
+ 5. Resume from the last completed step