[object Object]

← back to Pitch Guard

Fix Send followup: pass George external-send approval token

bcb6aaa90bb907f0a70c9ab889fad06e2cd524bc · 2026-06-18 15:42:21 -0700 · Steve Abrams

George's externalSendGuard 403-blocks all sends to external (customer)
recipients unless the request carries the human-approval token. PitchGuard's
authenticated Send-followup click IS that approval, so include
send_approval_token (from GEORGE_EXTERNAL_SEND_TOKEN) on every /api/send.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Files touched

Diff

commit bcb6aaa90bb907f0a70c9ab889fad06e2cd524bc
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Thu Jun 18 15:42:21 2026 -0700

    Fix Send followup: pass George external-send approval token
    
    George's externalSendGuard 403-blocks all sends to external (customer)
    recipients unless the request carries the human-approval token. PitchGuard's
    authenticated Send-followup click IS that approval, so include
    send_approval_token (from GEORGE_EXTERNAL_SEND_TOKEN) on every /api/send.
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---
 server.js | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/server.js b/server.js
index 5aade7a..c632a02 100644
--- a/server.js
+++ b/server.js
@@ -42,6 +42,10 @@ app.use(express.static(path.join(__dirname, 'public')));
 const PORT = process.env.PORT || 8123;
 const GEORGE = (process.env.GEORGE_URL || '').replace(/\/$/, '');
 const AUTH = process.env.GEORGE_BASIC_AUTH || '';
+// George blocks sends to external (customer) recipients unless the request carries
+// the human-approval token. In PitchGuard the human approval IS Steve clicking
+// "Send followup" behind nginx basic-auth, so we pass the token on every send.
+const EXT_SEND_TOKEN = process.env.GEORGE_EXTERNAL_SEND_TOKEN || '';
 const ACCOUNT = 'info'; // info@designerwallcoverings.com
 if (!GEORGE || !AUTH) {
   console.error('Missing GEORGE_URL / GEORGE_BASIC_AUTH — copy .env.example to .env and fill it in.');
@@ -479,7 +483,8 @@ app.post('/api/send', async (req, res) => {
         if (real.length) replyToMessageId = real[real.length - 1].id;
       } catch { /* fall back to plain threadId send */ }
     }
-    const payload = { account: ACCOUNT, to, subject, body, no_source_tag: true, ...(threadId ? { threadId } : {}), ...(replyToMessageId ? { replyToMessageId } : {}) };
+    const payload = { account: ACCOUNT, to, subject, body, no_source_tag: true, ...(EXT_SEND_TOKEN ? { send_approval_token: EXT_SEND_TOKEN } : {}), ...(threadId ? { threadId } : {}), ...(replyToMessageId ? { replyToMessageId } : {}) };
+    if (!EXT_SEND_TOKEN) console.warn('[send] GEORGE_EXTERNAL_SEND_TOKEN not set — external sends will be blocked by George.');
     const sent = await george('/api/send', { method: 'POST', body: payload });
     // durable record: the date + the actual letter we sent this person
     try {

← 75b161a Add Designer Wallcoverings logo to header; (GEORGE_URL fixed  ·  back to Pitch Guard  ·  PitchGuard: red 'already sent' alert + 4th Already-Sent colu 1e95bac →