Questo post è rivolto allo sviluppatore che vuole ottenere il massimo dalle capacità dei modelli email di SparkPost. Si presume che tu sia a tuo agio con la lettura di contenuti JSON e segua un flusso di programmazione di base. I termini che potrebbero essere nuovi per te vengono introdotti come RFC 5322, il testo è collegato alla sua fonte di riferimento. Ora che abbiamo chiarito questo, tuffiamoci subito.
Le capacità dei modelli e di trasmissione di SparkPost rendono l'invio di email semplice. Queste capacità forniscono un'astrazione per il contenuto testo e HTML, il che significa che nella maggior parte dei casi non è necessario codificare direttamente il formato email grezzo definito in RFC 5322 precedentemente noto come (RFC 822). Ma a volte potresti voler creare messaggi più complessi che abbiano altre parti Multipurpose Internet Mail Extensions (MIME) non direttamente esposte tramite l'interfaccia RESTful di SparkPost.
Composizione Email Semplificata
Per prima cosa, esaminiamo uno scenario favorevole per l'invio di un'email. Utilizza il punto finale di trasmissione per fornire il testo
e il contenuto HTML. Dietro le quinte, SparkPost si occupa di comporre un'email valida RFC 5322. SparkPost inserirà variabili di sostituzione da substitution_data nel contenuto testo e HTML. Questo è un modo potente per generare contenuti personalizzati per ogni destinatario in un modello comune.
Ecco un esempio di trasmissione con contenuto HTML e testo con 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>"
}
}
Sostituire Array di Dati
Molte persone si rendono conto che i punti finali di trasmissione e modello di SparkPost possono fare semplici sostituzioni nelle intestazioni e nei corpi delle email. Ma molti trascurano la capacità di fornire contenuti condizionali o array di dati che possono essere sostituiti. Puoi anche fornire contenuti unici per destinatario. In questo esempio inviamo un array di link unici a ciascun destinatario.
Questo si realizza fornendo un array JSON di dati che sarà popolato nel corpo dell'email. Una volta forniti i dati, SparkPost utilizzerà la logica nel modello per popolarli.
In questo esempio SparkPost cercherà dati di sostituzione chiamati “files_html” e farà un “for each” su ogni elemento nell'array. Creerà una riga con il valore di “file” nell'elemento “files_html”. Nota le triple graffe intorno a “loop_var.file“. Questo perché ogni elemento dell'array contiene HTML e dobbiamo dire al server di utilizzarlo così com'è e non scappare. La parte del testo sarà un'etichetta di testo semplice e l'URL del file.
<table>
{{each files_html}}
<tr>
<td>{{{loop_var.file}}}</td>
</tr>
{{ end }}
</table>
Qui c'è l'esempio finito e funzionante:
{
"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"
}
}
Consigli Professionali: Nel tuo codice è consigliabile mantenere la marcatura della vista separata dai dati, ma l'obiettivo qui era di mantenere l'esempio il più semplice e facile da seguire possibile, quindi abbiamo creato due array. Un array per la parte HTML e l'altro per la parte Testo. In un uso di produzione sarebbe comune avere un unico set di dati e scrivere la logica nel codice del modello.
Allegati nelle Capacità di Trasmissione
Il punto finale di trasmissione fornisce anche un'astrazione per l'invio di allegati. Di seguito vedrai che gli allegati sono specificati nella content.attachments array dove ogni oggetto nell'array descrive un elemento di allegato individuale. Proprio come prima, SparkPost si occuperà di codificare testo, HTML, sostituzioni e iterare attraverso l'array di allegati per codificare un messaggio email formato correttamente.
Le migliori pratiche stabiliscono che l'invio di allegati è meglio evitarlo a meno che non sia esplicitamente richiesto come parte del tuo servizio.
Di seguito sono riportati i campi richiesti per un allegato:
tipo: Il tipo MIME dell'allegato
nome: Il nome del file dell'allegato
dati: File di dati codificati in Base64
Questo è come appare un allegato all'interno del passaggio di contenuti di trasmissione:
"content": {
"attachments": [
{
"type": "audio/mp3",
"name": "voicemail.mp3",
"data": "TVAzIERhdGEK"
}
]
}
Puoi anche inviare “immagini inline” in una trasmissione. Queste sono molto simili agli allegati e sono specificate nell'array content.inline_images dove ciascun oggetto inline_image è simile all'oggetto allegato mostrato sopra.
Allegati nei Modelli
Ora che abbiamo lo sfondo corretto per l'invio di allegati con il punto finale di trasmissione, vediamo come farlo con i modelli. Al momento della scrittura, non esiste un'astrazione per gli allegati come si trova per le trasmissioni inline. Si potrebbe concludere che i modelli non possono essere creati con allegati. Saresti parzialmente corretto, ma c'è una soluzione alternativa, anche se non sarai più isolato dal formato RFC 5322.
Puoi realizzare allegati nei modelli codificando tu stesso il contenuto RFC 5322 che include gli allegati. La buona notizia è che non perderai la capacità di usare ancora i Dati di Sostituzione nelle tue intestazioni email, HTML e parti di testo. Tieni presente che questo tipo di modello limita le sostituzioni alle intestazioni e alla prima parte HTML e prima parte di testo.
Ecco un esempio di come si fa.
Email RFC822
Crea la tua email RFC 5322 con i dati di sostituzione che desideri. Ho creato questo con il mio client e-mail e l'ho inviato a me stesso. Una volta ricevuto, ho copiato la fonte e sostituito i campi che voglio sostituire dinamicamente.
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}}
<
L'ultima parte MIME di questo messaggio vedrai Content-Disposition: attachment; filename=myfile.txt”. Là è definito il nome del file. Il tuo contenuto dell'allegato sarà sicuramente molto più complesso, ma questo esempio sta cercando di mantenersi semplice.
Modello Memorizzato
Una volta che hai un'email RFC 5322 valida, memorizzala utilizzando la forma email_rfc822 del punto finale del modello invece di usare testo e campi HTML. Ecco un esempio di come appare il contenuto per quel messaggio:
{
"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"
}
Al completamento della richiesta, SparkPost risponderà con un identificatore univoco per il tuo nuovo modello. Ad esempio xxxxxxx.
Invio del Modello
La buona notizia è che creare il contenuto RFC 5322 è stata la parte difficile. Da questo punto in poi inviare quel modello con SparkPost è esattamente lo stesso che inviare qualsiasi altro modello.
Qui è come inviamo quel modello e popoliamo i dati di sostituzione:
{
"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
}
}
Modelli da un'API del Client di Posta
Se utilizzi un linguaggio di programmazione che ha una libreria per comporre un'email, puoi usarlo per creare programmanticamente il modello o anche inviare il messaggio inline. Ecco un esempio di utilizzo di JavaMail attraverso il punto finale di trasmissione di SparkPost. Questo metodo dovrebbe essere facilmente tradotto in PHP o nel linguaggio di tua scelta.
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();
}
}
}
}
Conclusione
Ora che hai visto come SparkPost può essere utilizzato per inviare email di quasi qualsiasi complessità, potresti voler dare un'occhiata a “SparkPost Supporta l'Invio di Email su Apple Watch” o dare un'occhiata alla sintassi di sostituzione per vedere come può essere usata con “if then else”, “espressioni nei condizionali” o “iterazione di array” direttamente all'interno del tuo modello o contenuto della trasmissione.