wxcli 1.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wxcli/__init__.py +4 -0
- wxcli/_playbook/.claude/agents/migration-advisor.md +239 -0
- wxcli/_playbook/.claude/agents/wxc-calling-builder.md +946 -0
- wxcli/_playbook/.claude/rules/cleanup.md +29 -0
- wxcli/_playbook/.claude/rules/cucm-migration.md +58 -0
- wxcli/_playbook/.claude/rules/org-health.md +14 -0
- wxcli/_playbook/.claude/settings.json +8 -0
- wxcli/_playbook/.claude/skills/audit-compliance/SKILL.md +515 -0
- wxcli/_playbook/.claude/skills/call-control/SKILL.md +747 -0
- wxcli/_playbook/.claude/skills/configure-features/SKILL.md +623 -0
- wxcli/_playbook/.claude/skills/configure-routing/SKILL.md +627 -0
- wxcli/_playbook/.claude/skills/contact-center/SKILL.md +1181 -0
- wxcli/_playbook/.claude/skills/cucm-migrate/SKILL.md +820 -0
- wxcli/_playbook/.claude/skills/customer-assist/SKILL.md +443 -0
- wxcli/_playbook/.claude/skills/device-platform/SKILL.md +407 -0
- wxcli/_playbook/.claude/skills/manage-call-settings/SKILL.md +757 -0
- wxcli/_playbook/.claude/skills/manage-devices/SKILL.md +790 -0
- wxcli/_playbook/.claude/skills/manage-identity/SKILL.md +638 -0
- wxcli/_playbook/.claude/skills/manage-licensing/SKILL.md +528 -0
- wxcli/_playbook/.claude/skills/manage-meetings/SKILL.md +708 -0
- wxcli/_playbook/.claude/skills/messaging-bots/SKILL.md +365 -0
- wxcli/_playbook/.claude/skills/messaging-spaces/SKILL.md +520 -0
- wxcli/_playbook/.claude/skills/org-health/SKILL.md +159 -0
- wxcli/_playbook/.claude/skills/provision-calling/SKILL.md +421 -0
- wxcli/_playbook/.claude/skills/query-live/SKILL.md +183 -0
- wxcli/_playbook/.claude/skills/query-live/domains/call-flow-trace.md +223 -0
- wxcli/_playbook/.claude/skills/query-live/domains/call-history.md +44 -0
- wxcli/_playbook/.claude/skills/query-live/domains/features.md +169 -0
- wxcli/_playbook/.claude/skills/query-live/domains/numbers.md +93 -0
- wxcli/_playbook/.claude/skills/query-live/domains/people-and-settings.md +146 -0
- wxcli/_playbook/.claude/skills/query-live/domains/routing.md +124 -0
- wxcli/_playbook/.claude/skills/reporting/SKILL.md +501 -0
- wxcli/_playbook/.claude/skills/reporting/references/cdr-recipes.md +1628 -0
- wxcli/_playbook/.claude/skills/reporting-cc/SKILL.md +251 -0
- wxcli/_playbook/.claude/skills/reporting-meetings/SKILL.md +290 -0
- wxcli/_playbook/.claude/skills/teardown/SKILL.md +214 -0
- wxcli/_playbook/.claude/skills/video-mesh/SKILL.md +379 -0
- wxcli/_playbook/.claude/skills/wxc-calling-debug/SKILL.md +475 -0
- wxcli/_playbook/CLAUDE.md +373 -0
- wxcli/_playbook/docs/reference/CLAUDE.md +25 -0
- wxcli/_playbook/docs/reference/admin-apps-data.md +643 -0
- wxcli/_playbook/docs/reference/admin-audit-security.md +322 -0
- wxcli/_playbook/docs/reference/admin-hybrid.md +383 -0
- wxcli/_playbook/docs/reference/admin-identity-scim.md +1007 -0
- wxcli/_playbook/docs/reference/admin-licensing.md +414 -0
- wxcli/_playbook/docs/reference/admin-org-management.md +586 -0
- wxcli/_playbook/docs/reference/admin-partner.md +357 -0
- wxcli/_playbook/docs/reference/archive/wxc-sdk-patterns.md +1229 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-advanced.md +835 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-core.md +743 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-devices-workspaces.md +1305 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-features.md +849 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-locations.md +938 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-person.md +1255 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-routing.md +1262 -0
- wxcli/_playbook/docs/reference/authentication.md +965 -0
- wxcli/_playbook/docs/reference/call-control.md +1205 -0
- wxcli/_playbook/docs/reference/call-features-additional.md +2541 -0
- wxcli/_playbook/docs/reference/call-features-major.md +1320 -0
- wxcli/_playbook/docs/reference/call-routing.md +2304 -0
- wxcli/_playbook/docs/reference/contact-center-analytics.md +1049 -0
- wxcli/_playbook/docs/reference/contact-center-core.md +1614 -0
- wxcli/_playbook/docs/reference/contact-center-journey.md +457 -0
- wxcli/_playbook/docs/reference/contact-center-routing.md +1138 -0
- wxcli/_playbook/docs/reference/devices-core.md +1869 -0
- wxcli/_playbook/docs/reference/devices-dect.md +1150 -0
- wxcli/_playbook/docs/reference/devices-platform.md +467 -0
- wxcli/_playbook/docs/reference/devices-workspaces.md +1426 -0
- wxcli/_playbook/docs/reference/emergency-services.md +1122 -0
- wxcli/_playbook/docs/reference/location-calling-core.md +2037 -0
- wxcli/_playbook/docs/reference/location-calling-media.md +1334 -0
- wxcli/_playbook/docs/reference/location-recording-advanced.md +1482 -0
- wxcli/_playbook/docs/reference/meetings-content.md +473 -0
- wxcli/_playbook/docs/reference/meetings-core.md +903 -0
- wxcli/_playbook/docs/reference/meetings-infrastructure.md +899 -0
- wxcli/_playbook/docs/reference/meetings-settings.md +850 -0
- wxcli/_playbook/docs/reference/messaging-bots.md +1091 -0
- wxcli/_playbook/docs/reference/messaging-spaces.md +695 -0
- wxcli/_playbook/docs/reference/person-call-settings-behavior.md +1639 -0
- wxcli/_playbook/docs/reference/person-call-settings-handling.md +1394 -0
- wxcli/_playbook/docs/reference/person-call-settings-media.md +1898 -0
- wxcli/_playbook/docs/reference/person-call-settings-permissions.md +1329 -0
- wxcli/_playbook/docs/reference/provisioning.md +1366 -0
- wxcli/_playbook/docs/reference/reporting-analytics.md +1318 -0
- wxcli/_playbook/docs/reference/self-service-call-settings.md +1020 -0
- wxcli/_playbook/docs/reference/virtual-lines.md +1132 -0
- wxcli/_playbook/docs/reference/webhooks-events.md +1444 -0
- wxcli/_playbook/docs/reference/wxcadm-xsi-realtime.md +953 -0
- wxcli/_version.py +24 -0
- wxcli/auth.py +137 -0
- wxcli/commands/__init__.py +0 -0
- wxcli/commands/_registry.py +181 -0
- wxcli/commands/activation_email.py +103 -0
- wxcli/commands/admin_recordings.py +585 -0
- wxcli/commands/analytics.py +105 -0
- wxcli/commands/announcement_playlists.py +219 -0
- wxcli/commands/announcements.py +519 -0
- wxcli/commands/archive_users.py +36 -0
- wxcli/commands/attachment_actions.py +60 -0
- wxcli/commands/audit_events.py +83 -0
- wxcli/commands/authorizations.py +113 -0
- wxcli/commands/auto_attendant.py +642 -0
- wxcli/commands/broadworks_billing_reports.py +126 -0
- wxcli/commands/broadworks_enterprises.py +160 -0
- wxcli/commands/broadworks_subscribers.py +319 -0
- wxcli/commands/broadworks_workspaces.py +108 -0
- wxcli/commands/call_controls.py +1304 -0
- wxcli/commands/call_park.py +494 -0
- wxcli/commands/call_pickup.py +229 -0
- wxcli/commands/call_queue.py +1878 -0
- wxcli/commands/call_recording.py +707 -0
- wxcli/commands/call_routing.py +1610 -0
- wxcli/commands/call_settings_for_me_phase_5.py +212 -0
- wxcli/commands/caller_reputation.py +169 -0
- wxcli/commands/calling_service.py +305 -0
- wxcli/commands/cc_address_book.py +770 -0
- wxcli/commands/cc_agent_greetings.py +242 -0
- wxcli/commands/cc_agent_summaries.py +39 -0
- wxcli/commands/cc_agent_wellbeing.py +216 -0
- wxcli/commands/cc_agents.py +425 -0
- wxcli/commands/cc_ai_assistant.py +55 -0
- wxcli/commands/cc_ai_feature.py +294 -0
- wxcli/commands/cc_audio_files.py +149 -0
- wxcli/commands/cc_auto_csat.py +311 -0
- wxcli/commands/cc_aux_code.py +458 -0
- wxcli/commands/cc_business_hour.py +353 -0
- wxcli/commands/cc_call_monitoring.py +228 -0
- wxcli/commands/cc_callbacks.py +194 -0
- wxcli/commands/cc_campaign.py +212 -0
- wxcli/commands/cc_captures.py +39 -0
- wxcli/commands/cc_contact_list.py +169 -0
- wxcli/commands/cc_contact_number.py +295 -0
- wxcli/commands/cc_data_sources.py +235 -0
- wxcli/commands/cc_desktop_layout.py +380 -0
- wxcli/commands/cc_desktop_profile.py +322 -0
- wxcli/commands/cc_dial_number.py +511 -0
- wxcli/commands/cc_dial_plan.py +347 -0
- wxcli/commands/cc_dnc.py +101 -0
- wxcli/commands/cc_entry_point.py +545 -0
- wxcli/commands/cc_ewt.py +51 -0
- wxcli/commands/cc_flow.py +477 -0
- wxcli/commands/cc_global_vars.py +430 -0
- wxcli/commands/cc_holiday_list.py +335 -0
- wxcli/commands/cc_journey.py +1261 -0
- wxcli/commands/cc_legacy_flows.py +49 -0
- wxcli/commands/cc_multimedia_profile.py +436 -0
- wxcli/commands/cc_notification.py +51 -0
- wxcli/commands/cc_outdial_ani.py +604 -0
- wxcli/commands/cc_overrides.py +341 -0
- wxcli/commands/cc_queue.py +1083 -0
- wxcli/commands/cc_queue_stats.py +55 -0
- wxcli/commands/cc_realtime.py +51 -0
- wxcli/commands/cc_resource_collection.py +312 -0
- wxcli/commands/cc_search.py +46 -0
- wxcli/commands/cc_site.py +400 -0
- wxcli/commands/cc_skill.py +350 -0
- wxcli/commands/cc_skill_profile.py +289 -0
- wxcli/commands/cc_subscriptions.py +426 -0
- wxcli/commands/cc_summaries.py +130 -0
- wxcli/commands/cc_tasks.py +844 -0
- wxcli/commands/cc_team.py +325 -0
- wxcli/commands/cc_user_profiles.py +349 -0
- wxcli/commands/cc_users.py +701 -0
- wxcli/commands/cc_work_types.py +363 -0
- wxcli/commands/cdr.py +89 -0
- wxcli/commands/classifications.py +38 -0
- wxcli/commands/cleanup.py +1427 -0
- wxcli/commands/client_settings.py +72 -0
- wxcli/commands/conference.py +328 -0
- wxcli/commands/configure.py +72 -0
- wxcli/commands/converged_recordings.py +347 -0
- wxcli/commands/converged_recordings_export.py +310 -0
- wxcli/commands/cq_playlists.py +42 -0
- wxcli/commands/cucm.py +2794 -0
- wxcli/commands/cucm_config.py +129 -0
- wxcli/commands/customer_assist.py +373 -0
- wxcli/commands/data_sources.py +227 -0
- wxcli/commands/dect_devices.py +787 -0
- wxcli/commands/device_configurations.py +77 -0
- wxcli/commands/device_dynamic_settings.py +320 -0
- wxcli/commands/device_settings.py +1489 -0
- wxcli/commands/devices.py +280 -0
- wxcli/commands/domains.py +142 -0
- wxcli/commands/ecm.py +178 -0
- wxcli/commands/emergency_services.py +827 -0
- wxcli/commands/events.py +83 -0
- wxcli/commands/external_voicemail.py +52 -0
- wxcli/commands/groups.py +206 -0
- wxcli/commands/guest_management.py +76 -0
- wxcli/commands/hds.py +340 -0
- wxcli/commands/hot_desk.py +67 -0
- wxcli/commands/hot_desking_members.py +118 -0
- wxcli/commands/hot_desking_portal.py +124 -0
- wxcli/commands/hunt_group.py +577 -0
- wxcli/commands/hybrid_clusters.py +71 -0
- wxcli/commands/hybrid_connectors.py +67 -0
- wxcli/commands/identity_org.py +159 -0
- wxcli/commands/init_playbook.py +155 -0
- wxcli/commands/licenses.py +106 -0
- wxcli/commands/live_monitoring.py +40 -0
- wxcli/commands/location_call_handling.py +577 -0
- wxcli/commands/location_schedules.py +341 -0
- wxcli/commands/location_settings.py +1297 -0
- wxcli/commands/location_voicemail.py +494 -0
- wxcli/commands/locations.py +336 -0
- wxcli/commands/meeting_captions.py +110 -0
- wxcli/commands/meeting_chats.py +63 -0
- wxcli/commands/meeting_invitees.py +234 -0
- wxcli/commands/meeting_messages.py +28 -0
- wxcli/commands/meeting_participants.py +278 -0
- wxcli/commands/meeting_polls.py +111 -0
- wxcli/commands/meeting_preferences.py +515 -0
- wxcli/commands/meeting_qa.py +78 -0
- wxcli/commands/meeting_qualities.py +43 -0
- wxcli/commands/meeting_reports.py +101 -0
- wxcli/commands/meeting_session_types.py +105 -0
- wxcli/commands/meeting_site.py +57 -0
- wxcli/commands/meeting_slido.py +44 -0
- wxcli/commands/meeting_summaries.py +92 -0
- wxcli/commands/meeting_tracking_codes.py +233 -0
- wxcli/commands/meeting_transcripts.py +230 -0
- wxcli/commands/meetings.py +1997 -0
- wxcli/commands/memberships.py +164 -0
- wxcli/commands/messages.py +213 -0
- wxcli/commands/mode_management.py +244 -0
- wxcli/commands/my_call_settings.py +3577 -0
- wxcli/commands/numbers.py +405 -0
- wxcli/commands/operating_modes.py +410 -0
- wxcli/commands/org_contacts.py +284 -0
- wxcli/commands/org_health_cli.py +55 -0
- wxcli/commands/org_settings.py +71 -0
- wxcli/commands/organizations.py +83 -0
- wxcli/commands/paging_group.py +257 -0
- wxcli/commands/partner_admins.py +141 -0
- wxcli/commands/partner_reports.py +188 -0
- wxcli/commands/partner_tags.py +216 -0
- wxcli/commands/people.py +279 -0
- wxcli/commands/person_call_settings.py +71 -0
- wxcli/commands/pstn.py +280 -0
- wxcli/commands/recording_report.py +154 -0
- wxcli/commands/report_templates.py +38 -0
- wxcli/commands/reports.py +144 -0
- wxcli/commands/resource_group_memberships.py +160 -0
- wxcli/commands/resource_groups.py +67 -0
- wxcli/commands/roles.py +63 -0
- wxcli/commands/room_tabs.py +160 -0
- wxcli/commands/rooms.py +225 -0
- wxcli/commands/scim_bulk.py +46 -0
- wxcli/commands/scim_groups.py +246 -0
- wxcli/commands/scim_schemas.py +82 -0
- wxcli/commands/scim_users.py +283 -0
- wxcli/commands/security_audit.py +54 -0
- wxcli/commands/service_apps.py +51 -0
- wxcli/commands/single_number_reach.py +209 -0
- wxcli/commands/team_memberships.py +155 -0
- wxcli/commands/teams.py +153 -0
- wxcli/commands/ucm_profile.py +42 -0
- wxcli/commands/update.py +219 -0
- wxcli/commands/user_settings.py +5116 -0
- wxcli/commands/video_mesh.py +1090 -0
- wxcli/commands/virtual_extensions.py +502 -0
- wxcli/commands/virtual_line_settings.py +2072 -0
- wxcli/commands/webhooks.py +176 -0
- wxcli/commands/wholesale_billing_reports.py +147 -0
- wxcli/commands/wholesale_provisioning.py +523 -0
- wxcli/commands/workspace_locations.py +339 -0
- wxcli/commands/workspace_metrics.py +103 -0
- wxcli/commands/workspace_personalization.py +70 -0
- wxcli/commands/workspace_settings.py +3347 -0
- wxcli/commands/workspaces.py +279 -0
- wxcli/commands/xapi.py +114 -0
- wxcli/config.py +139 -0
- wxcli/errors.py +77 -0
- wxcli/main.py +210 -0
- wxcli/migration/CLAUDE.md +106 -0
- wxcli/migration/__init__.py +1 -0
- wxcli/migration/advisory/CLAUDE.md +196 -0
- wxcli/migration/advisory/__init__.py +46 -0
- wxcli/migration/advisory/advisor.py +107 -0
- wxcli/migration/advisory/advisory_patterns.py +2552 -0
- wxcli/migration/advisory/recommendation_rules.py +835 -0
- wxcli/migration/cucm/CLAUDE.md +74 -0
- wxcli/migration/cucm/__init__.py +5 -0
- wxcli/migration/cucm/connection.py +265 -0
- wxcli/migration/cucm/discovery.py +225 -0
- wxcli/migration/cucm/extractors/__init__.py +1 -0
- wxcli/migration/cucm/extractors/announcements.py +92 -0
- wxcli/migration/cucm/extractors/base.py +90 -0
- wxcli/migration/cucm/extractors/device_profiles.py +98 -0
- wxcli/migration/cucm/extractors/devices.py +193 -0
- wxcli/migration/cucm/extractors/e911.py +103 -0
- wxcli/migration/cucm/extractors/features.py +309 -0
- wxcli/migration/cucm/extractors/helpers.py +73 -0
- wxcli/migration/cucm/extractors/informational.py +295 -0
- wxcli/migration/cucm/extractors/locations.py +221 -0
- wxcli/migration/cucm/extractors/moh.py +100 -0
- wxcli/migration/cucm/extractors/remote_destinations.py +96 -0
- wxcli/migration/cucm/extractors/routing.py +493 -0
- wxcli/migration/cucm/extractors/shared_lines.py +146 -0
- wxcli/migration/cucm/extractors/templates.py +229 -0
- wxcli/migration/cucm/extractors/tier4.py +173 -0
- wxcli/migration/cucm/extractors/users.py +240 -0
- wxcli/migration/cucm/extractors/voicemail.py +243 -0
- wxcli/migration/cucm/extractors/workspaces.py +88 -0
- wxcli/migration/cucm/unity_connection.py +304 -0
- wxcli/migration/execute/CLAUDE.md +372 -0
- wxcli/migration/execute/__init__.py +303 -0
- wxcli/migration/execute/batch.py +277 -0
- wxcli/migration/execute/dependency.py +483 -0
- wxcli/migration/execute/engine.py +964 -0
- wxcli/migration/execute/handlers.py +2232 -0
- wxcli/migration/execute/planner.py +1939 -0
- wxcli/migration/execute/runtime.py +571 -0
- wxcli/migration/export/CLAUDE.md +49 -0
- wxcli/migration/export/__init__.py +8 -0
- wxcli/migration/export/csv_export.py +126 -0
- wxcli/migration/export/deployment_plan.py +479 -0
- wxcli/migration/export/json_export.py +60 -0
- wxcli/migration/models.py +941 -0
- wxcli/migration/phone_models.py +50 -0
- wxcli/migration/preflight/CLAUDE.md +52 -0
- wxcli/migration/preflight/__init__.py +89 -0
- wxcli/migration/preflight/checks.py +911 -0
- wxcli/migration/preflight/runner.py +293 -0
- wxcli/migration/rate_limiter.py +144 -0
- wxcli/migration/report/CLAUDE.md +245 -0
- wxcli/migration/report/__init__.py +7 -0
- wxcli/migration/report/appendix.py +2437 -0
- wxcli/migration/report/assembler.py +183 -0
- wxcli/migration/report/charts.py +263 -0
- wxcli/migration/report/executive.py +776 -0
- wxcli/migration/report/explainer.py +704 -0
- wxcli/migration/report/helpers.py +74 -0
- wxcli/migration/report/ingest.py +152 -0
- wxcli/migration/report/notice_templates.py +192 -0
- wxcli/migration/report/score.py +375 -0
- wxcli/migration/report/styles.py +1052 -0
- wxcli/migration/report/user_diff.py +1052 -0
- wxcli/migration/report/user_notice.py +425 -0
- wxcli/migration/state.py +139 -0
- wxcli/migration/store.py +860 -0
- wxcli/migration/transform/CLAUDE.md +107 -0
- wxcli/migration/transform/__init__.py +12 -0
- wxcli/migration/transform/analysis_pipeline.py +453 -0
- wxcli/migration/transform/analyzers/__init__.py +142 -0
- wxcli/migration/transform/analyzers/css_permission.py +189 -0
- wxcli/migration/transform/analyzers/css_routing.py +335 -0
- wxcli/migration/transform/analyzers/device_compatibility.py +122 -0
- wxcli/migration/transform/analyzers/dn_ambiguity.py +131 -0
- wxcli/migration/transform/analyzers/duplicate_user.py +221 -0
- wxcli/migration/transform/analyzers/extension_conflict.py +173 -0
- wxcli/migration/transform/analyzers/feature_approximation.py +227 -0
- wxcli/migration/transform/analyzers/layout_overflow.py +174 -0
- wxcli/migration/transform/analyzers/location_ambiguity.py +184 -0
- wxcli/migration/transform/analyzers/missing_data.py +300 -0
- wxcli/migration/transform/analyzers/selective_call_handling.py +394 -0
- wxcli/migration/transform/analyzers/shared_line.py +170 -0
- wxcli/migration/transform/analyzers/voicemail_compatibility.py +267 -0
- wxcli/migration/transform/analyzers/workspace_license.py +212 -0
- wxcli/migration/transform/cross_reference.py +1136 -0
- wxcli/migration/transform/cucm_pattern.py +246 -0
- wxcli/migration/transform/decisions.py +301 -0
- wxcli/migration/transform/e164.py +145 -0
- wxcli/migration/transform/engine.py +256 -0
- wxcli/migration/transform/mappers/CLAUDE.md +123 -0
- wxcli/migration/transform/mappers/__init__.py +76 -0
- wxcli/migration/transform/mappers/announcement_mapper.py +122 -0
- wxcli/migration/transform/mappers/base.py +190 -0
- wxcli/migration/transform/mappers/button_template_mapper.py +186 -0
- wxcli/migration/transform/mappers/call_forwarding_mapper.py +228 -0
- wxcli/migration/transform/mappers/call_settings_mapper.py +144 -0
- wxcli/migration/transform/mappers/css_mapper.py +868 -0
- wxcli/migration/transform/mappers/dect_mapper.py +367 -0
- wxcli/migration/transform/mappers/device_layout_mapper.py +289 -0
- wxcli/migration/transform/mappers/device_mapper.py +227 -0
- wxcli/migration/transform/mappers/device_profile_mapper.py +190 -0
- wxcli/migration/transform/mappers/device_settings_mapper.py +464 -0
- wxcli/migration/transform/mappers/e911_mapper.py +129 -0
- wxcli/migration/transform/mappers/ecbn_mapper.py +263 -0
- wxcli/migration/transform/mappers/executive_assistant_mapper.py +156 -0
- wxcli/migration/transform/mappers/feature_mapper.py +1179 -0
- wxcli/migration/transform/mappers/line_mapper.py +310 -0
- wxcli/migration/transform/mappers/location_mapper.py +235 -0
- wxcli/migration/transform/mappers/moh_mapper.py +114 -0
- wxcli/migration/transform/mappers/monitoring_mapper.py +221 -0
- wxcli/migration/transform/mappers/receptionist_mapper.py +245 -0
- wxcli/migration/transform/mappers/routing_mapper.py +821 -0
- wxcli/migration/transform/mappers/snr_mapper.py +201 -0
- wxcli/migration/transform/mappers/softkey_mapper.py +205 -0
- wxcli/migration/transform/mappers/user_mapper.py +264 -0
- wxcli/migration/transform/mappers/voicemail_group_mapper.py +286 -0
- wxcli/migration/transform/mappers/voicemail_mapper.py +514 -0
- wxcli/migration/transform/mappers/workspace_mapper.py +464 -0
- wxcli/migration/transform/normalizers.py +2008 -0
- wxcli/migration/transform/pattern_converter.py +106 -0
- wxcli/migration/transform/pipeline.py +271 -0
- wxcli/migration/transform/rules.py +255 -0
- wxcli/org_health/CLAUDE.md +63 -0
- wxcli/org_health/__init__.py +7 -0
- wxcli/org_health/analyze.py +93 -0
- wxcli/org_health/checks.py +458 -0
- wxcli/org_health/collector.py +62 -0
- wxcli/org_health/models.py +78 -0
- wxcli/org_health/report.py +300 -0
- wxcli/output.py +101 -0
- wxcli-1.2.0.dist-info/METADATA +505 -0
- wxcli-1.2.0.dist-info/RECORD +413 -0
- wxcli-1.2.0.dist-info/WHEEL +5 -0
- wxcli-1.2.0.dist-info/entry_points.txt +2 -0
- wxcli-1.2.0.dist-info/licenses/LICENSE +191 -0
- wxcli-1.2.0.dist-info/scm_file_list.json +751 -0
- wxcli-1.2.0.dist-info/scm_version.json +8 -0
- wxcli-1.2.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,1997 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import typer
|
|
3
|
+
from wxcli.auth import get_api
|
|
4
|
+
from wxcli.errors import WebexError, handle_rest_error
|
|
5
|
+
from wxcli.output import print_table, print_json
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
app = typer.Typer(help="Manage Webex Meetings meetings.")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@app.command("show")
|
|
12
|
+
def show(
|
|
13
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
14
|
+
current: str = typer.Option(None, "--current", help="Whether or not to retrieve only the current scheduled meetin"),
|
|
15
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
16
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
17
|
+
):
|
|
18
|
+
"""Get a Meeting By an Admin."""
|
|
19
|
+
api = get_api(debug=debug)
|
|
20
|
+
url = f"https://webexapis.com/v1/admin/meetings/{meeting_id}"
|
|
21
|
+
params = {}
|
|
22
|
+
if current is not None:
|
|
23
|
+
params["current"] = current
|
|
24
|
+
try:
|
|
25
|
+
result = api.session.rest_get(url, params=params)
|
|
26
|
+
except WebexError as e:
|
|
27
|
+
handle_rest_error(e)
|
|
28
|
+
if output == "json":
|
|
29
|
+
print_json(result)
|
|
30
|
+
else:
|
|
31
|
+
if isinstance(result, dict):
|
|
32
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
33
|
+
elif isinstance(result, list):
|
|
34
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
35
|
+
else:
|
|
36
|
+
print_json(result)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@app.command("list")
|
|
41
|
+
def cmd_list(
|
|
42
|
+
meeting_number: str = typer.Option(None, "--meeting-number", help="Meeting number for the meeting objects being requested. `mee"),
|
|
43
|
+
web_link: str = typer.Option(None, "--web-link", help="URL encoded link to information page for the meeting objects"),
|
|
44
|
+
current: str = typer.Option(None, "--current", help="Flag identifying to retrieve the current scheduled meeting o"),
|
|
45
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
46
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
47
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
48
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
49
|
+
):
|
|
50
|
+
"""List Meetings By an Admin."""
|
|
51
|
+
api = get_api(debug=debug)
|
|
52
|
+
url = f"https://webexapis.com/v1/admin/meetings"
|
|
53
|
+
params = {}
|
|
54
|
+
if meeting_number is not None:
|
|
55
|
+
params["meetingNumber"] = meeting_number
|
|
56
|
+
if web_link is not None:
|
|
57
|
+
params["webLink"] = web_link
|
|
58
|
+
if current is not None:
|
|
59
|
+
params["current"] = current
|
|
60
|
+
if limit > 0:
|
|
61
|
+
params["max"] = limit
|
|
62
|
+
if offset > 0:
|
|
63
|
+
params["start"] = offset
|
|
64
|
+
try:
|
|
65
|
+
if limit > 0:
|
|
66
|
+
result = api.session.rest_get(url, params=params)
|
|
67
|
+
result = result or {}
|
|
68
|
+
items = result.get("items", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
69
|
+
else:
|
|
70
|
+
if "max" not in params:
|
|
71
|
+
params["max"] = 1000
|
|
72
|
+
items = list(api.session.follow_pagination(url=url, params=params, item_key="items"))
|
|
73
|
+
except WebexError as e:
|
|
74
|
+
handle_rest_error(e)
|
|
75
|
+
if output == "json":
|
|
76
|
+
print_json(items)
|
|
77
|
+
else:
|
|
78
|
+
print_table(items, columns=[('ID', 'id'), ('Title', 'title'), ('Start', 'start'), ('End', 'end'), ('State', 'state')], limit=limit)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
@app.command("list-meetings")
|
|
83
|
+
def list_meetings(
|
|
84
|
+
meeting_number: str = typer.Option(None, "--meeting-number", help="Meeting number for the meeting objects being requested. `mee"),
|
|
85
|
+
web_link: str = typer.Option(None, "--web-link", help="URL encoded link to information page for the meeting objects"),
|
|
86
|
+
room_id: str = typer.Option(None, "--room-id", help="Associated Webex space ID for the meeting objects being requ"),
|
|
87
|
+
meeting_series_id: str = typer.Option(None, "--meeting-series-id", help="Unique identifier for the meeting series. The meeting ID of"),
|
|
88
|
+
from_param: str = typer.Option(None, "--from", help="Start date and time (inclusive) for the range for which meet"),
|
|
89
|
+
to: str = typer.Option(None, "--to", help="End date and time (exclusive) for the range for which meetin"),
|
|
90
|
+
meeting_type: str = typer.Option(None, "--meeting-type", help="Choices: meetingSeries, scheduledMeeting, meeting"),
|
|
91
|
+
state: str = typer.Option(None, "--state", help="Choices: active, scheduled, ready, lobby, inProgress, ended, missed, expired"),
|
|
92
|
+
scheduled_type: str = typer.Option(None, "--scheduled-type", help="Choices: meeting, webinar, personalRoomMeeting"),
|
|
93
|
+
is_modified: str = typer.Option(None, "--is-modified", help="Flag identifying whether a meeting has been modified. Only a"),
|
|
94
|
+
has_chat: str = typer.Option(None, "--has-chat", help="Flag identifying whether a meeting has a chat log. Only appl"),
|
|
95
|
+
has_recording: str = typer.Option(None, "--has-recording", help="Flag identifying meetings which have been recorded. Only app"),
|
|
96
|
+
has_transcription: str = typer.Option(None, "--has-transcription", help="Flag identifying meetings with transcripts. Only applies to"),
|
|
97
|
+
has_summary: str = typer.Option(None, "--has-summary", help="Flag identifying meetings with summaries. Only applies to en"),
|
|
98
|
+
has_closed_caption: str = typer.Option(None, "--has-closed-caption", help="Flag identifying meetings with closed captions. Only applies"),
|
|
99
|
+
has_polls: str = typer.Option(None, "--has-polls", help="Flag identifying meetings with polls. Only applies to ended"),
|
|
100
|
+
has_qa: str = typer.Option(None, "--has-qa", help="Flag identifying meetings with Q&A. Only applies to ended me"),
|
|
101
|
+
has_slido: str = typer.Option(None, "--has-slido", help="Flag identifying meetings with Slido interactions. Only appl"),
|
|
102
|
+
current: str = typer.Option(None, "--current", help="Flag identifying to retrieve the current scheduled meeting o"),
|
|
103
|
+
host_email: str = typer.Option(None, "--host-email", help="Email address for the meeting host. This parameter is only u"),
|
|
104
|
+
site_url: str = typer.Option(None, "--site-url", help="URL of the Webex site which the API lists meetings from. If"),
|
|
105
|
+
integration_tag: str = typer.Option(None, "--integration-tag", help="External key created by an integration application. This par"),
|
|
106
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
107
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
108
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
109
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
110
|
+
):
|
|
111
|
+
"""List Meetings."""
|
|
112
|
+
api = get_api(debug=debug)
|
|
113
|
+
url = f"https://webexapis.com/v1/meetings"
|
|
114
|
+
params = {}
|
|
115
|
+
if meeting_number is not None:
|
|
116
|
+
params["meetingNumber"] = meeting_number
|
|
117
|
+
if web_link is not None:
|
|
118
|
+
params["webLink"] = web_link
|
|
119
|
+
if room_id is not None:
|
|
120
|
+
params["roomId"] = room_id
|
|
121
|
+
if meeting_series_id is not None:
|
|
122
|
+
params["meetingSeriesId"] = meeting_series_id
|
|
123
|
+
if from_param is not None:
|
|
124
|
+
params["from"] = from_param
|
|
125
|
+
if to is not None:
|
|
126
|
+
params["to"] = to
|
|
127
|
+
if meeting_type is not None:
|
|
128
|
+
params["meetingType"] = meeting_type
|
|
129
|
+
if state is not None:
|
|
130
|
+
params["state"] = state
|
|
131
|
+
if scheduled_type is not None:
|
|
132
|
+
params["scheduledType"] = scheduled_type
|
|
133
|
+
if is_modified is not None:
|
|
134
|
+
params["isModified"] = is_modified
|
|
135
|
+
if has_chat is not None:
|
|
136
|
+
params["hasChat"] = has_chat
|
|
137
|
+
if has_recording is not None:
|
|
138
|
+
params["hasRecording"] = has_recording
|
|
139
|
+
if has_transcription is not None:
|
|
140
|
+
params["hasTranscription"] = has_transcription
|
|
141
|
+
if has_summary is not None:
|
|
142
|
+
params["hasSummary"] = has_summary
|
|
143
|
+
if has_closed_caption is not None:
|
|
144
|
+
params["hasClosedCaption"] = has_closed_caption
|
|
145
|
+
if has_polls is not None:
|
|
146
|
+
params["hasPolls"] = has_polls
|
|
147
|
+
if has_qa is not None:
|
|
148
|
+
params["hasQA"] = has_qa
|
|
149
|
+
if has_slido is not None:
|
|
150
|
+
params["hasSlido"] = has_slido
|
|
151
|
+
if current is not None:
|
|
152
|
+
params["current"] = current
|
|
153
|
+
if host_email is not None:
|
|
154
|
+
params["hostEmail"] = host_email
|
|
155
|
+
if site_url is not None:
|
|
156
|
+
params["siteUrl"] = site_url
|
|
157
|
+
if integration_tag is not None:
|
|
158
|
+
params["integrationTag"] = integration_tag
|
|
159
|
+
if limit > 0:
|
|
160
|
+
params["max"] = limit
|
|
161
|
+
if offset > 0:
|
|
162
|
+
params["start"] = offset
|
|
163
|
+
try:
|
|
164
|
+
if limit > 0:
|
|
165
|
+
result = api.session.rest_get(url, params=params)
|
|
166
|
+
result = result or {}
|
|
167
|
+
items = result.get("items", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
168
|
+
else:
|
|
169
|
+
items = list(api.session.follow_pagination(url=url, params=params, item_key="items"))
|
|
170
|
+
except WebexError as e:
|
|
171
|
+
handle_rest_error(e)
|
|
172
|
+
if output == "json":
|
|
173
|
+
print_json(items)
|
|
174
|
+
else:
|
|
175
|
+
print_table(items, columns=[('ID', 'id'), ('Title', 'title'), ('Start', 'start'), ('End', 'end'), ('State', 'state')], limit=limit)
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
@app.command("create")
|
|
180
|
+
def create(
|
|
181
|
+
adhoc: bool = typer.Option(None, "--adhoc/--no-adhoc", help="Whether or not to create an ad-hoc meeting for the room spec"),
|
|
182
|
+
room_id: str = typer.Option(None, "--room-id", help="Unique identifier for the Webex space which the meeting is t"),
|
|
183
|
+
template_id: str = typer.Option(None, "--template-id", help="Unique identifier for meeting template. Please note that `st"),
|
|
184
|
+
title: str = typer.Option(None, "--title", help="(required) Meeting title. The title can be a maximum of 128 characters"),
|
|
185
|
+
agenda: str = typer.Option(None, "--agenda", help="Meeting agenda. The agenda can be a maximum of 1300 characte"),
|
|
186
|
+
password: str = typer.Option(None, "--password", help="Meeting password. Must conform to the site's password comple"),
|
|
187
|
+
start: str = typer.Option(None, "--start", help="(required) Date and time for the start of meeting in any [ISO 8601](htt"),
|
|
188
|
+
end: str = typer.Option(None, "--end", help="(required) Date and time for the end of meeting in any [ISO 8601](https"),
|
|
189
|
+
timezone: str = typer.Option(None, "--timezone", help="[Time zone](https://en.wikipedia.org/wiki/List_of_tz_databas"),
|
|
190
|
+
recurrence: str = typer.Option(None, "--recurrence", help="Meeting series recurrence rule (conforming with [RFC 2445](h"),
|
|
191
|
+
enabled_auto_record_meeting: bool = typer.Option(None, "--enabled-auto-record-meeting/--no-enabled-auto-record-meeting", help="Whether or not meeting is recorded automatically."),
|
|
192
|
+
allow_any_user_to_be_co_host: bool = typer.Option(None, "--allow-any-user-to-be-co-host/--no-allow-any-user-to-be-co-host", help="Whether or not to allow any attendee with a host account on"),
|
|
193
|
+
enabled_join_before_host: bool = typer.Option(None, "--enabled-join-before-host/--no-enabled-join-before-host", help="Whether or not to allow any attendee to join the meeting bef"),
|
|
194
|
+
enable_connect_audio_before_host: bool = typer.Option(None, "--enable-connect-audio-before-host/--no-enable-connect-audio-before-host", help="Whether or not to allow any attendee to connect audio in the"),
|
|
195
|
+
join_before_host_minutes: str = typer.Option(None, "--join-before-host-minutes", help="Number of minutes an attendee can join the meeting before th"),
|
|
196
|
+
exclude_password: bool = typer.Option(None, "--exclude-password/--no-exclude-password", help="Whether or not to exclude the meeting password from the emai"),
|
|
197
|
+
public_meeting: bool = typer.Option(None, "--public-meeting/--no-public-meeting", help="Whether or not to allow the meeting to be listed on the publ"),
|
|
198
|
+
reminder_time: str = typer.Option(None, "--reminder-time", help="The number of minutes before the meeting begins, that an ema"),
|
|
199
|
+
unlocked_meeting_join_security: str = typer.Option(None, "--unlocked-meeting-join-security", help="Choices: allowJoin, allowJoinWithLobby, blockFromJoin"),
|
|
200
|
+
session_type_id: str = typer.Option(None, "--session-type-id", help="Unique identifier for a meeting session type for the user. T"),
|
|
201
|
+
scheduled_type: str = typer.Option(None, "--scheduled-type", help="Choices: meeting, webinar, personalRoomMeeting"),
|
|
202
|
+
enabled_webcast_view: bool = typer.Option(None, "--enabled-webcast-view/--no-enabled-webcast-view", help="Whether or not webcast view is enabled. This parameter is ig"),
|
|
203
|
+
panelist_password: str = typer.Option(None, "--panelist-password", help="Password for panelists of a webinar meeting. Must conform to"),
|
|
204
|
+
enable_automatic_lock: bool = typer.Option(None, "--enable-automatic-lock/--no-enable-automatic-lock", help="Whether or not to automatically lock the meeting after it st"),
|
|
205
|
+
automatic_lock_minutes: str = typer.Option(None, "--automatic-lock-minutes", help="The number of minutes after the meeting begins, for automati"),
|
|
206
|
+
allow_first_user_to_be_co_host: bool = typer.Option(None, "--allow-first-user-to-be-co-host/--no-allow-first-user-to-be-co-host", help="Whether or not to allow the first attendee of the meeting wi"),
|
|
207
|
+
allow_authenticated_devices: bool = typer.Option(None, "--allow-authenticated-devices/--no-allow-authenticated-devices", help="Whether or not to allow authenticated video devices in the m"),
|
|
208
|
+
send_email: bool = typer.Option(None, "--send-email/--no-send-email", help="Whether or not to send emails to host and invitees. It is an"),
|
|
209
|
+
host_email: str = typer.Option(None, "--host-email", help="Email address for the meeting host. This attribute should on"),
|
|
210
|
+
site_url: str = typer.Option(None, "--site-url", help="URL of the Webex site which the meeting is created on. If no"),
|
|
211
|
+
enabled_breakout_sessions: bool = typer.Option(None, "--enabled-breakout-sessions/--no-enabled-breakout-sessions", help="Whether or not breakout sessions are enabled."),
|
|
212
|
+
enabled_audio_watermark: bool = typer.Option(None, "--enabled-audio-watermark/--no-enabled-audio-watermark", help="Whether or not the audio watermark is enabled. If it's `true"),
|
|
213
|
+
enabled_visual_watermark: bool = typer.Option(None, "--enabled-visual-watermark/--no-enabled-visual-watermark", help="Whether or not the visual watermark is enabled. If it's `tru"),
|
|
214
|
+
visual_watermark_opacity: str = typer.Option(None, "--visual-watermark-opacity", help="Opacity level for the visual watermark. The value must be be"),
|
|
215
|
+
require_attendee_login: bool = typer.Option(None, "--require-attendee-login/--no-require-attendee-login", help="Require attendees to sign in before joining the webinar. Thi"),
|
|
216
|
+
restrict_to_invitees: bool = typer.Option(None, "--restrict-to-invitees/--no-restrict-to-invitees", help="Restrict webinar to invited attendees only. This option work"),
|
|
217
|
+
enabled_live_stream: bool = typer.Option(None, "--enabled-live-stream/--no-enabled-live-stream", help="Whether or not live streaming is enabled. If it's enabled, t"),
|
|
218
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
219
|
+
output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
|
|
220
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
221
|
+
):
|
|
222
|
+
"""Create a Meeting\n\nExample --json-body:\n '{"title":"...","start":"...","end":"...","adhoc":true,"roomId":"...","templateId":"...","agenda":"...","password":"..."}'."""
|
|
223
|
+
api = get_api(debug=debug)
|
|
224
|
+
url = f"https://webexapis.com/v1/meetings"
|
|
225
|
+
if json_body:
|
|
226
|
+
body = json.loads(json_body)
|
|
227
|
+
else:
|
|
228
|
+
body = {}
|
|
229
|
+
if adhoc is not None:
|
|
230
|
+
body["adhoc"] = adhoc
|
|
231
|
+
if room_id is not None:
|
|
232
|
+
body["roomId"] = room_id
|
|
233
|
+
if template_id is not None:
|
|
234
|
+
body["templateId"] = template_id
|
|
235
|
+
if title is not None:
|
|
236
|
+
body["title"] = title
|
|
237
|
+
if agenda is not None:
|
|
238
|
+
body["agenda"] = agenda
|
|
239
|
+
if password is not None:
|
|
240
|
+
body["password"] = password
|
|
241
|
+
if start is not None:
|
|
242
|
+
body["start"] = start
|
|
243
|
+
if end is not None:
|
|
244
|
+
body["end"] = end
|
|
245
|
+
if timezone is not None:
|
|
246
|
+
body["timezone"] = timezone
|
|
247
|
+
if recurrence is not None:
|
|
248
|
+
body["recurrence"] = recurrence
|
|
249
|
+
if enabled_auto_record_meeting is not None:
|
|
250
|
+
body["enabledAutoRecordMeeting"] = enabled_auto_record_meeting
|
|
251
|
+
if allow_any_user_to_be_co_host is not None:
|
|
252
|
+
body["allowAnyUserToBeCoHost"] = allow_any_user_to_be_co_host
|
|
253
|
+
if enabled_join_before_host is not None:
|
|
254
|
+
body["enabledJoinBeforeHost"] = enabled_join_before_host
|
|
255
|
+
if enable_connect_audio_before_host is not None:
|
|
256
|
+
body["enableConnectAudioBeforeHost"] = enable_connect_audio_before_host
|
|
257
|
+
if join_before_host_minutes is not None:
|
|
258
|
+
body["joinBeforeHostMinutes"] = join_before_host_minutes
|
|
259
|
+
if exclude_password is not None:
|
|
260
|
+
body["excludePassword"] = exclude_password
|
|
261
|
+
if public_meeting is not None:
|
|
262
|
+
body["publicMeeting"] = public_meeting
|
|
263
|
+
if reminder_time is not None:
|
|
264
|
+
body["reminderTime"] = reminder_time
|
|
265
|
+
if unlocked_meeting_join_security is not None:
|
|
266
|
+
body["unlockedMeetingJoinSecurity"] = unlocked_meeting_join_security
|
|
267
|
+
if session_type_id is not None:
|
|
268
|
+
body["sessionTypeId"] = session_type_id
|
|
269
|
+
if scheduled_type is not None:
|
|
270
|
+
body["scheduledType"] = scheduled_type
|
|
271
|
+
if enabled_webcast_view is not None:
|
|
272
|
+
body["enabledWebcastView"] = enabled_webcast_view
|
|
273
|
+
if panelist_password is not None:
|
|
274
|
+
body["panelistPassword"] = panelist_password
|
|
275
|
+
if enable_automatic_lock is not None:
|
|
276
|
+
body["enableAutomaticLock"] = enable_automatic_lock
|
|
277
|
+
if automatic_lock_minutes is not None:
|
|
278
|
+
body["automaticLockMinutes"] = automatic_lock_minutes
|
|
279
|
+
if allow_first_user_to_be_co_host is not None:
|
|
280
|
+
body["allowFirstUserToBeCoHost"] = allow_first_user_to_be_co_host
|
|
281
|
+
if allow_authenticated_devices is not None:
|
|
282
|
+
body["allowAuthenticatedDevices"] = allow_authenticated_devices
|
|
283
|
+
if send_email is not None:
|
|
284
|
+
body["sendEmail"] = send_email
|
|
285
|
+
if host_email is not None:
|
|
286
|
+
body["hostEmail"] = host_email
|
|
287
|
+
if site_url is not None:
|
|
288
|
+
body["siteUrl"] = site_url
|
|
289
|
+
if enabled_breakout_sessions is not None:
|
|
290
|
+
body["enabledBreakoutSessions"] = enabled_breakout_sessions
|
|
291
|
+
if enabled_audio_watermark is not None:
|
|
292
|
+
body["enabledAudioWatermark"] = enabled_audio_watermark
|
|
293
|
+
if enabled_visual_watermark is not None:
|
|
294
|
+
body["enabledVisualWatermark"] = enabled_visual_watermark
|
|
295
|
+
if visual_watermark_opacity is not None:
|
|
296
|
+
body["visualWatermarkOpacity"] = visual_watermark_opacity
|
|
297
|
+
if require_attendee_login is not None:
|
|
298
|
+
body["requireAttendeeLogin"] = require_attendee_login
|
|
299
|
+
if restrict_to_invitees is not None:
|
|
300
|
+
body["restrictToInvitees"] = restrict_to_invitees
|
|
301
|
+
if enabled_live_stream is not None:
|
|
302
|
+
body["enabledLiveStream"] = enabled_live_stream
|
|
303
|
+
_missing = [f for f in ['title', 'start', 'end'] if f not in body or body[f] is None]
|
|
304
|
+
if _missing:
|
|
305
|
+
typer.echo("Error: Missing required fields: " + ", ".join(_missing), err=True)
|
|
306
|
+
raise typer.Exit(1)
|
|
307
|
+
try:
|
|
308
|
+
result = api.session.rest_post(url, json=body)
|
|
309
|
+
except WebexError as e:
|
|
310
|
+
handle_rest_error(e)
|
|
311
|
+
if output == "json":
|
|
312
|
+
print_json(result)
|
|
313
|
+
elif isinstance(result, dict) and "id" in result:
|
|
314
|
+
typer.echo(f"Created: {result['id']}")
|
|
315
|
+
elif not result or result == {}:
|
|
316
|
+
typer.echo("Created.")
|
|
317
|
+
else:
|
|
318
|
+
print_json(result)
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
@app.command("show-meetings")
|
|
323
|
+
def show_meetings(
|
|
324
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
325
|
+
current: str = typer.Option(None, "--current", help="Whether or not to retrieve only the current scheduled meetin"),
|
|
326
|
+
host_email: str = typer.Option(None, "--host-email", help="Email address for the meeting host. This parameter is only u"),
|
|
327
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
328
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
329
|
+
):
|
|
330
|
+
"""Get a Meeting."""
|
|
331
|
+
api = get_api(debug=debug)
|
|
332
|
+
url = f"https://webexapis.com/v1/meetings/{meeting_id}"
|
|
333
|
+
params = {}
|
|
334
|
+
if current is not None:
|
|
335
|
+
params["current"] = current
|
|
336
|
+
if host_email is not None:
|
|
337
|
+
params["hostEmail"] = host_email
|
|
338
|
+
try:
|
|
339
|
+
result = api.session.rest_get(url, params=params)
|
|
340
|
+
except WebexError as e:
|
|
341
|
+
handle_rest_error(e)
|
|
342
|
+
if output == "json":
|
|
343
|
+
print_json(result)
|
|
344
|
+
else:
|
|
345
|
+
if isinstance(result, dict):
|
|
346
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
347
|
+
elif isinstance(result, list):
|
|
348
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
349
|
+
else:
|
|
350
|
+
print_json(result)
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
@app.command("update")
|
|
355
|
+
def update(
|
|
356
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
357
|
+
title: str = typer.Option(None, "--title", help="Meeting title. The title can be a maximum of 128 characters"),
|
|
358
|
+
agenda: str = typer.Option(None, "--agenda", help="Meeting agenda. The agenda can be a maximum of 1300 characte"),
|
|
359
|
+
password: str = typer.Option(None, "--password", help="Meeting password. Must conform to the site's password comple"),
|
|
360
|
+
start: str = typer.Option(None, "--start", help="Date and time for the start of meeting in any [ISO 8601](htt"),
|
|
361
|
+
end: str = typer.Option(None, "--end", help="Date and time for the end of meeting in any [ISO 8601](https"),
|
|
362
|
+
timezone: str = typer.Option(None, "--timezone", help="[Time zone](https://en.wikipedia.org/wiki/List_of_tz_databas"),
|
|
363
|
+
recurrence: str = typer.Option(None, "--recurrence", help="Meeting series recurrence rule (conforming with [RFC 2445](h"),
|
|
364
|
+
enabled_auto_record_meeting: bool = typer.Option(None, "--enabled-auto-record-meeting/--no-enabled-auto-record-meeting", help="Whether or not meeting is recorded automatically."),
|
|
365
|
+
allow_any_user_to_be_co_host: bool = typer.Option(None, "--allow-any-user-to-be-co-host/--no-allow-any-user-to-be-co-host", help="Whether or not to allow any attendee with a host account on"),
|
|
366
|
+
enabled_join_before_host: bool = typer.Option(None, "--enabled-join-before-host/--no-enabled-join-before-host", help="Whether or not to allow any attendee to join the meeting bef"),
|
|
367
|
+
enable_connect_audio_before_host: bool = typer.Option(None, "--enable-connect-audio-before-host/--no-enable-connect-audio-before-host", help="Whether or not to allow any attendee to connect audio in the"),
|
|
368
|
+
join_before_host_minutes: str = typer.Option(None, "--join-before-host-minutes", help="Number of minutes an attendee can join the meeting before th"),
|
|
369
|
+
exclude_password: bool = typer.Option(None, "--exclude-password/--no-exclude-password", help="Whether or not to exclude the meeting password from the emai"),
|
|
370
|
+
public_meeting: bool = typer.Option(None, "--public-meeting/--no-public-meeting", help="Whether or not to allow the meeting to be listed on the publ"),
|
|
371
|
+
reminder_time: str = typer.Option(None, "--reminder-time", help="The number of minutes before the meeting begins, that an ema"),
|
|
372
|
+
unlocked_meeting_join_security: str = typer.Option(None, "--unlocked-meeting-join-security", help="Choices: allowJoin, allowJoinWithLobby, blockFromJoin"),
|
|
373
|
+
session_type_id: str = typer.Option(None, "--session-type-id", help="Unique identifier for a meeting session type for the user. T"),
|
|
374
|
+
enabled_webcast_view: bool = typer.Option(None, "--enabled-webcast-view/--no-enabled-webcast-view", help="Whether or not webcast view is enabled."),
|
|
375
|
+
panelist_password: str = typer.Option(None, "--panelist-password", help="Password for panelists of a webinar meeting. Must conform to"),
|
|
376
|
+
enable_automatic_lock: bool = typer.Option(None, "--enable-automatic-lock/--no-enable-automatic-lock", help="Whether or not to automatically lock the meeting after it st"),
|
|
377
|
+
automatic_lock_minutes: str = typer.Option(None, "--automatic-lock-minutes", help="The number of minutes after the meeting begins, for automati"),
|
|
378
|
+
allow_first_user_to_be_co_host: bool = typer.Option(None, "--allow-first-user-to-be-co-host/--no-allow-first-user-to-be-co-host", help="Whether or not to allow the first attendee of the meeting wi"),
|
|
379
|
+
allow_authenticated_devices: bool = typer.Option(None, "--allow-authenticated-devices/--no-allow-authenticated-devices", help="Whether or not to allow authenticated video devices in the m"),
|
|
380
|
+
send_email: bool = typer.Option(None, "--send-email/--no-send-email", help="Whether or not to send emails to host and invitees. It is an"),
|
|
381
|
+
host_email: str = typer.Option(None, "--host-email", help="Email address for the meeting host. This attribute should on"),
|
|
382
|
+
enabled_breakout_sessions: bool = typer.Option(None, "--enabled-breakout-sessions/--no-enabled-breakout-sessions", help="Whether or not breakout sessions are enabled. If the value o"),
|
|
383
|
+
enabled_audio_watermark: bool = typer.Option(None, "--enabled-audio-watermark/--no-enabled-audio-watermark", help="Whether or not the audio watermark is enabled. If it's `true"),
|
|
384
|
+
enabled_visual_watermark: bool = typer.Option(None, "--enabled-visual-watermark/--no-enabled-visual-watermark", help="Whether or not the visual watermark is enabled. If it's `tru"),
|
|
385
|
+
visual_watermark_opacity: str = typer.Option(None, "--visual-watermark-opacity", help="Opacity level for the visual watermark. The value must be be"),
|
|
386
|
+
require_attendee_login: bool = typer.Option(None, "--require-attendee-login/--no-require-attendee-login", help="Require attendees to sign in before joining the webinar. Thi"),
|
|
387
|
+
restrict_to_invitees: bool = typer.Option(None, "--restrict-to-invitees/--no-restrict-to-invitees", help="Restrict webinar to invited attendees only. This option work"),
|
|
388
|
+
enabled_live_stream: bool = typer.Option(None, "--enabled-live-stream/--no-enabled-live-stream", help="Whether or not live streaming is enabled."),
|
|
389
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
390
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
391
|
+
):
|
|
392
|
+
"""Update a Meeting\n\nExample --json-body:\n '{"title":"...","agenda":"...","password":"...","start":"...","end":"...","timezone":"...","recurrence":"...","enabledAutoRecordMeeting":true}'."""
|
|
393
|
+
api = get_api(debug=debug)
|
|
394
|
+
url = f"https://webexapis.com/v1/meetings/{meeting_id}"
|
|
395
|
+
if json_body:
|
|
396
|
+
body = json.loads(json_body)
|
|
397
|
+
else:
|
|
398
|
+
body = {}
|
|
399
|
+
if title is not None:
|
|
400
|
+
body["title"] = title
|
|
401
|
+
if agenda is not None:
|
|
402
|
+
body["agenda"] = agenda
|
|
403
|
+
if password is not None:
|
|
404
|
+
body["password"] = password
|
|
405
|
+
if start is not None:
|
|
406
|
+
body["start"] = start
|
|
407
|
+
if end is not None:
|
|
408
|
+
body["end"] = end
|
|
409
|
+
if timezone is not None:
|
|
410
|
+
body["timezone"] = timezone
|
|
411
|
+
if recurrence is not None:
|
|
412
|
+
body["recurrence"] = recurrence
|
|
413
|
+
if enabled_auto_record_meeting is not None:
|
|
414
|
+
body["enabledAutoRecordMeeting"] = enabled_auto_record_meeting
|
|
415
|
+
if allow_any_user_to_be_co_host is not None:
|
|
416
|
+
body["allowAnyUserToBeCoHost"] = allow_any_user_to_be_co_host
|
|
417
|
+
if enabled_join_before_host is not None:
|
|
418
|
+
body["enabledJoinBeforeHost"] = enabled_join_before_host
|
|
419
|
+
if enable_connect_audio_before_host is not None:
|
|
420
|
+
body["enableConnectAudioBeforeHost"] = enable_connect_audio_before_host
|
|
421
|
+
if join_before_host_minutes is not None:
|
|
422
|
+
body["joinBeforeHostMinutes"] = join_before_host_minutes
|
|
423
|
+
if exclude_password is not None:
|
|
424
|
+
body["excludePassword"] = exclude_password
|
|
425
|
+
if public_meeting is not None:
|
|
426
|
+
body["publicMeeting"] = public_meeting
|
|
427
|
+
if reminder_time is not None:
|
|
428
|
+
body["reminderTime"] = reminder_time
|
|
429
|
+
if unlocked_meeting_join_security is not None:
|
|
430
|
+
body["unlockedMeetingJoinSecurity"] = unlocked_meeting_join_security
|
|
431
|
+
if session_type_id is not None:
|
|
432
|
+
body["sessionTypeId"] = session_type_id
|
|
433
|
+
if enabled_webcast_view is not None:
|
|
434
|
+
body["enabledWebcastView"] = enabled_webcast_view
|
|
435
|
+
if panelist_password is not None:
|
|
436
|
+
body["panelistPassword"] = panelist_password
|
|
437
|
+
if enable_automatic_lock is not None:
|
|
438
|
+
body["enableAutomaticLock"] = enable_automatic_lock
|
|
439
|
+
if automatic_lock_minutes is not None:
|
|
440
|
+
body["automaticLockMinutes"] = automatic_lock_minutes
|
|
441
|
+
if allow_first_user_to_be_co_host is not None:
|
|
442
|
+
body["allowFirstUserToBeCoHost"] = allow_first_user_to_be_co_host
|
|
443
|
+
if allow_authenticated_devices is not None:
|
|
444
|
+
body["allowAuthenticatedDevices"] = allow_authenticated_devices
|
|
445
|
+
if send_email is not None:
|
|
446
|
+
body["sendEmail"] = send_email
|
|
447
|
+
if host_email is not None:
|
|
448
|
+
body["hostEmail"] = host_email
|
|
449
|
+
if enabled_breakout_sessions is not None:
|
|
450
|
+
body["enabledBreakoutSessions"] = enabled_breakout_sessions
|
|
451
|
+
if enabled_audio_watermark is not None:
|
|
452
|
+
body["enabledAudioWatermark"] = enabled_audio_watermark
|
|
453
|
+
if enabled_visual_watermark is not None:
|
|
454
|
+
body["enabledVisualWatermark"] = enabled_visual_watermark
|
|
455
|
+
if visual_watermark_opacity is not None:
|
|
456
|
+
body["visualWatermarkOpacity"] = visual_watermark_opacity
|
|
457
|
+
if require_attendee_login is not None:
|
|
458
|
+
body["requireAttendeeLogin"] = require_attendee_login
|
|
459
|
+
if restrict_to_invitees is not None:
|
|
460
|
+
body["restrictToInvitees"] = restrict_to_invitees
|
|
461
|
+
if enabled_live_stream is not None:
|
|
462
|
+
body["enabledLiveStream"] = enabled_live_stream
|
|
463
|
+
try:
|
|
464
|
+
result = api.session.rest_put(url, json=body)
|
|
465
|
+
except WebexError as e:
|
|
466
|
+
handle_rest_error(e)
|
|
467
|
+
typer.echo(f"Updated.")
|
|
468
|
+
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
@app.command("update-meetings")
|
|
472
|
+
def update_meetings(
|
|
473
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
474
|
+
title: str = typer.Option(None, "--title", help="Meeting title. The title can be a maximum of 128 characters"),
|
|
475
|
+
agenda: str = typer.Option(None, "--agenda", help="Meeting agenda. The agenda can be a maximum of 1300 characte"),
|
|
476
|
+
password: str = typer.Option(None, "--password", help="Meeting password. Must conform to the site's password comple"),
|
|
477
|
+
start: str = typer.Option(None, "--start", help="Date and time for the start of meeting in any [ISO 8601](htt"),
|
|
478
|
+
end: str = typer.Option(None, "--end", help="Date and time for the end of meeting in any [ISO 8601](https"),
|
|
479
|
+
timezone: str = typer.Option(None, "--timezone", help="[Time zone](https://en.wikipedia.org/wiki/List_of_tz_databas"),
|
|
480
|
+
recurrence: str = typer.Option(None, "--recurrence", help="Meeting series recurrence rule (conforming with [RFC 2445](h"),
|
|
481
|
+
enabled_auto_record_meeting: str = typer.Option(None, "--enabled-auto-record-meeting", help="Whether or not meeting is recorded automatically."),
|
|
482
|
+
allow_any_user_to_be_co_host: str = typer.Option(None, "--allow-any-user-to-be-co-host", help="Whether or not to allow any attendee with a host account on"),
|
|
483
|
+
enabled_join_before_host: str = typer.Option(None, "--enabled-join-before-host", help="Whether or not to allow any attendee to join the meeting bef"),
|
|
484
|
+
enable_connect_audio_before_host: str = typer.Option(None, "--enable-connect-audio-before-host", help="Whether or not to allow any attendee to connect audio in the"),
|
|
485
|
+
join_before_host_minutes: str = typer.Option(None, "--join-before-host-minutes", help="Number of minutes an attendee can join the meeting before th"),
|
|
486
|
+
exclude_password: str = typer.Option(None, "--exclude-password", help="Whether or not to exclude the meeting password from the emai"),
|
|
487
|
+
public_meeting: str = typer.Option(None, "--public-meeting", help="Whether or not to allow the meeting to be listed on the publ"),
|
|
488
|
+
reminder_time: str = typer.Option(None, "--reminder-time", help="The number of minutes before the meeting begins, that an ema"),
|
|
489
|
+
unlocked_meeting_join_security: str = typer.Option(None, "--unlocked-meeting-join-security", help="Choices: allowJoin, allowJoinWithLobby, blockFromJoin"),
|
|
490
|
+
session_type_id: str = typer.Option(None, "--session-type-id", help="Unique identifier for a meeting session type for the user. T"),
|
|
491
|
+
enabled_webcast_view: str = typer.Option(None, "--enabled-webcast-view", help="Whether or not webcast view is enabled."),
|
|
492
|
+
panelist_password: str = typer.Option(None, "--panelist-password", help="Password for panelists of a webinar meeting. Must conform to"),
|
|
493
|
+
enable_automatic_lock: str = typer.Option(None, "--enable-automatic-lock", help="Whether or not to automatically lock the meeting after it st"),
|
|
494
|
+
automatic_lock_minutes: str = typer.Option(None, "--automatic-lock-minutes", help="The number of minutes after the meeting begins, for automati"),
|
|
495
|
+
allow_first_user_to_be_co_host: str = typer.Option(None, "--allow-first-user-to-be-co-host", help="Whether or not to allow the first attendee of the meeting wi"),
|
|
496
|
+
allow_authenticated_devices: str = typer.Option(None, "--allow-authenticated-devices", help="Whether or not to allow authenticated video devices in the m"),
|
|
497
|
+
send_email: str = typer.Option(None, "--send-email", help="Whether or not to send emails to host and invitees. It is an"),
|
|
498
|
+
host_email: str = typer.Option(None, "--host-email", help="Email address for the meeting host. This attribute should on"),
|
|
499
|
+
enabled_breakout_sessions: str = typer.Option(None, "--enabled-breakout-sessions", help="Whether or not breakout sessions are enabled. If the value o"),
|
|
500
|
+
enabled_audio_watermark: str = typer.Option(None, "--enabled-audio-watermark", help="Whether or not the audio watermark is enabled. If it's `true"),
|
|
501
|
+
enabled_visual_watermark: str = typer.Option(None, "--enabled-visual-watermark", help="Whether or not the visual watermark is enabled. If it's `tru"),
|
|
502
|
+
visual_watermark_opacity: str = typer.Option(None, "--visual-watermark-opacity", help="Opacity level for the visual watermark. The value must be be"),
|
|
503
|
+
require_attendee_login: str = typer.Option(None, "--require-attendee-login", help="Require attendees to sign in before joining the webinar. Thi"),
|
|
504
|
+
restrict_to_invitees: str = typer.Option(None, "--restrict-to-invitees", help="Restrict webinar to invited attendees only. This option work"),
|
|
505
|
+
enabled_live_stream: str = typer.Option(None, "--enabled-live-stream", help="Whether or not live streaming is enabled."),
|
|
506
|
+
value: str = typer.Option(None, "--value", help="Value for replace op (JSON-parsed: string, number, bool, or array)"),
|
|
507
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
508
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
509
|
+
):
|
|
510
|
+
"""Patch a Meeting\n\nExample --json-body:\n '{"title":"...","agenda":"...","password":"...","start":"...","end":"...","timezone":"...","recurrence":"...","enabledAutoRecordMeeting":true}'."""
|
|
511
|
+
api = get_api(debug=debug)
|
|
512
|
+
url = f"https://webexapis.com/v1/meetings/{meeting_id}"
|
|
513
|
+
if json_body:
|
|
514
|
+
body = json.loads(json_body)
|
|
515
|
+
else:
|
|
516
|
+
patch_op = {}
|
|
517
|
+
if title is not None:
|
|
518
|
+
patch_op["title"] = title
|
|
519
|
+
if agenda is not None:
|
|
520
|
+
patch_op["agenda"] = agenda
|
|
521
|
+
if password is not None:
|
|
522
|
+
patch_op["password"] = password
|
|
523
|
+
if start is not None:
|
|
524
|
+
patch_op["start"] = start
|
|
525
|
+
if end is not None:
|
|
526
|
+
patch_op["end"] = end
|
|
527
|
+
if timezone is not None:
|
|
528
|
+
patch_op["timezone"] = timezone
|
|
529
|
+
if recurrence is not None:
|
|
530
|
+
patch_op["recurrence"] = recurrence
|
|
531
|
+
if enabled_auto_record_meeting is not None:
|
|
532
|
+
patch_op["enabledAutoRecordMeeting"] = enabled_auto_record_meeting
|
|
533
|
+
if allow_any_user_to_be_co_host is not None:
|
|
534
|
+
patch_op["allowAnyUserToBeCoHost"] = allow_any_user_to_be_co_host
|
|
535
|
+
if enabled_join_before_host is not None:
|
|
536
|
+
patch_op["enabledJoinBeforeHost"] = enabled_join_before_host
|
|
537
|
+
if enable_connect_audio_before_host is not None:
|
|
538
|
+
patch_op["enableConnectAudioBeforeHost"] = enable_connect_audio_before_host
|
|
539
|
+
if join_before_host_minutes is not None:
|
|
540
|
+
patch_op["joinBeforeHostMinutes"] = join_before_host_minutes
|
|
541
|
+
if exclude_password is not None:
|
|
542
|
+
patch_op["excludePassword"] = exclude_password
|
|
543
|
+
if public_meeting is not None:
|
|
544
|
+
patch_op["publicMeeting"] = public_meeting
|
|
545
|
+
if reminder_time is not None:
|
|
546
|
+
patch_op["reminderTime"] = reminder_time
|
|
547
|
+
if unlocked_meeting_join_security is not None:
|
|
548
|
+
patch_op["unlockedMeetingJoinSecurity"] = unlocked_meeting_join_security
|
|
549
|
+
if session_type_id is not None:
|
|
550
|
+
patch_op["sessionTypeId"] = session_type_id
|
|
551
|
+
if enabled_webcast_view is not None:
|
|
552
|
+
patch_op["enabledWebcastView"] = enabled_webcast_view
|
|
553
|
+
if panelist_password is not None:
|
|
554
|
+
patch_op["panelistPassword"] = panelist_password
|
|
555
|
+
if enable_automatic_lock is not None:
|
|
556
|
+
patch_op["enableAutomaticLock"] = enable_automatic_lock
|
|
557
|
+
if automatic_lock_minutes is not None:
|
|
558
|
+
patch_op["automaticLockMinutes"] = automatic_lock_minutes
|
|
559
|
+
if allow_first_user_to_be_co_host is not None:
|
|
560
|
+
patch_op["allowFirstUserToBeCoHost"] = allow_first_user_to_be_co_host
|
|
561
|
+
if allow_authenticated_devices is not None:
|
|
562
|
+
patch_op["allowAuthenticatedDevices"] = allow_authenticated_devices
|
|
563
|
+
if send_email is not None:
|
|
564
|
+
patch_op["sendEmail"] = send_email
|
|
565
|
+
if host_email is not None:
|
|
566
|
+
patch_op["hostEmail"] = host_email
|
|
567
|
+
if enabled_breakout_sessions is not None:
|
|
568
|
+
patch_op["enabledBreakoutSessions"] = enabled_breakout_sessions
|
|
569
|
+
if enabled_audio_watermark is not None:
|
|
570
|
+
patch_op["enabledAudioWatermark"] = enabled_audio_watermark
|
|
571
|
+
if enabled_visual_watermark is not None:
|
|
572
|
+
patch_op["enabledVisualWatermark"] = enabled_visual_watermark
|
|
573
|
+
if visual_watermark_opacity is not None:
|
|
574
|
+
patch_op["visualWatermarkOpacity"] = visual_watermark_opacity
|
|
575
|
+
if require_attendee_login is not None:
|
|
576
|
+
patch_op["requireAttendeeLogin"] = require_attendee_login
|
|
577
|
+
if restrict_to_invitees is not None:
|
|
578
|
+
patch_op["restrictToInvitees"] = restrict_to_invitees
|
|
579
|
+
if enabled_live_stream is not None:
|
|
580
|
+
patch_op["enabledLiveStream"] = enabled_live_stream
|
|
581
|
+
if value is not None:
|
|
582
|
+
try:
|
|
583
|
+
patch_op["value"] = json.loads(value)
|
|
584
|
+
except json.JSONDecodeError:
|
|
585
|
+
patch_op["value"] = value
|
|
586
|
+
body = [patch_op]
|
|
587
|
+
try:
|
|
588
|
+
result = api.session.rest_patch(url, json=body, content_type="application/json-patch+json")
|
|
589
|
+
except WebexError as e:
|
|
590
|
+
handle_rest_error(e)
|
|
591
|
+
typer.echo(f"Updated.")
|
|
592
|
+
|
|
593
|
+
|
|
594
|
+
|
|
595
|
+
@app.command("delete")
|
|
596
|
+
def delete(
|
|
597
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
598
|
+
host_email: str = typer.Option(None, "--host-email", help="Email address for the meeting host. This parameter is only u"),
|
|
599
|
+
send_email: str = typer.Option(None, "--send-email", help="Whether or not to send emails to host and invitees. It is an"),
|
|
600
|
+
force: bool = typer.Option(False, "--force", help="Skip confirmation"),
|
|
601
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
602
|
+
):
|
|
603
|
+
"""Delete a Meeting."""
|
|
604
|
+
if not force:
|
|
605
|
+
typer.confirm(f"Delete {meeting_id}?", abort=True)
|
|
606
|
+
api = get_api(debug=debug)
|
|
607
|
+
url = f"https://webexapis.com/v1/meetings/{meeting_id}"
|
|
608
|
+
params = {}
|
|
609
|
+
if host_email is not None:
|
|
610
|
+
params["hostEmail"] = host_email
|
|
611
|
+
if send_email is not None:
|
|
612
|
+
params["sendEmail"] = send_email
|
|
613
|
+
try:
|
|
614
|
+
api.session.rest_delete(url, params=params)
|
|
615
|
+
except WebexError as e:
|
|
616
|
+
handle_rest_error(e)
|
|
617
|
+
typer.echo(f"Deleted: {meeting_id}")
|
|
618
|
+
|
|
619
|
+
|
|
620
|
+
|
|
621
|
+
@app.command("create-join")
|
|
622
|
+
def create_join(
|
|
623
|
+
meeting_id: str = typer.Option(None, "--meeting-id", help="Unique identifier for the meeting. This parameter applies to"),
|
|
624
|
+
meeting_number: str = typer.Option(None, "--meeting-number", help="Meeting number. Applies to meeting series, scheduled meeting"),
|
|
625
|
+
web_link: str = typer.Option(None, "--web-link", help="Link to a meeting information page where the meeting client"),
|
|
626
|
+
join_directly: bool = typer.Option(None, "--join-directly/--no-join-directly", help="Whether or not to redirect to `joinLink`. It is an optional"),
|
|
627
|
+
email: str = typer.Option(None, "--email", help="Email address of meeting participant. If `email` is specifie"),
|
|
628
|
+
display_name: str = typer.Option(None, "--display-name", help="Display name of meeting participant. If `displayName` is spe"),
|
|
629
|
+
password: str = typer.Option(None, "--password", help="Required when the meeting is protected by a password and the"),
|
|
630
|
+
expiration_minutes: str = typer.Option(None, "--expiration-minutes", help="Expiration duration of `joinLink` in minutes. Must be betwee"),
|
|
631
|
+
registration_id: str = typer.Option(None, "--registration-id", help="Required when the meeting is webinar-enabled and enabled reg"),
|
|
632
|
+
host_email: str = typer.Option(None, "--host-email", help="Email address for the meeting host. This attribute should be"),
|
|
633
|
+
create_join_link_as_web_link: bool = typer.Option(None, "--create-join-link-as-web-link/--no-create-join-link-as-web-link", help="When `createJoinLinkAsWebLink` is true, the returned `joinLi"),
|
|
634
|
+
create_start_link_as_web_link: bool = typer.Option(None, "--create-start-link-as-web-link/--no-create-start-link-as-web-link", help="When `createStartLinkAsWebLink` is true, the returned `start"),
|
|
635
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
636
|
+
output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
|
|
637
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
638
|
+
):
|
|
639
|
+
"""Join a Meeting."""
|
|
640
|
+
api = get_api(debug=debug)
|
|
641
|
+
url = f"https://webexapis.com/v1/meetings/join"
|
|
642
|
+
if json_body:
|
|
643
|
+
body = json.loads(json_body)
|
|
644
|
+
else:
|
|
645
|
+
body = {}
|
|
646
|
+
if meeting_id is not None:
|
|
647
|
+
body["meetingId"] = meeting_id
|
|
648
|
+
if meeting_number is not None:
|
|
649
|
+
body["meetingNumber"] = meeting_number
|
|
650
|
+
if web_link is not None:
|
|
651
|
+
body["webLink"] = web_link
|
|
652
|
+
if join_directly is not None:
|
|
653
|
+
body["joinDirectly"] = join_directly
|
|
654
|
+
if email is not None:
|
|
655
|
+
body["email"] = email
|
|
656
|
+
if display_name is not None:
|
|
657
|
+
body["displayName"] = display_name
|
|
658
|
+
if password is not None:
|
|
659
|
+
body["password"] = password
|
|
660
|
+
if expiration_minutes is not None:
|
|
661
|
+
body["expirationMinutes"] = expiration_minutes
|
|
662
|
+
if registration_id is not None:
|
|
663
|
+
body["registrationId"] = registration_id
|
|
664
|
+
if host_email is not None:
|
|
665
|
+
body["hostEmail"] = host_email
|
|
666
|
+
if create_join_link_as_web_link is not None:
|
|
667
|
+
body["createJoinLinkAsWebLink"] = create_join_link_as_web_link
|
|
668
|
+
if create_start_link_as_web_link is not None:
|
|
669
|
+
body["createStartLinkAsWebLink"] = create_start_link_as_web_link
|
|
670
|
+
try:
|
|
671
|
+
result = api.session.rest_post(url, json=body)
|
|
672
|
+
except WebexError as e:
|
|
673
|
+
handle_rest_error(e)
|
|
674
|
+
if output == "json":
|
|
675
|
+
print_json(result)
|
|
676
|
+
elif isinstance(result, dict) and "id" in result:
|
|
677
|
+
typer.echo(f"Created: {result['id']}")
|
|
678
|
+
elif not result or result == {}:
|
|
679
|
+
typer.echo("Created.")
|
|
680
|
+
else:
|
|
681
|
+
print_json(result)
|
|
682
|
+
|
|
683
|
+
|
|
684
|
+
|
|
685
|
+
@app.command("list-templates")
|
|
686
|
+
def list_templates(
|
|
687
|
+
template_type: str = typer.Option(None, "--template-type", help="Choices: meeting, webinar"),
|
|
688
|
+
locale: str = typer.Option(None, "--locale", help="Locale for the meeting template objects being requested. If"),
|
|
689
|
+
is_default: str = typer.Option(None, "--is-default", help="The value is `true` or `false`. If it's `true`, return the d"),
|
|
690
|
+
is_standard: str = typer.Option(None, "--is-standard", help="The value is `true` or `false`. If it's `true`, return the s"),
|
|
691
|
+
host_email: str = typer.Option(None, "--host-email", help="Email address for the meeting host. This parameter is only u"),
|
|
692
|
+
site_url: str = typer.Option(None, "--site-url", help="URL of the Webex site which the API lists meeting templates"),
|
|
693
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
694
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
695
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
696
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
697
|
+
):
|
|
698
|
+
"""List Meeting Templates."""
|
|
699
|
+
api = get_api(debug=debug)
|
|
700
|
+
url = f"https://webexapis.com/v1/meetings/templates"
|
|
701
|
+
params = {}
|
|
702
|
+
if template_type is not None:
|
|
703
|
+
params["templateType"] = template_type
|
|
704
|
+
if locale is not None:
|
|
705
|
+
params["locale"] = locale
|
|
706
|
+
if is_default is not None:
|
|
707
|
+
params["isDefault"] = is_default
|
|
708
|
+
if is_standard is not None:
|
|
709
|
+
params["isStandard"] = is_standard
|
|
710
|
+
if host_email is not None:
|
|
711
|
+
params["hostEmail"] = host_email
|
|
712
|
+
if site_url is not None:
|
|
713
|
+
params["siteUrl"] = site_url
|
|
714
|
+
if limit > 0:
|
|
715
|
+
params["max"] = limit
|
|
716
|
+
if offset > 0:
|
|
717
|
+
params["start"] = offset
|
|
718
|
+
result = None
|
|
719
|
+
try:
|
|
720
|
+
result = api.session.rest_get(url, params=params)
|
|
721
|
+
except WebexError as e:
|
|
722
|
+
handle_rest_error(e)
|
|
723
|
+
result = result or []
|
|
724
|
+
items = result.get("items", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
725
|
+
if output == "json":
|
|
726
|
+
print_json(items)
|
|
727
|
+
else:
|
|
728
|
+
print_table(items, columns=[('ID', 'id'), ('Title', 'title'), ('Start', 'start'), ('End', 'end'), ('State', 'state')], limit=limit)
|
|
729
|
+
|
|
730
|
+
|
|
731
|
+
|
|
732
|
+
@app.command("show-templates")
|
|
733
|
+
def show_templates(
|
|
734
|
+
template_id: str = typer.Argument(help="templateId"),
|
|
735
|
+
host_email: str = typer.Option(None, "--host-email", help="Email address for the meeting host. This parameter is only u"),
|
|
736
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
737
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
738
|
+
):
|
|
739
|
+
"""Get a Meeting Template."""
|
|
740
|
+
api = get_api(debug=debug)
|
|
741
|
+
url = f"https://webexapis.com/v1/meetings/templates/{template_id}"
|
|
742
|
+
params = {}
|
|
743
|
+
if host_email is not None:
|
|
744
|
+
params["hostEmail"] = host_email
|
|
745
|
+
try:
|
|
746
|
+
result = api.session.rest_get(url, params=params)
|
|
747
|
+
except WebexError as e:
|
|
748
|
+
handle_rest_error(e)
|
|
749
|
+
if output == "json":
|
|
750
|
+
print_json(result)
|
|
751
|
+
else:
|
|
752
|
+
if isinstance(result, dict):
|
|
753
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
754
|
+
elif isinstance(result, list):
|
|
755
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
756
|
+
else:
|
|
757
|
+
print_json(result)
|
|
758
|
+
|
|
759
|
+
|
|
760
|
+
|
|
761
|
+
@app.command("show-controls")
|
|
762
|
+
def show_controls(
|
|
763
|
+
meeting_id: str = typer.Option(..., "--meeting-id", help="Unique identifier for the meeting. Does not support meeting"),
|
|
764
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
765
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
766
|
+
):
|
|
767
|
+
"""Get Meeting Control Status."""
|
|
768
|
+
api = get_api(debug=debug)
|
|
769
|
+
url = f"https://webexapis.com/v1/meetings/controls"
|
|
770
|
+
params = {}
|
|
771
|
+
if meeting_id is not None:
|
|
772
|
+
params["meetingId"] = meeting_id
|
|
773
|
+
try:
|
|
774
|
+
result = api.session.rest_get(url, params=params)
|
|
775
|
+
except WebexError as e:
|
|
776
|
+
handle_rest_error(e)
|
|
777
|
+
if output == "json":
|
|
778
|
+
print_json(result)
|
|
779
|
+
else:
|
|
780
|
+
if isinstance(result, dict):
|
|
781
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
782
|
+
elif isinstance(result, list):
|
|
783
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
784
|
+
else:
|
|
785
|
+
print_json(result)
|
|
786
|
+
|
|
787
|
+
|
|
788
|
+
|
|
789
|
+
@app.command("update-controls")
|
|
790
|
+
def update_controls(
|
|
791
|
+
meeting_id: str = typer.Option(..., "--meeting-id", help="Unique identifier for the meeting. Does not support meeting"),
|
|
792
|
+
recording_started: bool = typer.Option(None, "--recording-started/--no-recording-started", help="The value can be true or false. true means to start the reco"),
|
|
793
|
+
recording_paused: bool = typer.Option(None, "--recording-paused/--no-recording-paused", help="The value can be true or false, will be ignored if 'recordin"),
|
|
794
|
+
locked: bool = typer.Option(None, "--locked/--no-locked", help="The value is true or false."),
|
|
795
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
796
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
797
|
+
):
|
|
798
|
+
"""Update Meeting Control Status."""
|
|
799
|
+
api = get_api(debug=debug)
|
|
800
|
+
url = f"https://webexapis.com/v1/meetings/controls"
|
|
801
|
+
params = {}
|
|
802
|
+
if meeting_id is not None:
|
|
803
|
+
params["meetingId"] = meeting_id
|
|
804
|
+
if json_body:
|
|
805
|
+
body = json.loads(json_body)
|
|
806
|
+
else:
|
|
807
|
+
body = {}
|
|
808
|
+
if recording_started is not None:
|
|
809
|
+
body["recordingStarted"] = recording_started
|
|
810
|
+
if recording_paused is not None:
|
|
811
|
+
body["recordingPaused"] = recording_paused
|
|
812
|
+
if locked is not None:
|
|
813
|
+
body["locked"] = locked
|
|
814
|
+
try:
|
|
815
|
+
result = api.session.rest_put(url, json=body, params=params)
|
|
816
|
+
except WebexError as e:
|
|
817
|
+
handle_rest_error(e)
|
|
818
|
+
typer.echo(f"Updated.")
|
|
819
|
+
|
|
820
|
+
|
|
821
|
+
|
|
822
|
+
@app.command("list-session-types")
|
|
823
|
+
def list_session_types(
|
|
824
|
+
host_email: str = typer.Option(None, "--host-email", help="Email address for the user. This parameter is only used if t"),
|
|
825
|
+
site_url: str = typer.Option(None, "--site-url", help="Webex site URL to query. If `siteUrl` is not specified, the"),
|
|
826
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
827
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
828
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
829
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
830
|
+
):
|
|
831
|
+
"""List Meeting Session Types."""
|
|
832
|
+
api = get_api(debug=debug)
|
|
833
|
+
url = f"https://webexapis.com/v1/meetings/sessionTypes"
|
|
834
|
+
params = {}
|
|
835
|
+
if host_email is not None:
|
|
836
|
+
params["hostEmail"] = host_email
|
|
837
|
+
if site_url is not None:
|
|
838
|
+
params["siteUrl"] = site_url
|
|
839
|
+
if limit > 0:
|
|
840
|
+
params["max"] = limit
|
|
841
|
+
if offset > 0:
|
|
842
|
+
params["start"] = offset
|
|
843
|
+
result = None
|
|
844
|
+
try:
|
|
845
|
+
result = api.session.rest_get(url, params=params)
|
|
846
|
+
except WebexError as e:
|
|
847
|
+
handle_rest_error(e)
|
|
848
|
+
result = result or []
|
|
849
|
+
items = result.get("items", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
850
|
+
if output == "json":
|
|
851
|
+
print_json(items)
|
|
852
|
+
else:
|
|
853
|
+
print_table(items, columns=[('ID', 'id'), ('Title', 'title'), ('Start', 'start'), ('End', 'end'), ('State', 'state')], limit=limit)
|
|
854
|
+
|
|
855
|
+
|
|
856
|
+
|
|
857
|
+
@app.command("show-session-types")
|
|
858
|
+
def show_session_types(
|
|
859
|
+
session_type_id: str = typer.Argument(help="sessionTypeId"),
|
|
860
|
+
host_email: str = typer.Option(None, "--host-email", help="Email address for the user. This parameter is only used if t"),
|
|
861
|
+
site_url: str = typer.Option(None, "--site-url", help="Webex site URL to query. If `siteUrl` is not specified, the"),
|
|
862
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
863
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
864
|
+
):
|
|
865
|
+
"""Get a Meeting Session Type."""
|
|
866
|
+
api = get_api(debug=debug)
|
|
867
|
+
url = f"https://webexapis.com/v1/meetings/sessionTypes/{session_type_id}"
|
|
868
|
+
params = {}
|
|
869
|
+
if host_email is not None:
|
|
870
|
+
params["hostEmail"] = host_email
|
|
871
|
+
if site_url is not None:
|
|
872
|
+
params["siteUrl"] = site_url
|
|
873
|
+
try:
|
|
874
|
+
result = api.session.rest_get(url, params=params)
|
|
875
|
+
except WebexError as e:
|
|
876
|
+
handle_rest_error(e)
|
|
877
|
+
if output == "json":
|
|
878
|
+
print_json(result)
|
|
879
|
+
else:
|
|
880
|
+
if isinstance(result, dict):
|
|
881
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
882
|
+
elif isinstance(result, list):
|
|
883
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
884
|
+
else:
|
|
885
|
+
print_json(result)
|
|
886
|
+
|
|
887
|
+
|
|
888
|
+
|
|
889
|
+
@app.command("list-registration")
|
|
890
|
+
def list_registration(
|
|
891
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
892
|
+
current: str = typer.Option(None, "--current", help="Whether or not to retrieve only the current scheduled meetin"),
|
|
893
|
+
host_email: str = typer.Option(None, "--host-email", help="Email address for the meeting host. This parameter is only u"),
|
|
894
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
895
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
896
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
897
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
898
|
+
):
|
|
899
|
+
"""Get registration form for a meeting."""
|
|
900
|
+
api = get_api(debug=debug)
|
|
901
|
+
url = f"https://webexapis.com/v1/meetings/{meeting_id}/registration"
|
|
902
|
+
params = {}
|
|
903
|
+
if current is not None:
|
|
904
|
+
params["current"] = current
|
|
905
|
+
if host_email is not None:
|
|
906
|
+
params["hostEmail"] = host_email
|
|
907
|
+
if limit > 0:
|
|
908
|
+
params["max"] = limit
|
|
909
|
+
if offset > 0:
|
|
910
|
+
params["start"] = offset
|
|
911
|
+
result = None
|
|
912
|
+
try:
|
|
913
|
+
result = api.session.rest_get(url, params=params)
|
|
914
|
+
except WebexError as e:
|
|
915
|
+
handle_rest_error(e)
|
|
916
|
+
result = result or []
|
|
917
|
+
items = result.get("customizedQuestions", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
918
|
+
if output == "json":
|
|
919
|
+
print_json(items)
|
|
920
|
+
else:
|
|
921
|
+
print_table(items, columns=[('ID', 'id'), ('Title', 'title'), ('Start', 'start'), ('End', 'end'), ('State', 'state')], limit=limit)
|
|
922
|
+
|
|
923
|
+
|
|
924
|
+
|
|
925
|
+
@app.command("update-registration")
|
|
926
|
+
def update_registration(
|
|
927
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
928
|
+
host_email: str = typer.Option(None, "--host-email", help="- Email address for the meeting host. This parameter is only"),
|
|
929
|
+
auto_accept_request: bool = typer.Option(None, "--auto-accept-request/--no-auto-accept-request", help="Whether or not meeting registration requests are accepted au"),
|
|
930
|
+
require_first_name: bool = typer.Option(None, "--require-first-name/--no-require-first-name", help="Whether or not a registrant's first name is required for mee"),
|
|
931
|
+
require_last_name: bool = typer.Option(None, "--require-last-name/--no-require-last-name", help="Whether or not a registrant's last name is required for meet"),
|
|
932
|
+
require_email: bool = typer.Option(None, "--require-email/--no-require-email", help="Whether or not a registrant's email is required for meeting"),
|
|
933
|
+
require_job_title: bool = typer.Option(None, "--require-job-title/--no-require-job-title", help="Whether or not a registrant's job title is shown or required"),
|
|
934
|
+
require_company_name: bool = typer.Option(None, "--require-company-name/--no-require-company-name", help="Whether or not a registrant's company name is shown or requi"),
|
|
935
|
+
require_address1: bool = typer.Option(None, "--require-address1/--no-require-address1", help="Whether or not a registrant's first address field is shown o"),
|
|
936
|
+
require_address2: bool = typer.Option(None, "--require-address2/--no-require-address2", help="Whether or not a registrant's second address field is shown"),
|
|
937
|
+
require_city: bool = typer.Option(None, "--require-city/--no-require-city", help="Whether or not a registrant's city is shown or required for"),
|
|
938
|
+
require_state: bool = typer.Option(None, "--require-state/--no-require-state", help="Whether or not a registrant's state is shown or required for"),
|
|
939
|
+
require_zip_code: bool = typer.Option(None, "--require-zip-code/--no-require-zip-code", help="Whether or not a registrant's postal code is shown or requir"),
|
|
940
|
+
require_country_region: bool = typer.Option(None, "--require-country-region/--no-require-country-region", help="Whether or not a registrant's country or region is shown or"),
|
|
941
|
+
require_work_phone: bool = typer.Option(None, "--require-work-phone/--no-require-work-phone", help="Whether or not a registrant's work phone number is shown or"),
|
|
942
|
+
require_fax: bool = typer.Option(None, "--require-fax/--no-require-fax", help="Whether or not a registrant's fax number is shown or require"),
|
|
943
|
+
max_register_num: str = typer.Option(None, "--max-register-num", help="Maximum number of meeting registrations. This only applies t"),
|
|
944
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
945
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
946
|
+
):
|
|
947
|
+
"""Update Meeting Registration Form\n\nExample --json-body:\n '{"hostEmail":"...","autoAcceptRequest":true,"requireFirstName":true,"requireLastName":true,"requireEmail":true,"requireJobTitle":true,"requireCompanyName":true,"requireAddress1":true}'."""
|
|
948
|
+
api = get_api(debug=debug)
|
|
949
|
+
url = f"https://webexapis.com/v1/meetings/{meeting_id}/registration"
|
|
950
|
+
if json_body:
|
|
951
|
+
body = json.loads(json_body)
|
|
952
|
+
else:
|
|
953
|
+
body = {}
|
|
954
|
+
if host_email is not None:
|
|
955
|
+
body["hostEmail"] = host_email
|
|
956
|
+
if auto_accept_request is not None:
|
|
957
|
+
body["autoAcceptRequest"] = auto_accept_request
|
|
958
|
+
if require_first_name is not None:
|
|
959
|
+
body["requireFirstName"] = require_first_name
|
|
960
|
+
if require_last_name is not None:
|
|
961
|
+
body["requireLastName"] = require_last_name
|
|
962
|
+
if require_email is not None:
|
|
963
|
+
body["requireEmail"] = require_email
|
|
964
|
+
if require_job_title is not None:
|
|
965
|
+
body["requireJobTitle"] = require_job_title
|
|
966
|
+
if require_company_name is not None:
|
|
967
|
+
body["requireCompanyName"] = require_company_name
|
|
968
|
+
if require_address1 is not None:
|
|
969
|
+
body["requireAddress1"] = require_address1
|
|
970
|
+
if require_address2 is not None:
|
|
971
|
+
body["requireAddress2"] = require_address2
|
|
972
|
+
if require_city is not None:
|
|
973
|
+
body["requireCity"] = require_city
|
|
974
|
+
if require_state is not None:
|
|
975
|
+
body["requireState"] = require_state
|
|
976
|
+
if require_zip_code is not None:
|
|
977
|
+
body["requireZipCode"] = require_zip_code
|
|
978
|
+
if require_country_region is not None:
|
|
979
|
+
body["requireCountryRegion"] = require_country_region
|
|
980
|
+
if require_work_phone is not None:
|
|
981
|
+
body["requireWorkPhone"] = require_work_phone
|
|
982
|
+
if require_fax is not None:
|
|
983
|
+
body["requireFax"] = require_fax
|
|
984
|
+
if max_register_num is not None:
|
|
985
|
+
body["maxRegisterNum"] = max_register_num
|
|
986
|
+
try:
|
|
987
|
+
result = api.session.rest_put(url, json=body)
|
|
988
|
+
except WebexError as e:
|
|
989
|
+
handle_rest_error(e)
|
|
990
|
+
typer.echo(f"Updated.")
|
|
991
|
+
|
|
992
|
+
|
|
993
|
+
|
|
994
|
+
@app.command("delete-registration")
|
|
995
|
+
def delete_registration(
|
|
996
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
997
|
+
force: bool = typer.Option(False, "--force", help="Skip confirmation"),
|
|
998
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
999
|
+
):
|
|
1000
|
+
"""Delete Meeting Registration Form."""
|
|
1001
|
+
if not force:
|
|
1002
|
+
typer.confirm(f"Delete {meeting_id}?", abort=True)
|
|
1003
|
+
api = get_api(debug=debug)
|
|
1004
|
+
url = f"https://webexapis.com/v1/meetings/{meeting_id}/registration"
|
|
1005
|
+
try:
|
|
1006
|
+
api.session.rest_delete(url)
|
|
1007
|
+
except WebexError as e:
|
|
1008
|
+
handle_rest_error(e)
|
|
1009
|
+
typer.echo(f"Deleted: {meeting_id}")
|
|
1010
|
+
|
|
1011
|
+
|
|
1012
|
+
|
|
1013
|
+
@app.command("list-registrants")
|
|
1014
|
+
def list_registrants(
|
|
1015
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
1016
|
+
host_email: str = typer.Option(None, "--host-email", help="Email address for the meeting host. This parameter is only u"),
|
|
1017
|
+
current: str = typer.Option(None, "--current", help="Whether or not to retrieve only the current scheduled meetin"),
|
|
1018
|
+
email: str = typer.Option(None, "--email", help="Registrant's email to filter registrants."),
|
|
1019
|
+
registration_time_from: str = typer.Option(None, "--registration-time-from", help="The time registrants register a meeting starts from the spec"),
|
|
1020
|
+
registration_time_to: str = typer.Option(None, "--registration-time-to", help="The time registrants register a meeting before the specified"),
|
|
1021
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
1022
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
1023
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
1024
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1025
|
+
):
|
|
1026
|
+
"""List Meeting Registrants."""
|
|
1027
|
+
api = get_api(debug=debug)
|
|
1028
|
+
url = f"https://webexapis.com/v1/meetings/{meeting_id}/registrants"
|
|
1029
|
+
params = {}
|
|
1030
|
+
if host_email is not None:
|
|
1031
|
+
params["hostEmail"] = host_email
|
|
1032
|
+
if current is not None:
|
|
1033
|
+
params["current"] = current
|
|
1034
|
+
if email is not None:
|
|
1035
|
+
params["email"] = email
|
|
1036
|
+
if registration_time_from is not None:
|
|
1037
|
+
params["registrationTimeFrom"] = registration_time_from
|
|
1038
|
+
if registration_time_to is not None:
|
|
1039
|
+
params["registrationTimeTo"] = registration_time_to
|
|
1040
|
+
if limit > 0:
|
|
1041
|
+
params["max"] = limit
|
|
1042
|
+
if offset > 0:
|
|
1043
|
+
params["start"] = offset
|
|
1044
|
+
result = None
|
|
1045
|
+
try:
|
|
1046
|
+
result = api.session.rest_get(url, params=params)
|
|
1047
|
+
except WebexError as e:
|
|
1048
|
+
handle_rest_error(e)
|
|
1049
|
+
result = result or []
|
|
1050
|
+
items = result.get("items", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
1051
|
+
if output == "json":
|
|
1052
|
+
print_json(items)
|
|
1053
|
+
else:
|
|
1054
|
+
print_table(items, columns=[('ID', 'id'), ('Title', 'title'), ('Start', 'start'), ('End', 'end'), ('State', 'state')], limit=limit)
|
|
1055
|
+
|
|
1056
|
+
|
|
1057
|
+
|
|
1058
|
+
@app.command("create-registrants")
|
|
1059
|
+
def create_registrants(
|
|
1060
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
1061
|
+
current: str = typer.Option(None, "--current", help="Whether or not to retrieve only the current scheduled meetin"),
|
|
1062
|
+
host_email: str = typer.Option(None, "--host-email", help="Email address for the meeting host. This parameter is only u"),
|
|
1063
|
+
first_name: str = typer.Option(None, "--first-name", help="(required) The registrant's first name."),
|
|
1064
|
+
last_name: str = typer.Option(None, "--last-name", help="(required) The registrant's last name. (Required)"),
|
|
1065
|
+
email: str = typer.Option(None, "--email", help="(required) The registrant's email."),
|
|
1066
|
+
send_email: bool = typer.Option(None, "--send-email/--no-send-email", help="If `true` send email to the registrant. Default: `true`."),
|
|
1067
|
+
job_title: str = typer.Option(None, "--job-title", help="The registrant's job title. Registration options define whet"),
|
|
1068
|
+
company_name: str = typer.Option(None, "--company-name", help="The registrant's company. Registration options define whethe"),
|
|
1069
|
+
address1: str = typer.Option(None, "--address1", help="The registrant's first address line. Registration options de"),
|
|
1070
|
+
address2: str = typer.Option(None, "--address2", help="The registrant's second address line. Registration options d"),
|
|
1071
|
+
city: str = typer.Option(None, "--city", help="The registrant's city name. Registration options define whet"),
|
|
1072
|
+
state: str = typer.Option(None, "--state", help="The registrant's state. Registration options define whether"),
|
|
1073
|
+
zip_code: str = typer.Option(None, "--zip-code", help="The registrant's postal code. Registration options define wh"),
|
|
1074
|
+
country_region: str = typer.Option(None, "--country-region", help="The America is not a country or a specific region. Registrat"),
|
|
1075
|
+
work_phone: str = typer.Option(None, "--work-phone", help="The registrant's work phone number. Registration options def"),
|
|
1076
|
+
fax: str = typer.Option(None, "--fax", help="The registrant's FAX number. Registration options define whe"),
|
|
1077
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
1078
|
+
output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
|
|
1079
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1080
|
+
):
|
|
1081
|
+
"""Register a Meeting Registrant\n\nExample --json-body:\n '{"firstName":"...","lastName":"...","email":"...","sendEmail":true,"jobTitle":"...","companyName":"...","address1":"...","address2":"..."}'."""
|
|
1082
|
+
api = get_api(debug=debug)
|
|
1083
|
+
url = f"https://webexapis.com/v1/meetings/{meeting_id}/registrants"
|
|
1084
|
+
params = {}
|
|
1085
|
+
if current is not None:
|
|
1086
|
+
params["current"] = current
|
|
1087
|
+
if host_email is not None:
|
|
1088
|
+
params["hostEmail"] = host_email
|
|
1089
|
+
if json_body:
|
|
1090
|
+
body = json.loads(json_body)
|
|
1091
|
+
else:
|
|
1092
|
+
body = {}
|
|
1093
|
+
if first_name is not None:
|
|
1094
|
+
body["firstName"] = first_name
|
|
1095
|
+
if last_name is not None:
|
|
1096
|
+
body["lastName"] = last_name
|
|
1097
|
+
if email is not None:
|
|
1098
|
+
body["email"] = email
|
|
1099
|
+
if send_email is not None:
|
|
1100
|
+
body["sendEmail"] = send_email
|
|
1101
|
+
if job_title is not None:
|
|
1102
|
+
body["jobTitle"] = job_title
|
|
1103
|
+
if company_name is not None:
|
|
1104
|
+
body["companyName"] = company_name
|
|
1105
|
+
if address1 is not None:
|
|
1106
|
+
body["address1"] = address1
|
|
1107
|
+
if address2 is not None:
|
|
1108
|
+
body["address2"] = address2
|
|
1109
|
+
if city is not None:
|
|
1110
|
+
body["city"] = city
|
|
1111
|
+
if state is not None:
|
|
1112
|
+
body["state"] = state
|
|
1113
|
+
if zip_code is not None:
|
|
1114
|
+
body["zipCode"] = zip_code
|
|
1115
|
+
if country_region is not None:
|
|
1116
|
+
body["countryRegion"] = country_region
|
|
1117
|
+
if work_phone is not None:
|
|
1118
|
+
body["workPhone"] = work_phone
|
|
1119
|
+
if fax is not None:
|
|
1120
|
+
body["fax"] = fax
|
|
1121
|
+
_missing = [f for f in ['firstName', 'lastName', 'email'] if f not in body or body[f] is None]
|
|
1122
|
+
if _missing:
|
|
1123
|
+
typer.echo("Error: Missing required fields: " + ", ".join(_missing), err=True)
|
|
1124
|
+
raise typer.Exit(1)
|
|
1125
|
+
try:
|
|
1126
|
+
result = api.session.rest_post(url, json=body, params=params)
|
|
1127
|
+
except WebexError as e:
|
|
1128
|
+
handle_rest_error(e)
|
|
1129
|
+
if output == "json":
|
|
1130
|
+
print_json(result)
|
|
1131
|
+
elif isinstance(result, dict) and "id" in result:
|
|
1132
|
+
typer.echo(f"Created: {result['id']}")
|
|
1133
|
+
elif not result or result == {}:
|
|
1134
|
+
typer.echo("Created.")
|
|
1135
|
+
else:
|
|
1136
|
+
print_json(result)
|
|
1137
|
+
|
|
1138
|
+
|
|
1139
|
+
|
|
1140
|
+
@app.command("create-bulk-insert")
|
|
1141
|
+
def create_bulk_insert(
|
|
1142
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
1143
|
+
current: str = typer.Option(None, "--current", help="Whether or not to retrieve only the current scheduled meetin"),
|
|
1144
|
+
host_email: str = typer.Option(None, "--host-email", help="Email address for the meeting host. This parameter is only u"),
|
|
1145
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
1146
|
+
output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
|
|
1147
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1148
|
+
):
|
|
1149
|
+
"""Batch register Meeting Registrants\n\nExample --json-body:\n '{"items":[{"firstName":"...","lastName":"...","email":"...","sendEmail":"...","jobTitle":"...","companyName":"...","address1":"...","address2":"..."}]}'."""
|
|
1150
|
+
api = get_api(debug=debug)
|
|
1151
|
+
url = f"https://webexapis.com/v1/meetings/{meeting_id}/registrants/bulkInsert"
|
|
1152
|
+
params = {}
|
|
1153
|
+
if current is not None:
|
|
1154
|
+
params["current"] = current
|
|
1155
|
+
if host_email is not None:
|
|
1156
|
+
params["hostEmail"] = host_email
|
|
1157
|
+
if json_body:
|
|
1158
|
+
body = json.loads(json_body)
|
|
1159
|
+
else:
|
|
1160
|
+
body = {}
|
|
1161
|
+
try:
|
|
1162
|
+
result = api.session.rest_post(url, json=body, params=params)
|
|
1163
|
+
except WebexError as e:
|
|
1164
|
+
handle_rest_error(e)
|
|
1165
|
+
if output == "json":
|
|
1166
|
+
print_json(result)
|
|
1167
|
+
elif isinstance(result, dict) and "id" in result:
|
|
1168
|
+
typer.echo(f"Created: {result['id']}")
|
|
1169
|
+
elif not result or result == {}:
|
|
1170
|
+
typer.echo("Created.")
|
|
1171
|
+
else:
|
|
1172
|
+
print_json(result)
|
|
1173
|
+
|
|
1174
|
+
|
|
1175
|
+
|
|
1176
|
+
@app.command("show-registrants")
|
|
1177
|
+
def show_registrants(
|
|
1178
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
1179
|
+
registrant_id: str = typer.Argument(help="registrantId"),
|
|
1180
|
+
current: str = typer.Option(None, "--current", help="Whether or not to retrieve only the current scheduled meetin"),
|
|
1181
|
+
host_email: str = typer.Option(None, "--host-email", help="Email address for the meeting host. This parameter is only u"),
|
|
1182
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
1183
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1184
|
+
):
|
|
1185
|
+
"""Get Detailed Information for a Meeting Registrant."""
|
|
1186
|
+
api = get_api(debug=debug)
|
|
1187
|
+
url = f"https://webexapis.com/v1/meetings/{meeting_id}/registrants/{registrant_id}"
|
|
1188
|
+
params = {}
|
|
1189
|
+
if current is not None:
|
|
1190
|
+
params["current"] = current
|
|
1191
|
+
if host_email is not None:
|
|
1192
|
+
params["hostEmail"] = host_email
|
|
1193
|
+
try:
|
|
1194
|
+
result = api.session.rest_get(url, params=params)
|
|
1195
|
+
except WebexError as e:
|
|
1196
|
+
handle_rest_error(e)
|
|
1197
|
+
if output == "json":
|
|
1198
|
+
print_json(result)
|
|
1199
|
+
else:
|
|
1200
|
+
if isinstance(result, dict):
|
|
1201
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
1202
|
+
elif isinstance(result, list):
|
|
1203
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
1204
|
+
else:
|
|
1205
|
+
print_json(result)
|
|
1206
|
+
|
|
1207
|
+
|
|
1208
|
+
|
|
1209
|
+
@app.command("delete-registrants")
|
|
1210
|
+
def delete_registrants(
|
|
1211
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
1212
|
+
registrant_id: str = typer.Argument(help="registrantId"),
|
|
1213
|
+
current: str = typer.Option(None, "--current", help="Whether or not to retrieve only the current scheduled meetin"),
|
|
1214
|
+
host_email: str = typer.Option(None, "--host-email", help="Email address for the meeting host. This parameter is only u"),
|
|
1215
|
+
force: bool = typer.Option(False, "--force", help="Skip confirmation"),
|
|
1216
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1217
|
+
):
|
|
1218
|
+
"""Delete a Meeting Registrant."""
|
|
1219
|
+
if not force:
|
|
1220
|
+
typer.confirm(f"Delete {registrant_id}?", abort=True)
|
|
1221
|
+
api = get_api(debug=debug)
|
|
1222
|
+
url = f"https://webexapis.com/v1/meetings/{meeting_id}/registrants/{registrant_id}"
|
|
1223
|
+
params = {}
|
|
1224
|
+
if current is not None:
|
|
1225
|
+
params["current"] = current
|
|
1226
|
+
if host_email is not None:
|
|
1227
|
+
params["hostEmail"] = host_email
|
|
1228
|
+
try:
|
|
1229
|
+
api.session.rest_delete(url, params=params)
|
|
1230
|
+
except WebexError as e:
|
|
1231
|
+
handle_rest_error(e)
|
|
1232
|
+
typer.echo(f"Deleted: {registrant_id}")
|
|
1233
|
+
|
|
1234
|
+
|
|
1235
|
+
|
|
1236
|
+
@app.command("create-query")
|
|
1237
|
+
def create_query(
|
|
1238
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
1239
|
+
max: str = typer.Option(None, "--max", help="Limit the maximum number of registrants in the response, up"),
|
|
1240
|
+
current: str = typer.Option(None, "--current", help="Whether or not to retrieve only the current scheduled meetin"),
|
|
1241
|
+
host_email: str = typer.Option(None, "--host-email", help="Email address for the meeting host. This parameter is only u"),
|
|
1242
|
+
status: str = typer.Option(None, "--status", help="Choices: approved, pending, rejected"),
|
|
1243
|
+
order_type: str = typer.Option(None, "--order-type", help="Choices: DESC, ASC"),
|
|
1244
|
+
order_by: str = typer.Option(None, "--order-by", help="Choices: firstName, lastName, status, email"),
|
|
1245
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
1246
|
+
output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
|
|
1247
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1248
|
+
):
|
|
1249
|
+
"""Query Meeting Registrants\n\nExample --json-body:\n '{"emails":["..."],"status":"approved","orderType":"DESC","orderBy":"firstName"}'."""
|
|
1250
|
+
api = get_api(debug=debug)
|
|
1251
|
+
url = f"https://webexapis.com/v1/meetings/{meeting_id}/registrants/query"
|
|
1252
|
+
params = {}
|
|
1253
|
+
if max is not None:
|
|
1254
|
+
params["max"] = max
|
|
1255
|
+
if current is not None:
|
|
1256
|
+
params["current"] = current
|
|
1257
|
+
if host_email is not None:
|
|
1258
|
+
params["hostEmail"] = host_email
|
|
1259
|
+
if json_body:
|
|
1260
|
+
body = json.loads(json_body)
|
|
1261
|
+
else:
|
|
1262
|
+
body = {}
|
|
1263
|
+
if status is not None:
|
|
1264
|
+
body["status"] = status
|
|
1265
|
+
if order_type is not None:
|
|
1266
|
+
body["orderType"] = order_type
|
|
1267
|
+
if order_by is not None:
|
|
1268
|
+
body["orderBy"] = order_by
|
|
1269
|
+
try:
|
|
1270
|
+
result = api.session.rest_post(url, json=body, params=params)
|
|
1271
|
+
except WebexError as e:
|
|
1272
|
+
handle_rest_error(e)
|
|
1273
|
+
if output == "json":
|
|
1274
|
+
print_json(result)
|
|
1275
|
+
elif isinstance(result, dict) and "id" in result:
|
|
1276
|
+
typer.echo(f"Created: {result['id']}")
|
|
1277
|
+
elif not result or result == {}:
|
|
1278
|
+
typer.echo("Created.")
|
|
1279
|
+
else:
|
|
1280
|
+
print_json(result)
|
|
1281
|
+
|
|
1282
|
+
|
|
1283
|
+
|
|
1284
|
+
@app.command("create-approve")
|
|
1285
|
+
def create_approve(
|
|
1286
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
1287
|
+
current: str = typer.Option(None, "--current", help="Whether or not to retrieve only the current scheduled meetin"),
|
|
1288
|
+
host_email: str = typer.Option(None, "--host-email", help="Email address for the meeting host. This parameter is only u"),
|
|
1289
|
+
send_email: bool = typer.Option(None, "--send-email/--no-send-email", help="If `true` send email to registrants. Default: `true`."),
|
|
1290
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
1291
|
+
output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
|
|
1292
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1293
|
+
):
|
|
1294
|
+
"""Batch Approve Meeting Registrants\n\nExample --json-body:\n '{"sendEmail":true,"registrants":[{"id":"..."}]}'."""
|
|
1295
|
+
api = get_api(debug=debug)
|
|
1296
|
+
url = f"https://webexapis.com/v1/meetings/{meeting_id}/registrants/approve"
|
|
1297
|
+
params = {}
|
|
1298
|
+
if current is not None:
|
|
1299
|
+
params["current"] = current
|
|
1300
|
+
if host_email is not None:
|
|
1301
|
+
params["hostEmail"] = host_email
|
|
1302
|
+
if json_body:
|
|
1303
|
+
body = json.loads(json_body)
|
|
1304
|
+
else:
|
|
1305
|
+
body = {}
|
|
1306
|
+
if send_email is not None:
|
|
1307
|
+
body["sendEmail"] = send_email
|
|
1308
|
+
try:
|
|
1309
|
+
result = api.session.rest_post(url, json=body, params=params)
|
|
1310
|
+
except WebexError as e:
|
|
1311
|
+
handle_rest_error(e)
|
|
1312
|
+
if output == "json":
|
|
1313
|
+
print_json(result)
|
|
1314
|
+
elif isinstance(result, dict) and "id" in result:
|
|
1315
|
+
typer.echo(f"Created: {result['id']}")
|
|
1316
|
+
elif not result or result == {}:
|
|
1317
|
+
typer.echo("Created.")
|
|
1318
|
+
else:
|
|
1319
|
+
print_json(result)
|
|
1320
|
+
|
|
1321
|
+
|
|
1322
|
+
|
|
1323
|
+
@app.command("create-reject")
|
|
1324
|
+
def create_reject(
|
|
1325
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
1326
|
+
current: str = typer.Option(None, "--current", help="Whether or not to retrieve only the current scheduled meetin"),
|
|
1327
|
+
host_email: str = typer.Option(None, "--host-email", help="Email address for the meeting host. This parameter is only u"),
|
|
1328
|
+
send_email: bool = typer.Option(None, "--send-email/--no-send-email", help="If `true` send email to registrants. Default: `true`."),
|
|
1329
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
1330
|
+
output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
|
|
1331
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1332
|
+
):
|
|
1333
|
+
"""Batch Reject Meeting Registrants\n\nExample --json-body:\n '{"sendEmail":true,"registrants":[{"id":"..."}]}'."""
|
|
1334
|
+
api = get_api(debug=debug)
|
|
1335
|
+
url = f"https://webexapis.com/v1/meetings/{meeting_id}/registrants/reject"
|
|
1336
|
+
params = {}
|
|
1337
|
+
if current is not None:
|
|
1338
|
+
params["current"] = current
|
|
1339
|
+
if host_email is not None:
|
|
1340
|
+
params["hostEmail"] = host_email
|
|
1341
|
+
if json_body:
|
|
1342
|
+
body = json.loads(json_body)
|
|
1343
|
+
else:
|
|
1344
|
+
body = {}
|
|
1345
|
+
if send_email is not None:
|
|
1346
|
+
body["sendEmail"] = send_email
|
|
1347
|
+
try:
|
|
1348
|
+
result = api.session.rest_post(url, json=body, params=params)
|
|
1349
|
+
except WebexError as e:
|
|
1350
|
+
handle_rest_error(e)
|
|
1351
|
+
if output == "json":
|
|
1352
|
+
print_json(result)
|
|
1353
|
+
elif isinstance(result, dict) and "id" in result:
|
|
1354
|
+
typer.echo(f"Created: {result['id']}")
|
|
1355
|
+
elif not result or result == {}:
|
|
1356
|
+
typer.echo("Created.")
|
|
1357
|
+
else:
|
|
1358
|
+
print_json(result)
|
|
1359
|
+
|
|
1360
|
+
|
|
1361
|
+
|
|
1362
|
+
@app.command("create-cancel")
|
|
1363
|
+
def create_cancel(
|
|
1364
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
1365
|
+
current: str = typer.Option(None, "--current", help="Whether or not to retrieve only the current scheduled meetin"),
|
|
1366
|
+
host_email: str = typer.Option(None, "--host-email", help="Email address for the meeting host. This parameter is only u"),
|
|
1367
|
+
send_email: bool = typer.Option(None, "--send-email/--no-send-email", help="If `true` send email to registrants. Default: `true`."),
|
|
1368
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
1369
|
+
output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
|
|
1370
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1371
|
+
):
|
|
1372
|
+
"""Batch Cancel Meeting Registrants\n\nExample --json-body:\n '{"sendEmail":true,"registrants":[{"id":"..."}]}'."""
|
|
1373
|
+
api = get_api(debug=debug)
|
|
1374
|
+
url = f"https://webexapis.com/v1/meetings/{meeting_id}/registrants/cancel"
|
|
1375
|
+
params = {}
|
|
1376
|
+
if current is not None:
|
|
1377
|
+
params["current"] = current
|
|
1378
|
+
if host_email is not None:
|
|
1379
|
+
params["hostEmail"] = host_email
|
|
1380
|
+
if json_body:
|
|
1381
|
+
body = json.loads(json_body)
|
|
1382
|
+
else:
|
|
1383
|
+
body = {}
|
|
1384
|
+
if send_email is not None:
|
|
1385
|
+
body["sendEmail"] = send_email
|
|
1386
|
+
try:
|
|
1387
|
+
result = api.session.rest_post(url, json=body, params=params)
|
|
1388
|
+
except WebexError as e:
|
|
1389
|
+
handle_rest_error(e)
|
|
1390
|
+
if output == "json":
|
|
1391
|
+
print_json(result)
|
|
1392
|
+
elif isinstance(result, dict) and "id" in result:
|
|
1393
|
+
typer.echo(f"Created: {result['id']}")
|
|
1394
|
+
elif not result or result == {}:
|
|
1395
|
+
typer.echo("Created.")
|
|
1396
|
+
else:
|
|
1397
|
+
print_json(result)
|
|
1398
|
+
|
|
1399
|
+
|
|
1400
|
+
|
|
1401
|
+
@app.command("create-bulk-delete")
|
|
1402
|
+
def create_bulk_delete(
|
|
1403
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
1404
|
+
current: str = typer.Option(None, "--current", help="Whether or not to retrieve only the current scheduled meetin"),
|
|
1405
|
+
host_email: str = typer.Option(None, "--host-email", help="Email address for the meeting host. This parameter is only u"),
|
|
1406
|
+
send_email: bool = typer.Option(None, "--send-email/--no-send-email", help="If `true` send email to registrants. Default: `true`."),
|
|
1407
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
1408
|
+
output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
|
|
1409
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1410
|
+
):
|
|
1411
|
+
"""Batch Delete Meeting Registrants\n\nExample --json-body:\n '{"sendEmail":true,"registrants":[{"id":"..."}]}'."""
|
|
1412
|
+
api = get_api(debug=debug)
|
|
1413
|
+
url = f"https://webexapis.com/v1/meetings/{meeting_id}/registrants/bulkDelete"
|
|
1414
|
+
params = {}
|
|
1415
|
+
if current is not None:
|
|
1416
|
+
params["current"] = current
|
|
1417
|
+
if host_email is not None:
|
|
1418
|
+
params["hostEmail"] = host_email
|
|
1419
|
+
if json_body:
|
|
1420
|
+
body = json.loads(json_body)
|
|
1421
|
+
else:
|
|
1422
|
+
body = {}
|
|
1423
|
+
if send_email is not None:
|
|
1424
|
+
body["sendEmail"] = send_email
|
|
1425
|
+
try:
|
|
1426
|
+
result = api.session.rest_post(url, json=body, params=params)
|
|
1427
|
+
except WebexError as e:
|
|
1428
|
+
handle_rest_error(e)
|
|
1429
|
+
if output == "json":
|
|
1430
|
+
print_json(result)
|
|
1431
|
+
elif isinstance(result, dict) and "id" in result:
|
|
1432
|
+
typer.echo(f"Created: {result['id']}")
|
|
1433
|
+
elif not result or result == {}:
|
|
1434
|
+
typer.echo("Created.")
|
|
1435
|
+
else:
|
|
1436
|
+
print_json(result)
|
|
1437
|
+
|
|
1438
|
+
|
|
1439
|
+
|
|
1440
|
+
@app.command("update-simultaneous-interpretation")
|
|
1441
|
+
def update_simultaneous_interpretation(
|
|
1442
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
1443
|
+
enabled: bool = typer.Option(None, "--enabled/--no-enabled", help="Whether or not simultaneous interpretation is enabled."),
|
|
1444
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
1445
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1446
|
+
):
|
|
1447
|
+
"""Update Meeting Simultaneous interpretation\n\nExample --json-body:\n '{"enabled":true,"interpreters":[{"languageCode1":"...","languageCode2":"...","email":"...","displayName":"..."}]}'."""
|
|
1448
|
+
api = get_api(debug=debug)
|
|
1449
|
+
url = f"https://webexapis.com/v1/meetings/{meeting_id}/simultaneousInterpretation"
|
|
1450
|
+
if json_body:
|
|
1451
|
+
body = json.loads(json_body)
|
|
1452
|
+
else:
|
|
1453
|
+
body = {}
|
|
1454
|
+
if enabled is not None:
|
|
1455
|
+
body["enabled"] = enabled
|
|
1456
|
+
try:
|
|
1457
|
+
result = api.session.rest_put(url, json=body)
|
|
1458
|
+
except WebexError as e:
|
|
1459
|
+
handle_rest_error(e)
|
|
1460
|
+
typer.echo(f"Updated.")
|
|
1461
|
+
|
|
1462
|
+
|
|
1463
|
+
|
|
1464
|
+
@app.command("list-interpreters")
|
|
1465
|
+
def list_interpreters(
|
|
1466
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
1467
|
+
host_email: str = typer.Option(None, "--host-email", help="Email address for the meeting host. This parameter is only u"),
|
|
1468
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
1469
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
1470
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
1471
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1472
|
+
):
|
|
1473
|
+
"""List Meeting Interpreters."""
|
|
1474
|
+
api = get_api(debug=debug)
|
|
1475
|
+
url = f"https://webexapis.com/v1/meetings/{meeting_id}/interpreters"
|
|
1476
|
+
params = {}
|
|
1477
|
+
if host_email is not None:
|
|
1478
|
+
params["hostEmail"] = host_email
|
|
1479
|
+
if limit > 0:
|
|
1480
|
+
params["max"] = limit
|
|
1481
|
+
if offset > 0:
|
|
1482
|
+
params["start"] = offset
|
|
1483
|
+
result = None
|
|
1484
|
+
try:
|
|
1485
|
+
result = api.session.rest_get(url, params=params)
|
|
1486
|
+
except WebexError as e:
|
|
1487
|
+
handle_rest_error(e)
|
|
1488
|
+
result = result or []
|
|
1489
|
+
items = result.get("items", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
1490
|
+
if output == "json":
|
|
1491
|
+
print_json(items)
|
|
1492
|
+
else:
|
|
1493
|
+
print_table(items, columns=[('ID', 'id'), ('Title', 'title'), ('Start', 'start'), ('End', 'end'), ('State', 'state')], limit=limit)
|
|
1494
|
+
|
|
1495
|
+
|
|
1496
|
+
|
|
1497
|
+
@app.command("create-interpreters")
|
|
1498
|
+
def create_interpreters(
|
|
1499
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
1500
|
+
language_code1: str = typer.Option(None, "--language-code1", help="(required) The pair of `languageCode1` and `languageCode2` form a bi-di"),
|
|
1501
|
+
language_code2: str = typer.Option(None, "--language-code2", help="(required) The pair of `languageCode1` and `languageCode2` form a bi-di"),
|
|
1502
|
+
email: str = typer.Option(None, "--email", help="Email address of meeting interpreter. If not specified, an e"),
|
|
1503
|
+
display_name: str = typer.Option(None, "--display-name", help="Display name of meeting interpreter. If the interpreter is a"),
|
|
1504
|
+
host_email: str = typer.Option(None, "--host-email", help="Email address for the meeting host. This attribute should on"),
|
|
1505
|
+
send_email: bool = typer.Option(None, "--send-email/--no-send-email", help="If `true`, send email to the interpreter."),
|
|
1506
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
1507
|
+
output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
|
|
1508
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1509
|
+
):
|
|
1510
|
+
"""Create a Meeting Interpreter."""
|
|
1511
|
+
api = get_api(debug=debug)
|
|
1512
|
+
url = f"https://webexapis.com/v1/meetings/{meeting_id}/interpreters"
|
|
1513
|
+
if json_body:
|
|
1514
|
+
body = json.loads(json_body)
|
|
1515
|
+
else:
|
|
1516
|
+
body = {}
|
|
1517
|
+
if language_code1 is not None:
|
|
1518
|
+
body["languageCode1"] = language_code1
|
|
1519
|
+
if language_code2 is not None:
|
|
1520
|
+
body["languageCode2"] = language_code2
|
|
1521
|
+
if email is not None:
|
|
1522
|
+
body["email"] = email
|
|
1523
|
+
if display_name is not None:
|
|
1524
|
+
body["displayName"] = display_name
|
|
1525
|
+
if host_email is not None:
|
|
1526
|
+
body["hostEmail"] = host_email
|
|
1527
|
+
if send_email is not None:
|
|
1528
|
+
body["sendEmail"] = send_email
|
|
1529
|
+
_missing = [f for f in ['languageCode1', 'languageCode2'] if f not in body or body[f] is None]
|
|
1530
|
+
if _missing:
|
|
1531
|
+
typer.echo("Error: Missing required fields: " + ", ".join(_missing), err=True)
|
|
1532
|
+
raise typer.Exit(1)
|
|
1533
|
+
try:
|
|
1534
|
+
result = api.session.rest_post(url, json=body)
|
|
1535
|
+
except WebexError as e:
|
|
1536
|
+
handle_rest_error(e)
|
|
1537
|
+
if output == "json":
|
|
1538
|
+
print_json(result)
|
|
1539
|
+
elif isinstance(result, dict) and "id" in result:
|
|
1540
|
+
typer.echo(f"Created: {result['id']}")
|
|
1541
|
+
elif not result or result == {}:
|
|
1542
|
+
typer.echo("Created.")
|
|
1543
|
+
else:
|
|
1544
|
+
print_json(result)
|
|
1545
|
+
|
|
1546
|
+
|
|
1547
|
+
|
|
1548
|
+
@app.command("show-interpreters")
|
|
1549
|
+
def show_interpreters(
|
|
1550
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
1551
|
+
interpreter_id: str = typer.Argument(help="interpreterId"),
|
|
1552
|
+
host_email: str = typer.Option(None, "--host-email", help="Email address for the meeting host. This parameter is only u"),
|
|
1553
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
1554
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1555
|
+
):
|
|
1556
|
+
"""Get a Meeting Interpreter."""
|
|
1557
|
+
api = get_api(debug=debug)
|
|
1558
|
+
url = f"https://webexapis.com/v1/meetings/{meeting_id}/interpreters/{interpreter_id}"
|
|
1559
|
+
params = {}
|
|
1560
|
+
if host_email is not None:
|
|
1561
|
+
params["hostEmail"] = host_email
|
|
1562
|
+
try:
|
|
1563
|
+
result = api.session.rest_get(url, params=params)
|
|
1564
|
+
except WebexError as e:
|
|
1565
|
+
handle_rest_error(e)
|
|
1566
|
+
if output == "json":
|
|
1567
|
+
print_json(result)
|
|
1568
|
+
else:
|
|
1569
|
+
if isinstance(result, dict):
|
|
1570
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
1571
|
+
elif isinstance(result, list):
|
|
1572
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
1573
|
+
else:
|
|
1574
|
+
print_json(result)
|
|
1575
|
+
|
|
1576
|
+
|
|
1577
|
+
|
|
1578
|
+
@app.command("update-interpreters")
|
|
1579
|
+
def update_interpreters(
|
|
1580
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
1581
|
+
interpreter_id: str = typer.Argument(help="interpreterId"),
|
|
1582
|
+
language_code1: str = typer.Option(None, "--language-code1", help="The pair of `languageCode1` and `languageCode2` form a bi-di"),
|
|
1583
|
+
language_code2: str = typer.Option(None, "--language-code2", help="The pair of `languageCode1` and `languageCode2` form a bi-di"),
|
|
1584
|
+
email: str = typer.Option(None, "--email", help="Email address of meeting interpreter. If not specified, it'l"),
|
|
1585
|
+
display_name: str = typer.Option(None, "--display-name", help="Display name of meeting interpreter. If the interpreter is a"),
|
|
1586
|
+
host_email: str = typer.Option(None, "--host-email", help="Email address for the meeting host. This attribute should on"),
|
|
1587
|
+
send_email: bool = typer.Option(None, "--send-email/--no-send-email", help="If `true`, send email to the interpreter."),
|
|
1588
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
1589
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1590
|
+
):
|
|
1591
|
+
"""Update a Meeting Interpreter."""
|
|
1592
|
+
api = get_api(debug=debug)
|
|
1593
|
+
url = f"https://webexapis.com/v1/meetings/{meeting_id}/interpreters/{interpreter_id}"
|
|
1594
|
+
if json_body:
|
|
1595
|
+
body = json.loads(json_body)
|
|
1596
|
+
else:
|
|
1597
|
+
body = {}
|
|
1598
|
+
if language_code1 is not None:
|
|
1599
|
+
body["languageCode1"] = language_code1
|
|
1600
|
+
if language_code2 is not None:
|
|
1601
|
+
body["languageCode2"] = language_code2
|
|
1602
|
+
if email is not None:
|
|
1603
|
+
body["email"] = email
|
|
1604
|
+
if display_name is not None:
|
|
1605
|
+
body["displayName"] = display_name
|
|
1606
|
+
if host_email is not None:
|
|
1607
|
+
body["hostEmail"] = host_email
|
|
1608
|
+
if send_email is not None:
|
|
1609
|
+
body["sendEmail"] = send_email
|
|
1610
|
+
try:
|
|
1611
|
+
result = api.session.rest_put(url, json=body)
|
|
1612
|
+
except WebexError as e:
|
|
1613
|
+
handle_rest_error(e)
|
|
1614
|
+
typer.echo(f"Updated.")
|
|
1615
|
+
|
|
1616
|
+
|
|
1617
|
+
|
|
1618
|
+
@app.command("delete-interpreters")
|
|
1619
|
+
def delete_interpreters(
|
|
1620
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
1621
|
+
interpreter_id: str = typer.Argument(help="interpreterId"),
|
|
1622
|
+
host_email: str = typer.Option(None, "--host-email", help="Email address for the meeting host. This parameter is only u"),
|
|
1623
|
+
send_email: str = typer.Option(None, "--send-email", help="If `true`, send email to the interpreter."),
|
|
1624
|
+
force: bool = typer.Option(False, "--force", help="Skip confirmation"),
|
|
1625
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1626
|
+
):
|
|
1627
|
+
"""Delete a Meeting Interpreter."""
|
|
1628
|
+
if not force:
|
|
1629
|
+
typer.confirm(f"Delete {interpreter_id}?", abort=True)
|
|
1630
|
+
api = get_api(debug=debug)
|
|
1631
|
+
url = f"https://webexapis.com/v1/meetings/{meeting_id}/interpreters/{interpreter_id}"
|
|
1632
|
+
params = {}
|
|
1633
|
+
if host_email is not None:
|
|
1634
|
+
params["hostEmail"] = host_email
|
|
1635
|
+
if send_email is not None:
|
|
1636
|
+
params["sendEmail"] = send_email
|
|
1637
|
+
try:
|
|
1638
|
+
api.session.rest_delete(url, params=params)
|
|
1639
|
+
except WebexError as e:
|
|
1640
|
+
handle_rest_error(e)
|
|
1641
|
+
typer.echo(f"Deleted: {interpreter_id}")
|
|
1642
|
+
|
|
1643
|
+
|
|
1644
|
+
|
|
1645
|
+
@app.command("list-breakout-sessions")
|
|
1646
|
+
def list_breakout_sessions(
|
|
1647
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
1648
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
1649
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
1650
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
1651
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1652
|
+
):
|
|
1653
|
+
"""List Meeting Breakout Sessions."""
|
|
1654
|
+
api = get_api(debug=debug)
|
|
1655
|
+
url = f"https://webexapis.com/v1/meetings/{meeting_id}/breakoutSessions"
|
|
1656
|
+
params = {}
|
|
1657
|
+
if limit > 0:
|
|
1658
|
+
params["max"] = limit
|
|
1659
|
+
if offset > 0:
|
|
1660
|
+
params["start"] = offset
|
|
1661
|
+
result = None
|
|
1662
|
+
try:
|
|
1663
|
+
result = api.session.rest_get(url, params=params)
|
|
1664
|
+
except WebexError as e:
|
|
1665
|
+
handle_rest_error(e)
|
|
1666
|
+
result = result or []
|
|
1667
|
+
items = result.get("items", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
1668
|
+
if output == "json":
|
|
1669
|
+
print_json(items)
|
|
1670
|
+
else:
|
|
1671
|
+
print_table(items, columns=[('ID', 'id'), ('Title', 'title'), ('Start', 'start'), ('End', 'end'), ('State', 'state')], limit=limit)
|
|
1672
|
+
|
|
1673
|
+
|
|
1674
|
+
|
|
1675
|
+
@app.command("update-breakout-sessions")
|
|
1676
|
+
def update_breakout_sessions(
|
|
1677
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
1678
|
+
host_email: str = typer.Option(None, "--host-email", help="Email address for the meeting host. This parameter is only u"),
|
|
1679
|
+
send_email: bool = typer.Option(None, "--send-email/--no-send-email", help="Whether or not to send emails to host and invitees. It is an"),
|
|
1680
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
1681
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1682
|
+
):
|
|
1683
|
+
"""Update Meeting Breakout Sessions\n\nExample --json-body:\n '{"hostEmail":"...","sendEmail":true,"items":[{"name":"...","invitees":"..."}]}'."""
|
|
1684
|
+
api = get_api(debug=debug)
|
|
1685
|
+
url = f"https://webexapis.com/v1/meetings/{meeting_id}/breakoutSessions"
|
|
1686
|
+
if json_body:
|
|
1687
|
+
body = json.loads(json_body)
|
|
1688
|
+
else:
|
|
1689
|
+
body = {}
|
|
1690
|
+
if host_email is not None:
|
|
1691
|
+
body["hostEmail"] = host_email
|
|
1692
|
+
if send_email is not None:
|
|
1693
|
+
body["sendEmail"] = send_email
|
|
1694
|
+
try:
|
|
1695
|
+
result = api.session.rest_put(url, json=body)
|
|
1696
|
+
except WebexError as e:
|
|
1697
|
+
handle_rest_error(e)
|
|
1698
|
+
typer.echo(f"Updated.")
|
|
1699
|
+
|
|
1700
|
+
|
|
1701
|
+
|
|
1702
|
+
@app.command("delete-breakout-sessions")
|
|
1703
|
+
def delete_breakout_sessions(
|
|
1704
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
1705
|
+
send_email: str = typer.Option(None, "--send-email", help="Whether or not to send emails to host and invitees. It is an"),
|
|
1706
|
+
force: bool = typer.Option(False, "--force", help="Skip confirmation"),
|
|
1707
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1708
|
+
):
|
|
1709
|
+
"""Delete Meeting Breakout Sessions."""
|
|
1710
|
+
if not force:
|
|
1711
|
+
typer.confirm(f"Delete {meeting_id}?", abort=True)
|
|
1712
|
+
api = get_api(debug=debug)
|
|
1713
|
+
url = f"https://webexapis.com/v1/meetings/{meeting_id}/breakoutSessions"
|
|
1714
|
+
params = {}
|
|
1715
|
+
if send_email is not None:
|
|
1716
|
+
params["sendEmail"] = send_email
|
|
1717
|
+
try:
|
|
1718
|
+
api.session.rest_delete(url, params=params)
|
|
1719
|
+
except WebexError as e:
|
|
1720
|
+
handle_rest_error(e)
|
|
1721
|
+
typer.echo(f"Deleted: {meeting_id}")
|
|
1722
|
+
|
|
1723
|
+
|
|
1724
|
+
|
|
1725
|
+
@app.command("list-survey")
|
|
1726
|
+
def list_survey(
|
|
1727
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
1728
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
1729
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
1730
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
1731
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1732
|
+
):
|
|
1733
|
+
"""Get a Meeting Survey."""
|
|
1734
|
+
api = get_api(debug=debug)
|
|
1735
|
+
url = f"https://webexapis.com/v1/meetings/{meeting_id}/survey"
|
|
1736
|
+
params = {}
|
|
1737
|
+
if limit > 0:
|
|
1738
|
+
params["max"] = limit
|
|
1739
|
+
if offset > 0:
|
|
1740
|
+
params["start"] = offset
|
|
1741
|
+
result = None
|
|
1742
|
+
try:
|
|
1743
|
+
result = api.session.rest_get(url, params=params)
|
|
1744
|
+
except WebexError as e:
|
|
1745
|
+
handle_rest_error(e)
|
|
1746
|
+
result = result or []
|
|
1747
|
+
items = result.get("questions", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
1748
|
+
if output == "json":
|
|
1749
|
+
print_json(items)
|
|
1750
|
+
else:
|
|
1751
|
+
print_table(items, columns=[('ID', 'id'), ('Title', 'title'), ('Start', 'start'), ('End', 'end'), ('State', 'state')], limit=limit)
|
|
1752
|
+
|
|
1753
|
+
|
|
1754
|
+
|
|
1755
|
+
@app.command("list-survey-results")
|
|
1756
|
+
def list_survey_results(
|
|
1757
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
1758
|
+
meeting_start_time_from: str = typer.Option(None, "--meeting-start-time-from", help="Start date and time (inclusive) in any [ISO 8601](https://en"),
|
|
1759
|
+
meeting_start_time_to: str = typer.Option(None, "--meeting-start-time-to", help="End date and time (exclusive) in any [ISO 8601](https://en.w"),
|
|
1760
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
1761
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
1762
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
1763
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1764
|
+
):
|
|
1765
|
+
"""List Meeting Survey Results."""
|
|
1766
|
+
api = get_api(debug=debug)
|
|
1767
|
+
url = f"https://webexapis.com/v1/meetings/{meeting_id}/surveyResults"
|
|
1768
|
+
params = {}
|
|
1769
|
+
if meeting_start_time_from is not None:
|
|
1770
|
+
params["meetingStartTimeFrom"] = meeting_start_time_from
|
|
1771
|
+
if meeting_start_time_to is not None:
|
|
1772
|
+
params["meetingStartTimeTo"] = meeting_start_time_to
|
|
1773
|
+
if limit > 0:
|
|
1774
|
+
params["max"] = limit
|
|
1775
|
+
if offset > 0:
|
|
1776
|
+
params["start"] = offset
|
|
1777
|
+
result = None
|
|
1778
|
+
try:
|
|
1779
|
+
result = api.session.rest_get(url, params=params)
|
|
1780
|
+
except WebexError as e:
|
|
1781
|
+
handle_rest_error(e)
|
|
1782
|
+
result = result or []
|
|
1783
|
+
items = result.get("items", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
1784
|
+
if output == "json":
|
|
1785
|
+
print_json(items)
|
|
1786
|
+
else:
|
|
1787
|
+
print_table(items, columns=[('ID', 'id'), ('Title', 'title'), ('Start', 'start'), ('End', 'end'), ('State', 'state')], limit=limit)
|
|
1788
|
+
|
|
1789
|
+
|
|
1790
|
+
|
|
1791
|
+
@app.command("create-survey-links")
|
|
1792
|
+
def create_survey_links(
|
|
1793
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
1794
|
+
host_email: str = typer.Option(None, "--host-email", help="Email address for the meeting host. This parameter is only u"),
|
|
1795
|
+
meeting_start_time_from: str = typer.Option(None, "--meeting-start-time-from", help="Start date and time (inclusive) in any [ISO 8601](https://en"),
|
|
1796
|
+
meeting_start_time_to: str = typer.Option(None, "--meeting-start-time-to", help="End date and time (exclusive) in any [ISO 8601](https://en.w"),
|
|
1797
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
1798
|
+
output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
|
|
1799
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1800
|
+
):
|
|
1801
|
+
"""Get Meeting Survey Links\n\nExample --json-body:\n '{"hostEmail":"...","meetingStartTimeFrom":"...","meetingStartTimeTo":"...","emails":["..."]}'."""
|
|
1802
|
+
api = get_api(debug=debug)
|
|
1803
|
+
url = f"https://webexapis.com/v1/meetings/{meeting_id}/surveyLinks"
|
|
1804
|
+
if json_body:
|
|
1805
|
+
body = json.loads(json_body)
|
|
1806
|
+
else:
|
|
1807
|
+
body = {}
|
|
1808
|
+
if host_email is not None:
|
|
1809
|
+
body["hostEmail"] = host_email
|
|
1810
|
+
if meeting_start_time_from is not None:
|
|
1811
|
+
body["meetingStartTimeFrom"] = meeting_start_time_from
|
|
1812
|
+
if meeting_start_time_to is not None:
|
|
1813
|
+
body["meetingStartTimeTo"] = meeting_start_time_to
|
|
1814
|
+
try:
|
|
1815
|
+
result = api.session.rest_post(url, json=body)
|
|
1816
|
+
except WebexError as e:
|
|
1817
|
+
handle_rest_error(e)
|
|
1818
|
+
if output == "json":
|
|
1819
|
+
print_json(result)
|
|
1820
|
+
elif isinstance(result, dict) and "id" in result:
|
|
1821
|
+
typer.echo(f"Created: {result['id']}")
|
|
1822
|
+
elif not result or result == {}:
|
|
1823
|
+
typer.echo("Created.")
|
|
1824
|
+
else:
|
|
1825
|
+
print_json(result)
|
|
1826
|
+
|
|
1827
|
+
|
|
1828
|
+
|
|
1829
|
+
@app.command("list-invitation-sources")
|
|
1830
|
+
def list_invitation_sources(
|
|
1831
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
1832
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
1833
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
1834
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
1835
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1836
|
+
):
|
|
1837
|
+
"""List Invitation Sources."""
|
|
1838
|
+
api = get_api(debug=debug)
|
|
1839
|
+
url = f"https://webexapis.com/v1/meetings/{meeting_id}/invitationSources"
|
|
1840
|
+
params = {}
|
|
1841
|
+
if limit > 0:
|
|
1842
|
+
params["max"] = limit
|
|
1843
|
+
if offset > 0:
|
|
1844
|
+
params["start"] = offset
|
|
1845
|
+
result = None
|
|
1846
|
+
try:
|
|
1847
|
+
result = api.session.rest_get(url, params=params)
|
|
1848
|
+
except WebexError as e:
|
|
1849
|
+
handle_rest_error(e)
|
|
1850
|
+
result = result or []
|
|
1851
|
+
items = result.get("items", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
1852
|
+
if output == "json":
|
|
1853
|
+
print_json(items)
|
|
1854
|
+
else:
|
|
1855
|
+
print_table(items, columns=[('ID', 'id'), ('Title', 'title'), ('Start', 'start'), ('End', 'end'), ('State', 'state')], limit=limit)
|
|
1856
|
+
|
|
1857
|
+
|
|
1858
|
+
|
|
1859
|
+
@app.command("create-invitation-sources")
|
|
1860
|
+
def create_invitation_sources(
|
|
1861
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
1862
|
+
host_email: str = typer.Option(None, "--host-email", help="Email address for the meeting host. This parameter is only u"),
|
|
1863
|
+
person_id: str = typer.Option(None, "--person-id", help="Unique identifier for the meeting host. Should only be set i"),
|
|
1864
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
1865
|
+
output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
|
|
1866
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1867
|
+
):
|
|
1868
|
+
"""Create Invitation Sources\n\nExample --json-body:\n '{"hostEmail":"...","personId":"...","items":[{"sourceId":"...","sourceEmail":"..."}]}'."""
|
|
1869
|
+
api = get_api(debug=debug)
|
|
1870
|
+
url = f"https://webexapis.com/v1/meetings/{meeting_id}/invitationSources"
|
|
1871
|
+
if json_body:
|
|
1872
|
+
body = json.loads(json_body)
|
|
1873
|
+
else:
|
|
1874
|
+
body = {}
|
|
1875
|
+
if host_email is not None:
|
|
1876
|
+
body["hostEmail"] = host_email
|
|
1877
|
+
if person_id is not None:
|
|
1878
|
+
body["personId"] = person_id
|
|
1879
|
+
try:
|
|
1880
|
+
result = api.session.rest_post(url, json=body)
|
|
1881
|
+
except WebexError as e:
|
|
1882
|
+
handle_rest_error(e)
|
|
1883
|
+
if output == "json":
|
|
1884
|
+
print_json(result)
|
|
1885
|
+
elif isinstance(result, dict) and "id" in result:
|
|
1886
|
+
typer.echo(f"Created: {result['id']}")
|
|
1887
|
+
elif not result or result == {}:
|
|
1888
|
+
typer.echo("Created.")
|
|
1889
|
+
else:
|
|
1890
|
+
print_json(result)
|
|
1891
|
+
|
|
1892
|
+
|
|
1893
|
+
|
|
1894
|
+
@app.command("list-tracking-codes")
|
|
1895
|
+
def list_tracking_codes(
|
|
1896
|
+
site_url: str = typer.Option(None, "--site-url", help="URL of the Webex site which the API retrieves the tracking c"),
|
|
1897
|
+
service: str = typer.Option(..., "--service", help="Service for schedule or sign-up pages."),
|
|
1898
|
+
host_email: str = typer.Option(None, "--host-email", help="Email address for the meeting host. This parameter is only u"),
|
|
1899
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
1900
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
1901
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
1902
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1903
|
+
):
|
|
1904
|
+
"""List Meeting Tracking Codes."""
|
|
1905
|
+
api = get_api(debug=debug)
|
|
1906
|
+
url = f"https://webexapis.com/v1/meetings/trackingCodes"
|
|
1907
|
+
params = {}
|
|
1908
|
+
if site_url is not None:
|
|
1909
|
+
params["siteUrl"] = site_url
|
|
1910
|
+
if service is not None:
|
|
1911
|
+
params["service"] = service
|
|
1912
|
+
if host_email is not None:
|
|
1913
|
+
params["hostEmail"] = host_email
|
|
1914
|
+
if limit > 0:
|
|
1915
|
+
params["max"] = limit
|
|
1916
|
+
if offset > 0:
|
|
1917
|
+
params["start"] = offset
|
|
1918
|
+
result = None
|
|
1919
|
+
try:
|
|
1920
|
+
result = api.session.rest_get(url, params=params)
|
|
1921
|
+
except WebexError as e:
|
|
1922
|
+
handle_rest_error(e)
|
|
1923
|
+
result = result or []
|
|
1924
|
+
items = result.get("items", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
1925
|
+
if output == "json":
|
|
1926
|
+
print_json(items)
|
|
1927
|
+
else:
|
|
1928
|
+
print_table(items, columns=[('ID', 'id'), ('Title', 'title'), ('Start', 'start'), ('End', 'end'), ('State', 'state')], limit=limit)
|
|
1929
|
+
|
|
1930
|
+
|
|
1931
|
+
|
|
1932
|
+
@app.command("create-reassign-host")
|
|
1933
|
+
def create_reassign_host(
|
|
1934
|
+
host_email: str = typer.Option(None, "--host-email", help="(required) Email address of the new meeting host."),
|
|
1935
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
1936
|
+
output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
|
|
1937
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1938
|
+
):
|
|
1939
|
+
"""Reassign Meetings to a New Host\n\nExample --json-body:\n '{"hostEmail":"...","meetingIds":["..."]}'."""
|
|
1940
|
+
api = get_api(debug=debug)
|
|
1941
|
+
url = f"https://webexapis.com/v1/meetings/reassignHost"
|
|
1942
|
+
if json_body:
|
|
1943
|
+
body = json.loads(json_body)
|
|
1944
|
+
else:
|
|
1945
|
+
body = {}
|
|
1946
|
+
if host_email is not None:
|
|
1947
|
+
body["hostEmail"] = host_email
|
|
1948
|
+
_missing = [f for f in ['hostEmail'] if f not in body or body[f] is None]
|
|
1949
|
+
if _missing:
|
|
1950
|
+
typer.echo("Error: Missing required fields: " + ", ".join(_missing), err=True)
|
|
1951
|
+
raise typer.Exit(1)
|
|
1952
|
+
try:
|
|
1953
|
+
result = api.session.rest_post(url, json=body)
|
|
1954
|
+
except WebexError as e:
|
|
1955
|
+
handle_rest_error(e)
|
|
1956
|
+
if output == "json":
|
|
1957
|
+
print_json(result)
|
|
1958
|
+
elif isinstance(result, dict) and "id" in result:
|
|
1959
|
+
typer.echo(f"Created: {result['id']}")
|
|
1960
|
+
elif not result or result == {}:
|
|
1961
|
+
typer.echo("Created.")
|
|
1962
|
+
else:
|
|
1963
|
+
print_json(result)
|
|
1964
|
+
|
|
1965
|
+
|
|
1966
|
+
|
|
1967
|
+
@app.command("create-end")
|
|
1968
|
+
def create_end(
|
|
1969
|
+
meeting_id: str = typer.Argument(help="meetingId"),
|
|
1970
|
+
reason: str = typer.Option(None, "--reason", help="The reason for ending the meeting. This field is optional."),
|
|
1971
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
1972
|
+
output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
|
|
1973
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
1974
|
+
):
|
|
1975
|
+
"""End a Meeting."""
|
|
1976
|
+
api = get_api(debug=debug)
|
|
1977
|
+
url = f"https://webexapis.com/v1/meetings/{meeting_id}/end"
|
|
1978
|
+
if json_body:
|
|
1979
|
+
body = json.loads(json_body)
|
|
1980
|
+
else:
|
|
1981
|
+
body = {}
|
|
1982
|
+
if reason is not None:
|
|
1983
|
+
body["reason"] = reason
|
|
1984
|
+
try:
|
|
1985
|
+
result = api.session.rest_post(url, json=body)
|
|
1986
|
+
except WebexError as e:
|
|
1987
|
+
handle_rest_error(e)
|
|
1988
|
+
if output == "json":
|
|
1989
|
+
print_json(result)
|
|
1990
|
+
elif isinstance(result, dict) and "id" in result:
|
|
1991
|
+
typer.echo(f"Created: {result['id']}")
|
|
1992
|
+
elif not result or result == {}:
|
|
1993
|
+
typer.echo("Created.")
|
|
1994
|
+
else:
|
|
1995
|
+
print_json(result)
|
|
1996
|
+
|
|
1997
|
+
|