Skip to content

fix: emit absolute approval URLs from messenger push scripts - #100

Merged
retog merged 2 commits into
mainfrom
fix/absolute-approval-url
Aug 16, 2026
Merged

fix: emit absolute approval URLs from messenger push scripts#100
retog merged 2 commits into
mainfrom
fix/absolute-approval-url

Conversation

@retog

@retog retog commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

Problem

When an outbound messenger send is queued for approval (verify policy), the push scripts (whatsapp-push.py, signal-push.py, telegram-push.py) print an approval link. The gateways build that link from SEND_APPROVAL_BASE_URL only — when that variable is unset, they return a bare relative path (/sends/<account>/<id>). The scripts printed it verbatim, so the host had to be prepended downstream by hand, which repeatedly produced the wrong host.

Fix

Absolutize the relative approval path against CONVERSATION_BASE_URL, which is already present in the container that runs the push scripts. This mirrors the existing, correct fallback in email_client.approval_url():

base = (os.environ.get("SEND_APPROVAL_BASE_URL")
        or os.environ.get("CONVERSATION_BASE_URL", "")).rstrip("/")

After this change the printed link is always complete and copy-ready, on every channel — the host can no longer be assembled (and mis-assembled) by hand.

Safety

  • No regression when CONVERSATION_BASE_URL is unset: falls back to the relative path (today's behaviour).
  • No change when the gateway already returns an absolute URL (path does not start with /, so it is left untouched).

Follow-up after merge

python3 /workspace/scripts/self-update.py to roll the change into the running stack.

The messenger gateways build the pending-send approval URL from
SEND_APPROVAL_BASE_URL only; when that is unset they return a bare
relative path (/sends/<account>/<id>). The push scripts printed it
verbatim, leaving the host to be prepended by hand downstream — an
error-prone step that produced wrong hosts.

Absolutize the relative path against CONVERSATION_BASE_URL, which is
already present in the container running the push scripts. This mirrors
the existing fallback in email_client.approval_url() and makes every
channel's approval link complete and copy-ready. No regression when
CONVERSATION_BASE_URL is unset (falls back to the relative path) or when
the gateway already returns an absolute URL (left untouched).

Co-Authored-By: Claude <noreply@anthropic.com>
@aros-agent

Copy link
Copy Markdown
Contributor

Written by Aros, the project's AI agent, from my own account @aros-agent.

Reviewed at head 0e46686. The fix is correct and it sits at the right layer: the three gateway services have no env_file in docker-compose.yml, so they can never see CONVERSATION_BASE_URL — only the container running the push scripts can (it gets the whole .env via env_file). Verified against source rather than the PR body: signal-gateway.py:1754 does return the bare relative path when SEND_APPROVAL_BASE_URL is unset, import os is present in all three scripts, and startswith("/") correctly leaves an already-absolute URL untouched, so there is no double-prefix case.

One consistency note, not a defect in the shipped wiring:

The in-code comment says the block "mirrors email_client.approval_url()", but the mirror is partial. email_client.py:999 is

base = (os.environ.get("SEND_APPROVAL_BASE_URL")
        or os.environ.get("CONVERSATION_BASE_URL", "")).rstrip("/")

while the new block reads only CONVERSATION_BASE_URL. In the shipped compose this never bites — a SEND_APPROVAL_BASE_URL set in .env reaches the gateways, which then return absolute URLs and the fallback is inert. The narrow window is a deployment where the push-script container has SEND_APPROVAL_BASE_URL but the gateway process doesn't (e.g. the variable was added to .env and the gateway container wasn't recreated): the link then stays relative even though a usable base is one os.environ.get away. Using the exact two-variable expression from email_client costs one line per script and makes the comment literally true.

Fine to merge as-is; the note is cheap to fold in now or ignore.

Align the approval-URL absolutization with email_client.approval_url(),
which prefers SEND_APPROVAL_BASE_URL and falls back to
CONVERSATION_BASE_URL. Previously the push scripts read only
CONVERSATION_BASE_URL, so the comment's claim to mirror that helper was
only partially true.

Co-Authored-By: Claude <noreply@anthropic.com>
@retog
retog merged commit 3a86a23 into main Aug 16, 2026
@retog
retog deleted the fix/absolute-approval-url branch August 16, 2026 14:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants