Posting ini ditujukan untuk pengembang yang ingin memanfaatkan sepenuhnya kemampuan template email SparkPost. Diasumsikan Anda sudah nyaman membaca konten JSON dan mengikuti alur pemrograman dasar. Ketika istilah-istilah baru bagi Anda diperkenalkan seperti RFC 5322, teks akan terhubung ke referensi sumbernya. Dengan menjelaskan hal tersebut, mari langsung lompat masuk.
Kemampuan template dan transmission SparkPost membuat pengiriman email menjadi sederhana. Kemampuan ini menyediakan abstraksi untuk konten text dan HTML yang berarti kebanyakan waktu tidak perlu secara langsung meng-encode format email mentah yang didefinisikan dalam RFC 5322 yang sebelumnya dikenal dengan (RFC 822). Namun terkadang Anda mungkin ingin membuat pesan yang lebih kompleks dengan bagian Multipurpose Internet Mail Extensions (MIME) lain yang tidak langsung diekspos melalui antarmuka RESTful SparkPost.
Penyusunan Email yang Disederhanakan
Pertama, mari kita tinjau skenario hari cerah untuk mengirim email. Gunakan endpoint transmission untuk menyediakan konten text
dan HTML. Di balik layar, SparkPost mengurus penyusunan email RFC 5322 yang valid. SparkPost akan memasukkan variabel substitusi dari substitution_data ke dalam teks dan konten HTML. Ini adalah cara yang kuat untuk menghasilkan konten khusus untuk setiap penerima dalam template umum.
Berikut adalah contoh transmission dengan konten HTML dan teks dengan 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>"
}
}
Subsitusi Array Data
Banyak orang menyadari bahwa endpoint transmisi dan template SparkPost dapat melakukan substitusi konten sederhana dalam header email dan badan email. Namun banyak yang mengabaikan kemampuan untuk menyediakan konten bersyarat atau array data yang juga dapat digantikan. Anda juga dapat menyediakan konten unik untuk setiap penerima. Dalam contoh ini kami mengirim array tautan unik kepada setiap penerima.
Ini dicapai dengan menyediakan array JSON data yang akan diisi ke dalam badan email. Setelah data disediakan, SparkPost akan menggunakan logika dalam template untuk mengisinya.
Dalam contoh ini SparkPost akan mencari data substitusi bernama “files_html” dan melakukan “for each” pada setiap elemen dalam array. Ini akan membuat baris dengan nilai dari “file” dalam elemen “files_html”. Perhatikan tanda kurung kurawal tiga kali di sekitar “loop_var.file“. Ini karena setiap elemen dari array berisi HTML dan kita perlu memberi tahu server untuk menggunakannya apa adanya dan tidak mengeskapnya. Bagian teks akan berupa label teks sederhana dan URL ke file.
<table>
{{each files_html}}
<tr>
<td>{{{loop_var.file}}}</td>
</tr>
{{ end }}
</table>
Berikut adalah contoh kerja yang telah selesai:
{
"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"
}
}
Pro Tip: Dalam kode Anda, disarankan untuk menyimpan markup tampilan terpisah dari data tetapi tujuannya di sini adalah untuk menjaga contoh semudah dan sejelas mungkin sehingga kami membuat dua array. Satu array untuk bagian HTML dan yang lainnya untuk bagian Teks. Dalam penggunaan produksi akan umum untuk memiliki satu set data dan menulis logika dalam kode template.
Lampiran dalam Kemampuan Pengiriman
Endpoint transmisi juga menyediakan abstraksi untuk mengirim lampiran. Di bawah ini Anda akan melihat lampiran ditentukan dalam array content.attachments di mana setiap objek dalam array menggambarkan item lampiran individu. Sama seperti sebelumnya, SparkPost akan mengurus meng-encode text, HTML, substitutions dan iterasi melalui array lampiran untuk meng-encode pesan email yang terbentuk dengan baik.
Praktik terbaik menyarankan bahwa pengiriman lampiran sebaiknya dihindari kecuali secara eksplisit diperlukan sebagai bagian dari layanan Anda.
Di bawah ini adalah bidang yang diperlukan untuk lampiran:
type: Jenis MIME dari lampiran
name: Nama file dari lampiran
data: Data file yang telah di-encode menggunakan Base64
Beginilah tampilan lampiran di dalam stanza konten transmisi:
"content": {
"attachments": [
{
"type": "audio/mp3",
"name": "voicemail.mp3",
"data": "TVAzIERhdGEK"
}
]
}
Anda juga dapat mengirim "inline images" dalam sebuah transmisi. Ini sangat mirip dengan lampiran dan ditentukan dalam array content.inline_images di mana masing-masing objek inline_image mirip dengan objek lampiran yang ditunjukkan di atas.
Lampiran dalam Templates
Sekarang setelah kita memiliki latar belakang yang tepat untuk mengirim lampiran dengan endpoint transmisi, mari kita lihat cara melakukannya dengan templates. Pada saat penulisan ini, tidak ada abstraksi lampiran seperti yang Anda temukan untuk transmisi inline. Seseorang mungkin menyimpulkan bahwa templates tidak dapat dibuat dengan lampiran. Anda sebagian benar tetapi ada solusinya, meskipun Anda tidak lagi terpisah dari format RFC 5322.
Anda dapat mencapainya dengan meng-encode konten RFC 5322 Anda sendiri yang meliputi lampiran. Kabar baiknya adalah Anda tidak akan kehilangan kemampuan untuk tetap menggunakan Substitution Data dalam email headers, HTML, dan bagian text Anda. Harap perhatikan bahwa jenis template ini membatasi substitusi pada headers dan bagian HTML pertama dan bagian text pertama.
Berikut adalah contoh cara melakukannya.
Email RFC822
Buat email RFC 5322 Anda dengan data substitusi yang Anda inginkan. Saya membuat yang ini di klien email saya dan mengirimkannya ke diri saya sendiri. Begitu saya menerimanya, saya menyalin sumber dan mengganti bidang yang ingin saya substitusi secara dinamis.
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}}
<
Bagian MIME terakhir dalam pesan ini Anda akan melihat Content-Disposition: attachment; filename=myfile.txt”. Di situlah nama file ditentukan. Konten lampiran Anda tentu saja akan jauh lebih kompleks tetapi contoh ini mencoba menjaga agar tetap sederhana.
Stored Template
Begitu Anda memiliki email RFC 5322 yang valid, simpanlah menggunakan form email_rfc822 dari endpoint template bukan menggunakan bidang text dan HTML. Berikut adalah contoh bagaimana content terlihat untuk pesan tersebut:
{
"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"
}
Ketika permintaan selesai, SparkPost akan merespons dengan pengenal unik untuk template baru Anda. Misalnya xxxxxxx.
Mengirim Template
Kabar baiknya adalah membuat konten RFC 5322 adalah bagian yang sulit. Dari sini seterusnya mengirimkan template tersebut dengan SparkPost persis sama seperti mengirimkan template lainnya.
Berikut adalah cara kami mengirimkan template tersebut dan mengisi data substitusi:
{
"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
}
}
Template dari API Klien Email
Jika Anda menggunakan bahasa pemrograman yang memiliki pustaka untuk menyusun email, Anda dapat menggunakan itu untuk secara programatik membuat template atau bahkan mengirim pesan secara inline. Berikut adalah contoh menggunakan JavaMail melalui endpoint transmisi SparkPost. Metode ini harus mudah diterjemahkan ke PHP atau bahasa pilihan Anda.
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();
}
}
}
}
Kesimpulan
Sekarang, setelah Anda melihat bagaimana SparkPost dapat digunakan untuk mengirim email dengan hampir semua kerumitan, Anda mungkin ingin melihat "SparkPost Supports Sending Email on Apple Watch" atau melihat substitution syntax untuk melihat bagaimana itu dapat digunakan dengan "if then else", "ekspresi dalam kondisi" atau "Iterasi array" langsung di dalam template atau konten transmisi Anda.