Skip to content

Commit

Permalink
Add option for one-way sync
Browse files Browse the repository at this point in the history
  • Loading branch information
wpf500 committed Jul 31, 2024
1 parent 774372d commit 69408d1
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 45 deletions.
98 changes: 57 additions & 41 deletions apps/backend/src/apps/settings/apps/newsletters/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,11 @@ interface ReportData {

async function handleResync(
statusSource: "ours" | "theirs",
dryRun: boolean,
removeUnsubscribed: boolean
opts: {
updateThem: boolean;
dryRun: boolean;
removeUnsubscribed: boolean;
}
) {
try {
await setResyncStatus("In progress: Fetching contact lists");
Expand All @@ -96,7 +99,10 @@ async function handleResync(
statusSource === "ours"
? contact.profile.newsletterStatus
: nlContact.status;
if (status === NewsletterStatus.Unsubscribed && removeUnsubscribed) {
if (
status === NewsletterStatus.Unsubscribed &&
opts.removeUnsubscribed
) {
existingContactsToArchive.push(contact);
}

Expand Down Expand Up @@ -134,17 +140,19 @@ async function handleResync(
} as ReportData)
);

if (dryRun) {
if (opts.dryRun) {
await setResyncStatus(
`DRY RUN: Successfully synced all contacts. ${nlContactsToImport.length} imported, ${mismatchedContacts.length} fixed, ${existingContactsToArchive.length} archived and ${newContactsToUpload.length} newly uploaded`
);
return;
}

await setResyncStatus(
`In progress: Uploading ${newContactsToUpload.length} new contacts to the newsletter list`
);
await NewsletterService.upsertContacts(newContactsToUpload);
if (opts.updateThem) {
await setResyncStatus(
`In progress: Uploading ${newContactsToUpload.length} new contacts to the newsletter list`
);
await NewsletterService.upsertContacts(newContactsToUpload);
}

// Must fix status before mass update to avoid overwriting in the wrong direction
if (statusSource === "theirs") {
Expand All @@ -164,35 +172,37 @@ async function handleResync(
}
}

await setResyncStatus(
`In progress: Updating ${existingContacts.length} contacts in newsletter list`
);
await NewsletterService.upsertContacts(existingContacts);
if (opts.updateThem) {
await setResyncStatus(
`In progress: Updating ${existingContacts.length} contacts in newsletter list`
);
await NewsletterService.upsertContacts(existingContacts);

// Sync tags before archiving
await setResyncStatus(
`In progress: Updating active member tag for ${mismatchedContacts.length} contacts in newsletter list`
);
// Sync tags before archiving
await setResyncStatus(
`In progress: Updating active member tag for ${mismatchedContacts.length} contacts in newsletter list`
);

await NewsletterService.addTagToContacts(
mismatchedContacts
.filter(([m]) => m.membership?.isActive)
.map(([m]) => m),
OptionsService.getText("newsletter-active-member-tag")
);
await NewsletterService.removeTagFromContacts(
mismatchedContacts
.filter(([m]) => !m.membership?.isActive)
.map(([m]) => m),
OptionsService.getText("newsletter-active-member-tag")
);
await NewsletterService.addTagToContacts(
mismatchedContacts
.filter(([m]) => m.membership?.isActive)
.map(([m]) => m),
OptionsService.getText("newsletter-active-member-tag")
);
await NewsletterService.removeTagFromContacts(
mismatchedContacts
.filter(([m]) => !m.membership?.isActive)
.map(([m]) => m),
OptionsService.getText("newsletter-active-member-tag")
);

// TODO: Check other tags
// TODO: Check other tags

await setResyncStatus(
`In progress: Archiving ${existingContactsToArchive.length} contacts from newsletter list`
);
await NewsletterService.archiveContacts(existingContactsToArchive);
await setResyncStatus(
`In progress: Archiving ${existingContactsToArchive.length} contacts from newsletter list`
);
await NewsletterService.archiveContacts(existingContactsToArchive);
}

await setResyncStatus(
`In progress: Importing ${nlContactsToImport.length} contacts from newsletter list`
Expand All @@ -214,9 +224,15 @@ async function handleResync(
);
}

await setResyncStatus(
`Successfully synced all contacts. ${nlContactsToImport.length} imported, ${mismatchedContacts.length} fixed, ${existingContactsToArchive.length} archived and ${newContactsToUpload.length} newly uploaded`
);
if (opts.updateThem) {
await setResyncStatus(
`Successfully synced all contacts. ${nlContactsToImport.length} imported, ${mismatchedContacts.length} fixed, ${existingContactsToArchive.length} archived, ${newContactsToUpload.length} newly uploaded`
);
} else {
await setResyncStatus(
`Successfully synced all contacts. ${nlContactsToImport.length} imported, ${mismatchedContacts.length} fixed`
);
}
} catch (error: any) {
log.error("Newsletter sync failed", error);
await setResyncStatus("Error: " + error.message);
Expand All @@ -231,11 +247,11 @@ app.post(
req.flash("success", "newsletter-resync-started");
res.redirect(req.originalUrl);

handleResync(
req.body.statusSource,
req.body.dryRun === "true",
req.body.removeUnsubscribed === "true"
);
handleResync(req.body.statusSource, {
updateThem: req.body.updateThem === "true",
dryRun: req.body.dryRun === "true",
removeUnsubscribed: req.body.removeUnsubscribed === "true"
});
}
})
);
Expand Down
18 changes: 14 additions & 4 deletions apps/backend/src/apps/settings/apps/newsletters/views/index.pug
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ block contents
form(method='post')
+csrf
p.
Sometimes the subscription status can differ between the system and
Sometimes the subscription status can differ between the system and
the newsletter provider. Who should we believe if it does?
p
span.radio-inline
Expand All @@ -48,15 +48,25 @@ block contents
| Provider

p.
The syncing process can remove unsubscribed contacts from the
The syncing process can remove unsubscribed contacts from the
newsletter provider. Would you like it to do so?
.checkbox
label
input(type='checkbox' name='archiveUnsubscribed' value='true')
| Yes, remove unsubscribed contacts

p.
This will perform the following #[b irrevisble] actions:
→ You can update the mismatched data on both systems, or just on the
membership system.
p
.checkbox-inline
label
input(type='checkbox' name='updateThem' value='true' checked)
| Also update the data on the newsletter provider


p.
→ This will perform the following #[b irrevisble] actions:

ul
li Import new contacts from the newsletter list
Expand All @@ -71,6 +81,6 @@ block contents
| I understand the risks
.checkbox
label
input(type='checkbox' name='dryRun' value='true')
input(type='checkbox' name='dryRun' value='true' checked)
| Dry run
button(name='action' value='resync').btn.btn-danger Resync

0 comments on commit 69408d1

Please sign in to comment.