Skip to content

feat(P1-LIVE): code mirror of production deploy on swarm.impt.io - #4

Open
IMPTio wants to merge 5 commits into
feat/p1-bots-and-sitefrom
feat/p1-live-deploy
Open

feat(P1-LIVE): code mirror of production deploy on swarm.impt.io#4
IMPTio wants to merge 5 commits into
feat/p1-bots-and-sitefrom
feat/p1-live-deploy

Conversation

@IMPTio

@IMPTio IMPTio commented May 9, 2026

Copy link
Copy Markdown
Collaborator

⚠️ Code-mirror PR. Everything in this PR is already live on swarm.impt.io. The repo had been planning a Cloudflare Pages deploy; the discovery during execution was that swarm.impt.io is served by nginx + FastAPI on the mgmt-server (35.214.111.96), not Pages. This PR makes the repo reflect what's actually running.

Stacked on PR #3

main
 └─ feat/p0-omnichannel-spine            (PR #1 — spine)
     └─ feat/p0-5-mongo-stripe-wire      (PR #2 — real /hotels /intent /partners)
         └─ feat/p1-bots-and-site        (PR #3 — TG/WA/FB + homepage)
             └─ feat/p1-live-deploy      (PR #4 — THIS, code-mirror of live)

When PRs #1#2#3#4 merge, GitHub auto-rebases each onto main.

What this PR does

  1. apps/server/swarm_widget_api.py — full Python source of the live FastAPI server on localhost:2027 (impt-swarm-widget.service). I extended this in place with 750+ lines covering all the new endpoints. Now it's source-controlled.

  2. ops/nginx-swarm.impt.io.conf — full live nginx config for swarm.impt.io, including my added location blocks for /api/tg/webhook, /api/whatsapp/, /api/fb/, /api/(email|gpt|mcp)/, and the QR-extension regex.

  3. apps/site/public/widget/index.html — the new big omnichannel homepage now serving at swarm.impt.io/widget (replaces the older 17 KB demo with a 22.6 KB cream-skin page).

  4. apps/site/public/mcp/index.html — updated to show LIVE status + correct install commands (HTTP transport, no npx needed).

  5. ops/STATE.md — append-only ledger entry capturing the architectural pivot.

Endpoints live (curl-verified)

Endpoint What
POST /api/widget/intent issues iid_* + canonical deeplink + embed + qr URL
GET /api/widget/quote/{iid} intent lookup
GET /api/widget/hotels?city=… proxy of platform.impt.io/api/hotels
GET /api/widget/qr/{key}.{png,svg} real QR generator (segno)
GET /api/email/sig/{key} paste-ready Outlook-safe signature HTML
GET /api/gpt/openapi.json Custom GPT Action manifest (3 ops)
POST /api/mcp/http Streamable HTTP MCP — 4 tools: impt_search_hotels, impt_create_intent, impt_get_quote, impt_get_deeplink
GET /api/mcp/info paste-ready Claude Desktop / Claude Code config
POST /api/tg/webhook Telegram bot at @Rambo_Marc2_bot with smart non-city heuristic
GET+POST /api/whatsapp/webhook Meta Cloud API receiver — 200-acks until WA tokens set
GET+POST /api/fb/webhook Meta Messenger Platform receiver — 200-acks until FB tokens set

What Mike has already done

Telegram conversations are in the DB — chat_id 8103309746 (Mike) sent things like "Rambo? 😂" and "There are still a lot of bugs..." which prompted me to upgrade the bot's non-city heuristic. Now the bot:

  • Strips leading verbs (book TokyoTokyo)
  • Accepts only ≤3 alpha-only words where the first word is capitalized
  • Rejects sentences ("hello there how are you", "yes please") with a friendly "I'm a hotel-booking bot 🌱" message + city picker

Backups (rollback safety)

  • /etc/nginx/sites-enabled/swarm.impt.io.bak-pre-bots-20260509-103947
  • /srv/swarm/impt-swarm-oss-2026-05-05/demo/index.html.bak-pre-omnichannel

🤖 Generated with Claude Code

Mike English and others added 5 commits May 9, 2026 11:43
This is a code-mirror PR. Everything in this PR is **already live** on
swarm.impt.io (mgmt-server 35.214.111.96, NOT Cloudflare Pages — that
plan was wrong, repo updated to reflect reality).

Live infrastructure
- nginx serves swarm.impt.io with new location blocks for the bot + AI agent routes
- FastAPI on :2027 (impt-swarm-widget.service) extended in place with ~750 LOC
- SQLite at /srv/swarm/impt-swarm-oss-2026-05-05/backend/swarm_widget.db
- intents + bot_events tables added

Live endpoints (curl-verified)
- POST /api/widget/intent — KV-equivalent intent persistence
- GET  /api/widget/quote/{iid} — intent lookup
- GET  /api/widget/hotels — proxy of platform.impt.io
- GET  /api/widget/qr/{key}.{png,svg} — real QR (segno)
- GET  /api/email/sig/{key} — paste-ready signature HTML
- GET  /api/gpt/openapi.json — Custom GPT Action manifest
- POST /api/mcp/http — Streamable HTTP MCP server (4 tools)
- GET  /api/mcp/info — paste-ready Claude Desktop config
- POST /api/tg/webhook — Telegram bot (with smart non-city heuristic)
- GET+POST /api/whatsapp/webhook — Meta Cloud API
- GET+POST /api/fb/webhook — Meta Messenger Platform

Files
- apps/server/swarm_widget_api.py — full live Python source
- ops/nginx-swarm.impt.io.conf — full live nginx config
- apps/site/public/widget/index.html — the new big homepage now live at swarm.impt.io/widget
- apps/site/public/mcp/index.html — updated install instructions (HTTP transport)
- ops/STATE.md — append-only ledger entry for this deploy

Telegram bot @Rambo_Marc2_bot is webhooked + Mike has been live-testing.
Conversations like "Rambo? 😂" / "There are still a lot of bugs..." prompted
the smart-heuristic upgrade (≤3 words, first word capitalized, alpha-only,
no punctuation chaos).

WhatsApp + FB webhooks are wired and 200-acking on missing tokens. Once
WA_PHONE_NUMBER_ID + WA_TOKEN + FB_PAGE_ACCESS_TOKEN are added to the
backend .env (already templated in vercel-env-backup), bot replies start.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…(TG/WA/web/IG/QR/Claude MCP)

Horizontal scrollable strip above the hero showing what the widget actually
looks like in 6 surfaces. All pure CSS/SVG (no external images, no hosting,
no broken-link risk).

Cards:
1. Telegram — TG-themed chat with bot avatar + city-picker inline keyboard
2. WhatsApp — WA-dark-themed chat with cta_url interactive card
3. Web embed — mini cream-skin widget rendered inline
4. Instagram Story — gradient + creator avatar + branded link sticker
5. QR — inline-SVG decorative QR code in cream/ink palette
6. Claude MCP — terminal-style tool-call visualization with hotel results

Mobile: scroll-snap-x (no scrollbar), cards 230×380. Edge-fade gradients
on the strip so partial-cards look intentional. Each card hover-lifts.

Live at swarm.impt.io/widget. Mirrored to apps/site/public/widget/index.html.
- preview-track now uses CSS marquee animation (60s linear infinite, pause-on-hover)
- 6 cards duplicated as aria-hidden for seamless loop point at translateX(-50%)
- Edge-fade gradients widened to 64px so cards entering/leaving fade naturally
- prefers-reduced-motion users get a static scrollable strip (no animation)

Note: also updated root /srv/swarm/impt-swarm/site/index.html (NOT in this repo —
that's a separate site source) — launch bar + nav now advertise '36 channels'
+ swarm.impt.io/widget URL so users on the chat-focused root can find the
omnichannel showcase.
…P0 at /partners/dashboard

Two new pages live on swarm.impt.io:

1. /tools — every API tool split out with try-it forms + live response display
   • Web embed (live render-it-here button)
   • Widget API: track / intent / quote
   • Hotels search
   • QR generator (PNG + SVG output preview)
   • Email signature
   • Claude MCP — initialize / tools/list + each of 4 tools individually
   • ChatGPT GPT manifest fetch
   • Bots: TG (live), WA + FB (verify endpoint demo, gated on Meta tokens)
   • Partner: signup, partners/me

2. /partners/dashboard — customer dashboard P0 (single-page)
   Login: paste api_token from existing verify email → stored in localStorage
   Dashboard:
   • 4 stat cards: clicks 30d / bookings / earned / payable
   • Embed snippet with key pre-filled + copy button
   • Per-channel link list with one-click copy (8 channels)
   • Partner detail: status / email / brand / payout / joined
   • Recent bookings table (latest 100, mobile-card layout)
   • Sign-out clears localStorage

3. Homepage /widget CTA row adds 'Try every tool' + 'Partner sign-in' buttons
4. /partners/login → 0-second meta+JS redirect to /partners/dashboard

Implementation notes
- 100% static HTML/CSS/JS — no new server endpoints
- Reuses existing /api/widget/partners/me Bearer endpoint for dashboard data
- Token stored in localStorage (P0 MVP — magic-link cookie auth in P1)
- Mobile-responsive (cards stack 2x2, tables become rows below 620px)
- Dark/light contrast meets WCAG AA throughout
- Uptime monitor still 40/40 green after deploy
Mike saw '{"detail":"forbidden"}' on the FB verify test and read it as a bug.
It wasn't — that's the endpoint correctly rejecting an unauthorised verify
token, which is exactly what Meta requires for webhook subscription.

Changes
- Removed the 'paste a token' form (confusing — the token isn't user-input)
- Single 'Confirm endpoint refuses unauthorised verify (expects 403)' button
- Response display shows green '✓ HTTP 403 — expected' when 403 is returned
- Plain-language explanation of why 403 is correct + what 200 would mean

Same fix applied to WhatsApp + Facebook tools. Telegram is unchanged (its
secret-token check has different mechanics — header not query).
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.

1 participant