-
-
Notifications
You must be signed in to change notification settings - Fork 37.1k
Add iOS Live Activity webhook handlers to mobile_app #166072
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from 14 commits
acaa98a
01604ad
bd08936
5d27da3
a0c8bd7
dea3db7
4d450fd
6ec5302
57ec417
62b09f7
ca84c70
4ce2a2e
9be40d9
b381fe4
29a27c7
9548dbb
e60ec73
0aa42a1
3f43e96
ae9d27b
2dd5151
aa4b2fa
fc20efd
ee0974e
311f7f2
0d466f3
9567852
c3d3eb0
e0ae7da
db1b8f5
83ac025
33cb529
7379af0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -66,10 +66,12 @@ | |
| ATTR_DEVICE_NAME, | ||
| ATTR_EVENT_DATA, | ||
| ATTR_EVENT_TYPE, | ||
| ATTR_LIVE_ACTIVITY_TAG, | ||
| ATTR_MANUFACTURER, | ||
| ATTR_MODEL, | ||
| ATTR_NO_LEGACY_ENCRYPTION, | ||
| ATTR_OS_VERSION, | ||
| ATTR_PUSH_TOKEN, | ||
| ATTR_SENSOR_ATTRIBUTES, | ||
| ATTR_SENSOR_DEVICE_CLASS, | ||
| ATTR_SENSOR_DISABLED, | ||
|
|
@@ -90,6 +92,7 @@ | |
| ATTR_WEBHOOK_DATA, | ||
| ATTR_WEBHOOK_ENCRYPTED, | ||
| ATTR_WEBHOOK_ENCRYPTED_DATA, | ||
| ATTR_WEBHOOK_ID, | ||
| ATTR_WEBHOOK_TYPE, | ||
| CONF_CLOUDHOOK_URL, | ||
| CONF_REMOTE_UI_URL, | ||
|
|
@@ -98,12 +101,15 @@ | |
| DATA_CONFIG_ENTRIES, | ||
| DATA_DELETED_IDS, | ||
| DATA_DEVICES, | ||
| DATA_LIVE_ACTIVITY_TOKENS, | ||
| DATA_PENDING_UPDATES, | ||
| DOMAIN, | ||
| ERR_ENCRYPTION_ALREADY_ENABLED, | ||
| ERR_ENCRYPTION_REQUIRED, | ||
| ERR_INVALID_FORMAT, | ||
| ERR_SENSOR_NOT_REGISTERED, | ||
| EVENT_LIVE_ACTIVITY_DISMISSED, | ||
| EVENT_LIVE_ACTIVITY_TOKEN_UPDATED, | ||
| SCHEMA_APP_DATA, | ||
| SENSOR_TYPES, | ||
| SIGNAL_LOCATION_UPDATE, | ||
|
|
@@ -797,3 +803,84 @@ async def webhook_scan_tag( | |
| registration_context(config_entry.data), | ||
| ) | ||
| return empty_okay_response() | ||
|
|
||
|
|
||
| @WEBHOOK_COMMANDS.register("update_live_activity_token") | ||
| @validate_schema( | ||
| { | ||
| vol.Required(ATTR_LIVE_ACTIVITY_TAG): cv.string, | ||
rwarner marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| vol.Required(ATTR_PUSH_TOKEN): vol.All(cv.string, vol.Length(min=1)), | ||
| } | ||
| ) | ||
| async def webhook_update_live_activity_token( | ||
| hass: HomeAssistant, config_entry: ConfigEntry, data: dict[str, Any] | ||
| ) -> Response: | ||
| """Handle a Live Activity token update from the iOS companion app. | ||
|
|
||
| When the iOS app creates a Live Activity locally, ActivityKit provides | ||
| a per-activity APNs push token. The app sends this token so HA can | ||
| later include it as live_activity_token in the push relay request. | ||
| The relay server places it in the FCM message's apns.liveActivityToken | ||
| field, and FCM handles APNs delivery automatically. | ||
| """ | ||
| webhook_id = config_entry.data[CONF_WEBHOOK_ID] | ||
| activity_tag = data[ATTR_LIVE_ACTIVITY_TAG] | ||
|
|
||
| live_activity_tokens = hass.data[DOMAIN][DATA_LIVE_ACTIVITY_TOKENS] | ||
| live_activity_tokens.setdefault(webhook_id, {})[activity_tag] = { | ||
| ATTR_PUSH_TOKEN: data[ATTR_PUSH_TOKEN], | ||
rwarner marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
rwarner marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| device: dr.DeviceEntry = hass.data[DOMAIN][DATA_DEVICES][webhook_id] | ||
| hass.bus.async_fire( | ||
| EVENT_LIVE_ACTIVITY_TOKEN_UPDATED, | ||
| { | ||
| ATTR_LIVE_ACTIVITY_TAG: activity_tag, | ||
| ATTR_DEVICE_ID: device.id, | ||
| ATTR_WEBHOOK_ID: webhook_id, | ||
| }, | ||
| EventOrigin.remote, | ||
| context=registration_context(config_entry.data), | ||
| ) | ||
rwarner marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| return empty_okay_response() | ||
|
|
||
|
|
||
| @WEBHOOK_COMMANDS.register("live_activity_dismissed") | ||
| @validate_schema( | ||
| { | ||
| vol.Required(ATTR_LIVE_ACTIVITY_TAG): vol.All(cv.string, vol.Length(min=1)), | ||
| } | ||
| ) | ||
| async def webhook_live_activity_dismissed( | ||
| hass: HomeAssistant, config_entry: ConfigEntry, data: dict[str, str] | ||
| ) -> Response: | ||
| """Handle a Live Activity dismissal from the iOS companion app. | ||
|
|
||
| When a Live Activity ends on the device (user dismissal, expiration, | ||
| or an explicit end event), the app notifies HA so the stored push | ||
| token for that activity can be cleaned up. | ||
| """ | ||
| webhook_id = config_entry.data[CONF_WEBHOOK_ID] | ||
| activity_tag = data[ATTR_LIVE_ACTIVITY_TAG] | ||
|
|
||
| live_activity_tokens = hass.data[DOMAIN][DATA_LIVE_ACTIVITY_TOKENS] | ||
| if webhook_id in live_activity_tokens: | ||
| live_activity_tokens[webhook_id].pop(activity_tag, None) | ||
| # Clean up the device key if no activities remain. | ||
| if not live_activity_tokens[webhook_id]: | ||
| del live_activity_tokens[webhook_id] | ||
|
|
||
| device: dr.DeviceEntry = hass.data[DOMAIN][DATA_DEVICES][webhook_id] | ||
| hass.bus.async_fire( | ||
| EVENT_LIVE_ACTIVITY_DISMISSED, | ||
|
||
| { | ||
| ATTR_LIVE_ACTIVITY_TAG: activity_tag, | ||
| ATTR_DEVICE_ID: device.id, | ||
| ATTR_WEBHOOK_ID: webhook_id, | ||
| }, | ||
| EventOrigin.remote, | ||
| context=registration_context(config_entry.data), | ||
| ) | ||
|
|
||
| return empty_okay_response() | ||
Uh oh!
There was an error while loading. Please reload this page.