Skip to content

push: add support for registering fcm pushers - #26

Merged
iFixRobots merged 5 commits into
mainfrom
codex/gvoice-delivery-errors
Sep 22, 2026
Merged

iFixRobots merged 5 commits into
mainfrom
codex/gvoice-delivery-errors

Conversation

@iFixRobots

@iFixRobots iFixRobots commented Sep 12, 2026 •

Copy link
Copy Markdown
Contributor

Registers Google Voice's FCM destination and syncs the pushed conversation when Beeper wakes the on-device bridge, including conversations outside the recent thread list. Uses the existing cookie login and client push flow.

Keeps failed syncs eligible for retry. Catch-up checks backfill completion and processes messages in order before advancing its saved position. Buffered cloud events retain their existing queue semantics.

Verified on a Pixel 6: incoming notifications with the bridge stopped, recovery after a missed push, and duplicate suppression after process restart. Cookie-only provider registration, Go build, vet and CI also pass. No client changes.

Device checks used a controlled relay. The shared relay changes in beeper/hungryserv#588 and beeper/push-receiver#4 have now merged.

Preserves the push-device ID across relogin using the existing metadata merge hook, so refreshing credentials does not create another destination identity. The six-line fix builds successfully; it does not change the login flow.

Fresh iOS onboarding remains unresolved: Google accepted push registration, but the last ordinary-login test received no FCM event. The downstream iOS notification path passed with saved Chrome-session credentials.

@iFixRobots iFixRobots changed the title handlegvoice: keep failed events eligible for retry connector: add push notifications Sep 12, 2026
Comment thread pkg/libgv/push.go Outdated
_, err := ReadProtoResponse[*gvproto.RespRegisterDestination](
c.MakeRequest(ctx, http.MethodPost, APIBaseURL+"/api2notifications/registerdestination", nil, http.Header{
"Content-Type": {ContentTypeProtobuf},
"X-Gv-Rpc-Id": {"1639"},

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this meant to be hardcoded? It sounds like it might be a request transaction id rather than a method identifier

Also this should probably just be in client.go with the rest of the methods, since there's no other push handling in libgv

Comment thread pkg/connector/handlegvoice.go Outdated
Comment on lines +156 to +204
config := gc.Main.Bridge.Config.Backfill
backfill := &gvBackfillData{
thread: thread,
expected: config.Enabled && (config.MaxInitialMessages > 0 || config.MaxCatchupMessages > 0),
}
result := gc.Main.Bridge.QueueRemoteEvent(gc.UserLogin, &simplevent.ChatResync{
EventMeta: simplevent.EventMeta{
Type: bridgev2.RemoteEventChatResync,
PortalKey: portalKey,
CreatePortal: true,
},
ChatInfo: gc.wrapChatInfo(ctx, thread),
LatestMessageTS: lastMessageTS,
BundledBackfillData: thread,
BundledBackfillData: backfill,
GetChatInfoFunc: func(ctx context.Context, portal *bridgev2.Portal) (*bridgev2.ChatInfo, error) {
if portal.MXID == "" {
backfill.expected = config.Enabled && !gc.Main.Bridge.Background && config.MaxInitialMessages > 0
}
return gc.wrapChatInfo(ctx, thread), nil
},
CheckNeedsBackfillFunc: func(_ context.Context, latest *database.Message) (bool, error) {
limit := config.MaxCatchupMessages
if latest == nil {
limit = config.MaxInitialMessages
}
backfill.expected = limit > 0 && (latest == nil || lastMessageTS.After(latest.Timestamp))
return backfill.expected, nil
},
})
continue
if !result.Success || result.Error != nil {
if result.Error != nil {
errs = append(errs, fmt.Errorf("failed to resync chat %s: %w", thread.ID, result.Error))
} else {
errs = append(errs, fmt.Errorf("failed to resync chat %s", thread.ID))
}
continue
}
if result.Queued {
gc.lastEvents[thread.ID] = lastMessageTS
continue
}
if backfill.err != nil {
errs = append(errs, fmt.Errorf("failed to backfill chat %s: %w", thread.ID, backfill.err))
continue
} else if backfill.expected && !backfill.completed {
errs = append(errs, fmt.Errorf("backfill did not complete for chat %s", thread.ID))
continue
}
if backfill.messages != nil {
messages = backfill.messages
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part looks very sus. Why is it backfilling messages and then continuing to handle them as new messages? Different behavior for queued vs not is also unusual

Comment thread pkg/connector/handlegvoice.go Outdated
}
for _, msg := range thread.Messages {
for i := len(messages) - 1; i >= 0; i-- {
msg := messages[i]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this was always bridging in the wrong order? slices.Backward is better than manual iteration

Comment thread pkg/connector/handlegvoice.go Outdated
Comment on lines +233 to +237
if result.Error != nil {
errs = append(errs, fmt.Errorf("failed to handle message %s in chat %s: %w", msg.ID, thread.ID, result.Error))
} else {
errs = append(errs, fmt.Errorf("failed to handle message %s in chat %s", msg.ID, thread.ID))
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should always be attaching errors to non-successes

Suggested change
if result.Error != nil {
errs = append(errs, fmt.Errorf("failed to handle message %s in chat %s: %w", msg.ID, thread.ID, result.Error))
} else {
errs = append(errs, fmt.Errorf("failed to handle message %s in chat %s", msg.ID, thread.ID))
}
errs = append(errs, fmt.Errorf("failed to handle message %s in chat %s: %w", msg.ID, thread.ID, result.Error))

@tulir tulir changed the title connector: add push notifications push: add support for registering fcm pushers Sep 12, 2026
@iFixRobots
iFixRobots requested a review from Fizzadar September 15, 2026 10:38
@iFixRobots
iFixRobots merged commit fa4611d into main Sep 22, 2026
11 checks passed
@iFixRobots
iFixRobots deleted the codex/gvoice-delivery-errors branch September 22, 2026 14:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants