# 21-Jun-2026 — build the push service worker in the image, harden Google Cloud setup, and make push de... [#293](https://github.com/nbarrett/ngx-ramblers/issues/293)

## [build 713](https://github.com/nbarrett/ngx-ramblers/actions/runs/27910715314) — [commit 63fc039](https://github.com/nbarrett/ngx-ramblers/commit/63fc03946e9585275d0b18c676855afc436831b5)

_____

Follow-ups to the Gmail inbox work, found testing on staging and EKWG:

- Dockerfile: the image build ran `npx ng build` directly, which skips the
`prebuild` npm hook that compiles inbox-push-sw.ts into dist-sw/. The Angular
asset copy then had nothing to copy, so /inbox-push-sw.js returned 404 in every
deployed image and the inbox web-push service worker failed to register (it
only worked locally, where `npm run build` triggers `prebuild`). The image
build now runs `npm run build:sw` before `ng build`.

- inbox-google-setup: setup is now resilient on a project where the required
APIs are not already enabled. It enables the Cloud Resource Manager, Gmail and
Pub/Sub APIs and resolves the project's canonical ID via Resource Manager.
Google's API enablement takes a few minutes to propagate, so the project
lookup and the Pub/Sub steps (create topic, grant publisher, create push
subscription) now retry with backoff over roughly 2.5 minutes when they hit
the "API has not been used before or is disabled" error, instead of failing.
Crucially, the topic and subscription are now named with the project ID rather
than the project number: Gmail's users.watch validates the topic name against
the project ID, so the number-form name was rejected ("Invalid topicName does
not match projects/<id>/topics/*") even though Pub/Sub itself accepts the
number. This also corrects the stored pubsubProjectId from the display name to
the real ID.

- system-inbox-mailbox-connections: switching a mailbox to push now always
re-fetches the configured Pub/Sub topic before applying the watch, rather than
trusting a cached value that can be stale right after setup (which completes in
the background). So push applies with the correct topic without a manual page
refresh.

- inbox-notification.service: the header unread badge now wires its websocket
subscriptions before connecting (and relies on the client's own reconnect), so
a failed or dropped initial connection - e.g. while a deploy restarts the app -
no longer leaves the badge without a live feed. It picks up the next event and
updates without a page refresh.