From 845c8e70ea87566ee5ede8d2e62551f2463de286 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 11 Apr 2016 15:37:04 -0500 Subject: [PATCH 1/2] Adds example of importing Mandrill blacklist into SparkPost's Suppression List. --- .../samples/mandrillBlacklistExample.csv | 15 ++ .../samples/MandrillBlacklistImport.java | 142 ++++++++++++++++++ 2 files changed, 157 insertions(+) create mode 100644 apps/sparkpost-samples-app/samples/mandrillBlacklistExample.csv create mode 100644 apps/sparkpost-samples-app/src/main/java/com/sparkpost/samples/MandrillBlacklistImport.java diff --git a/apps/sparkpost-samples-app/samples/mandrillBlacklistExample.csv b/apps/sparkpost-samples-app/samples/mandrillBlacklistExample.csv new file mode 100644 index 0000000..3563a32 --- /dev/null +++ b/apps/sparkpost-samples-app/samples/mandrillBlacklistExample.csv @@ -0,0 +1,15 @@ +email,reason,detail,created_at,expires_at,last_event_at,expires_at,subaccount +00000000@EXAMPLE.com,soft-bounce,,"2015-11-03 10:22:19.9567","2015-11-04 10:22:19","2015-11-03 10:22:19.95665","2015-11-04 10:22:19", +01904758111@example.COM,hard-bounce,"SMTP; 550 5.4.1 [01904758111@EXAMPLE.COM]: Recipient address rejected: Access denied","2016-01-14 19:08:17.51258","2016-01-21 19:08:17","2016-01-14 19:08:17.51253","2016-01-21 19:08:17", +01906204000@EXANPLE.COM,hard-bounce,"smtp;550 5.1.10 RESOLVER.ADR.RecipientNotFound; Recipient not found by SMTP address lookup","2015-12-18 17:49:49.74724","2016-01-28 19:44:39","2016-01-14 19:44:39.83638","2016-01-28 19:44:39", +01906823929@EXAMPLE.COM,hard-bounce,"SMTP; 550 5.4.1 [01906823929@EXAMPLE.COM]: Recipient address rejected: Access denied","2016-02-11 21:13:03.00523","2016-02-18 21:13:03","2016-02-11 21:13:03.00518","2016-02-18 21:13:03", +0uojuc1q5p@gmail.com,hard-bounce,"smtp;550 5.1.1 The email account that you tried to reach does not exist. Please try double-checking the recipient's email address for typos or unnecessary spaces. Learn more at https://support.google.com/mail/answer/6596 c188si8742007ywf.98 - gsmtp","2016-03-29 16:37:24.59657","2016-04-05 16:37:24","2016-03-29 16:37:24.59654","2016-04-05 16:37:24", +10687603@example.com.ar,soft-bounce,,"2015-06-05 19:50:18.09675","2015-06-11 21:04:00","2015-06-10 21:04:00.63428","2015-06-11 21:04:00", +10742937@example.com.ar,soft-bounce,,"2015-06-09 18:17:29.87352","2015-06-10 18:17:29","2015-06-09 18:17:29.87349","2015-06-10 18:17:29", +10803057@example.com.ar,soft-bounce,,"2015-05-19 20:50:11.78634","2015-06-09 19:28:15","2015-06-05 19:28:15.04113","2015-06-09 19:28:15", +10835434@example.com.ar,soft-bounce,,"2015-05-15 18:27:48.64675","2015-05-16 18:27:48","2015-05-15 18:27:48.6467","2015-05-16 18:27:48", +10835594@example.com.ar,soft-bounce,,"2015-06-09 14:10:20.86574","2015-06-11 14:21:03","2015-06-10 14:21:03.89673","2015-06-11 14:21:03", +10835805@example.com.ar,soft-bounce,,"2015-05-19 21:42:09.13229","2015-05-28 18:55:13","2015-05-27 18:55:13.1885","2015-05-28 18:55:13", +10835886@example.com.ar,soft-bounce,,"2015-05-19 14:16:12.35937","2015-05-23 13:26:26","2015-05-22 13:26:26.0547","2015-05-23 13:26:26", +10847089@example.com.ar,soft-bounce,,"2015-06-09 19:04:32.1635","2015-06-10 19:04:32","2015-06-09 19:04:32.16347","2015-06-10 19:04:32", +10849915@example.com.ar,soft-bounce,,"2015-06-09 22:37:12.14275","2015-06-10 22:37:12","2015-06-09 22:37:12.1427","2015-06-10 22:37:12", diff --git a/apps/sparkpost-samples-app/src/main/java/com/sparkpost/samples/MandrillBlacklistImport.java b/apps/sparkpost-samples-app/src/main/java/com/sparkpost/samples/MandrillBlacklistImport.java new file mode 100644 index 0000000..0c1b843 --- /dev/null +++ b/apps/sparkpost-samples-app/src/main/java/com/sparkpost/samples/MandrillBlacklistImport.java @@ -0,0 +1,142 @@ + +package com.sparkpost.samples; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; + +import org.apache.commons.lang3.StringUtils; +import org.apache.log4j.Level; +import org.apache.log4j.Logger; + +import com.sparkpost.Client; +import com.sparkpost.exception.SparkPostException; +import com.sparkpost.model.SuppressionList; +import com.sparkpost.model.SuppressionListEntry; +import com.sparkpost.model.responses.Response; +import com.sparkpost.resources.ResourceSuppressionList; +import com.sparkpost.sdk.samples.helpers.SparkPostBaseApp; +import com.sparkpost.transport.RestConnection; + +/** + * Lists all Sending Domains + */ +public class MandrillBlacklistImport extends SparkPostBaseApp { + + static final Logger logger = Logger.getLogger(MandrillBlacklistImport.class); + + private Client client; + + public static class Fields { + + public static final int EMAIL_COL = 0; + public static final int REASON_COL = 1; + public static final int DESCRIPTION_COL = 2; + public static final int CREATED_AT_COL = 3; + public static final int EXPIRES_AT_COL = 4; + public static final int LAST_EVENT_AT_COL = 5; + public static final int EXPIRES_AT2_COL = 6; + public static final int SUBACCOUNT_COL = 7;// Unused + + } + + public static void main(String[] args) throws SparkPostException, IOException { + Logger.getRootLogger().setLevel(Level.DEBUG); + + MandrillBlacklistImport sample = new MandrillBlacklistImport(); + sample.runApp(); + } + + /* + * How to export Mandrill blacklist: https://mandrill.zendesk.com/hc/en-us/articles/205582997 + * Beware some samples I've received from Mandrill are not 100% correctly formated. I've found it necessary to remove some corrupt lines. + */ + private void runApp() throws SparkPostException, IOException { + + this.client = this.newConfiguredClient(); + RestConnection connection = new RestConnection(this.client, getEndPoint()); + + SuppressionList suppressionList = new SuppressionList(); + suppressionList.setRecipients(new ArrayList()); + + // Load sample Mandrill Blacklist file + String csvFile = "samples/mandrillBlacklistExample.csv"; + BufferedReader br = null; + String line = ""; + String cvsSplitBy = ","; + + int row = 0; + try { + br = new BufferedReader(new FileReader(csvFile)); + while ((line = br.readLine()) != null) { + row++; + if (StringUtils.isEmpty(line)) { + System.out.println("Warning: LN:" + row + " is empty"); + continue; + } + String[] entryRow = line.split(cvsSplitBy); + + if (entryRow.length < Fields.EXPIRES_AT2_COL) { + System.out.println("Error: LN:" + row + " too short (" + entryRow.length + "),\n \"" + line + "\"\n"); + } + + String email = entryRow[Fields.EMAIL_COL]; + System.out.println("Parse: " + line); + + if (StringUtils.isEmpty(email)) { + // Ignore rows that do not have an email address since it is required. Should we fail instead? + System.out.println("Ignore header row"); + continue; + } else if (email.equalsIgnoreCase("email")) { + // First row is column names so skip it + System.out.println("Warning: LN:" + row + " Ignore blank email row\""); + continue; + } else if (StringUtils.isEmpty(entryRow[Fields.REASON_COL]) || !entryRow[Fields.REASON_COL].equalsIgnoreCase("hard-bounce")) { + // ignore empty reason or soft-bounces + //System.out.println("Ignore reason: " + entryRow[Fields.REASON_COL]); + System.out.println("LN:" + row + " Ignore reason: " + entryRow[Fields.REASON_COL]); + continue; + } + + System.out.println("LN:" + row + " adding " + entryRow[Fields.EMAIL_COL]); + + SuppressionListEntry entry = new SuppressionListEntry(); + // MBL: = Mandrill Blacklist + entry.setDescription("MBL: " + line); + entry.setEmail(entryRow[Fields.EMAIL_COL]); + // Assumes Mandrill blacklist is only for non-transactional email + entry.setTransactional(false); + entry.setNonTransactional(true); + + // Leave off source so it is set to "Manually Added" + // entry.setSource(null); + + // Maybe a Set is better to make sure addresses are unique + suppressionList.getRecipients().add(entry); + } + + } finally { + System.out.println("Last row: " + row); + System.out.println("Last Line: " + line); + if (br != null) { + try { + br.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + System.out.println("Done"); + + if (suppressionList.getRecipients() == null || suppressionList.getRecipients().size() == 0) { + System.out.println("There are no members of blacklist to add or update"); + return; + + } + Response result = ResourceSuppressionList.insertOrUpdateBulk(connection, suppressionList); + System.out.println("Supression List Result: " + result); + + } +} From 281484fb6e9c104090ea74ec982f2aaf0e0b1cbe Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 11 Apr 2016 15:50:03 -0500 Subject: [PATCH 2/2] Reads file as UTF-8 instead of system default charset. --- .../java/com/sparkpost/samples/MandrillBlacklistImport.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/sparkpost-samples-app/src/main/java/com/sparkpost/samples/MandrillBlacklistImport.java b/apps/sparkpost-samples-app/src/main/java/com/sparkpost/samples/MandrillBlacklistImport.java index 0c1b843..acd1898 100644 --- a/apps/sparkpost-samples-app/src/main/java/com/sparkpost/samples/MandrillBlacklistImport.java +++ b/apps/sparkpost-samples-app/src/main/java/com/sparkpost/samples/MandrillBlacklistImport.java @@ -2,8 +2,9 @@ package com.sparkpost.samples; import java.io.BufferedReader; -import java.io.FileReader; +import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStreamReader; import java.util.ArrayList; import org.apache.commons.lang3.StringUtils; @@ -68,7 +69,8 @@ private void runApp() throws SparkPostException, IOException { int row = 0; try { - br = new BufferedReader(new FileReader(csvFile)); + br = new BufferedReader(new InputStreamReader(new FileInputStream(csvFile), "UTF-8")); + while ((line = br.readLine()) != null) { row++; if (StringUtils.isEmpty(line)) {