Commit Graph

8 Commits

Author SHA1 Message Date
will c375916f05 Scope sync to campaigns changed since a given commit
CI / test (push) Successful in 8s
Add SyncChanged (and the ChangedSlugs git-diff helper it's built on) as
an opt-in narrower version of SyncDir: pass the push's "before" SHA and
only the campaign directories that actually changed get looked at at
all, instead of every campaign getting resolved and diffed against
listmonk on every push. An empty or unresolvable since (new branch's
first push, a shallow clone missing that commit, any git failure) always
falls back to a full scan -- this can only ever cause more work than
strictly necessary, never a silently-skipped campaign. SyncDir itself is
now a thin wrapper (SyncChanged with since=""), so every existing caller
and test is unaffected.

campaigns sync PATH now accepts an optional trailing SINCE_SHA.
2026-08-13 13:40:10 -04:00
will 34d61c2e69 Stop failing sync over already-sent campaigns still in the repo
CI / test (push) Successful in 9s
A campaign.md is meant to stay around after it's sent as a record of what
went out and when. Treating any non-draft campaign as a hard rejection
forced deleting it just to keep CI green, and there was no way to fail on
resolving a stale list/attachment reference either -- an archived
campaign has nothing left to resolve, so check status before doing any of
that work. Non-draft campaigns now report as a distinct, non-error
"skipped" bucket instead of "rejected".
2026-08-13 13:24:39 -04:00
will 0c8bc6bd3b Fix spurious re-sync/preview for campaigns without an explicit template_id
CI / test (push) Successful in 21s
campaignUnchanged compared input.TemplateID (0 when unset) literally
against existing.TemplateID, but listmonk always assigns a real, nonzero
template_id server-side even when create/update omits it. Every campaign
without an explicit template_id was therefore flagged "changed" on every
sync, forever, firing an unwanted extra preview email each time — caught
via reground-campaigns' welcome/campaign.md re-previewing on an unrelated
push. Treat TemplateID 0 as "don't compare" instead. Test fake now mirrors
listmonk's real default-assignment behavior so this class of bug is caught.
2026-08-13 11:35:52 -04:00
will 6227d59eae Track altbody in change-detection so existing campaigns actually re-sync
CI / test (push) Successful in 10s
Campaign/parseCampaign never fetched altbody, so campaignUnchanged()
compared everything except it -- a campaign synced before v0.1.3
(altbody always null) whose content otherwise hasn't changed would be
judged unchanged forever and never get updated with the new altbody,
even though every subsequent sync now intends to send one.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 22:13:13 -04:00
will 4006dca9f5 Split tool from content: eec-campaigns becomes a standalone CLI
CI / test (push) Successful in 12s
Campaign content and listmonk credentials now live in separate
per-domain repos that install this tool at a pinned version, so a
client with access to one domain's content repo has no path to
another domain's secrets. Renames the module to the actual Gitea
host path so `go install` works without vanity-import redirects,
drops the four workflows that assumed campaigns/ content lived here,
adds real go-test CI, and rewrites the README for the tool's new
audience.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-10 20:00:52 -04:00
will a630a8f8ab Add template-as-code sync (campaigns template NAME PATH)
Answers "can the unsubscribe template be added via git+API too": commit
listmonk's own stock campaign template (already unsubscribe-capable) as
email-templates/campaign.html, add a small find-or-create-or-update
Template client (confirmed against knadh/listmonk's actual model/handlers),
a new `template` subcommand, and a manual-dispatch-only workflow to push it
in as the default campaign template. Unlike campaign sync there's no
draft/live status to protect, so this is always a safe overwrite.
2026-07-10 08:54:31 -04:00
will bcf8df5579 Fix campaign/listmonk API shapes against confirmed source, not guesses
Read knadh/listmonk's actual Go source (cmd/campaigns.go, cmd/subscribers.go)
instead of relying on incomplete public docs. Two corrections: the media
attach field is "media" (plain IDs), not "media_ids" as originally guessed;
and there's a single query-based bulk list action
(PUT /api/subscribers/query/lists) that applies a segment_query server-side,
so resolveSegment no longer fetches subscriber IDs client-side before
bulk-adding them. Create-status-defaults-to-draft and the test-send
"subscribers" field are now confirmed rather than flagged TODO(verify).
2026-07-10 08:37:07 -04:00
will b16d2b6c5f Initial implementation of the eec-campaigns tool
Drives listmonk's real Campaign API from git-authored Markdown+frontmatter,
so broadcast/segment emails get listmonk's mature unsubscribe/bulk-send/
attachment handling instead of reimplementing it. sync only ever creates or
updates a draft (idempotent, diff-based, refuses to touch a non-draft
campaign); a pushed send/<slug> tag or manual workflow run is the only way
to actually trigger a send. Includes list-name resolution, segment_query
materialization into managed lists, content-hash-deduped attachment
uploads, and an automatic post-sync preview email.
2026-07-10 07:30:45 -04:00