Ten post jest skierowany do dewelopera, który chce jak najlepiej wykorzystać możliwości szablonów e-mail SparkPost. Zakłada się, że jesteś dobrze zaznajomiony z czytaniem zawartości JSON i śledzeniem podstawowego przepływu programowania. Jeśli pojawiają się terminy, które mogą być dla Ciebie nowe, jak RFC 5322, tekst jest powiązany z jego źródłem. Z tą kwestią załatwioną, przejdźmy od razu do rzeczy.
Szablony i możliwości transmisji SparkPost sprawiają, że wysyłanie e-maili jest proste. Te możliwości zapewniają abstrakcję dla treści tekstowych i HTML, co oznacza, że zazwyczaj nie ma potrzeby bezpośredniego kodowania surowego formatu e-mail, który jest zdefiniowany w RFC 5322 wcześniej znanym jako (RFC 822). Ale czasami możesz chcieć tworzyć bardziej złożone wiadomości, które mają inne części Multipurpose Internet Mail Extensions (MIME), które nie są bezpośrednio dostępne przez interfejs RESTful SparkPost.
Uproszczona Kompozycja E-mail
Najpierw przeanalizujemy scenariusz bezproblemowego wysyłania e-maila. Użyj punktu końcowego transmission do dostarczenia tekstu
i treści HTML. W tle SparkPost zajmuje się tworzeniem poprawnego e-maila RFC 5322. SparkPost wstawi zmienne zastępcze z substitution_data w treści tekstowej i HTML. Jest to potężny sposób na generowanie dostosowanej treści dla każdego odbiorcy w typowym szablonie.
Oto przykład transmission z treścią HTML i tekstową zawierającą substitution_data.
{
"options": {
"open_tracking": true,
"click_tracking": true
},
"campaign_id": "christmas_campaign",
"return_path": "bounces-christmas-campaign@domain.com",
"metadata": {
"user_type": "students"
},
"substitution_data": {
"sender": "Big Store Team"
},
"recipients": [
{
"return_path": "123@bounces.domain.com",
"address": {
"email": "wilma@domain.com",
"name": "Wilma Flintstone"
},
"tags": [
"greeting",
"prehistoric",
"fred",
"flintstone"
],
"metadata": {
"place": "Bedrock"
},
"substitution_data": {
"customer_type": "Platinum"
}
}
],
"content": {
"from": {
"name": "Fred Flintstone",
"email": "fred@domain.com"
},
"subject": "Big Christmas savings!",
"reply_to": "Christmas Sales <sales@domain.com>",
"headers": {
"X-Customer-Campaign-ID": "christmas_campaign"
},
"text": "Hi {{address.name}} \nSave big this Christmas in your area {{place}}! \nClick http://www.mysite.com and get huge discount\n Hurry, this offer is only to {{user_type}}\n {{sender}}",
"html": "<p>Hi {{address.name}} <br>Save big this Christmas in your area {{place}}! <br>Click <a href=\"http://www.mysite.com\">here</a> and get huge discount</p><p>Hurry, this offer is only to {{user_type}}</p><p>{{sender}}</p>"
}
}
Zamiana Tablic Danych
Wiele osób zdaje sobie sprawę, że końcowe punkty transmisji i szablonów SparkPost mogą wykonywać prostą zamianę treści w nagłówkach e-mail i treściach e-mail. Ale wielu przeocza możliwość dostarczania warunkowej treści lub tablic danych, które można również zastępować. Możesz także dostarczyć unikalną treść dla każdego odbiorcy. W tym przykładzie wysyłamy tablicę unikalnych linków do każdego odbiorcy.
To osiąga się poprzez dostarczenie tablicy danych w formacie JSON, która będzie wypełniona w ciele e-maila. Gdy dane zostaną dostarczone, SparkPost użyje logiki w szablonie do ich wypełnienia.
W tym przykładzie SparkPost będzie szukać danych zastępczych zwanych „files_html” i wykona „for each” na każdym elemencie w tablicy. Utworzy wiersz z wartością „file” w elemencie „files_html”. Zauważ potrójny nawias klamrowy wokół „loop_var.file“. Dzieje się tak, ponieważ każdy element tablicy zawiera HTML i musimy powiedzieć serwerowi, aby użył go w takiej formie, a nie go escape’ował. Część tekstowa będzie prostą etykietą tekstową i adresem URL do pliku.
<table>
{{each files_html}}
<tr>
<td>{{{loop_var.file}}}</td>
</tr>
{{ end }}
</table>
Oto gotowy działający przykład:
{
"recipients": [
{
"address": {
"email": "recipient1@domain.com"
},
"substitution_data": {
"files_html": [
{
"file": "<a href=\"http://domain.com/file1a.txt\">File 1a Description</a>"
},
{
"file": "<a href=\"http://domain.com/file2a.txt\">File 2a Description</a>"
}
],
"files_plain": [
{
"file": "File 1a -- http://domain.com/file1a.txt"
},
{
"file": "File 2a -- http://domain.com/file2a.txt"
}
]
}
},
{
"address": {
"email": "recipient2@domain.com"
},
"substitution_data": {
"files_html": [
{
"file": "<a href=\"http://domain.com/file1b.txt\">File 1b Description</a>"
},
{
"file": "<a href=\"http://domain.com/file2b.txt\">File 2b Description</a>"
}
],
"files_plain": [
{
"file": "File 1b -- http://domain.com/file1b.txt"
},
{
"file": "File 2b -- http://domain.com/file2b.txt"
}
]
}
}
],
"return_path": "chris@test.domain.com",
"content": {
"from": {
"name": "chris@test.domain.com",
"email": "chris@test.domain.com"
},
"subject": "Sending with SparkPost is Fun",
"html": "<b>Your Files:</b><br>\n<table>\n {{each files_html}}\n <tr><td>{{{loop_var.file}}}</td></tr>\n {{ end }}\n</table>\n",
"text": "Your Files:\n{{each files_plain}} {{loop_var.file}}\n{{ end }}\n"
}
}
Wskazówka: W kodzie zaleca się oddzielić znacznik widoku od danych, ale celem tutaj było utrzymanie przykładu jak najprostszym i łatwym do śledzenia, więc stworzyliśmy dwie tablice. Jedna tablica jest dla części HTML, a druga dla części tekstowej. W produkcji powszechnym rozwiązaniem jest posiadanie jednego zestawu danych i pisanie logiki w kodzie szablonu.
Załączniki w Możliwościach Transmisji
Końcowy punkt transmisji zapewnia również abstrakcję do wysyłania załączników. Poniżej zobaczysz, że załączniki są określone w content.attachments tablica, gdzie każdy obiekt w tablicy opisuje pojedynczy element załącznika. Tak jak wcześniej, SparkPost zajmuje się kodowaniem tekst, HTML, zamiennikami i iteracją przez tablicę załączników, aby zakodować poprawnie sformatowaną wiadomość e-mail.
Najlepsze praktyki sugerują unikanie wysyłania załączników, chyba że jest to wyraźnie wymagane jako część twojej usługi.
Poniżej znajdują się wymagane pola dla załącznika:
type: Typ MIME załącznika
name: Nazwa pliku załącznika
data: Dane pliku w formacie Base64
Tak wygląda załącznik w ramach treści transmisji:
"content": {
"attachments": [
{
"type": "audio/mp3",
"name": "voicemail.mp3",
"data": "TVAzIERhdGEK"
}
]
}
Możesz również wysyłać „obrazy osadzone” w transmisji. Są one bardzo podobne do załączników i są określone w tablicy content.inline_images, gdzie każdy z obiektów inline_image jest podobny do obiektu załącznika pokazanym powyżej.
Załączniki w Szablonach
Teraz, gdy mamy odpowiednie podstawy do wysyłania załączników z końcowego punktu transmisji, przyjrzymy się, jak to zrobić za pomocą szablonów. W momencie pisania tego tekstu nie ma jeszcze abstrakcji dla załączników, takiej jak dla transmisji inline. Można by wnioskować, że szablonów nie da się tworzyć z załącznikami. Byłbyś częściowo poprawny, ale istnieje obejście, chociaż nie będziesz już izolowany od formatu RFC 5322.
Możesz osiągnąć załączniki w szablonach, kodując samodzielnie treść RFC 5322, która zawiera załączniki. Dobrą wiadomością jest to, że nadal będziesz mógł używać danych zastępczych Substitution Data w nagłówkach e-mail, HTML i częściach tekstowych. Weź jednak pod uwagę, że ten rodzaj szablonu ogranicza zastępstwa do nagłówków i pierwszej części HTML oraz tekstowej.
Oto jak to się robi.
E-mail RFC822
Stwórz swój e-mail RFC 5322 z danymi zastępczymi, które chcesz. Stworzyłem go w swoim kliencie poczty i wysłałem do siebie. Po jego otrzymaniu skopiowałem źródło i zastąpiłem pola, które chcę dynamicznie zamienić.
MIME-Version: 1.0
Reply-To: {{replyto}}
Subject: {{subject}}
From: {{from}}
To: {{address.email}}
Content-Type: multipart/mixed; boundary="001a113c48b0b89d92052d3051da"
--001a113c48b0b89d92052d3051da
Content-Type: multipart/alternative; boundary="001a113c48b0b89d89052d3051d8"
--001a113c48b0b89d89052d3051d8
Content-Type: text/plain; charset=UTF-8
Email with a *text attachment*.
{{body2}}
--001a113c48b0b89d89052d3051d8
Content-Type: text/html; charset=UTF-8
<div dir="ltr">
<div>Email with a <i>text attachment</i>.</div>
{{body1}}
<
Ostatnia część MIME tej wiadomości zawiera Content-Disposition: attachment; filename=myfile.txt”. To tu zdefiniowana jest nazwa pliku. Treść twojego załącznika będzie z pewnością dużo bardziej złożona, ale ten przykład ma być jak najprostszy.
Przechowywany Szablon
Gdy masz poprawny e-mail RFC 5322, przechowaj go używając formy email_rfc822 końcowego punktu szablonu zamiast używać text i HTML. Oto, jak wygląda content dla tej wiadomości:
{
"content": {
"email_rfc822": "MIME-Version: 1.0\nReply-To: {{replyto}}\nSubject: {{subject}}\nFrom: {{from}}\nTo: {{address.email}}\nContent-Type: multipart/mixed; boundary=001a113c48b0b89d92052d3051da\n\n--001a113c48b0b89d92052d3051da\nContent-Type: multipart/alternative; boundary=001a113c48b0b89d89052d3051d8\n\n--001a113c48b0b89d89052d3051d8\nContent-Type: text/plain; charset=UTF-8\n\nEmail with a *text attachment*.\n\n{{body2}}\n\n--001a113c48b0b89d89052d3051d8\nContent-Type: text/html; charset=UTF-8\n\n<div dir=\"ltr\"><div>Email with a <i>text attachment</i>.</div>\n\n{{body1}}\n</div>\n\n--001a113c48b0b89d89052d3051d8--\n--001a113c48b0b89d92052d3051da\nContent-Type: text/plain; charset=US-ASCII; name=\"myfile.txt\"\nContent-Disposition: attachment; filename=\"myfile.txt\"\nContent-Transfer-Encoding: base64\nX-Attachment-Id: f_ild455ce0\n\nVGhpcyBpcyBteSBzaW1wbGUgdGV4dCBmaWxlLgo=\n--001a113c48b0b89d92052d3051da--"
},
"name": "_TMP_TEMPLATE_TEST"
}
Gdy żądanie zostanie zrealizowane, SparkPost odpowie unikalnym identyfikatorem dla nowego szablonu. Na przykład xxxxxxx.
Wysyłanie Szablonu
Dobra wiadomość jest taka, że utworzenie treści RFC 5322 było najtrudniejszą częścią. Od tego momentu wysyłanie tego szablonu za pomocą SparkPost jest dokładnie takie samo, jak wysyłanie każdego innego szablonu.
Tak wysyłamy ten szablon i wypełniamy dane zastępcze:
{
"campaign_id": "MyCampaign",
"return_path": "myReturnPath@yourdomain.com",
"substitution_data": {
"replyto": "myReplyToh@yourdomain.com",
"from": "MyFrom@yourdomain.com",
"subject": "my subject",
"body1": "Extra content for the HTML part",
"body2": "Extra content for the text part"
},
"recipients": [
{
"substitution_data": {},
"address": {
"email": "test1@domain.com",
"name": "test1"
}
}
],
"content": {
"template_id": "xxxxxxx",
"use_draft_template": true
}
}
Szablony z API Klienta Mailowego
Jeśli używasz języka programowania, który ma bibliotekę do komponowania e-maila, możesz z niej skorzystać, aby programowo stworzyć szablon lub nawet wysłać wiadomość inline. Oto przykład użycia JavaMail przez końcowy punkt transmisji SparkPost. Ta metoda powinna być łatwo przetłumaczona na PHP lub wybrany język.
public class App extends SparkPostBaseApp {
public static void main(String[] args) throws Exception {
Logger.getRootLogger().setLevel(Level.DEBUG);
App app = new App();
app.runApp();
}
private void runApp() throws Exception {
Message message = createMultipartMessage();
String rfc822Content = getMessageAsString(message);
rfc822Content = "To: {{address.email}}\r\nFrom: {{from}}\r\n" + rfc822Content;
String fromAddress = getFromAddress();
String[] recipients = getTestRecipients();
sendEmail(fromAddress, recipients, rfc822Content);
}
private void sendEmail(String from, String[] recipients, String email)
throws SparkPostException, IOException {
Client sparkpostClient = newConfiguredClient();
TransmissionWithRecipientArray transmission = new TransmissionWithRecipientArray();
List<RecipientAttributes> recipientArray = new ArrayList<>();
for (String recipient : recipients) {
RecipientAttributes recipientAttribs = new RecipientAttributes();
recipientAttribs.setAddress(new AddressAttributes(recipient));
recipientArray.add(recipientAttribs);
}
transmission.setRecipientArray(recipientArray);
transmission.setReturnPath(from);
Map<String, String> substitutionData = new HashMap<>();
substitutionData.put("from", from);
substitutionData.put("name", "Your Name Here");
transmission.setSubstitutionData(substitutionData);
TemplateContentAttributes contentAttributes = new TemplateContentAttributes();
contentAttributes.setEmailRFC822(email);
transmission.setContentAttributes(contentAttributes);
RestConnection connection = new RestConnection(sparkpostClient, getEndPoint());
Response response = ResourceTransmissions.create(connection, 0, transmission);
if (response.getResponseCode() == 200) {
System.out.println("✅ Transmission Response: " + response);
} else {
System.err.println("❌ TRANSMISSION ERROR: " + response);
}
}
private Message createMultipartMessage() throws MessagingException {
Properties props = new Properties();
props.put("mail.smtp.host", "none");
Session session = Session.getDefaultInstance(props, null);
Message message = new MimeMessage(session);
message.setSubject("A multipart MIME message demo");
Multipart multiPart = new MimeMultipart("mixed");
MimeMultipart altPart = new MimeMultipart("alternative");
MimeBodyPart textPart = new MimeBodyPart();
textPart.setText("{{name}},\r\nplain text content", "utf-8");
MimeBodyPart htmlPart = new MimeBodyPart();
htmlPart.setContent("<b>{{name}},<br><br>Our HTML content</b>", "text/html; charset=utf-8");
altPart.addBodyPart(textPart);
altPart.addBodyPart(htmlPart);
MimeBodyPart altBodyPart = new MimeBodyPart();
altBodyPart.setContent(altPart);
multiPart.addBodyPart(altBodyPart);
MimeBodyPart attachmentPart = new MimeBodyPart();
String filename = "java_SparkPost_background.pdf";
DataSource source = new FileDataSource(filename);
attachmentPart.setDataHandler(new DataHandler(source));
attachmentPart.setFileName(filename);
multiPart.addBodyPart(attachmentPart);
message.setContent(multiPart);
return message;
}
private String getMessageAsString(Message msg) throws IOException, MessagingException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
msg.writeTo(out);
return out.toString("UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("UTF-8 not found! " + e.getMessage());
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Podsumowanie
Teraz, gdy widzisz, jak SparkPost może być używany do wysyłania e-maili o prawie dowolnej złożoności, możesz chcieć przyjrzeć się „SparkPost Wspiera Wysyłanie E-maili na Apple Watch” lub przyjrzeć się syntaksie zamiany, aby zobaczyć, jak można ją używać z „if then else”, „wyrażeniami w warunkach” lub „Iteracją tablicy” bezpośrednio w twoim szablonie lub treści transmisji.