Skip to content

Commit

Permalink
Switch to FCMv1 for push messages
Browse files Browse the repository at this point in the history
This is the initial commit for work to switch to FCMv1 push messages due to imminent deprecation of old method.
  • Loading branch information
Tom Sightler committed Jun 20, 2024
1 parent 07a4be4 commit 7664738
Show file tree
Hide file tree
Showing 8 changed files with 348 additions and 220 deletions.
438 changes: 267 additions & 171 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/homebridge-ring/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"extends": "tsconfig/tsconfig.json",
"extends": "../tsconfig/tsconfig.json",
"compilerOptions": {
"outDir": "./lib",
"types": ["@homebridge/plugin-ui-utils/dist/ui.interface"],
Expand Down
27 changes: 19 additions & 8 deletions packages/ring-client-api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,14 @@ export class RingApi extends Subscribed {
const credentials =
this.restClient._internalOnly_pushNotificationCredentials,
pushReceiver = new PushReceiver({
firebase: {
apiKey: "AIzaSyCv-hdFBmmdBBJadNy-TFwB-xN_H5m3Bk8",
projectId: "ring-17770",
messagingSenderId: "876313859327", // for Ring android app. 703521446232 for ring-site
appId: "1:876313859327:android:e10ec6ddb3c81f39"
},
credentials,
logLevel: 'NONE',
senderId: '876313859327', // for Ring android app. 703521446232 for ring-site
debug: false,
}),
devicesById: { [id: number]: RingCamera | RingIntercom | undefined } = {},
sendToDevice = (id: number, notification: PushNotification) => {
Expand Down Expand Up @@ -271,6 +276,15 @@ export class RingApi extends Subscribed {
device: {
metadata: {
...this.restClient.baseSessionMetadata,
/*
api_version: '11',
app_brand: 'ring',
app_build: '70477131',
app_version: "3.73.1",
is_tablet: false,
os_version: "13 (33)",
*/
pn_dict_version: "2.0.0",
pn_service: 'fcm',
},
os: 'android',
Expand Down Expand Up @@ -302,18 +316,15 @@ export class RingApi extends Subscribed {
return
}

const dataJson = message.data?.gcmData as string
const dataJson = message.data as unknown as string

try {
const notification = JSONbig({ storeAsString: true }).parse(
dataJson,
) as PushNotification

if ('ding' in notification) {
sendToDevice(notification.ding.doorbot_id, notification)
} else if ('alarm_meta' in notification) {
// Alarm notification, such as intercom unlocked
sendToDevice(notification.alarm_meta.device_zid, notification)
if ('ding' in notification.data?.event) {
sendToDevice(notification.data?.device?.id, notification)
}
} catch (e) {
logError(e)
Expand Down
4 changes: 2 additions & 2 deletions packages/ring-client-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"test:watch": "jest --watch"
},
"dependencies": {
"@eneris/push-receiver": "^3.1.5",
"@eneris/push-receiver": "^4.1.2",
"@homebridge/camera-utils": "^2.2.5",
"@peculiar/asn1-schema": "^2.3.8",
"@peculiar/webcrypto": "^1.4.3",
Expand All @@ -33,7 +33,7 @@
"systeminformation": "^5.21.20",
"uuid": "^9.0.1",
"webcrypto-core": "^1.7.7",
"werift": "0.18.17",
"werift": "0.18.3",
"ws": "^8.15.1"
},
"devDependencies": {
Expand Down
14 changes: 7 additions & 7 deletions packages/ring-client-api/ring-camera.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,14 @@ export class RingCamera extends Subscribed {
onActiveNotifications = new BehaviorSubject<PushNotificationDing[]>([])
onDoorbellPressed = this.onNewNotification.pipe(
filter(
(notification) => notification.action === PushNotificationAction.Ding,
(notification) => notification.android_config.category === PushNotificationAction.Ding,
),
share(),
)
onMotionDetected = this.onActiveNotifications.pipe(
map((notifications) =>
notifications.some(
(notification) => notification.action === PushNotificationAction.Motion,
(notification) => notification.android_config.category === PushNotificationAction.Motion,
),
),
distinctUntilChanged(),
Expand Down Expand Up @@ -238,7 +238,7 @@ export class RingCamera extends Subscribed {

get latestNotificationSnapshotUuid() {
const notification = this.latestNotification
return notification?.ding.image_uuid
return notification?.img.snapshot_uuid
}

get batteryLevel() {
Expand Down Expand Up @@ -403,22 +403,22 @@ export class RingCamera extends Subscribed {

private removeDingById(idToRemove: string) {
const allActiveDings = this.activeNotifications,
otherDings = allActiveDings.filter(({ ding }) => ding.id !== idToRemove)
otherDings = allActiveDings.filter(({ data }) => data.event.ding.id !== idToRemove)

this.onActiveNotifications.next(otherDings)
}

processPushNotification(notification: PushNotification) {
if (!('ding' in notification)) {
if (!('ding' in notification.data?.event)) {
// only process ding/motion notifications
return
}

const activeDings = this.activeNotifications,
dingId = notification.ding.id
dingId = notification.data.event.ding.id

this.onActiveNotifications.next(
activeDings.filter((d) => d.ding.id !== dingId).concat([notification]),
activeDings.filter((d) => d.data.event.ding.id !== dingId).concat([notification]),
)
this.onNewNotification.next(notification)

Expand Down
4 changes: 2 additions & 2 deletions packages/ring-client-api/ring-intercom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,9 @@ export class RingIntercom {
}

processPushNotification(notification: PushNotification) {
if (notification.action === PushNotificationAction.Ding) {
if (notification.android_config.category === PushNotificationAction.Ding) {
this.onDing.next()
} else if (notification.action === PushNotificationAction.IntercomUnlock) {
} else if (notification.android_config.category === PushNotificationAction.IntercomUnlock) {
this.onUnlocked.next()
}
}
Expand Down
77 changes: 49 additions & 28 deletions packages/ring-client-api/ring-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1007,38 +1007,60 @@ export enum NotificationDetectionType {

// eslint-disable-next-line no-shadow
export enum PushNotificationAction {
Ding = 'com.ring.push.HANDLE_NEW_DING',
Motion = 'com.ring.push.HANDLE_NEW_motion',
Ding = 'com.ring.pn.live-event.ding',
Motion = 'com.ring.pn.live-event.motion',
IntercomUnlock = 'com.ring.pn.live-event.intercom',
LowBattery = 'com.ring.push.LOW_BATTERY_ALERT',
IntercomUnlock = 'com.ring.push.INTERCOM_UNLOCK_FROM_APP',
}

export interface PushNotificationDing {
ding: {
streaming_protocol: 'ring_media_server'
location_id: string
device_name: string
doorbot_id: number
e2ee_enabled: boolean
streaming_data_hash: string
device_kind: RingCameraKind
detection_type: NotificationDetectionType
human_detected?: boolean
id: string
pod_id: number
request_id: string
image_uuid: string
properties: {
active_streaming_profile: 'rms'
is_sidewalk: boolean
}
version: '2.0.0' | string
android_config: {
category: PushNotificationAction | string
body: string
},
analytics: {
server_correlation_id: string
server_id: "com.ring.pns" | string
subcategory: string
triggered_at: number
sent_at: number
referring_item_type: string
referring_item_id: string
}
aps: {
alert: string
sound: string
data: {
device: {
e2ee_enabled: boolean
id: number
kind: RingCameraKind
name: string
}
event: {
ding: {
id: string
created_at: string
subtype: 'motion' | 'ding' | 'human' | string
detection_type: NotificationDetectionType
}
eventito: {
type: string
timestamp: number
},
riid: string
is_sidewalk: boolean
live_session: {
active_streaming_profile: "rms" | string
default_audio_route: string
max_duration: number
}
}
location: {
id: string
}
}
subtype: 'motion' | 'ding' | 'human' | string
action: PushNotificationAction | string
img: {
snapshot_uuid: string
}
}

export interface PushNotificationAlarm {
Expand Down Expand Up @@ -1068,8 +1090,7 @@ export interface PushNotificationLowBattery {

export type PushNotification =
| PushNotificationDing
| PushNotificationAlarm
| PushNotificationLowBattery


export interface SocketTicketResponse {
ticket: string
Expand Down
2 changes: 1 addition & 1 deletion packages/ring-client-api/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"extends": "tsconfig/tsconfig.json",
"extends": "../tsconfig/tsconfig.json",
"compilerOptions": {
"outDir": "lib"
},
Expand Down

0 comments on commit 7664738

Please sign in to comment.