Conversation
Live Activity push tokens from ActivityKit are direct APNs tokens (hex-encoded), not FCM tokens. The existing iOSV1 endpoint cannot handle them — this adds a dedicated iOSLiveActivityV1 endpoint that sends directly to the APNs HTTP/2 API using JWT authentication, bypassing FCM entirely. New files: - apns.js: APNs HTTP/2 client with ES256 JWT auth (Node built-ins only, no new dependencies). JWT cached and rotated every 45 min. HTTP/2 sessions cached per environment (sandbox/production). - live-activity.js: payload builder for start/update/end events. Maps content_state fields to the HALiveActivityAttributes struct expected by the iOS companion app. Sets apns-push-type: liveactivity and routes to correct APNs topic using bundle ID from registration_info. Updated files: - handlers.js: adds handleLiveActivityRequest(), which validates hex APNs tokens, applies rate limiting, sends via apns.js, and handles BadDeviceToken (400) without error reporting. - index.js: exports iOSLiveActivityV1 Cloud Function. - webapp.js: adds /api/sendPush/iOS/liveActivity/v1 route for local dev. Tests: 20 tests across fixture-driven createPayload tests and handleLiveActivityRequest integration tests covering success, token validation, rate limiting, APNs error mapping, and end-event rate-limit bypass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Moves createLiveActivityPayload() from the standalone live-activity.js into ios.js as a second export, keeping all iOS-specific logic in one place consistent with the existing android.js/ios.js pattern. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Follows the existing test naming convention (legacy.test.js -> legacy.js) now that the Live Activity payload builder lives in ios.js. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix misleading comment in webapp.js (was "Import the functions from index.js") - Validate APNs token length (must be exactly 64 hex chars) in isValidApnsToken; add test - Normalize apnsEnvironment to 'sandbox'|'production' to prevent unbounded session cache growth - Guard JSON.parse in apns.js against non-JSON APNs responses - Fix test: pass body overrides flat to createLiveActivityRequest (not nested under body:) - Add explanatory comments throughout apns.js, ios.js, and handlers.js for non-obvious decisions Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Firebase Admin SDK v13.5.0+ supports the liveActivityToken field in the apns config object, which tells FCM to automatically set apns-push-type: liveactivity and route the notification to APNs. This eliminates the need for a custom direct APNs HTTP/2 client. Changes: - Delete apns.js (custom HTTP/2 + JWT APNs client) — no longer needed - Bump firebase-admin from ^12.1.0 to ^13.5.0 - Rewrite ios.js: createPayload detects live_activity_token in request body and builds FCM payload with apns.liveActivityToken (camelCase) - Remove handleLiveActivityRequest from handlers.js — existing handleRequest + messaging.send() handles everything - Remove iOSLiveActivityV1 endpoint from index.js and webapp.js - Rewrite tests for FCM-based delivery path - Update fixtures to use FCM payload structure The relay server no longer needs APNS_TEAM_ID, APNS_KEY_ID, or APNS_PRIVATE_KEY environment variables. HA core sends both the FCM registration token (push_token) and the Live Activity APNs token (live_activity_token) to the same /api/sendPush/iOS/v1 endpoint. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All live activity pushes (start, update, end) now count against the rate limit. End events still have an APNs delivery cost, so exempting them was not justified. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
HALiveActivityAttributes must only appear in push-to-start payloads — APNs rejects update/end payloads that include attributes-type. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4 tasks
Contributor
There was a problem hiding this comment.
Pull request overview
Adds iOS Live Activity push payload translation and accompanying fixture-driven/integration tests so the relay can send ActivityKit Live Activity updates through FCM’s apns.liveActivityToken support.
Changes:
- Add Live Activity detection and payload builder in
functions/ios.js(includingapsmapping and a dedicated analytics label). - Add extensive Jest coverage for Live Activity payload construction and
handleRequestintegration, plus JSON fixtures. - Minor cleanup/housekeeping updates (webapp handler comment, dependency entry formatting).
Reviewed changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| functions/webapp.js | Updates an inline comment to reflect handler imports. |
| functions/ios.js | Adds Live Activity payload builder and content-state translation logic. |
| functions/test/ios.test.js | Adds fixture-driven and integration tests for iOS Live Activity payloads. |
| functions/test/fixtures/live-activity/start-push-to-start.json | Adds “start” Live Activity fixture input/expectations. |
| functions/test/fixtures/live-activity/update-basic.json | Adds basic “update” Live Activity fixture input/expectations. |
| functions/test/fixtures/live-activity/update-full.json | Adds full-field “update” Live Activity fixture input/expectations. |
| functions/test/fixtures/live-activity/end.json | Adds “end” Live Activity fixture input/expectations. |
| functions/package.json | Updates dependencies, but currently with a formatting inconsistency. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
21 tasks
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #309 +/- ##
==========================================
+ Coverage 77.24% 78.98% +1.73%
==========================================
Files 9 10 +1
Lines 545 628 +83
Branches 147 197 +50
==========================================
+ Hits 421 496 +75
- Misses 105 113 +8
Partials 19 19 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Continuation from PR: #278
iOS PR: home-assistant/iOS#4696
Adds data model translator to delivery live activity push to iOS.