
Ten post jest skierowany do programisty, który chce w pełni wykorzystać możliwości szablonów e-mailowych SparkPost. Zakłada się, że potrafisz czytać zawartość JSON i śledzić podstawowy przepływ programowania. Gdy pojawiają się terminy, które mogą być dla ciebie nowe, takie jak RFC 5322, tekst jest powiązany z jego źródłem.
Ten wpis jest skierowany do programisty, który chce w pełni wykorzystać możliwości szablonu e-mail SparkPost. Zakłada się, że jesteś zaznajomiony z czytaniem treści JSON i śledzeniem podstawowego przepływu programowania. Terminy, które mogą być Ci nowe, takie jak RFC 5322, są połączone z ich źródłami referencyjnymi. Skoro mamy to za sobą, zanurzmy się od razu.
Możliwości szablonów i transmisji SparkPost umożliwiają wysyłanie e-maili w prosty sposób. Te możliwości zapewniają abstrakcję dla zawartości tekstowej i HTML, co oznacza, że najczęściej 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ć stworzyć bardziej złożone wiadomości, które mają inne części Multipurpose Internet Mail Extensions (MIME), które nie są bezpośrednio udostępniane poprzez interfejs RESTful SparkPost.
Uproszczona Kompozycja Email
Najpierw przejrzyjmy scenariusz słonecznego dnia dotyczący wysyłania e-maili. Użyj końcówki transmisji do dostarczenia treści tekstowej
i HTML. W tle, SparkPost zajmie się skomponowaniem poprawnego e-maila RFC 5322. SparkPost wprowadzi zmienne substytucyjne z substitution_data do tekstowej i HTML treści. To jest potężny sposób generowania personalizowanej treści dla każdego odbiorcy we wspólnym szablonie.
Oto przykład transmisji z treścią HTML i tekstową z 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}} \nSave big this Christmas in your area {{place}}! \nClick http://www.mysite.com and get huge discount\n</p><p>Hurry, this offer is only to {{user_type}}\n</p><p>{{sender}}</p>" } }
Substitute Arrays of Data
Wielu ludzi zdaje sobie sprawę, że SparkPost’s transmission and template endpoints can do simple content substitution w nagłówkach e-maili i ich treściach. Ale wiele osób przeoczy możliwość dostarczenia treści warunkowej lub tablic danych, które również mogą być podstawiane. Możesz także dostarczać unikalną treść dla każdego odbiorcy. W tym przykładzie wysyłamy tablicę unikalnych linków do każdego odbiorcy.
Osiąga się to poprzez dostarczenie tablicy danych JSON, która zostanie uwzględniona w treści e-maila. Gdy dane zostaną dostarczone, SparkPost użyje logiki w szablonie, aby je wypełnić.
W tym przykładzie SparkPost będzie szukał danych podstawienia o nazwie „files_html” i wykona „for each” na każdym elemencie w tablicy. Utworzy wiersz z wartością „file” w elemencie „files_html”. Zwróć uwagę na potrójny nawias wokół „loop_var.file“. To dlatego, że każdy element tablicy zawiera HTML, i musimy powiedzieć serwerowi, aby używał go bez zmian, nie escape'ując go. Część tekstowa będzie prostą etykietą tekstową i URL do pliku.
<table> {{each files_html}} <tr><td> {{{loop_var.file}}} </td></tr> {{ end }} </table>
Oto ukończony przykład działający:
{ "recipients": [ { "address": { "email": "recipient1@domain.com" }, "substitution_data": { "files_html": [ { "file": "<a href=\"http://domain.com/file1a.txt\">Opis Pliku 1a</a>" }, { "file": "<a href=\"http://domain.com/file2a.txt\">Opis Pliku 2a</a>" } ], "files_plain": [ { "file": "Plik 1a -- http://domain.com/file1a.txt" }, { "file": "Plik 2a -- http://domain.com/file2a.txt" } ] } }, { "address": { "email": "recipient2@domain.com" }, "substitution_data": { "files_html": [ { "file": "<a href=\"http://domain.com/file1b.txt\">Opis Pliku 1b</a>" }, { "file": "<a href=\"http://domain.com/file2b.txt\">Opis Pliku 2b</a>" } ], "files_plain": [ { "file": "Plik 1b -- http://domain.com/file1b.txt" }, { "file": "Plik 2b -- http://domain.com/file2b.txt" } ] } } ], "return_path": "chris@test.domain.com", "content": { "from": { "name": "chris@test.domain.com", "email": "chris@test.domain.com" }, "html": "<b>Twoje Pliki:</b><br>\n<table>\n{{each files_html}} <tr><td> {{{loop_var.file}}} </td></tr>\n{{ end }} </table>\n\n", "text": "Twoje Pliki:\n{{each files_plain}} {{loop_var.file}} \n{{ end }} \n\n\n\n", "subject": "Sending with SparkPost is Fun" } }
Pro Tip: W Twoim kodzie zaleca się trzymać markup widoku osobno od danych, ale celem było utrzymanie przykładu tak prostego i łatwego do zrozumienia, jak to możliwe, dlatego stworzyliśmy dwie tablice. Jedna tablica jest dla części HTML, a druga dla części tekstowej. W zastosowaniach produkcyjnych zazwyczaj używa się jednego zestawu danych i zapisuje logikę w kodzie szablonu.
Załączniki w Możliwościach Transmisji
Endpoint transmisji zapewnia również abstrakcję dla wysyłania załączników. Poniżej zobaczysz, że załączniki są specyfikowane w tablicy content.attachments, gdzie każdy obiekt w tablicy opisuje pojedynczy element załącznika. Tak jak wcześniej SparkPost zajmie się kodowaniem tekstu, HTML, substytucji oraz przechodzeniem przez tablicę załączników, aby zakodować poprawnie sformatowaną wiadomość e-mail.
Zalecane praktyki sugerują, że wysyłanie załączników najlepiej unikać, chyba że jest to wyraźnie wymagane jako część Twojej usługi.
nametypetypeTyp MIME załącznikanameTermin załącznikadataDane pliku zakodowane w Base64
Tak wygląda załącznik wewnątrz strefy zawartości transmisji:
"content":{ "attachments":[ { "type":"audio/mp3", "name":"voicemail.mp3", "data":"TVAzIERhdGEK" } ] }
Możesz także wysyłać „obrazy w linii” w transmisji. Są one bardzo podobne do załączników i są specyfikowane w tablicy content.inline_images , gdzie każdy z obiektów inline_image jest podobny do tego pokazano powyżej.
Załączniki w Szablonach
Teraz, gdy mamy odpowiednie tło na temat wysyłania załączników z endpointem transmisji, przejdźmy do tego, jak to zrobić przy użyciu szablonów. W momencie pisania tego tekstu, nie ma abstrakcji załączników, jaką znajdziemy przy transmisjach w linii. Można by wyciągnąć wniosek, że szablonów nie można tworzyć z załącznikami. Byłoby to częściowo prawdą, ale istnieje obejście, chociaż nie będziesz już odseparowany od formatu RFC 5322.
Można osiągnąć załączniki w szablonach poprzez kodowanie treści RFC 5322 samodzielnie, co obejmuje załączniki. Dobrą wiadomością jest to, że nebudeš tracił możliwości użycia Substitution Data w nagłówkach e-mail, HTML i częściach tekstowych. Bądź świadomy, że ten rodzaj szablonu ogranicza zamiany do nagłówków i pierwszej HTML i pierwszej części tekstowej.
Oto przykład, jak to się robi.
RFC822 Email
Utwórz swojego e-maila RFC 5322 z danymi podstawienia, które chcesz. Utworzyłem tego, w swoim kliencie pocztowym i wysłałem go do siebie. Gdy go otrzymałem, skopiowałem źródło i zastąpiłem pola, które chcę dynamicznie wymieniać.
Wersja MIME: 1.0 Odpowiedź do: {{replyto}} Temat: {{subject}} Od: {{from}} Do: {{address.email}} Typ treści: multipart/mieszany; boundary=001a113c48b0b89d92052d3051da --001a113c48b0b89d92052d3051da Typ treści: multipart/alternatywna; boundary=001a113c48b0b89d89052d3051d8 --001a113c48b0b89d89052d3051d8 Typ treści: text/plain; charset=UTF-8 E-mail z załącznikiem *tekstowym*. {{body2}} --001a113c48b0b89d89052d3051d8 Typ treści: text/html; charset=UTF-8 <div dir="ltr"><div>Email z <i>załącznikiem tekstowym</i>.</div> {{body1}} </div> --001a113c48b0b89d89052d3051d8-- --001a113c48b0b89d92052d3051da Typ treści: text/plain; charset=US-ASCII; name="myfile.txt" Dyspozycja zawartości: załącznik; filename="myfile.txt" Transfer-Encoding zawartości: base64 X-Identyfikator-załącznika: f_ild455ce0 VGhpcyBpcyBteSBzaW1wbGUgdGV4dCBmaWxlLgo= --001a113c48b0b89d92052d3051da--
Ostatnia część MIME w tej wiadomości, zobaczycie Dyspozycja zawartości: załącznik; filename=myfile.txt”. To jest miejsce, gdzie zdefiniowano nazwę pliku. Zawartość Twojego załącznika na pewno będzie dużo bardziej złożona, ale ten przykład stara się ją utrzymać prostą.
Przechowywany Szablon
Gdy masz prawidłowego e-maila RFC 5322 przechowaj go używając formy endpointu szablonu email_rfc822 zamiast używać pól tekstowych i HTML. Oto przykład, jak wygląda treść dla tej wiadomości:
{ "content": { "email_rfc822": "Wersja MIME: 1.0\nOdpowiedź do: {{replyto}}\nTemat: {{subject}}\nOd: {{from}}\nDo: {{address.email}}\nTyp treści: multipart/mieszany; boundary=001a113c48b0b89d92052d3051da\n\n--001a113c48b0b89d92052d3051da\nTyp treści: multipart/alternatywna; boundary=001a113c48b0b89d89052d3051d8\n\n--001a113c48b0b89d89052d3051d8\nTyp treści: text/plain; charset=UTF-8\n\nE-mail z załącznikiem *tekstowym*.\n\n{{body2}}\n\n--001a113c48b0b89d89052d3051d8\nTyp treści: text/html; charset=UTF-8\n\n<div dir=\"ltr\"><div>Email z <i>załącznikiem tekstowym</i>.</div>\n\n{{body1}}\n</div>\n\n--001a113c48b0b89d89052d3051d8--\n--001a113c48b0b89d92052d3051da\nTyp treści: text/plain; charset=US-ASCII; name=\"myfile.txt\"\nDyspozycja zawartości: załącznik; filename=\"myfile.txt\"\nTransfer-Encoding zawartości: base64\nX-Identyfikator-załącznika: f_ild455ce0\n\nVGhpcyBpcyBteSBzaW1wbGUgdGV4dCBmaWxlLgo=\n--001a113c48b0b89d92052d3051da--" }, "name": "_TMP_TEMPLATE_TEST" }
Kiedy żądanie zostanie zakończone, SparkPost odpowie z unikalnym identyfikatorem Twojego nowego szablonu. Na przykład xxxxxxx.
Wysyłanie Szablonu
Dobrą wiadomością jest to, że utworzenie treści RFC 5322 było trudną częścią. Od teraz wysyłanie tego szablonu za pomocą SparkPost jest dokładnie takie samo jak wysyłanie dowolnego innego szablonu.
Oto jak wysyłamy ten szablon i wypełniamy dane podstawiania:
{ "campaign_id": "MyCampaign", "return_path": "myReturnPath@yourdomain.com", "substitution_data": { "replyto": "myReplyToh@yourdomain.com", "from": "MyFrom@yourdomain.com", "subject":"my subject", "body1": "Dodatkowa treść dla części HTML", "body2": "Dodatkowa treść dla części tekstowej" }, "recipients": [ { "substitution_data": {}, "address": { "email": "test1@domain.com", "name": "test1" } } ], "content": { "template_id": "xxxxxxx", "use_draft_template":true } }
Szablony z API Mail Clienta
Jeśli używasz języka programowania, który posiada bibliotekę do komponowania e-maila, możesz użyć jej do programowego tworzenia szablonu lub nawet wysyłania wiadomości w linii. Tutaj znajdziesz przykład użycia JavaMail do tego celu poprzez interfejs RESTful SparkPost. Ta metoda powinna być łatwo przetłumaczona na PHP lub Twój preferowany język.
/** * Ta demonstracja użycia JavaMail MIME message z interfejsem RESTful SparkPosts * / publiczna klasa App rozciąga 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(); // Konwertuj wiadomość JavaMail na string do transmisji String rfc822Content = getMessageAsString(message); // Dodaj pole TO i pole From, które zostaną wypełnione z danych podstawienia SparkPost rfc822Content = "Do: {{address.email}}\r\nOd: {{from}}\r\n" + rfc822Content; // Ładuje e-mail do wysłania z systemu plików 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(); // Zapełnij odbiorców List<RecipientAttributes> recipientArray = new ArrayList<RecipientAttributes>(); for (String recipient : recipients) { RecipientAttributes recipientAttribs = new RecipientAttributes(); recipientAttribs.setAddress(new AddressAttributes(recipient)); recipientArray.add(recipientAttribs); } transmission.setRecipientArray(recipientArray); transmission.setReturnPath(from); // Zapełnij dane podstawienia Map<String, String> substitutionData = new HashMap<String, String>(); substitutionData.put("from", from); // SparkPost ustawi pola w częściach HTML i/lub tekstowych z wartością tutaj // Zobacz: https://developers.sparkpost.com/api/#/introduction/substitutions-reference substitutionData.put("name", "Twoje Imię"); transmission.setSubstitutionData(substitutionData); // Zapełnij treść e-maila TemplateContentAttributes contentAttributes = new TemplateContentAttributes(); contentAttributes.setEmailRFC822(email); transmission.setContentAttributes(contentAttributes); // Wyślij E-mail RestConnection connection = new RestConnection(sparkpostClient, getEndPoint()); Response response = ResourceTransmissions.create(connection, 0, transmission); if (response.getResponseCode() == 200) { // Wiadomość wysłana pomyślnie System.out.println("Od odpowiedzi transmisji: " + response); } else { // Wystąpił błąd System.err.println("BŁĄD TRANSMISJI: " + response); } } /** * Tworzy e-maila z tekstową, HTML i załączoną częścią * * @return wiadomość JavaMail * @throws MessagingException */ private Message createMultipartMessage() throws MessagingException { Properties props = new Properties(); // To nie jest używane, ale musimy to ustawić, aby JavaMail utworzył // wiadomość props.put("mail.smtp.host", "none"); Session session = Session.getDefaultInstance(props, null); Message message = new MimeMessage(session); message.setSubject("Demonstracja wiadomości MIME multipart"); Multipart multiPart = new MimeMultipart("alternative"); // Tworzenie części tekstowej MimeBodyPart textPart = new MimeBodyPart(); textPart.setText("{{name}},\r\nplain text content", "utf-8"); // Budowanie części HTML e-maila MimeBodyPart htmlPart = new MimeBodyPart(); htmlPart.setContent("<b>{{name}},<br><br>Nasza treść HTML</b>", "text/html; charset=utf-8"); // Połącz wszystkie części multiPart.addBodyPart(textPart); multiPart.addBodyPart(htmlPart); message.setContent(multiPart); // Dodaj załącznik do e-maila 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); return message; } /** * Przekształć wiadomość JavaMail into treści RFC822 * * @param msg * wiadomość, która będzie przekonwertowana * @return treść RFC822 * @throws MessagingException * @throws IOException */ private String getMessageAsString(Message msg) throws IOException, MessagingException { String content = ""; ByteArrayOutputStream out = new ByteArrayOutputStream(); try { msg.writeTo(out); content = new String(out.toByteArray(), "UTF-8"); return content; } catch (UnsupportedEncodingException e) { // To nie powinno się wydarzyć, ale jeśli nastąpi, zatrzymaj wszystko tutaj throw new Throwable("UTF-8 nie znaleziono! " + e.getMessage()); } finally { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } // Fail return null; } }
Konkluzja
Teraz, gdy widzisz, jak SparkPost może być używany do wysyłania e-maili o niemal dowolnej złożoności, możesz zechcieć rzucić okiem na „SparkPost wspiera wysyłanie e-maili na Apple Watch” lub przyjrzeć się składni podstawiania, aby zobaczyć, jak można ją użyć z „if then else”, „wyrażeniami w warunkach” lub „Iteracją po tablicach” bezpośrednio w Twoim szablonie lub treści transmisji.