gigafibre-fsm/scripts
louispaulb e1283f30e8 feat(campaigns): add Giftbit API client + validate end-to-end with sandbox
Adds create_giftbit_campaign.js — Node CLI that POSTs to the Giftbit
API (testbed or production), creates a campaign with
delivery_type=SHORTLINK so Giftbit does NOT send their own English
template emails, polls /gifts?campaign_uuid=... until the redemption
shortlinks are generated, then writes a gifts CSV ready to feed into
send_gift_campaign.js.

Two non-obvious things learned while wiring it up:

1. The right endpoint to get the shortlinks is /gifts (not /links).
   /links/{uuid} returned 0 rows on our sandbox account; /gifts has
   a `shortlink` field on each gift once delivery_status transitions
   from QUEUED → LINKCREATED. Polled with 2s interval, up to 20 tries.

2. delivery_type=SHORTLINK is mandatory. Default is GIFTBIT_EMAIL,
   which fires their English template immediately — defeating the
   whole point of bridging through our French Mailjet template.
   Confirmed in the campaign GET response that delivery_type echoes
   back correctly when we send "SHORTLINK".

Validated end-to-end (entirely synthetic data — Alice/Bob/Charlie at
@example.com, no real customer info in the sandbox):
  ✓ Auth probe via /ping returns 200
  ✓ POST /campaign returns campaign UUID
  ✓ After ~12s, /gifts returns 3 gifts each with a working shortlink
  ✓ send_gift_campaign.js consumes the gifts CSV + the contacts CSV
  ✓ FR template renders: "Bonjour Alice", http://gtbt.co/7TKGFDBNVZq
    embedded in the CTA button href, address in the footer line

The --sandbox flag does double duty: routes the API to
api-testbed.giftbit.com AND replaces every recipient email with
louis@targo.ca so we can't accidentally hit real customer inboxes
with the non-redeemable test gifts.

README updated with the two-stage pipeline (create → send), explicit
warnings about the customer-matching gap (only 25% of source rows
resolve via legacy_delivery_id — the rest use a different ID space
from the source Map tool), and the sandbox-quirk where Giftbit
collapses recipient_name when emails are duplicated.

Token NOT committed — pulled from GIFTBIT_TOKEN env var per the
script's contract. In production we'll store it in the hub's
.env alongside SMTP_USER / SMTP_PASS.
2026-05-21 16:20:28 -04:00
..
campaigns feat(campaigns): add Giftbit API client + validate end-to-end with sandbox 2026-05-21 16:20:28 -04:00
migration fix(migration): clean address_line + postal_code + connection_type at import 2026-05-08 15:38:19 -04:00
test refactor: major cleanup — remove dead dispatch app, commit all backend code, extract client composables 2026-04-08 17:38:38 -04:00
bulk_submit.py feat: inline editing, search, notifications + full repo cleanup 2026-03-31 07:34:41 -04:00
fix_ple_groupby.py feat: inline editing, search, notifications + full repo cleanup 2026-03-31 07:34:41 -04:00
fix_ple_postgres.sh feat: inline editing, search, notifications + full repo cleanup 2026-03-31 07:34:41 -04:00
import-legacy-accounts.js refactor: reduce token count, DRY code, consolidate docs 2026-04-13 08:39:58 -04:00
server_bulk_submit.py feat: telephony UI, performance indexes, Twilio softphone, lazy-load invoices 2026-04-02 13:59:59 -04:00