Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mailchimp upsert contacts/update tags in batch #124

Merged
merged 1 commit into from
Jul 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 130 additions & 1 deletion src/main/java/com/impactupgrade/nucleus/client/MailchimpClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@

import com.ecwid.maleorang.MailchimpException;
import com.ecwid.maleorang.MailchimpObject;
import com.ecwid.maleorang.method.v3_0.batches.BatchStatus;
import com.ecwid.maleorang.method.v3_0.batches.GetBatchStatusMethod;
import com.ecwid.maleorang.method.v3_0.batches.StartBatchMethod;
import com.ecwid.maleorang.method.v3_0.lists.members.DeleteMemberMethod;
import com.ecwid.maleorang.method.v3_0.lists.members.EditMemberMethod;
import com.ecwid.maleorang.method.v3_0.lists.members.GetMemberMethod;
Expand All @@ -14,15 +17,20 @@
import com.ecwid.maleorang.method.v3_0.lists.merge_fields.EditMergeFieldMethod;
import com.ecwid.maleorang.method.v3_0.lists.merge_fields.GetMergeFieldsMethod;
import com.ecwid.maleorang.method.v3_0.lists.merge_fields.MergeFieldInfo;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.impactupgrade.nucleus.environment.EnvironmentConfig;
import org.apache.commons.collections.CollectionUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -80,6 +88,28 @@ public void upsertContact(String listId, MemberInfo contact) throws IOException,
}
}

public String upsertContactsBatch(String listId, List<MemberInfo> contacts) throws IOException, MailchimpException {
List<EditMemberMethod.CreateOrUpdate> upsertMemberMethods = contacts.stream()
.map(contact -> {
EditMemberMethod.CreateOrUpdate upsertMemberMethod = new EditMemberMethod.CreateOrUpdate(listId, contact.email_address);
upsertMemberMethod.status_if_new = contact.status;
upsertMemberMethod.mapping.putAll(contact.mapping);
upsertMemberMethod.merge_fields.mapping.putAll(contact.merge_fields.mapping);
upsertMemberMethod.interests.mapping.putAll(contact.interests.mapping);
upsertMemberMethod.tags = contact.tags;
return upsertMemberMethod;
})
.collect(Collectors.toList());

StartBatchMethod startBatchMethod = new StartBatchMethod(upsertMemberMethods);
BatchStatus batchStatus = client.execute(startBatchMethod);
return batchStatus.id;
}

public List<MemberInfo> getListMembers(String listId) throws IOException, MailchimpException {
return getListMembers(listId, null, null);
}

// public List<MemberInfo> getListMembers(String listId, String status) throws IOException, MailchimpException {
// return getListMembers(listId, status, null);
// }
Expand All @@ -96,7 +126,7 @@ public List<MemberInfo> getListMembers(String listId, String status, Calendar si
}
GetMembersMethod.Response getMemberResponse = client.execute(getMembersMethod);
List<MemberInfo> members = new ArrayList<>(getMemberResponse.members);
while(getMemberResponse.total_items > members.size()) {
while (getMemberResponse.total_items > members.size()) {
getMembersMethod.offset = members.size();
log.info("retrieving list {} contacts (offset {} of total {})", listId, getMembersMethod.offset, getMemberResponse.total_items);
getMemberResponse = client.execute(getMembersMethod);
Expand All @@ -119,6 +149,16 @@ public void archiveContact(String listId, String email) throws IOException, Mail
}
}

public String archiveContactsBatch(String listId, List<String> emails) throws IOException, MailchimpException {
List<DeleteMemberMethod> deleteMemberMethods = emails.stream()
.map(email -> new DeleteMemberMethod(listId, email))
.collect(Collectors.toList());

StartBatchMethod startBatchMethod = new StartBatchMethod(deleteMemberMethods);
BatchStatus batchStatus = client.execute(startBatchMethod);
return batchStatus.id;
}

// TODO: TEST THIS
public Set<String> getContactGroupIds(String listId, String contactEmail) throws IOException, MailchimpException {
MemberInfo contact = getContactInfo(listId, contactEmail);
Expand All @@ -131,6 +171,18 @@ public List<String> getContactTags(String listId, String contactEmail) throws IO
return tags.stream().map(t -> t.mapping.get(TAG_NAME).toString()).collect(Collectors.toList());
}

public Map<String, List<String>> getContactsTags(String listId) throws IOException, MailchimpException {
VSydor marked this conversation as resolved.
Show resolved Hide resolved
List<MemberInfo> memberInfos = getListMembers(listId);
Map<String, List<String>> tagsMap = memberInfos.stream()
.collect(Collectors.toMap(
memberInfo -> memberInfo.email_address, memberInfo -> {
List<MailchimpObject> tags = (List<MailchimpObject>) memberInfo.mapping.get(TAGS);
return tags.stream().map(t -> t.mapping.get(TAG_NAME).toString()).collect(Collectors.toList());
}
));
return tagsMap;
}

public void updateContactTags(String listId, String contactEmail, List<String> activeTags, List<String> inactiveTags) throws IOException, MailchimpException {
ArrayList<MailchimpObject> tags = new ArrayList<>();
for (String activeTag : activeTags) {
Expand All @@ -151,6 +203,46 @@ public void updateContactTags(String listId, String contactEmail, List<String> a
client.execute(editMemberMethod);
}

public String updateContactTagsBatch(String listId, List<EmailContact> emailContacts) throws IOException, MailchimpException {
List<EditMemberMethod.AddorRemoveTag> editMemberMethods =
emailContacts.stream()
.map(emailContact -> {
List<String> active = emailContact.activeTags;
List<String> inactive = emailContact.inactiveTags;
ArrayList<MailchimpObject> tags = new ArrayList<>();
if (CollectionUtils.isNotEmpty(active)) {
for (String activeTag : active) {
MailchimpObject tag = new MailchimpObject();
tag.mapping.put(TAG_STATUS, TAG_ACTIVE);
tag.mapping.put(TAG_NAME, activeTag);
tags.add(tag);
}
}
if (CollectionUtils.isNotEmpty(inactive)) {
for (String inactiveTag : inactive) {
MailchimpObject tag = new MailchimpObject();
tag.mapping.put(TAG_STATUS, TAG_INACTIVE);
tag.mapping.put(TAG_NAME, inactiveTag);
tags.add(tag);
}
}

EditMemberMethod.AddorRemoveTag editMemberMethod = new EditMemberMethod.AddorRemoveTag(listId, emailContact.email);
editMemberMethod.tags = tags;

return editMemberMethod;
}).collect(Collectors.toList());

StartBatchMethod startBatchMethod = new StartBatchMethod(editMemberMethods);
BatchStatus batchStatus = client.execute(startBatchMethod);
return batchStatus.id;
}

public BatchStatus getBatchStatus(String batchStatusId) throws IOException, MailchimpException {
GetBatchStatusMethod getBatchStatusMethod = new GetBatchStatusMethod(batchStatusId);
return client.execute(getBatchStatusMethod);
}

public List<MergeFieldInfo> getMergeFields(String listId) throws IOException, MailchimpException {
GetMergeFieldsMethod getMergeFields = new GetMergeFieldsMethod(listId);
getMergeFields.count = 1000; // the max
Expand All @@ -174,4 +266,41 @@ public String exceptionToString(MailchimpException e) {
}
return description;
}

public record EmailContact(String email, List<String> activeTags, List<String> inactiveTags) {};

@JsonIgnoreProperties(ignoreUnknown = true)
public static final class BatchOperation {
@JsonProperty("status_code")
public Integer status;
@JsonProperty("operation_id")
public String operationId;
public BatchOperationResponse response;
}

@JsonIgnoreProperties(ignoreUnknown = true)
public static final class BatchOperationResponse {
public String id;
@JsonProperty("merge_fields")
public Map<String, Object> mergeFields;
@JsonProperty("contact_id")
public String contactId;
@JsonProperty("email_address")
public String email;
@JsonProperty("full_name")
public String fullName;
@JsonProperty("tags_count")
public Integer tagsCount;
@JsonProperty("last_changed")
public Date lastChangedAt;
@JsonProperty("list_id")
public String listId;

// error response fields
public String instance;
public String detail;
public String type;
public String title;
public String status;
}
}
Loading
Loading