AtlatestRepositorysigil-postmark
1# sigil-postmark
2
3A Sigil library for the [Postmark](https://postmarkapp.com) email API. Send transactional and broadcast email, query bounces, and parse delivery / bounce / complaint / open / click webhooks — all with a single server-token header, no request signing.
4
5Designed to drop in as a replacement for `sigil-ses` when you'd rather not fight AWS sandbox approval.
6
7## Features
8
9- **Single send** — plain text + HTML with To / Cc / Bcc / ReplyTo, tagging, metadata, and message streams.
10- **Batch send** — up to 500 messages per request, one HTTP round trip.
11- **Bounce queries** — list bounces with filters, fetch by ID, re-activate inactive addresses.
12- **Webhook parsing** — typed records for bounce, spam-complaint, delivery, open, and click events. Includes both JSON-string and pre-parsed dict input.
14## Quickstart
16```scheme
17(import (postmark api))
19(define client
20 (postmark-client server-token: (getenv "POSTMARK_SERVER_TOKEN")))
22;; Single send
23(let ((result (postmark-send client
26 "Hello from Sigil"
27 text: "Plain-text body."
28 html: "<h1>Hello</h1><p>HTML body.</p>"
29 tag: "newsletter"
30 reply-to: "[email protected]")))
31 (display (postmark-email-result-message-id result)))
33;; Send to multiple recipients
34(postmark-send client
37 "Issue #42"
38 text: "Content…"
41;; Batch send — hand-build each payload
42(postmark-send-batch client
43 (list
44 (build-send-payload "[email protected]" "[email protected]"
45 "Subject A" text: "Body A")
46 (build-send-payload "[email protected]" "[email protected]"
47 "Subject B" text: "Body B")))
49;; Query bounces
50(postmark-list-bounces client count: 100 type: "HardBounce")
52;; Reactivate a bounced address
53(postmark-activate-bounce client 12345)
54```
56## Webhook parsing
58Configure a Postmark webhook to POST to your HTTP handler, then:
60```scheme
61(import (postmark webhook))
63(let ((ev (postmark-parse-webhook json-body)))
64 (when ev
65 (cond
66 ((postmark-hard-bounce-event? ev)
67 ;; deactivate the address
68 (remove-subscriber (postmark-webhook-event-recipient ev)))
69 ((postmark-spam-complaint-event? ev)
70 (unsubscribe (postmark-webhook-event-recipient ev)))
71 ((postmark-delivery-event? ev)
72 (log-delivered (postmark-webhook-event-message-id ev))))))
73```
75`postmark-webhook-event` carries:
77- `type` — `'bounce`, `'spam-complaint`, `'delivery`, `'open`, `'click`
78- `message-id` — Postmark message ID
79- `recipient` — affected address
80- `details` — event-specific dict (bounce type code, user agent, click target, …)
81- `raw` — the original parsed dict, for any field not exposed above
83## Environment variables
85Consumers typically read a single variable:
87- `POSTMARK_SERVER_TOKEN` — per-server API token from the Postmark console.
89The bundled `examples/live-send.sgl` script also honours:
91- `POSTMARK_FROM` — verified sender (default `[email protected]`)
92- `POSTMARK_TO` — recipient for the integration test
94## Dependencies
96- `sigil-stdlib` ^0.13.0
97- `sigil-http` ^0.13.0
98- `sigil-json` ^0.13.0
100(No `sigil-crypto` — Postmark does not sign requests.)
102## Building
104```bash
105sigil deps install
106sigil build
107sigil test
108```
110## License
112BSD-3-Clause