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>
This commit is contained in:
2026-07-23 22:13:13 -04:00
parent e238bde036
commit 6227d59eae
3 changed files with 11 additions and 2 deletions
+4
View File
@@ -217,6 +217,10 @@ func attachmentFilename(slug, relPath string, content []byte) string {
func campaignUnchanged(existing *listmonk.Campaign, input listmonk.CampaignInput) bool { func campaignUnchanged(existing *listmonk.Campaign, input listmonk.CampaignInput) bool {
return existing.Subject == input.Subject && return existing.Subject == input.Subject &&
existing.Body == input.Body && existing.Body == input.Body &&
// altbody always mirrors body (see CampaignInput.payload) -- comparing
// it here is what catches a campaign synced before that started, whose
// stored altbody is still null even though its body hasn't changed.
existing.AltBody == input.Body &&
existing.FromEmail == input.FromEmail && existing.FromEmail == input.FromEmail &&
existing.TemplateID == input.TemplateID && existing.TemplateID == input.TemplateID &&
existing.Type == input.Type && existing.Type == input.Type &&
+4 -2
View File
@@ -31,6 +31,7 @@ type fakeCampaign struct {
Status string Status string
Subject string Subject string
Body string Body string
AltBody string
FromEmail string FromEmail string
TemplateID int TemplateID int
Type string Type string
@@ -138,7 +139,7 @@ func (c fakeCampaign) toJSON() map[string]any {
} }
return map[string]any{ return map[string]any{
"id": c.ID, "name": c.Name, "status": c.Status, "subject": c.Subject, "id": c.ID, "name": c.Name, "status": c.Status, "subject": c.Subject,
"body": c.Body, "from_email": c.FromEmail, "template_id": c.TemplateID, "body": c.Body, "altbody": c.AltBody, "from_email": c.FromEmail, "template_id": c.TemplateID,
"type": c.Type, "tags": c.Tags, "lists": lists, "media": media, "type": c.Type, "tags": c.Tags, "lists": lists, "media": media,
} }
} }
@@ -155,7 +156,7 @@ func (f *fakeListmonk) createCampaign(w http.ResponseWriter, r *http.Request) {
body := decodeBody(r) body := decodeBody(r)
c := fakeCampaign{ c := fakeCampaign{
ID: f.id(), Name: str(body["name"]), Status: "draft", ID: f.id(), Name: str(body["name"]), Status: "draft",
Subject: str(body["subject"]), Body: str(body["body"]), Subject: str(body["subject"]), Body: str(body["body"]), AltBody: str(body["altbody"]),
FromEmail: str(body["from_email"]), TemplateID: toInt(body["template_id"]), FromEmail: str(body["from_email"]), TemplateID: toInt(body["template_id"]),
Type: str(body["type"]), Tags: toStrings(body["tags"]), Type: str(body["type"]), Tags: toStrings(body["tags"]),
ListIDs: toInts(body["lists"]), MediaIDs: toInts(body["media"]), ListIDs: toInts(body["lists"]), MediaIDs: toInts(body["media"]),
@@ -171,6 +172,7 @@ func (f *fakeListmonk) updateCampaign(w http.ResponseWriter, r *http.Request) {
if f.campaigns[i].ID == id { if f.campaigns[i].ID == id {
f.campaigns[i].Subject = str(body["subject"]) f.campaigns[i].Subject = str(body["subject"])
f.campaigns[i].Body = str(body["body"]) f.campaigns[i].Body = str(body["body"])
f.campaigns[i].AltBody = str(body["altbody"])
f.campaigns[i].FromEmail = str(body["from_email"]) f.campaigns[i].FromEmail = str(body["from_email"])
f.campaigns[i].TemplateID = toInt(body["template_id"]) f.campaigns[i].TemplateID = toInt(body["template_id"])
f.campaigns[i].Type = str(body["type"]) f.campaigns[i].Type = str(body["type"])
+3
View File
@@ -289,6 +289,7 @@ type Campaign struct {
Status string Status string
Subject string Subject string
Body string Body string
AltBody string
FromEmail string FromEmail string
TemplateID int TemplateID int
Type string Type string
@@ -381,6 +382,7 @@ func parseCampaign(data []byte) (*Campaign, error) {
Status string `json:"status"` Status string `json:"status"`
Subject string `json:"subject"` Subject string `json:"subject"`
Body string `json:"body"` Body string `json:"body"`
AltBody string `json:"altbody"`
FromEmail string `json:"from_email"` FromEmail string `json:"from_email"`
TemplateID int `json:"template_id"` TemplateID int `json:"template_id"`
Type string `json:"type"` Type string `json:"type"`
@@ -409,6 +411,7 @@ func parseCampaign(data []byte) (*Campaign, error) {
Status: parsed.Status, Status: parsed.Status,
Subject: parsed.Subject, Subject: parsed.Subject,
Body: parsed.Body, Body: parsed.Body,
AltBody: parsed.AltBody,
FromEmail: parsed.FromEmail, FromEmail: parsed.FromEmail,
TemplateID: parsed.TemplateID, TemplateID: parsed.TemplateID,
Type: parsed.Type, Type: parsed.Type,