@cometchat/skills 4.4.2 → 5.0.1
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.
- package/.claude-plugin/marketplace.json +55 -0
- package/.claude-plugin/plugin.json +14 -0
- package/CHANGELOG.md +44 -0
- package/LICENSE +21 -0
- package/MIGRATING.md +187 -0
- package/README.md +52 -156
- package/RULES.md +125 -0
- package/bin/cometchat-skills.mjs +1280 -0
- package/bin/legacy-skills.json +95 -0
- package/catalogs/android-v6.json +1646 -0
- package/catalogs/flutter-v6.json +651 -0
- package/catalogs/ios-v5.json +1383 -0
- package/catalogs/rn-calls-v5.json +134 -0
- package/catalogs/rn-calls-v5.symbols.txt +58 -0
- package/catalogs/rn-sdk-v4.json +672 -0
- package/catalogs/rn-v5.json +449 -0
- package/catalogs/rn-v5.symbols.txt +216 -0
- package/catalogs/sdk-android-v5.json +514 -0
- package/contracts.android-calls-v5.json +122 -0
- package/contracts.android-v6.json +135 -0
- package/contracts.angular-v5.json +694 -0
- package/contracts.flutter-calls-v5.json +77 -0
- package/contracts.flutter-v6.json +126 -0
- package/contracts.ios-calls-v5.json +67 -0
- package/contracts.ios-v5.json +436 -0
- package/contracts.json +82 -0
- package/contracts.rn-calls-v5.json +77 -0
- package/contracts.rn-v5.json +727 -0
- package/contracts.sdk-android-v5.json +15 -0
- package/contracts.web-calls-v5.json +45 -0
- package/features.android-calls-v5.json +246 -0
- package/features.android-v6.json +65 -0
- package/features.angular-v5.json +521 -0
- package/features.flutter-calls-v5.json +286 -0
- package/features.flutter-v6.json +484 -0
- package/features.ios-calls-v5.json +236 -0
- package/features.ios-v5.json +573 -0
- package/features.json +61 -0
- package/features.rn-calls-v5.json +187 -0
- package/features.rn-v5.json +614 -0
- package/features.sdk-android-v5.json +40 -0
- package/features.sdk-jsv4.json +24 -0
- package/features.web-calls-v5.json +108 -0
- package/package.json +156 -74
- package/peers.yaml +355 -0
- package/registry/README.md +31 -0
- package/registry/android-calls-v5.json +94 -0
- package/registry/android-v6.json +177 -0
- package/registry/angular-v5.json +154 -0
- package/registry/flutter-calls-v5.json +94 -0
- package/registry/flutter-v6.json +159 -0
- package/registry/ios-calls-v5.json +99 -0
- package/registry/ios-v5.json +152 -0
- package/registry/rn-calls-v5.json +99 -0
- package/registry/rn-v5.json +169 -0
- package/registry/sdk-android-v5.json +93 -0
- package/registry/sdk-jsv4.json +93 -0
- package/registry/web-calls-v5.json +94 -0
- package/registry/web-v7.json +154 -0
- package/skills/cometchat/SKILL.md +47 -2096
- package/skills/cometchat-a11y/SKILL.md +44 -472
- package/skills/cometchat-analytics/SKILL.md +61 -0
- package/skills/cometchat-android-v5-calls-sdk/SKILL.md +206 -0
- package/skills/cometchat-android-v5-calls-sdk/references/build-truth.md +63 -0
- package/skills/cometchat-android-v5-calls-sdk/references/docs-map.md +119 -0
- package/skills/cometchat-android-v5-calls-sdk/references/method-map.md +53 -0
- package/skills/cometchat-android-v5-calls-sdk/references/pitfalls.md +72 -0
- package/skills/cometchat-android-v5-calls-sdk/references/ringing.md +92 -0
- package/skills/cometchat-android-v5-calls-sdk/references/user-switch.md +90 -0
- package/skills/cometchat-android-v5-sdk/SKILL.md +127 -0
- package/skills/cometchat-android-v5-sdk/references/app-surface.md +88 -0
- package/skills/cometchat-android-v5-sdk/references/docs-map.md +91 -0
- package/skills/cometchat-android-v6-builder-settings/SKILL.md +51 -137
- package/skills/cometchat-android-v6-calls/SKILL.md +128 -413
- package/skills/cometchat-android-v6-compose-components/SKILL.md +84 -194
- package/skills/cometchat-android-v6-compose-customization/SKILL.md +66 -411
- package/skills/cometchat-android-v6-compose-placement/SKILL.md +154 -237
- package/skills/cometchat-android-v6-core/SKILL.md +236 -672
- package/skills/cometchat-android-v6-core/references/anti-patterns.md +31 -0
- package/skills/cometchat-android-v6-core/references/component-props.md +168 -0
- package/skills/cometchat-android-v6-core/references/docs-map.md +153 -0
- package/skills/cometchat-android-v6-core/references/layout.md +112 -0
- package/skills/cometchat-android-v6-core/references/lifecycle.md +75 -0
- package/skills/cometchat-android-v6-core/references/setup-credentials.md +105 -0
- package/skills/cometchat-android-v6-core/references/troubleshooting.md +36 -0
- package/skills/cometchat-android-v6-events/SKILL.md +46 -184
- package/skills/cometchat-android-v6-extensions/SKILL.md +39 -179
- package/skills/cometchat-android-v6-features/SKILL.md +74 -143
- package/skills/cometchat-android-v6-kotlin-components/SKILL.md +75 -193
- package/skills/cometchat-android-v6-kotlin-customization/SKILL.md +67 -419
- package/skills/cometchat-android-v6-kotlin-placement/SKILL.md +77 -223
- package/skills/cometchat-android-v6-migration/SKILL.md +67 -378
- package/skills/cometchat-android-v6-production/SKILL.md +41 -179
- package/skills/cometchat-android-v6-push/SKILL.md +39 -289
- package/skills/cometchat-android-v6-testing/SKILL.md +50 -265
- package/skills/cometchat-android-v6-troubleshooting/SKILL.md +70 -254
- package/skills/cometchat-angular-v5-calls/SKILL.md +193 -0
- package/skills/cometchat-angular-v5-components/SKILL.md +131 -0
- package/skills/cometchat-angular-v5-components/references/catalog.md +111 -0
- package/skills/cometchat-angular-v5-components/references/host-composed.md +46 -0
- package/skills/cometchat-angular-v5-core/SKILL.md +300 -0
- package/skills/cometchat-angular-v5-core/references/anti-patterns.md +49 -0
- package/skills/cometchat-angular-v5-core/references/component-props.md +55 -0
- package/skills/cometchat-angular-v5-core/references/dependencies.md +66 -0
- package/skills/cometchat-angular-v5-core/references/docs-map.md +132 -0
- package/skills/cometchat-angular-v5-core/references/layout.md +64 -0
- package/skills/cometchat-angular-v5-core/references/lifecycle.md +202 -0
- package/skills/cometchat-angular-v5-core/references/setup-credentials.md +137 -0
- package/skills/cometchat-angular-v5-core/references/theming.md +70 -0
- package/skills/cometchat-angular-v5-core/references/troubleshooting.md +27 -0
- package/skills/cometchat-angular-v5-customization/SKILL.md +94 -0
- package/skills/cometchat-angular-v5-features/SKILL.md +107 -0
- package/skills/cometchat-angular-v5-features/references/custom-messages.md +133 -0
- package/skills/cometchat-angular-v5-features/references/formatters.md +28 -0
- package/skills/cometchat-angular-v5-features/references/host-composed-extensions.md +85 -0
- package/skills/cometchat-angular-v5-migration/SKILL.md +40 -0
- package/skills/cometchat-angular-v5-migration/references/migration-guide.md +165 -0
- package/skills/cometchat-angular-v5-patterns/SKILL.md +107 -0
- package/skills/cometchat-angular-v5-placement/SKILL.md +133 -0
- package/skills/cometchat-angular-v5-placement/references/combined-app.md +174 -0
- package/skills/cometchat-angular-v5-placement/references/core-surface.md +199 -0
- package/skills/cometchat-angular-v5-production/SKILL.md +102 -0
- package/skills/cometchat-angular-v5-push/SKILL.md +61 -0
- package/skills/cometchat-angular-v5-testing/SKILL.md +112 -0
- package/skills/cometchat-angular-v5-troubleshooting/SKILL.md +96 -0
- package/skills/cometchat-audit/SKILL.md +61 -0
- package/skills/cometchat-compliance/SKILL.md +63 -0
- package/skills/cometchat-flutter-v5-sdk/SKILL.md +188 -0
- package/skills/cometchat-flutter-v5-sdk/references/doc-corrections.md +55 -0
- package/skills/cometchat-flutter-v5-sdk/references/docs-map.md +211 -0
- package/skills/cometchat-flutter-v5-sdk/references/platform-notes.md +48 -0
- package/skills/cometchat-flutter-v5-sdk/references/transcription.md +87 -0
- package/skills/cometchat-flutter-v6-calls/SKILL.md +75 -389
- package/skills/cometchat-flutter-v6-components/SKILL.md +88 -361
- package/skills/cometchat-flutter-v6-core/SKILL.md +154 -593
- package/skills/cometchat-flutter-v6-core/references/anti-patterns.md +55 -0
- package/skills/cometchat-flutter-v6-core/references/docs-map.md +143 -0
- package/skills/cometchat-flutter-v6-core/references/layout.md +45 -0
- package/skills/cometchat-flutter-v6-core/references/lifecycle.md +87 -0
- package/skills/cometchat-flutter-v6-core/references/setup-credentials.md +84 -0
- package/skills/cometchat-flutter-v6-core/references/troubleshooting.md +26 -0
- package/skills/cometchat-flutter-v6-customization/SKILL.md +70 -712
- package/skills/cometchat-flutter-v6-events/SKILL.md +79 -174
- package/skills/cometchat-flutter-v6-features/SKILL.md +55 -394
- package/skills/cometchat-flutter-v6-migration/SKILL.md +68 -367
- package/skills/cometchat-flutter-v6-migration/references/migration-guide.md +132 -0
- package/skills/cometchat-flutter-v6-patterns/SKILL.md +61 -0
- package/skills/cometchat-flutter-v6-placement/SKILL.md +94 -381
- package/skills/cometchat-flutter-v6-production/SKILL.md +59 -615
- package/skills/cometchat-flutter-v6-push/SKILL.md +46 -455
- package/skills/cometchat-flutter-v6-testing/SKILL.md +68 -299
- package/skills/cometchat-flutter-v6-troubleshooting/SKILL.md +54 -878
- package/skills/cometchat-i18n/SKILL.md +35 -404
- package/skills/cometchat-ios-calls/SKILL.md +112 -563
- package/skills/cometchat-ios-components/SKILL.md +44 -834
- package/skills/cometchat-ios-core/SKILL.md +182 -1068
- package/skills/cometchat-ios-core/references/anti-patterns.md +113 -0
- package/skills/cometchat-ios-core/references/docs-map.md +124 -0
- package/skills/cometchat-ios-core/references/install.md +23 -0
- package/skills/cometchat-ios-core/references/layout.md +219 -0
- package/skills/cometchat-ios-core/references/setup-credentials.md +197 -0
- package/skills/cometchat-ios-core/references/swiftui.md +91 -0
- package/skills/cometchat-ios-core/references/troubleshooting.md +100 -0
- package/skills/cometchat-ios-customization/SKILL.md +33 -968
- package/skills/cometchat-ios-features/SKILL.md +29 -738
- package/skills/cometchat-ios-migration/SKILL.md +39 -0
- package/skills/cometchat-ios-placement/SKILL.md +51 -729
- package/skills/cometchat-ios-production/SKILL.md +67 -723
- package/skills/cometchat-ios-push/SKILL.md +24 -602
- package/skills/cometchat-ios-testing/SKILL.md +36 -355
- package/skills/cometchat-ios-troubleshooting/SKILL.md +31 -989
- package/skills/cometchat-ios-v5-sdk/SKILL.md +161 -0
- package/skills/cometchat-ios-v5-sdk/references/docs-map.md +326 -0
- package/skills/cometchat-js-v5-sdk/SKILL.md +95 -0
- package/skills/cometchat-js-v5-sdk/references/docs-map.md +114 -0
- package/skills/cometchat-migrate-from-getstream/SKILL.md +65 -0
- package/skills/cometchat-migrate-from-getstream/references/concept-map.md +98 -0
- package/skills/cometchat-migrate-from-getstream/references/data-migration.md +74 -0
- package/skills/cometchat-migrate-from-getstream/references/feature-map.md +108 -0
- package/skills/cometchat-migrate-from-getstream/references/inventory.md +82 -0
- package/skills/cometchat-migrate-from-getstream/references/native-build.md +9 -0
- package/skills/cometchat-migrate-from-getstream/references/report-template.md +59 -0
- package/skills/cometchat-migrate-from-sendbird/SKILL.md +64 -0
- package/skills/cometchat-migrate-from-sendbird/references/concept-map.md +99 -0
- package/skills/cometchat-migrate-from-sendbird/references/data-migration.md +74 -0
- package/skills/cometchat-migrate-from-sendbird/references/feature-map.md +104 -0
- package/skills/cometchat-migrate-from-sendbird/references/inventory.md +86 -0
- package/skills/cometchat-migrate-from-sendbird/references/native-build.md +10 -0
- package/skills/cometchat-migrate-from-sendbird/references/report-template.md +59 -0
- package/skills/cometchat-migrate-from-twilio/SKILL.md +52 -0
- package/skills/cometchat-migrate-from-twilio/references/concept-map.md +49 -0
- package/skills/cometchat-migrate-from-twilio/references/data-migration.md +50 -0
- package/skills/cometchat-migrate-from-twilio/references/feature-map.md +27 -0
- package/skills/cometchat-migrate-from-twilio/references/inventory.md +53 -0
- package/skills/cometchat-migrate-from-twilio/references/report-template.md +52 -0
- package/skills/cometchat-moderation/SKILL.md +58 -0
- package/skills/cometchat-onboarding/SKILL.md +92 -0
- package/skills/cometchat-onboarding/references/archetypes.md +51 -0
- package/skills/cometchat-onboarding/references/calling-first.md +77 -0
- package/skills/cometchat-onboarding/references/not-in-this-pack.md +8 -0
- package/skills/cometchat-onboarding/references/plan-artifact.md +133 -0
- package/skills/cometchat-onboarding/references/platforms.md +105 -0
- package/skills/cometchat-react-native-bare-patterns/SKILL.md +120 -0
- package/skills/cometchat-react-native-calls/SKILL.md +200 -0
- package/skills/cometchat-react-native-components/SKILL.md +142 -0
- package/skills/cometchat-react-native-core/SKILL.md +335 -0
- package/skills/cometchat-react-native-core/references/anti-patterns.md +79 -0
- package/skills/cometchat-react-native-core/references/component-props.md +105 -0
- package/skills/cometchat-react-native-core/references/dependencies.md +62 -0
- package/skills/cometchat-react-native-core/references/docs-map.md +127 -0
- package/skills/cometchat-react-native-core/references/layout.md +61 -0
- package/skills/cometchat-react-native-core/references/lifecycle.md +64 -0
- package/skills/cometchat-react-native-core/references/setup-credentials.md +39 -0
- package/skills/cometchat-react-native-customization/SKILL.md +198 -0
- package/skills/cometchat-react-native-expo-patterns/SKILL.md +116 -0
- package/skills/cometchat-react-native-features/SKILL.md +122 -0
- package/skills/cometchat-react-native-migration/SKILL.md +103 -0
- package/skills/cometchat-react-native-placement/SKILL.md +158 -0
- package/skills/cometchat-react-native-production/SKILL.md +79 -0
- package/skills/cometchat-react-native-push/SKILL.md +88 -0
- package/skills/cometchat-react-native-sdk/SKILL.md +133 -0
- package/skills/cometchat-react-native-sdk/references/method-map.md +239 -0
- package/skills/cometchat-react-native-sdk/references/page-map.md +96 -0
- package/skills/cometchat-react-native-testing/SKILL.md +94 -0
- package/skills/cometchat-react-native-troubleshooting/SKILL.md +174 -0
- package/skills/cometchat-react-native-v5-sdk/SKILL.md +150 -0
- package/skills/cometchat-react-native-v5-sdk/references/docs-map.md +127 -0
- package/skills/cometchat-react-native-v5-sdk/references/ringing-voip.md +369 -0
- package/skills/cometchat-react-v7-calls/SKILL.md +75 -0
- package/skills/cometchat-react-v7-components/SKILL.md +72 -0
- package/skills/cometchat-react-v7-core/SKILL.md +101 -0
- package/skills/cometchat-react-v7-core/references/anti-patterns.md +19 -0
- package/skills/cometchat-react-v7-core/references/component-props.md +82 -0
- package/skills/cometchat-react-v7-core/references/dependencies.md +23 -0
- package/skills/cometchat-react-v7-core/references/docs-map.md +117 -0
- package/skills/cometchat-react-v7-core/references/layout.md +150 -0
- package/skills/cometchat-react-v7-core/references/lifecycle.md +74 -0
- package/skills/cometchat-react-v7-core/references/setup-credentials.md +58 -0
- package/skills/cometchat-react-v7-core/references/ssr.md +11 -0
- package/skills/cometchat-react-v7-core/references/theming.md +52 -0
- package/skills/cometchat-react-v7-customization/SKILL.md +84 -0
- package/skills/cometchat-react-v7-features/SKILL.md +92 -0
- package/skills/cometchat-react-v7-migration/SKILL.md +39 -0
- package/skills/cometchat-react-v7-migration/references/migration-guide.md +119 -0
- package/skills/cometchat-react-v7-patterns/SKILL.md +43 -0
- package/skills/cometchat-react-v7-placement/SKILL.md +106 -0
- package/skills/cometchat-react-v7-placement/references/recipes.md +354 -0
- package/skills/cometchat-react-v7-production/SKILL.md +84 -0
- package/skills/cometchat-react-v7-push/SKILL.md +53 -0
- package/skills/cometchat-react-v7-testing/SKILL.md +60 -0
- package/skills/cometchat-react-v7-troubleshooting/SKILL.md +47 -0
- package/skills/cometchat-security/SKILL.md +80 -0
- package/skills/cometchat-self-host/SKILL.md +56 -0
- package/test-suite/README.md +70 -0
- package/test-suite/catalogs/android-calls-v5.json +830 -0
- package/test-suite/catalogs/android-calls-v5.symbols.txt +499 -0
- package/test-suite/catalogs/android-v6.json +1646 -0
- package/test-suite/catalogs/android-v6.symbols.txt +298 -0
- package/test-suite/catalogs/angular-v5.json +7587 -0
- package/test-suite/catalogs/flutter-calls-v5.json +196 -0
- package/test-suite/catalogs/flutter-calls-v5.symbols.txt +59 -0
- package/test-suite/catalogs/flutter-v6.json +651 -0
- package/test-suite/catalogs/ios-calls-v5.json +158 -0
- package/test-suite/catalogs/ios-calls-v5.symbols.txt +70 -0
- package/test-suite/catalogs/ios-v5.json +1383 -0
- package/test-suite/catalogs/ios-v5.symbols.txt +699 -0
- package/test-suite/catalogs/rn-calls-v5.json +134 -0
- package/test-suite/catalogs/rn-sdk-v4.json +672 -0
- package/test-suite/catalogs/rn-v5.json +449 -0
- package/test-suite/catalogs/sdk-android-v5.json +514 -0
- package/test-suite/catalogs/sdk-android-v5.symbols.txt +254 -0
- package/test-suite/catalogs/sdk-jsv4.json +800 -0
- package/test-suite/catalogs/web-calls-v5.json +195 -0
- package/test-suite/catalogs/web-v7.json +1243 -0
- package/test-suite/scripts/build-registry.mjs +113 -0
- package/test-suite/scripts/catalog-refresh-dart.mjs +151 -0
- package/test-suite/scripts/catalog-refresh.mjs +100 -0
- package/test-suite/scripts/lint-skills.mjs +932 -0
- package/test-suite/scripts/measure-tokens.mjs +169 -0
- package/test-suite/scripts/typecheck-fences-dart.mjs +437 -0
- package/test-suite/scripts/typecheck-fences-kotlin.mjs +269 -0
- package/test-suite/scripts/typecheck-fences.mjs +206 -0
- package/test-suite/scripts/verify-catalog.mjs +242 -0
- package/test-suite/scripts/verify-contract-fences.mjs +94 -0
- package/test-suite/scripts/verify-detection.mjs +178 -0
- package/test-suite/scripts/verify-docs-base.mjs +91 -0
- package/test-suite/scripts/verify-family-agnostic.mjs +134 -0
- package/test-suite/scripts/verify-golden-path.mjs +138 -0
- package/test-suite/scripts/verify-oracle-components.mjs +133 -0
- package/test-suite/scripts/verify-template-bindings.mjs +148 -0
- package/test-suite/typecheck/angular-v5/package.json +21 -0
- package/test-suite/typecheck/angular-v5/tsconfig.json +21 -0
- package/test-suite/typecheck/flutter-v6/analysis_options.yaml +25 -0
- package/test-suite/typecheck/flutter-v6/pubspec.yaml +21 -0
- package/test-suite/typecheck/web-v7/package.json +18 -0
- package/test-suite/typecheck/web-v7/tsconfig.json +19 -0
- package/bin/install.js +0 -1003
- package/skills/.claude-plugin/marketplace.json +0 -86
- package/skills/cometchat/references/asking-questions.md +0 -48
- package/skills/cometchat-android-v5/SKILL.md +0 -121
- package/skills/cometchat-android-v5-calls/SKILL.md +0 -429
- package/skills/cometchat-android-v5-calls/references/README.md +0 -53
- package/skills/cometchat-android-v5-calls/references/add-calls-to-existing-chat.md +0 -197
- package/skills/cometchat-android-v5-calls/references/audio-controls.md +0 -91
- package/skills/cometchat-android-v5-calls/references/background-handling.md +0 -168
- package/skills/cometchat-android-v5-calls/references/call-layouts.md +0 -131
- package/skills/cometchat-android-v5-calls/references/call-logs.md +0 -113
- package/skills/cometchat-android-v5-calls/references/call-session.md +0 -274
- package/skills/cometchat-android-v5-calls/references/custom-ui.md +0 -150
- package/skills/cometchat-android-v5-calls/references/event-listeners.md +0 -123
- package/skills/cometchat-android-v5-calls/references/group-calls.md +0 -205
- package/skills/cometchat-android-v5-calls/references/idle-timeout.md +0 -117
- package/skills/cometchat-android-v5-calls/references/in-call-chat.md +0 -134
- package/skills/cometchat-android-v5-calls/references/join-session.md +0 -120
- package/skills/cometchat-android-v5-calls/references/migration-v4-to-v5.md +0 -222
- package/skills/cometchat-android-v5-calls/references/participant-management.md +0 -110
- package/skills/cometchat-android-v5-calls/references/picture-in-picture.md +0 -106
- package/skills/cometchat-android-v5-calls/references/raise-hand.md +0 -248
- package/skills/cometchat-android-v5-calls/references/recording.md +0 -101
- package/skills/cometchat-android-v5-calls/references/ringing-integration.md +0 -152
- package/skills/cometchat-android-v5-calls/references/screen-sharing.md +0 -78
- package/skills/cometchat-android-v5-calls/references/server-fcm-voip.md +0 -215
- package/skills/cometchat-android-v5-calls/references/session-settings.md +0 -121
- package/skills/cometchat-android-v5-calls/references/setup.md +0 -137
- package/skills/cometchat-android-v5-calls/references/share-invite.md +0 -156
- package/skills/cometchat-android-v5-calls/references/video-controls.md +0 -87
- package/skills/cometchat-android-v5-calls/references/voip-calling.md +0 -526
- package/skills/cometchat-android-v5-components/SKILL.md +0 -431
- package/skills/cometchat-android-v5-core/SKILL.md +0 -486
- package/skills/cometchat-android-v5-customization/SKILL.md +0 -469
- package/skills/cometchat-android-v5-extensions/SKILL.md +0 -127
- package/skills/cometchat-android-v5-features/SKILL.md +0 -131
- package/skills/cometchat-android-v5-placement/SKILL.md +0 -277
- package/skills/cometchat-android-v5-production/SKILL.md +0 -95
- package/skills/cometchat-android-v5-push/SKILL.md +0 -619
- package/skills/cometchat-android-v5-testing/SKILL.md +0 -188
- package/skills/cometchat-android-v5-theming/SKILL.md +0 -167
- package/skills/cometchat-android-v5-troubleshooting/SKILL.md +0 -74
- package/skills/cometchat-android-v6/SKILL.md +0 -108
- package/skills/cometchat-android-v6-calls/references/add-calls-to-existing-chat.md +0 -97
- package/skills/cometchat-android-v6-calls/references/advanced-features.md +0 -87
- package/skills/cometchat-android-v6-calls/references/call-layouts.md +0 -100
- package/skills/cometchat-android-v6-calls/references/call-session.md +0 -163
- package/skills/cometchat-android-v6-calls/references/device-management.md +0 -172
- package/skills/cometchat-android-v6-calls/references/group-calls.md +0 -191
- package/skills/cometchat-android-v6-calls/references/idle-timeout.md +0 -110
- package/skills/cometchat-android-v6-calls/references/in-call-chat.md +0 -141
- package/skills/cometchat-android-v6-calls/references/raise-hand.md +0 -188
- package/skills/cometchat-android-v6-calls/references/ringing-integration.md +0 -176
- package/skills/cometchat-android-v6-calls/references/server-fcm-voip.md +0 -127
- package/skills/cometchat-android-v6-calls/references/share-invite.md +0 -105
- package/skills/cometchat-android-v6-compose-theming/SKILL.md +0 -250
- package/skills/cometchat-android-v6-kotlin-theming/SKILL.md +0 -233
- package/skills/cometchat-angular-calls/SKILL.md +0 -380
- package/skills/cometchat-angular-calls/references/add-calls-to-existing-chat.md +0 -96
- package/skills/cometchat-angular-calls/references/call-layouts.md +0 -123
- package/skills/cometchat-angular-calls/references/call-session.md +0 -167
- package/skills/cometchat-angular-calls/references/custom-ui.md +0 -239
- package/skills/cometchat-angular-calls/references/device-management.md +0 -154
- package/skills/cometchat-angular-calls/references/group-calls.md +0 -433
- package/skills/cometchat-angular-calls/references/idle-timeout.md +0 -161
- package/skills/cometchat-angular-calls/references/in-call-chat.md +0 -148
- package/skills/cometchat-angular-calls/references/lazy-loading-pitfalls.md +0 -205
- package/skills/cometchat-angular-calls/references/migration-v4-to-v5.md +0 -53
- package/skills/cometchat-angular-calls/references/ngzone-and-async-callbacks.md +0 -184
- package/skills/cometchat-angular-calls/references/picture-in-picture.md +0 -285
- package/skills/cometchat-angular-calls/references/raise-hand.md +0 -172
- package/skills/cometchat-angular-calls/references/recording-screen-share.md +0 -260
- package/skills/cometchat-angular-calls/references/ringing-integration.md +0 -133
- package/skills/cometchat-angular-calls/references/server-web-push-vapid.md +0 -100
- package/skills/cometchat-angular-calls/references/share-invite.md +0 -122
- package/skills/cometchat-angular-calls/references/virtual-background.md +0 -29
- package/skills/cometchat-angular-components/SKILL.md +0 -235
- package/skills/cometchat-angular-core/SKILL.md +0 -386
- package/skills/cometchat-angular-customization/SKILL.md +0 -616
- package/skills/cometchat-angular-features/SKILL.md +0 -329
- package/skills/cometchat-angular-patterns/SKILL.md +0 -256
- package/skills/cometchat-angular-placement/SKILL.md +0 -314
- package/skills/cometchat-angular-production/SKILL.md +0 -564
- package/skills/cometchat-angular-push/SKILL.md +0 -389
- package/skills/cometchat-angular-testing/SKILL.md +0 -605
- package/skills/cometchat-angular-theming/SKILL.md +0 -290
- package/skills/cometchat-angular-troubleshooting/SKILL.md +0 -364
- package/skills/cometchat-astro-patterns/SKILL.md +0 -708
- package/skills/cometchat-calls/SKILL.md +0 -364
- package/skills/cometchat-calls/references/use-case-broadcast.md +0 -199
- package/skills/cometchat-calls/references/use-case-marketplace.md +0 -157
- package/skills/cometchat-calls/references/use-case-support.md +0 -189
- package/skills/cometchat-calls/references/use-case-team.md +0 -180
- package/skills/cometchat-calls/references/use-case-telehealth.md +0 -153
- package/skills/cometchat-components/SKILL.md +0 -1142
- package/skills/cometchat-core/SKILL.md +0 -1048
- package/skills/cometchat-customization/SKILL.md +0 -580
- package/skills/cometchat-customization/references/component-catalog.md +0 -236
- package/skills/cometchat-features/SKILL.md +0 -861
- package/skills/cometchat-flutter-v5/SKILL.md +0 -173
- package/skills/cometchat-flutter-v5-calls/SKILL.md +0 -455
- package/skills/cometchat-flutter-v5-calls/references/add-calls-to-existing-chat.md +0 -193
- package/skills/cometchat-flutter-v5-calls/references/call-layouts.md +0 -103
- package/skills/cometchat-flutter-v5-calls/references/call-session.md +0 -285
- package/skills/cometchat-flutter-v5-calls/references/device-management.md +0 -124
- package/skills/cometchat-flutter-v5-calls/references/group-calls.md +0 -181
- package/skills/cometchat-flutter-v5-calls/references/idle-timeout.md +0 -99
- package/skills/cometchat-flutter-v5-calls/references/in-call-chat.md +0 -135
- package/skills/cometchat-flutter-v5-calls/references/migration-v4-to-v5.md +0 -210
- package/skills/cometchat-flutter-v5-calls/references/raise-hand.md +0 -255
- package/skills/cometchat-flutter-v5-calls/references/ringing-integration.md +0 -196
- package/skills/cometchat-flutter-v5-calls/references/server-push-bridge.md +0 -101
- package/skills/cometchat-flutter-v5-calls/references/share-invite.md +0 -148
- package/skills/cometchat-flutter-v5-conversations/SKILL.md +0 -118
- package/skills/cometchat-flutter-v5-core/SKILL.md +0 -239
- package/skills/cometchat-flutter-v5-customization/SKILL.md +0 -358
- package/skills/cometchat-flutter-v5-events/SKILL.md +0 -156
- package/skills/cometchat-flutter-v5-messages/SKILL.md +0 -259
- package/skills/cometchat-flutter-v5-production/SKILL.md +0 -216
- package/skills/cometchat-flutter-v5-push/SKILL.md +0 -285
- package/skills/cometchat-flutter-v5-testing/SKILL.md +0 -401
- package/skills/cometchat-flutter-v5-theming/SKILL.md +0 -161
- package/skills/cometchat-flutter-v5-troubleshooting/SKILL.md +0 -130
- package/skills/cometchat-flutter-v5-users-groups/SKILL.md +0 -152
- package/skills/cometchat-flutter-v6/SKILL.md +0 -446
- package/skills/cometchat-flutter-v6-calls/references/add-calls-to-existing-chat.md +0 -136
- package/skills/cometchat-flutter-v6-calls/references/advanced-features.md +0 -89
- package/skills/cometchat-flutter-v6-calls/references/call-layouts.md +0 -105
- package/skills/cometchat-flutter-v6-calls/references/call-session.md +0 -229
- package/skills/cometchat-flutter-v6-calls/references/device-management.md +0 -105
- package/skills/cometchat-flutter-v6-calls/references/group-calls.md +0 -190
- package/skills/cometchat-flutter-v6-calls/references/idle-timeout.md +0 -88
- package/skills/cometchat-flutter-v6-calls/references/in-call-chat.md +0 -125
- package/skills/cometchat-flutter-v6-calls/references/raise-hand.md +0 -275
- package/skills/cometchat-flutter-v6-calls/references/ringing-integration.md +0 -171
- package/skills/cometchat-flutter-v6-calls/references/server-push-bridge.md +0 -93
- package/skills/cometchat-flutter-v6-calls/references/share-invite.md +0 -102
- package/skills/cometchat-flutter-v6-conversations/SKILL.md +0 -238
- package/skills/cometchat-flutter-v6-messages/SKILL.md +0 -384
- package/skills/cometchat-flutter-v6-theming/SKILL.md +0 -293
- package/skills/cometchat-flutter-v6-users-groups/SKILL.md +0 -224
- package/skills/cometchat-ios/SKILL.md +0 -325
- package/skills/cometchat-ios-calls/references/add-calls-to-existing-chat.md +0 -181
- package/skills/cometchat-ios-calls/references/audio-modes-and-controls.md +0 -45
- package/skills/cometchat-ios-calls/references/avaudiosession-routing.md +0 -188
- package/skills/cometchat-ios-calls/references/call-layouts.md +0 -76
- package/skills/cometchat-ios-calls/references/call-session.md +0 -218
- package/skills/cometchat-ios-calls/references/callkit-and-pushkit.md +0 -357
- package/skills/cometchat-ios-calls/references/custom-ui.md +0 -322
- package/skills/cometchat-ios-calls/references/device-management.md +0 -171
- package/skills/cometchat-ios-calls/references/group-calls.md +0 -359
- package/skills/cometchat-ios-calls/references/idle-timeout.md +0 -184
- package/skills/cometchat-ios-calls/references/in-call-chat.md +0 -179
- package/skills/cometchat-ios-calls/references/migration-v4-to-v5.md +0 -196
- package/skills/cometchat-ios-calls/references/picture-in-picture.md +0 -246
- package/skills/cometchat-ios-calls/references/raise-hand.md +0 -26
- package/skills/cometchat-ios-calls/references/recording-screen-share.md +0 -252
- package/skills/cometchat-ios-calls/references/ringing-integration.md +0 -143
- package/skills/cometchat-ios-calls/references/server-apns-pushkit.md +0 -267
- package/skills/cometchat-ios-calls/references/share-invite.md +0 -148
- package/skills/cometchat-ios-calls/references/swiftui-uikit-hosting.md +0 -246
- package/skills/cometchat-ios-calls/references/voip-cert-setup.md +0 -166
- package/skills/cometchat-ios-theming/SKILL.md +0 -667
- package/skills/cometchat-native-bare-patterns/SKILL.md +0 -550
- package/skills/cometchat-native-calls/SKILL.md +0 -671
- package/skills/cometchat-native-calls/references/add-calls-to-existing-chat.md +0 -203
- package/skills/cometchat-native-calls/references/call-layouts.md +0 -125
- package/skills/cometchat-native-calls/references/call-session.md +0 -182
- package/skills/cometchat-native-calls/references/custom-ui.md +0 -254
- package/skills/cometchat-native-calls/references/device-management.md +0 -158
- package/skills/cometchat-native-calls/references/expo-vs-bare.md +0 -179
- package/skills/cometchat-native-calls/references/group-calls.md +0 -296
- package/skills/cometchat-native-calls/references/idle-timeout.md +0 -128
- package/skills/cometchat-native-calls/references/in-call-chat.md +0 -145
- package/skills/cometchat-native-calls/references/migration-v4-to-v5.md +0 -72
- package/skills/cometchat-native-calls/references/picture-in-picture.md +0 -276
- package/skills/cometchat-native-calls/references/raise-hand.md +0 -205
- package/skills/cometchat-native-calls/references/recording-screen-share.md +0 -169
- package/skills/cometchat-native-calls/references/ringing-integration.md +0 -118
- package/skills/cometchat-native-calls/references/server-push-bridge.md +0 -135
- package/skills/cometchat-native-calls/references/server-push-payloads.md +0 -193
- package/skills/cometchat-native-calls/references/share-invite.md +0 -146
- package/skills/cometchat-native-calls/references/voip-push-end-to-end.md +0 -319
- package/skills/cometchat-native-components/SKILL.md +0 -628
- package/skills/cometchat-native-core/SKILL.md +0 -679
- package/skills/cometchat-native-customization/SKILL.md +0 -716
- package/skills/cometchat-native-expo-patterns/SKILL.md +0 -552
- package/skills/cometchat-native-features/SKILL.md +0 -638
- package/skills/cometchat-native-placement/SKILL.md +0 -509
- package/skills/cometchat-native-production/SKILL.md +0 -700
- package/skills/cometchat-native-push/SKILL.md +0 -594
- package/skills/cometchat-native-testing/SKILL.md +0 -582
- package/skills/cometchat-native-theming/SKILL.md +0 -681
- package/skills/cometchat-native-troubleshooting/SKILL.md +0 -501
- package/skills/cometchat-nextjs-patterns/SKILL.md +0 -899
- package/skills/cometchat-placement/SKILL.md +0 -1360
- package/skills/cometchat-production/SKILL.md +0 -1027
- package/skills/cometchat-react-calls/SKILL.md +0 -752
- package/skills/cometchat-react-calls/references/add-calls-to-existing-chat.md +0 -146
- package/skills/cometchat-react-calls/references/call-layouts.md +0 -160
- package/skills/cometchat-react-calls/references/call-session.md +0 -235
- package/skills/cometchat-react-calls/references/custom-ui.md +0 -247
- package/skills/cometchat-react-calls/references/device-management.md +0 -210
- package/skills/cometchat-react-calls/references/group-calls.md +0 -257
- package/skills/cometchat-react-calls/references/idle-timeout.md +0 -188
- package/skills/cometchat-react-calls/references/in-call-chat.md +0 -212
- package/skills/cometchat-react-calls/references/migration-v4-to-v5.md +0 -170
- package/skills/cometchat-react-calls/references/picture-in-picture.md +0 -245
- package/skills/cometchat-react-calls/references/raise-hand.md +0 -238
- package/skills/cometchat-react-calls/references/recording-screen-share.md +0 -144
- package/skills/cometchat-react-calls/references/ringing-integration.md +0 -255
- package/skills/cometchat-react-calls/references/server-web-push-vapid.md +0 -241
- package/skills/cometchat-react-calls/references/share-invite.md +0 -175
- package/skills/cometchat-react-calls/references/testing-calls-on-web.md +0 -216
- package/skills/cometchat-react-calls/references/virtual-background.md +0 -32
- package/skills/cometchat-react-calls/references/voip-and-web-push.md +0 -165
- package/skills/cometchat-react-patterns/SKILL.md +0 -628
- package/skills/cometchat-react-push/SKILL.md +0 -634
- package/skills/cometchat-react-router-patterns/SKILL.md +0 -758
- package/skills/cometchat-react-testing/SKILL.md +0 -413
- package/skills/cometchat-theming/SKILL.md +0 -498
- package/skills/cometchat-troubleshooting/SKILL.md +0 -294
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
# Recording + screen sharing on web
|
|
2
|
-
|
|
3
|
-
Both features ship with the Calls SDK; both have web-specific gotchas the kit's defaults don't handle.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Recording
|
|
8
|
-
|
|
9
|
-
### Server-side: enable in the dashboard first
|
|
10
|
-
|
|
11
|
-
Recording is a paid feature gated by your CometChat plan. Enable it in **Dashboard → Chat & Messaging → Calls → Recording**. Without that, the client-side flag below is a no-op.
|
|
12
|
-
|
|
13
|
-
### Client-side: opt-in per session
|
|
14
|
-
|
|
15
|
-
```ts
|
|
16
|
-
// SessionSettings object passed to joinSession(token, settings, container).
|
|
17
|
-
// These are object fields — NOT CallSettingsBuilder methods (the v4 builder had
|
|
18
|
-
// enableRecording/setShowRecordingButton; v5 uses the object below).
|
|
19
|
-
const settings = {
|
|
20
|
-
sessionType: 'VIDEO', // 'VOICE' for audio-only (replaces setIsAudioOnly)
|
|
21
|
-
autoStartRecording: true, // ← server starts recording when the session begins
|
|
22
|
-
hideRecordingButton: false, // ← keep the user-toggleable Record button visible
|
|
23
|
-
};
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
Two fields, two behaviors:
|
|
27
|
-
|
|
28
|
-
- `autoStartRecording: true` — recording starts the moment the session begins. Server-side flag.
|
|
29
|
-
- `hideRecordingButton: false` — exposes a "Record" toggle in the default control panel. User decides when to start/stop. Custom-UI code must wire its own button (`CometChatCalls.startRecording()` / `stopRecording()` — there is no `toggleRecording()`; track state yourself and call the right one).
|
|
30
|
-
|
|
31
|
-
**Compliance note:** in some jurisdictions you must notify all participants before recording starts. The default kit UI shows a small "Recording" indicator; if you're using custom UI, you must render this yourself. The skill's verification checklist flags this.
|
|
32
|
-
|
|
33
|
-
### Recording lifecycle events
|
|
34
|
-
|
|
35
|
-
```ts
|
|
36
|
-
// v5 uses the static event bus; addEventListener returns an unsubscribe fn.
|
|
37
|
-
const offStarted = CometChatCalls.addEventListener("onRecordingStarted", () => {
|
|
38
|
-
// server confirmed recording is active
|
|
39
|
-
});
|
|
40
|
-
const offStopped = CometChatCalls.addEventListener("onRecordingStopped", () => {
|
|
41
|
-
// server stopped — file will appear in dashboard within ~30 seconds
|
|
42
|
-
});
|
|
43
|
-
// Cleanup when the call ends: offStarted(); offStopped();
|
|
44
|
-
//
|
|
45
|
-
// NOTE: there is no `onRecordingFailed` event on the v5 bus (and no
|
|
46
|
-
// onRecordingFailed member on OngoingCallListener). Plan-limit / storage-quota
|
|
47
|
-
// failures surface as a rejection from generateToken/joinSession or a server
|
|
48
|
-
// error — handle those, not a dedicated recording-failed callback.
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
### Where the recordings go
|
|
52
|
-
|
|
53
|
-
CometChat hosts the file. It appears in **Dashboard → Calls → Recordings** with a download link. The skill points users at the dashboard path; there is no client-side download API.
|
|
54
|
-
|
|
55
|
-
---
|
|
56
|
-
|
|
57
|
-
## Screen sharing
|
|
58
|
-
|
|
59
|
-
### Two roles: presenter + viewer
|
|
60
|
-
|
|
61
|
-
- **Presenter** (the user sharing their screen) — calls `CometChatCalls.startScreenSharing()`; the SDK handles `getDisplayMedia` + signaling internally
|
|
62
|
-
- **Viewer** (everyone else) — sees the presenter's screen as another video tile, no special API call needed
|
|
63
|
-
|
|
64
|
-
Browser support: Chrome/Edge (full), Firefox (full), Safari 13+ (full). On mobile browsers, `getDisplayMedia` is supported on iOS 16+ Safari and recent Android Chrome.
|
|
65
|
-
|
|
66
|
-
### Presenter — start sharing
|
|
67
|
-
|
|
68
|
-
```ts
|
|
69
|
-
async function startScreenShare() {
|
|
70
|
-
try {
|
|
71
|
-
CometChatCalls.startScreenSharing();
|
|
72
|
-
// SDK handled getDisplayMedia + signaling; UI updates via onScreenShareStarted
|
|
73
|
-
} catch (err: unknown) {
|
|
74
|
-
if ((err as Error).name === "NotAllowedError") {
|
|
75
|
-
// user clicked "Cancel" on the picker — no error UI needed
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
setError("Couldn't start screen share");
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
Stop sharing:
|
|
84
|
-
|
|
85
|
-
```ts
|
|
86
|
-
CometChatCalls.stopScreenSharing();
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
The browser also fires its own "Stop sharing" button (the system overlay Chrome shows during a screen-share). The SDK listens for this too; `onScreenShareStopped` fires either way.
|
|
90
|
-
|
|
91
|
-
### Viewer — listen for screen-share events
|
|
92
|
-
|
|
93
|
-
```ts
|
|
94
|
-
// The v5 bus callbacks take NO arguments — they're notifications, not stream
|
|
95
|
-
// handoffs. The SDK renders the presenter's screen as a tile in its own layout;
|
|
96
|
-
// you don't receive a MediaStream to attach yourself (that was the v4 model).
|
|
97
|
-
const offStart = CometChatCalls.addEventListener("onScreenShareStarted", () => {
|
|
98
|
-
setSomeoneSharing(true);
|
|
99
|
-
});
|
|
100
|
-
const offStop = CometChatCalls.addEventListener("onScreenShareStopped", () => {
|
|
101
|
-
setSomeoneSharing(false);
|
|
102
|
-
});
|
|
103
|
-
// Cleanup: offStart(); offStop();
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
The SDK composes the screen-share tile alongside the camera tiles automatically. (Truly hand-rendering the shared stream requires the deprecated `OngoingCallListener` + `startSession` track-level path — see `custom-ui.md`.)
|
|
107
|
-
|
|
108
|
-
### Audio passthrough during screen share
|
|
109
|
-
|
|
110
|
-
By default, `getDisplayMedia` captures video only. To capture system audio (for sharing a video with sound), pass `audio: true`:
|
|
111
|
-
|
|
112
|
-
```ts
|
|
113
|
-
// Browser-level API — the SDK's startScreenSharing wraps this internally
|
|
114
|
-
const stream = await navigator.mediaDevices.getDisplayMedia({
|
|
115
|
-
video: true,
|
|
116
|
-
audio: true,
|
|
117
|
-
});
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
Browser support is uneven — Chrome desktop has it; Firefox does not; Safari has it for tab capture but not full-screen.
|
|
121
|
-
|
|
122
|
-
The Calls SDK's `startScreenSharing()` does NOT request audio by default. If you need audio passthrough, use the lower-level `getDisplayMedia` API directly + pipe the audio track via a custom track-add hook (covered in `custom-ui.md`).
|
|
123
|
-
|
|
124
|
-
---
|
|
125
|
-
|
|
126
|
-
## Combining recording + screen-share
|
|
127
|
-
|
|
128
|
-
Server-side recording captures the active video composition, including screen-share when a participant is sharing. The recording file is one MP4 with the layout the kit was rendering at the time.
|
|
129
|
-
|
|
130
|
-
If you're using custom UI, the recording captures what the SDK sends to the server — not your custom DOM. The composition is determined by the SDK's internal layout, not your CSS.
|
|
131
|
-
|
|
132
|
-
---
|
|
133
|
-
|
|
134
|
-
## Browser permissions for screen-share
|
|
135
|
-
|
|
136
|
-
Like `getUserMedia`, `getDisplayMedia` requires HTTPS or `localhost`. It also requires an active user gesture (click/tap) — you cannot start it from a `useEffect` or timer. The skill scaffolds the API call inside an onClick handler.
|
|
137
|
-
|
|
138
|
-
System-level: macOS 10.15+ asks the user once to grant Chrome/Safari/Firefox permission to record the screen (System Preferences → Security & Privacy → Screen Recording). If the user denies, `getDisplayMedia` throws `NotAllowedError` with no remediation path inside the browser — surface a "Open System Preferences" instruction.
|
|
139
|
-
|
|
140
|
-
---
|
|
141
|
-
|
|
142
|
-
## Cleanup
|
|
143
|
-
|
|
144
|
-
Both recording and screen-share are part of the call session. `CometChatCalls.leaveSession()` stops both automatically. Custom UI must NOT separately call `getTracks().forEach(t => t.stop())` on the SDK's screen-share stream — the SDK owns it. Stop only the streams YOUR code created (e.g. local preview).
|
|
@@ -1,255 +0,0 @@
|
|
|
1
|
-
# Ringing — call signaling with custom UI (web)
|
|
2
|
-
|
|
3
|
-
The Ringing flow uses the **Chat SDK's call entity** for signaling (initiate / ring / accept / reject / cancel) and the **Calls SDK** for the actual WebRTC session. This is the right pattern when you want a custom incoming-call UI on top of CometChat's signaling — not the kit's prebuilt `CometChatIncomingCall`.
|
|
4
|
-
|
|
5
|
-
**Three calling modes — pick the right one:**
|
|
6
|
-
|
|
7
|
-
| Mode | Driver | When to use |
|
|
8
|
-
|---|---|---|
|
|
9
|
-
| **Standard** | UI Kit (`CometChatCallButtons` + `CometChatIncomingCall`) | 80% case — chat-driven calls with prebuilt UI |
|
|
10
|
-
| **Ringing (this doc)** | Chat SDK call entity + Calls SDK session | Custom incoming/outgoing call UI on top of CometChat signaling |
|
|
11
|
-
| **Call Session** (see `call-session.md`) | Calls SDK `joinSession` directly | Meeting-room URLs, scheduled calls, no ringing |
|
|
12
|
-
|
|
13
|
-
**Canonical docs:** https://www.cometchat.com/docs/calls/javascript/ringing
|
|
14
|
-
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
## Architecture
|
|
18
|
-
|
|
19
|
-
```
|
|
20
|
-
Caller CometChat Recipient
|
|
21
|
-
│ │ │
|
|
22
|
-
│ CometChat.initiateCall(call) │ │
|
|
23
|
-
├────────────────────────────────────>│ │
|
|
24
|
-
│ │ onIncomingCallReceived │
|
|
25
|
-
│ ├───────────────────────────────>│
|
|
26
|
-
│ │ │
|
|
27
|
-
│ │ CometChat.acceptCall(sid) │
|
|
28
|
-
│ │<───────────────────────────────│
|
|
29
|
-
│ onOutgoingCallAccepted │ │
|
|
30
|
-
│<────────────────────────────────────┤ │
|
|
31
|
-
│ │ │
|
|
32
|
-
│ CometChatCalls.joinSession(token) │ CometChatCalls.joinSession(token)
|
|
33
|
-
├────────────────────────────────────>│<───────────────────────────────│
|
|
34
|
-
│ ───── WebRTC session active ───── │
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
The Chat SDK is the signaling channel; the Calls SDK is the media channel. Same sessionId binds them.
|
|
38
|
-
|
|
39
|
-
---
|
|
40
|
-
|
|
41
|
-
## Hard rules
|
|
42
|
-
|
|
43
|
-
1. **Both SDKs must be initialized** — `CometChat.init` for signaling, `CometChatCalls.init` for media. Sequential, in that order.
|
|
44
|
-
2. **`addCallListener` must be live BEFORE you start receiving calls.** Add it on app start, after login. Otherwise incoming-call events are missed.
|
|
45
|
-
3. **`CometChatCalls.joinSession` happens AFTER `CometChat.acceptCall` resolves** — accepting tells the backend you're ready; joining the session enters WebRTC. Reversing this fires media before the chat-side state agrees.
|
|
46
|
-
4. **End the call on BOTH SDKs.** `CometChatCalls.leaveSession()` for media, `CometChat.endCall(sessionId)` for the chat-side call record. Skipping either leaves a zombie.
|
|
47
|
-
5. **Listen for `onCallEndedMessageReceived`** for the case where the OTHER party ended. Without it, your UI keeps showing "in-call" while the session is dead.
|
|
48
|
-
6. **Custom timeout (default 45s)** — `CometChat.initiateCall(call, 60)` sets ringing duration. After timeout, the backend auto-cancels and the recipient stops seeing the call.
|
|
49
|
-
|
|
50
|
-
---
|
|
51
|
-
|
|
52
|
-
## Initiate (caller side)
|
|
53
|
-
|
|
54
|
-
```ts
|
|
55
|
-
import { CometChat } from "@cometchat/chat-sdk-javascript";
|
|
56
|
-
|
|
57
|
-
async function initiateCall(receiverUid: string, callType: "audio" | "video" = "video") {
|
|
58
|
-
const call = new CometChat.Call(
|
|
59
|
-
receiverUid,
|
|
60
|
-
callType === "video" ? CometChat.CALL_TYPE.VIDEO : CometChat.CALL_TYPE.AUDIO,
|
|
61
|
-
CometChat.RECEIVER_TYPE.USER,
|
|
62
|
-
);
|
|
63
|
-
// Optional: 60-second ring timeout (default 45)
|
|
64
|
-
const outgoingCall = await CometChat.initiateCall(call, 60);
|
|
65
|
-
showOutgoingCallScreen(outgoingCall);
|
|
66
|
-
return outgoingCall;
|
|
67
|
-
}
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
For **group calls**, change `RECEIVER_TYPE` to `CometChat.RECEIVER_TYPE.GROUP` and use the group GUID. Only group members get the ring.
|
|
71
|
-
|
|
72
|
-
---
|
|
73
|
-
|
|
74
|
-
## Listen for events (recipient + caller)
|
|
75
|
-
|
|
76
|
-
```tsx
|
|
77
|
-
import { useEffect } from "react";
|
|
78
|
-
|
|
79
|
-
const LISTENER_ID = "app-call-listener";
|
|
80
|
-
|
|
81
|
-
export function useCometChatCallListener() {
|
|
82
|
-
useEffect(() => {
|
|
83
|
-
CometChat.addCallListener(
|
|
84
|
-
LISTENER_ID,
|
|
85
|
-
new CometChat.CallListener({
|
|
86
|
-
onIncomingCallReceived: (call) => {
|
|
87
|
-
// Show your custom incoming-call UI
|
|
88
|
-
showIncomingCallScreen(call);
|
|
89
|
-
},
|
|
90
|
-
onOutgoingCallAccepted: (acceptedCall) => {
|
|
91
|
-
// Other party accepted — start the session
|
|
92
|
-
hideOutgoingCallScreen();
|
|
93
|
-
startCallSession(acceptedCall.getSessionId());
|
|
94
|
-
},
|
|
95
|
-
onOutgoingCallRejected: (rejectedCall) => {
|
|
96
|
-
hideOutgoingCallScreen();
|
|
97
|
-
// Optional: toast "User declined"
|
|
98
|
-
},
|
|
99
|
-
onIncomingCallCancelled: (cancelledCall) => {
|
|
100
|
-
// Caller hung up before you accepted
|
|
101
|
-
hideIncomingCallScreen();
|
|
102
|
-
},
|
|
103
|
-
onCallEndedMessageReceived: (endedCall) => {
|
|
104
|
-
// Other party ended the active session
|
|
105
|
-
teardownCallUI();
|
|
106
|
-
},
|
|
107
|
-
}),
|
|
108
|
-
);
|
|
109
|
-
return () => CometChat.removeCallListener(LISTENER_ID);
|
|
110
|
-
}, []);
|
|
111
|
-
}
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
Mount this hook at app root (e.g. in `App.tsx`) so listeners survive route changes — the same reasoning as for `<CometChatIncomingCall />`.
|
|
115
|
-
|
|
116
|
-
---
|
|
117
|
-
|
|
118
|
-
## Accept (recipient side)
|
|
119
|
-
|
|
120
|
-
```ts
|
|
121
|
-
async function acceptIncomingCall(call: CometChat.Call) {
|
|
122
|
-
const accepted = await CometChat.acceptCall(call.getSessionId());
|
|
123
|
-
hideIncomingCallScreen();
|
|
124
|
-
startCallSession(accepted.getSessionId());
|
|
125
|
-
}
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
---
|
|
129
|
-
|
|
130
|
-
## Reject (recipient side)
|
|
131
|
-
|
|
132
|
-
```ts
|
|
133
|
-
async function rejectIncomingCall(call: CometChat.Call) {
|
|
134
|
-
await CometChat.rejectCall(
|
|
135
|
-
call.getSessionId(),
|
|
136
|
-
CometChat.CALL_STATUS.REJECTED,
|
|
137
|
-
);
|
|
138
|
-
hideIncomingCallScreen();
|
|
139
|
-
}
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
---
|
|
143
|
-
|
|
144
|
-
## Cancel outgoing (caller side, before recipient answers)
|
|
145
|
-
|
|
146
|
-
```ts
|
|
147
|
-
async function cancelOutgoingCall(call: CometChat.Call) {
|
|
148
|
-
await CometChat.rejectCall(
|
|
149
|
-
call.getSessionId(),
|
|
150
|
-
CometChat.CALL_STATUS.CANCELLED,
|
|
151
|
-
);
|
|
152
|
-
hideOutgoingCallScreen();
|
|
153
|
-
}
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
`rejectCall` is the same API for both recipient-rejecting and caller-cancelling — the `CALL_STATUS` enum distinguishes intent.
|
|
157
|
-
|
|
158
|
-
---
|
|
159
|
-
|
|
160
|
-
## Start the session (both parties, after accept)
|
|
161
|
-
|
|
162
|
-
```tsx
|
|
163
|
-
async function startCallSession(sessionId: string) {
|
|
164
|
-
const container = document.getElementById("call-container")!;
|
|
165
|
-
const tokenResult = await CometChatCalls.generateToken(sessionId);
|
|
166
|
-
|
|
167
|
-
await CometChatCalls.joinSession(
|
|
168
|
-
tokenResult.token,
|
|
169
|
-
{ sessionType: "VIDEO", layout: "TILE" },
|
|
170
|
-
container,
|
|
171
|
-
);
|
|
172
|
-
|
|
173
|
-
// Listen for session end (you ended it OR connection lost)
|
|
174
|
-
const unsub = CometChatCalls.addEventListener("onSessionLeft", () => {
|
|
175
|
-
endCall(sessionId);
|
|
176
|
-
unsub();
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
The container element must exist in the DOM **before** calling `joinSession`. In React, render a div with `id="call-container"` inside your call screen component, and call `startCallSession` from `useEffect`.
|
|
182
|
-
|
|
183
|
-
---
|
|
184
|
-
|
|
185
|
-
## End the call
|
|
186
|
-
|
|
187
|
-
```ts
|
|
188
|
-
async function endCall(sessionId: string) {
|
|
189
|
-
CometChatCalls.leaveSession();
|
|
190
|
-
await CometChat.endCall(sessionId);
|
|
191
|
-
teardownCallUI();
|
|
192
|
-
}
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
---
|
|
196
|
-
|
|
197
|
-
## Custom incoming-call UI
|
|
198
|
-
|
|
199
|
-
```tsx
|
|
200
|
-
function IncomingCallScreen({ call, onAccept, onReject }: Props) {
|
|
201
|
-
const caller = call.getCallInitiator();
|
|
202
|
-
return (
|
|
203
|
-
<div role="alertdialog" aria-labelledby="incoming-title" className="incoming-call-overlay">
|
|
204
|
-
<div className="card">
|
|
205
|
-
<img src={caller.getAvatar()} alt="" />
|
|
206
|
-
<h3 id="incoming-title">{caller.getName()}</h3>
|
|
207
|
-
<p>Incoming {call.getType()} call</p>
|
|
208
|
-
<div className="actions">
|
|
209
|
-
<button onClick={onReject} className="reject" aria-label="Decline call">Decline</button>
|
|
210
|
-
<button onClick={onAccept} className="accept" aria-label="Accept call">Accept</button>
|
|
211
|
-
</div>
|
|
212
|
-
</div>
|
|
213
|
-
<audio src="/sounds/ringtone.mp3" autoPlay loop />
|
|
214
|
-
</div>
|
|
215
|
-
);
|
|
216
|
-
}
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
`role="alertdialog"` is the right ARIA role — interrupting modal that requires user action. `<audio autoPlay loop>` plays ringtone; pause it on accept/reject in the parent.
|
|
220
|
-
|
|
221
|
-
---
|
|
222
|
-
|
|
223
|
-
## Anti-patterns
|
|
224
|
-
|
|
225
|
-
1. **`addCallListener` inside the chat route component.** Listener tears down on route change → calls received while user is on home screen are silently dropped.
|
|
226
|
-
2. **Calling `joinSession` before `acceptCall` resolves.** Race — recipient enters WebRTC before backend marks the call as "ongoing." Caller's `onOutgoingCallAccepted` may never fire.
|
|
227
|
-
3. **Forgetting to `removeCallListener` on unmount.** Multiple listeners → events fire N times. Causes "double accept" toasts.
|
|
228
|
-
4. **No `onCallEndedMessageReceived` handler.** The other party ends the call → your UI stays "in-call" → user has to refresh.
|
|
229
|
-
5. **Using `endCall` on the chat SDK without `leaveSession` on the calls SDK.** Camera light stays on; mic stays hot. The flex-shrink trap of calls.
|
|
230
|
-
6. **Mounting `CometChatIncomingCall` (kit) AND custom listener AT THE SAME TIME.** Both fire — you get duplicate incoming-call UIs. Pick one mode per app.
|
|
231
|
-
7. **`CometChat.initiateCall` without timeout when phone-ringing UX is the goal.** Default 45s is fine; if your UX rings longer, override explicitly so the recipient sees consistent UI.
|
|
232
|
-
|
|
233
|
-
---
|
|
234
|
-
|
|
235
|
-
## Verification checklist
|
|
236
|
-
|
|
237
|
-
- [ ] Both SDKs initialized in order (`CometChat.init` → `CometChatCalls.init`)
|
|
238
|
-
- [ ] `addCallListener` registered at app root (survives route changes)
|
|
239
|
-
- [ ] `removeCallListener` on unmount
|
|
240
|
-
- [ ] `acceptCall` precedes `joinSession`
|
|
241
|
-
- [ ] `endCall` (chat) AND `leaveSession` (calls) both fire on hangup
|
|
242
|
-
- [ ] `onCallEndedMessageReceived` tears down UI when other party ends
|
|
243
|
-
- [ ] `onIncomingCallCancelled` tears down UI when caller cancels mid-ring
|
|
244
|
-
- [ ] Custom UI: `role="alertdialog"`, ringtone audio, accept/decline buttons with aria-labels
|
|
245
|
-
- [ ] Smoke: **two ISOLATED browser contexts** (normal + Incognito window, or two browsers/devices — NOT two tabs of one browser; the Chat SDK is a single shared session per origin, so a second tab can't be an independent callee), caller initiates → recipient sees custom incoming UI → accept → both join session → either ends → both UIs dismiss
|
|
246
|
-
|
|
247
|
-
---
|
|
248
|
-
|
|
249
|
-
## Pointers
|
|
250
|
-
|
|
251
|
-
- `cometchat-react-calls/SKILL.md` — architecture + seven hard rules
|
|
252
|
-
- `cometchat-react-calls/references/call-session.md` — Mode 3 (joinSession with no ringing)
|
|
253
|
-
- `cometchat-react-calls/references/in-call-chat.md` — chat panel during a call
|
|
254
|
-
- `cometchat-react-calls/references/recording-screen-share.md` — recording mid-call
|
|
255
|
-
- Canonical docs: https://www.cometchat.com/docs/calls/javascript/ringing
|
|
@@ -1,241 +0,0 @@
|
|
|
1
|
-
# Server-side Web Push VAPID for browser ringing
|
|
2
|
-
|
|
3
|
-
Browsers don't have a true VoIP-push equivalent (the way iOS PushKit + Android FCM data-messages do). But **Web Push** with VAPID is the closest analog: when a CometChat call event fires, your server sends a push, the browser's Service Worker receives it (even with the tab closed), and posts a notification + plays a ringtone.
|
|
4
|
-
|
|
5
|
-
**Caveat — set expectations:** Web Push is best-effort. It works reliably when:
|
|
6
|
-
- The user has the tab open OR a recent installed PWA
|
|
7
|
-
- The browser is running (Chrome/Edge/Firefox running but minimized → ✓)
|
|
8
|
-
- Battery saver isn't aggressive
|
|
9
|
-
|
|
10
|
-
It does NOT work when:
|
|
11
|
-
- The user closed all browser windows
|
|
12
|
-
- iOS Safari except in PWA-only mode (16.4+)
|
|
13
|
-
- The user denied notification permission
|
|
14
|
-
|
|
15
|
-
For production-grade ringing on the web, recommend customers offer the iOS/Android app for unreliable-recipient scenarios.
|
|
16
|
-
|
|
17
|
-
**Canonical docs:** https://datatracker.ietf.org/doc/html/rfc8030 (Web Push), https://datatracker.ietf.org/doc/html/rfc8292 (VAPID), https://developer.mozilla.org/en-US/docs/Web/API/Push_API
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
## Hard rules
|
|
22
|
-
|
|
23
|
-
1. **VAPID keys are mandatory.** Browsers will reject pushes without them since 2018.
|
|
24
|
-
2. **Use the `web-push` library or its equivalents** — implementing VAPID JWT + AES128GCM payload encryption from scratch is error-prone.
|
|
25
|
-
3. **HTTPS required.** Web Push doesn't work on HTTP except localhost.
|
|
26
|
-
4. **Subscriptions expire.** Browsers rotate `endpoint` URLs every ~3 months on Chrome desktop. Implement re-subscription on push failure (410 Gone).
|
|
27
|
-
5. **TTL ≤ 60s for VoIP-style ringing.** A push that arrives 5 minutes late is worse than no push.
|
|
28
|
-
6. **Topic must be set** so a fresh ringing push displaces an older queued one (avoid stacking).
|
|
29
|
-
|
|
30
|
-
---
|
|
31
|
-
|
|
32
|
-
## Generate VAPID keys (one-time)
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
npx web-push generate-vapid-keys
|
|
36
|
-
# Output:
|
|
37
|
-
# Public Key: BNa... (paste into your client code)
|
|
38
|
-
# Private Key: 3kL... (server-side env var only)
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
Or via Node API:
|
|
42
|
-
|
|
43
|
-
```js
|
|
44
|
-
import webpush from "web-push";
|
|
45
|
-
const keys = webpush.generateVAPIDKeys();
|
|
46
|
-
console.log("VAPID_PUBLIC_KEY=", keys.publicKey);
|
|
47
|
-
console.log("VAPID_PRIVATE_KEY=", keys.privateKey);
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
---
|
|
51
|
-
|
|
52
|
-
## Node.js template
|
|
53
|
-
|
|
54
|
-
```js
|
|
55
|
-
// npm install web-push
|
|
56
|
-
import webpush from "web-push";
|
|
57
|
-
|
|
58
|
-
webpush.setVapidDetails(
|
|
59
|
-
`mailto:${process.env.VAPID_CONTACT_EMAIL}`,
|
|
60
|
-
process.env.VAPID_PUBLIC_KEY,
|
|
61
|
-
process.env.VAPID_PRIVATE_KEY,
|
|
62
|
-
);
|
|
63
|
-
|
|
64
|
-
export async function sendWebVoipPush(opts) {
|
|
65
|
-
const { recipientUid, sessionId, callerName, callerUid, callType } = opts;
|
|
66
|
-
|
|
67
|
-
// A user may have multiple subscriptions (laptop + work computer); fan out.
|
|
68
|
-
const subscriptions = await db.getWebPushSubscriptions(recipientUid);
|
|
69
|
-
|
|
70
|
-
const payload = JSON.stringify({
|
|
71
|
-
type: "incoming_call",
|
|
72
|
-
sessionId,
|
|
73
|
-
callerName,
|
|
74
|
-
callerUid,
|
|
75
|
-
callType,
|
|
76
|
-
timestamp: Date.now(),
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
await Promise.allSettled(
|
|
80
|
-
subscriptions.map(async (sub) => {
|
|
81
|
-
try {
|
|
82
|
-
await webpush.sendNotification(sub, payload, {
|
|
83
|
-
TTL: 30, // Hard Rule 5
|
|
84
|
-
urgency: "high", // urgency header
|
|
85
|
-
topic: `call-${sessionId}`.slice(0, 32), // Hard Rule 6 — replaces older with same topic
|
|
86
|
-
});
|
|
87
|
-
} catch (err) {
|
|
88
|
-
if (err.statusCode === 410 || err.statusCode === 404) {
|
|
89
|
-
// Endpoint dead — purge from DB
|
|
90
|
-
await db.removeWebPushSubscription(recipientUid, sub.endpoint);
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
console.error("Web push failed", err);
|
|
94
|
-
}
|
|
95
|
-
}),
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
---
|
|
101
|
-
|
|
102
|
-
## Python template (pywebpush)
|
|
103
|
-
|
|
104
|
-
```python
|
|
105
|
-
# pip install pywebpush
|
|
106
|
-
from pywebpush import webpush, WebPushException
|
|
107
|
-
import json, os
|
|
108
|
-
|
|
109
|
-
VAPID_CLAIMS = {"sub": f"mailto:{os.environ['VAPID_CONTACT_EMAIL']}"}
|
|
110
|
-
VAPID_PRIVATE_KEY = os.environ["VAPID_PRIVATE_KEY"]
|
|
111
|
-
|
|
112
|
-
def send_web_voip_push(subscription_info: dict, payload: dict):
|
|
113
|
-
try:
|
|
114
|
-
webpush(
|
|
115
|
-
subscription_info=subscription_info,
|
|
116
|
-
data=json.dumps(payload),
|
|
117
|
-
vapid_private_key=VAPID_PRIVATE_KEY,
|
|
118
|
-
vapid_claims=VAPID_CLAIMS,
|
|
119
|
-
ttl=30,
|
|
120
|
-
headers={
|
|
121
|
-
"Urgency": "high",
|
|
122
|
-
"Topic": f"call-{payload['sessionId']}"[:32],
|
|
123
|
-
},
|
|
124
|
-
)
|
|
125
|
-
except WebPushException as ex:
|
|
126
|
-
if ex.response and ex.response.status_code in (404, 410):
|
|
127
|
-
return "expired"
|
|
128
|
-
raise
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
---
|
|
132
|
-
|
|
133
|
-
## Receiver: Service Worker
|
|
134
|
-
|
|
135
|
-
`/public/sw.js`:
|
|
136
|
-
|
|
137
|
-
```js
|
|
138
|
-
self.addEventListener("push", (event) => {
|
|
139
|
-
if (!event.data) return;
|
|
140
|
-
const data = event.data.json();
|
|
141
|
-
if (data.type !== "incoming_call") return;
|
|
142
|
-
|
|
143
|
-
event.waitUntil((async () => {
|
|
144
|
-
// 1. Show notification (must happen synchronously in `push` event,
|
|
145
|
-
// otherwise browser shows "[App] is sending notifications in the background"
|
|
146
|
-
// indicator and may unsubscribe you).
|
|
147
|
-
await self.registration.showNotification(`Incoming call from ${data.callerName}`, {
|
|
148
|
-
body: data.callType === "video" ? "Video call" : "Audio call",
|
|
149
|
-
tag: `call-${data.sessionId}`,
|
|
150
|
-
icon: "/icons/incoming-call-192.png",
|
|
151
|
-
badge: "/icons/badge-72.png",
|
|
152
|
-
requireInteraction: true, // stays until user acts
|
|
153
|
-
silent: false, // play default ringtone (some OSes ignore this for browser pushes)
|
|
154
|
-
vibrate: [500, 200, 500], // mobile haptic
|
|
155
|
-
actions: [
|
|
156
|
-
{ action: "accept", title: "Accept" },
|
|
157
|
-
{ action: "reject", title: "Decline" },
|
|
158
|
-
],
|
|
159
|
-
data: {
|
|
160
|
-
sessionId: data.sessionId,
|
|
161
|
-
callerName: data.callerName,
|
|
162
|
-
callerUid: data.callerUid,
|
|
163
|
-
callType: data.callType,
|
|
164
|
-
},
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
// 2. Wake any open clients so the in-app ringer can fire too
|
|
168
|
-
const clients = await self.clients.matchAll({ type: "window", includeUncontrolled: true });
|
|
169
|
-
clients.forEach((client) => client.postMessage({ type: "incoming_call", ...data }));
|
|
170
|
-
})());
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
self.addEventListener("notificationclick", (event) => {
|
|
174
|
-
const { sessionId } = event.notification.data;
|
|
175
|
-
event.notification.close();
|
|
176
|
-
const url = `/call/${sessionId}?action=${event.action || "open"}`;
|
|
177
|
-
|
|
178
|
-
event.waitUntil((async () => {
|
|
179
|
-
const clients = await self.clients.matchAll({ type: "window" });
|
|
180
|
-
const existing = clients.find((c) => c.url.includes(`/call/${sessionId}`));
|
|
181
|
-
if (existing) {
|
|
182
|
-
return existing.focus();
|
|
183
|
-
}
|
|
184
|
-
return self.clients.openWindow(url);
|
|
185
|
-
})());
|
|
186
|
-
});
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
Register in `main.tsx`:
|
|
190
|
-
|
|
191
|
-
```tsx
|
|
192
|
-
useEffect(() => {
|
|
193
|
-
if (!("serviceWorker" in navigator)) return;
|
|
194
|
-
navigator.serviceWorker.register("/sw.js")
|
|
195
|
-
.then(async (reg) => {
|
|
196
|
-
const sub = await reg.pushManager.subscribe({
|
|
197
|
-
userVisibleOnly: true,
|
|
198
|
-
applicationServerKey: urlBase64ToUint8Array(import.meta.env.VITE_VAPID_PUBLIC_KEY),
|
|
199
|
-
});
|
|
200
|
-
await api.registerWebPushSubscription(currentUserUid, sub.toJSON());
|
|
201
|
-
})
|
|
202
|
-
.catch((err) => console.warn("SW register / push subscribe failed:", err));
|
|
203
|
-
}, []);
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
---
|
|
207
|
-
|
|
208
|
-
## Anti-patterns
|
|
209
|
-
|
|
210
|
-
1. **Embedding VAPID private key in client code.** Push spam by anyone who views source. Server-only.
|
|
211
|
-
2. **Skipping `requireInteraction: true`.** Notification disappears in 5s on Chrome desktop — call seems to "ring once" then vanish.
|
|
212
|
-
3. **No `tag` on the notification.** Multiple incoming-call notifications stack.
|
|
213
|
-
4. **TTL: 0.** Notification dies the instant the device is offline. Use 30s minimum.
|
|
214
|
-
5. **`silent: true`.** Browser doesn't ring, only shows the visual notification.
|
|
215
|
-
6. **Forgetting to handle `notificationclick`.** User taps notification → nothing happens.
|
|
216
|
-
7. **Implementing Web Push for iOS Safari without checking PWA-only mode.** iOS Safari requires the user to "Add to Home Screen" first — Web Push doesn't work in regular tabs.
|
|
217
|
-
|
|
218
|
-
---
|
|
219
|
-
|
|
220
|
-
## Verification checklist
|
|
221
|
-
|
|
222
|
-
- [ ] VAPID keys generated; private key in env var
|
|
223
|
-
- [ ] HTTPS (or localhost for dev)
|
|
224
|
-
- [ ] Subscription stored server-side keyed to user UID
|
|
225
|
-
- [ ] `topic` set so newer push replaces older
|
|
226
|
-
- [ ] `requireInteraction: true` + `tag` set on notification
|
|
227
|
-
- [ ] 410/404 responses purge dead subscriptions
|
|
228
|
-
- [ ] `notificationclick` opens a call route
|
|
229
|
-
- [ ] Smoke: 2 browsers, recipient minimizes window, caller dials, recipient sees notification + ringtone
|
|
230
|
-
|
|
231
|
-
---
|
|
232
|
-
|
|
233
|
-
## Pointers
|
|
234
|
-
|
|
235
|
-
- `cometchat-react-calls/SKILL.md` — calls architecture
|
|
236
|
-
- `cometchat-react-push/SKILL.md` — chat web push (sister, different payload)
|
|
237
|
-
- `cometchat-ios-calls/references/server-apns-pushkit.md` — iOS sibling
|
|
238
|
-
- `cometchat-android-v5-calls/references/server-fcm-voip.md` — Android sibling
|
|
239
|
-
- Web Push spec (RFC 8030): https://datatracker.ietf.org/doc/html/rfc8030
|
|
240
|
-
- VAPID (RFC 8292): https://datatracker.ietf.org/doc/html/rfc8292
|
|
241
|
-
- web-push npm: https://www.npmjs.com/package/web-push
|