The PHP app, Apache, and .htaccess are replaced by a single Go binary
(standard library only). Routing, the JSON response, the landing page,
the shared email design, and all four parsers are ported with the same
output; JSON object keys are kept in sender order via an ordered decoder.
- mail.go: SMTP delivery with quoted-printable body and RFC 2047 subject
- main.go: routing, client IP from the proxy, /healthz, -check flag
- render.go: email shell, escaping, table helpers, generic renderer
- parser_*.go: github, grafana, json, wxinteract
- main_test.go: handler, response shape, IP forwarding, every parser
- Dockerfile: multi-stage build to distroless static, non-root, HEALTHCHECK
- deploy/webhooks.dixon.cx.service: systemd unit for the container
- README and PARSER_PROMPT updated for Go; IMPLEMENTATION_SUMMARY removed
The guide lived one directory above the repo, so the README links were
broken on GitHub. It also described the old layout: parsers inside
index.php, a copied <style> block, and div-based tables. It now covers
parsers/{name}.php, emailShell(), esc(), real table markup,
case-insensitive headers, and local testing with a sendmail override.
REMOTE_ADDR inside the container is 172.17.0.1. When the peer is a
private or loopback address, use X-Real-IP (or the first hop of
X-Forwarded-For) that nginx sets. Public peers cannot spoof it.
- esc() helper escapes free-text values and converts newlines to <br>;
used for commit messages, SMS text, annotations, and all JSON values
- JSON parser accepts scalar bodies (string, number, bool, null) and
renders them as a one-row table instead of falling back to the
default template
- Arrays of plain values render as one table under their path
breadcrumb, so nested string lists are no longer anonymous
- GitHub commits render as cards with a sha pill linked to the commit
Metadata blocks were divs styled with display:table. Nested blocks and
orphan cells created phantom columns that squeezed the value column to
a character or two. Every metadata block is now a real <table>/<tr>/<td>,
which mail clients lay out reliably, and the value column always fills
the remaining width.
The shared shell gets a gradient hero header, timestamp pill, dark
frame, and refreshed section, card, and code-block styling.
Header names arrive lowercase over HTTP/2 (the nginx front end enables
it) and Apache preserves that case, so the X-GitHub-Event lookup missed
and every email reported "Unknown". Normalise header keys once.
- docs.htm: dark single-page redesign in plain CSS, live URL builder,
all four parsers documented, Bootstrap CDN dependency dropped
- index.php: respond with pretty-printed JSON (success and 400 error);
email "Parsed Variables" block uses JSON instead of print_r
- parsers/helpers.php: emailShell() provides one stylesheet, header and
footer for every email template; five duplicated stylesheets removed
- Detailed documentation for all 7 event types
- Configuration instructions
- Testing examples with cURL
- Email organization tips
- Troubleshooting section
- Links to official API documentation
- Added wxinteractParse() function supporting all SMS API events:
* Outbound SMS (submitted, delivered, failed)
* Shortlink clicked
* Inbound SMS received
* SMS opt out
* Contacts callback
- Helper functions for each event type with formatted HTML
- Test samples file for all event types
- Updated README with Webex Interact documentation
- Follows existing parser style and security guidelines