Modèles d'e-mail avancés

Oiseau

25 mars 2016

Email

1 min read

Modèles d'e-mail avancés

Oiseau

25 mars 2016

Email

1 min read

Modèles d'e-mail avancés

Ce post s'adresse au développeur qui souhaite tirer le meilleur parti des capacités de modèle d'email de SparkPost. On suppose que vous êtes à l'aise avec la lecture de contenu JSON et le suivi d'un flux de programmation basique. Au fur et à mesure que des termes qui pourraient vous être nouveaux, comme la RFC 5322, sont introduits, le texte est lié à sa référence source.

Business in a box.

Découvrez nos solutions.

Ce post est destiné au développeur qui souhaite tirer le meilleur parti des capacités de modèle d'email de SparkPost. On suppose que vous êtes à l'aise avec la lecture de contenu JSON et le suivi de flux de programmation de base. Les termes qui pourraient être nouveaux pour vous, comme RFC 5322, sont liés à leur référence source. Maintenant que cela est clarifié, plongeons directement dedans.

Les modèles et les capacités de transmission de SparkPost rendent l'envoi d'emails simple. Ces capacités fournissent une abstraction pour le contenu texte et HTML, ce qui signifie que la plupart du temps, il n'est pas nécessaire de coder directement le format d'email brut qui est défini dans RFC 5322, anciennement connu sous le nom de (RFC 822). Mais parfois, vous voudrez peut-être créer des messages plus complexes qui ont d'autres parties Multipurpose Internet Mail Extensions (MIME) qui ne sont pas directement exposées via l'interface RESTful de SparkPost.

Composition simplifiée d'email

D'abord, examinons un scénario idéal pour l'envoi d'un email. Utilisez le point de terminaison transmission pour fournir le contenu texte et HTML. En coulisses, SparkPost s'occupe de composer un email RFC 5322 valide. SparkPost insérera des variables de substitution à partir de substitution_data dans le contenu texte et HTML. C'est un moyen puissant de générer du contenu personnalisé pour chaque destinataire dans un modèle commun.

Voici un exemple de transmission avec du contenu HTML et texte avec 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>"
  }
}

Substituer des Tableaux de Données

Beaucoup de gens réalisent que les points de terminaison de transmission et de modèle de SparkPost peuvent effectuer une substitution simple de contenu dans les en-têtes d'email et les corps d'email. Mais beaucoup négligent la capacité de fournir du contenu conditionnel ou des tableaux de données qui peuvent également être substitués. Vous pouvez également fournir du contenu unique par destinataire. Dans cet exemple, nous envoyons un tableau de liens uniques à chaque destinataire.

Cela est accompli en fournissant un tableau JSON de données qui sera peuplé dans le corps de l'email. Une fois les données fournies, SparkPost utilisera la logique dans le modèle pour les peupler.

Dans cet exemple, SparkPost recherchera des données de substitution appelées « files_html » et effectuera un « pour chaque » élément dans le tableau. Il créera une ligne avec la valeur de « fichier » dans l'élément « files_html ». Notez les triples accolades autour de « loop_var.file ». C'est parce que chaque élément du tableau contient du HTML et nous devons indiquer au serveur de l'utiliser tel quel sans l'échapper. La partie texte sera une simple étiquette de texte et l'URL vers le fichier.

<table>
  {{each files_html}}
    <tr>
      <td>{{{loop_var.file}}}</td>
    </tr>
  {{ end }}
</table>

Voici l'exemple de travail complet :

{
  "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"
  }
}

Astuce Professionnelle : Dans votre code, il est conseillé de séparer le balisage de vue des données, mais l'objectif ici était de garder l'exemple aussi simple et facile à suivre que possible, donc nous avons créé deux tableaux. Un tableau est pour la partie HTML et l'autre est pour la partie Texte. À des fins de production, il serait courant d'avoir un seul ensemble de données et d'écrire la logique dans le code du modèle.

Pièces Jointes dans les Capacités de Transmission

Le point de terminaison de transmission fournit également une abstraction pour l'envoi de pièces jointes. Vous verrez ci-dessous que les pièces jointes sont spécifiées dans le tableau content.attachments où chaque objet du tableau décrit un élément de pièce jointe individuel. Comme auparavant, SparkPost s'occupera de coder en texte, HTML, substitutions et d'itérer à travers le tableau des pièces jointes pour coder un message d'email correctement formé.

Les bonnes pratiques dictent qu'il est préférable d'éviter d'envoyer des pièces jointes sauf si cela est explicitement requis dans le cadre de votre service.

Ci-dessous se trouvent les champs requis pour une pièce jointe :

  • type : Le type MIME de la pièce jointe

  • nom : Le nom de fichier de la pièce jointe

  • données : Données du fichier encodées en Base64

Voici à quoi ressemble une pièce jointe à l'intérieur de la strophe de contenu de transmission :

"content": {
  "attachments": [
    {
      "type": "audio/mp3",
      "name": "voicemail.mp3",
      "data": "TVAzIERhdGEK"
    }
  ]
}

Vous pouvez également envoyer des « images intégrées » dans une transmission. Celles-ci sont très similaires aux pièces jointes et sont spécifiées dans le tableau content.inline_images où chacun des objets inline_image est similaire à l'objet pièce jointe montré ci-dessus.

Pièces Jointes dans les Modèles

Maintenant que nous avons les bases appropriées pour envoyer des pièces jointes avec le point de terminaison de transmission, examinons comment faire cela avec les modèles. À l'heure où nous écrivons ces lignes, il n'y a pas d'abstraction pour les pièces jointes comme vous le trouvez pour les transmissions intégrées. On pourrait conclure que les modèles ne peuvent pas être créés avec des pièces jointes. Vous auriez partiellement raison, mais il existe une solution, bien que vous ne serez plus isolé du format RFC 5322.

Vous pouvez réaliser des pièces jointes dans les modèles en codant vous-même le contenu RFC 5322 qui inclut les pièces jointes. La bonne nouvelle est que vous ne perdrez pas la capacité d'utiliser encore Substitution Data dans vos en-têtes d'email, HTML et parties texte. Soyez conscient que ce type de modèle limite les substitutions aux en-têtes et à la première partie HTML et première partie texte.

Voici un exemple de la manière dont cela est accompli.

Email RFC822

Créez votre email RFC 5322 avec les données de substitution souhaitées. J'ai créé celui-ci dans mon client de messagerie et me l'ai envoyé à moi-même. Une fois que je l'ai reçu, j'ai copié la source et remplacé les champs que je veux substituer dynamiquement.

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}}
<

La dernière partie MIME de ce message vous verrez Content-Disposition: attachment; filename=myfile.txt”. C'est là que se trouve le nom du fichier est défini. Votre contenu de pièce jointe sera très certainement bien plus complexe, mais cet exemple essaie de rester simple.

Modèle Stocké

Une fois que vous avez un email RFC 5322 valide, stockez-le en utilisant le formulaire email_rfc822 du point de terminaison de modèle au lieu d'utiliser les champs texte et HTML. Voici à quoi ressemble le contenu de ce message :

{
  "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"
}

Lorsque la demande est complétée, SparkPost répondra avec un identifiant unique pour votre nouveau modèle. Par exemple xxxxxxx.

Envoyer le Modèle

La bonne nouvelle est que créer le contenu RFC 5322 était la partie la plus difficile. À partir de maintenant, envoyer ce modèle avec SparkPost est exactement le même que pour n'importe quel autre modèle.

Voici comment nous envoyons ce modèle et peuplons les données de substitution :

{
  "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
  }
}

Modèles à partir de l'API d'un Client de Messagerie

Si vous utilisez un langage de programmation qui dispose d'une bibliothèque pour composer un email, vous pouvez l'utiliser pour créer le modèle ou même envoyer le message en ligne. Ici se trouve un exemple d'utilisation de JavaMail pour faire cela via le point de terminaison de transmission de SparkPost. Cette méthode devrait être facilement traduite en PHP ou dans votre langage de prédilection.

/**
 * Demonstration of using JavaMail MIME message with the SparkPost RESTful interface
 */
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();
        // Convert JavaMail message into a string for transmission
        String rfc822Content = getMessageAsString(message);
        // Add dynamic To and From using SparkPost substitution syntax
        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();
        // Populate Recipients
        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);
        // Populate Substitution Data
        Map<String, String> substitutionData = new HashMap<>();
        substitutionData.put("from", from);
        substitutionData.put("name", "Your Name Here");
        transmission.setSubstitutionData(substitutionData);
        // Populate Email Body with RFC822 MIME
        TemplateContentAttributes contentAttributes = new TemplateContentAttributes();
        contentAttributes.setEmailRFC822(email);
        transmission.setContentAttributes(contentAttributes);
        // Send Email
        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);
        }
    }
    /**
     * Builds an email with text, HTML, and attachment parts
     */
    private Message createMultipartMessage() throws MessagingException {
        Properties props = new Properties();
        props.put("mail.smtp.host", "none"); // Required for JavaMail to work
        Session session = Session.getDefaultInstance(props, null);
        Message message = new MimeMessage(session);
        message.setSubject("A multipart MIME message demo");
        // Main multipart container
        Multipart multiPart = new MimeMultipart("mixed");
        // Sub multipart for text + HTML
        MimeMultipart altPart = new MimeMultipart("alternative");
        // Text part
        MimeBodyPart textPart = new MimeBodyPart();
        textPart.setText("{{name}},\r\nplain text content", "utf-8");
        // HTML part
        MimeBodyPart htmlPart = new MimeBodyPart();
        htmlPart.setContent("<b>{{name}},<br><br>Our HTML content</b>", "text/html; charset=utf-8");
        // Add text and HTML to the alternative container
        altPart.addBodyPart(textPart);
        altPart.addBodyPart(htmlPart);
        // Wrap alternative part in a MimeBodyPart so it can be added to mixed container
        MimeBodyPart altBodyPart = new MimeBodyPart();
        altBodyPart.setContent(altPart);
        // Add alternative section to mixed container
        multiPart.addBodyPart(altBodyPart);
        // Add attachment
        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);
        // Set full content
        message.setContent(multiPart);
        return message;
    }
    /**
     * Converts a JavaMail message into an RFC822 string
     */
    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();
            }
        }
    }
}

Conclusion

Maintenant que vous voyez comment SparkPost peut être utilisé pour envoyer des emails de presque n'importe quelle complexité, vous voudrez peut-être jeter un œil à « SparkPost Supports Sending Email on Apple Watch » ou examiner la syntaxe de substitution pour voir comment elle peut être utilisée avec « if then else », « expressions in conditionals » ou « array Iteration » directement dans votre contenu de modèle ou de transmission.

Connectons-vous avec un expert Bird.
Découvrez toute la puissance du Bird en 30 minutes.

En soumettant, vous acceptez que Bird puisse vous contacter au sujet de nos produits et services.

Vous pouvez vous désabonner à tout moment. Consultez la Déclaration de confidentialité de Bird pour plus de détails sur le traitement des données.

Company

Newsletter

Restez à jour avec Bird grâce aux mises à jour hebdomadaires dans votre boîte de réception.

Connectons-vous avec un expert Bird.
Découvrez toute la puissance du Bird en 30 minutes.

En soumettant, vous acceptez que Bird puisse vous contacter au sujet de nos produits et services.

Vous pouvez vous désabonner à tout moment. Consultez la Déclaration de confidentialité de Bird pour plus de détails sur le traitement des données.

Company

Newsletter

Restez à jour avec Bird grâce aux mises à jour hebdomadaires dans votre boîte de réception.

Connectons-vous avec un expert Bird.
Découvrez toute la puissance du Bird en 30 minutes.

En soumettant, vous acceptez que Bird puisse vous contacter au sujet de nos produits et services.

Vous pouvez vous désabonner à tout moment. Consultez la Déclaration de confidentialité de Bird pour plus de détails sur le traitement des données.

R

Atteindre

G

Grow

M

Manage

A

Automate

Company

Newsletter

Restez à jour avec Bird grâce aux mises à jour hebdomadaires dans votre boîte de réception.