diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 97c7e08..ef6448f 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -131,10 +131,11 @@ and fail-soft, so one being down never blocks the other: - **Bluesky** (always): `uploadBlob` then `putRecord` on `app.bsky.actor.profile`, preserving every other profile field. Tracks the full state hash. -- **Signal** (optional): `PUT /v1/profiles/{number}` on a `signal-cli-rest-api` - sidecar (Signal has no official API; the sidecar must be linked to the account - once via QR). In `events` mode Signal tracks only `bg`+`holiday`, so the daily - weather/ring churn doesn't push there; in `all` mode it mirrors every change. +- **Signal** (optional): `PUT /v1/profiles/{number}` (raw-base64 avatar) on a + `signal-cli-rest-api` sidecar running in json-rpc mode (Signal has no official + API; the sidecar must be linked to the account once via QR). In `events` mode + Signal tracks only `bg`+`holiday`, so the daily weather/ring churn doesn't push + there; in `all` mode it mirrors every change. **Per-target idempotency:** `state/last.json` stores the last applied key per target. A target pushes only when its own key changed, so a target that failed diff --git a/deploy/README.md b/deploy/README.md index b94dbf2..70cdeca 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -65,22 +65,34 @@ sudo docker exec bsky-avatar node src/index.js --force # force an immediate ## Optional: Signal mirroring Mirrors the avatar to your Signal profile via a `signal-cli-rest-api` sidecar. +**Linking** needs `normal` mode; **serving** runs in `json-rpc` mode (reliable for +a linked account — `normal` mode cold-starts a JVM per request and is flaky). ```bash -# 1. Run the sidecar (8080 is often taken; map to a free host port like 8099) +# 1. Start the sidecar in NORMAL mode for linking (8080 is often taken; use 8099) sudo docker run -d --name signal-api --restart unless-stopped \ -p 8099:8080 -v /volume1/docker/signal-api:/home/.local/share/signal-cli \ -e MODE=normal bbernhard/signal-cli-rest-api:latest -# 2. Link it to your account: open the QR and scan it from -# Signal app -> Settings -> Linked Devices -> Link New Device -# (the QR PNG is returned by this endpoint) -curl -s "http://:8099/v1/qrcodelink?device_name=bsky-avatar" -o signal-link-qr.png +# 2. Link your account. The /v1/qrcodelink request returns the QR ~8s in and +# HOLDS THE CONNECTION ~30s — keep it open and scan within that window. +# Be on Signal -> Settings -> Linked Devices -> Link New Device FIRST, then: +( curl -s "http://localhost:8099/v1/qrcodelink?device_name=bsky-avatar" -o /tmp/qr.png & ) ; sleep 8 +# Copy /tmp/qr.png to a screen and scan it immediately (before the ~30s elapses). -# 3. Confirm the linked number -curl -s "http://:8099/v1/accounts" +# 3. Confirm the linked number appears +curl -s "http://localhost:8099/v1/accounts" # -> ["+316..."] + +# 4. Switch to JSON-RPC for serving (the linked account persists in the volume). +# NOTE: AUTO_RECEIVE_SCHEDULE is INCOMPATIBLE with json-rpc — never set it +# (it crash-loops the container). +sudo docker rm -f signal-api +sudo docker run -d --name signal-api --restart unless-stopped \ + -p 8099:8080 -v /volume1/docker/signal-api:/home/.local/share/signal-cli \ + -e MODE=json-rpc bbernhard/signal-cli-rest-api:latest ``` -Then set `SIGNAL_API_URL`, `SIGNAL_NUMBER`, `SIGNAL_PROFILE_NAME` in `.env` and -recreate the `bsky-avatar` container (it's an `--env-file` change). `signalMirror` -in `settings.yaml` chooses `events` (calm) or `all`. +Then set `SIGNAL_API_URL` (e.g. `http://:8099`), `SIGNAL_NUMBER` (+E.164) +and `SIGNAL_PROFILE_NAME` in `.env`, and recreate the `bsky-avatar` container +(it's an `--env-file` change). `signalMirror` in `settings.yaml` chooses `events` +(only push on bg/holiday change) or `all` (mirror everything).