Send HTML email with plain text fallback via Gmail API

一曲冷凌霜 提交于 2019-12-01 03:38:05

问题


An answered question at StackOverflow suggests that adding html-markup to the body of the email will do the trick. Is that solution correct?

But what if the recipient's email server/client does not support HTML email?

E.g. when using Apache commons email, I do the following:

// set the html message
email.setHtmlMsg("<html>Our logo - <img src=\"cid:"+cid+"\"></html>");
// set the alternative message
email.setTextMsg("Your email client does not support HTML messages");

Is there any way to tell Gmail API what email to fall back to if the recipient email server/client does not support HTML?

P.S. I'm especially interested in Java code samples.

Thanks


回答1:


To give two alternatives, you can set the Content-Type to mixed/alternative instead of either text/plain or text/html:

If we want to try this out in the API explorer, we just Base64-encode the mail, and make it url-safe by replacing all / with _ and all + with -.

In the Developer Console:

btoa(
  "Subject: Example Subject\r\n" +
  "From: <example@gmail.com>\r\n" +
  "To: <example@gmail.com>\r\n" +
  "Content-Type: multipart/alternative; boundary=\"foo_bar\"\r\n\r\n" +

  "--foo_bar\r\n" +
  "Content-Type: text/plain; charset=UTF-8\r\n\r\n" +

  "*Bold example message text*\r\n\r\n" +

  "--foo_bar\r\n" +
  "Content-Type: text/html; charset=UTF-8\r\n\r\n" +

  "<div dir=\"ltr\"><b>Bold example message text</b></div>\r\n\r\n" +

  "--foo_bar--" 
).replace(/\+/g, '-').replace(/\//g, '_');

POST https://www.googleapis.com/gmail/v1/users/me/messages/send?access_token={YOUR_API_KEY}

{
 "raw": "U3ViamVjdDogRXhhbXBsZSBTdWJqZWN0DQpGcm9tOiA8ZXhhbXBsZUBnbWFpbC5jb20-DQpUbzogPGV4YW1wbGVAZ21haWwuY29tPg0KQ29udGVudC1UeXBlOiBtdWx0aXBhcnQvYWx0ZXJuYXRpdmU7IGJvdW5kYXJ5PSJmb29fYmFyIg0KDQotLWZvb19iYXINCkNvbnRlbnQtVHlwZTogdGV4dC9wbGFpbjsgY2hhcnNldD1VVEYtOA0KDQoqQm9sZCBleGFtcGxlIG1lc3NhZ2UgdGV4dCoNCg0KLS1mb29fYmFyDQpDb250ZW50LVR5cGU6IHRleHQvaHRtbDsgY2hhcnNldD1VVEYtOA0KDQo8ZGl2IGRpcj0ibHRyIj48Yj5Cb2xkIGV4YW1wbGUgbWVzc2FnZSB0ZXh0PC9iPjwvZGl2Pg0KDQotLWZvb19iYXItLQ=="
}

To do the equivalent in Java, you could do:

Message message = new MimeMessage(session);
Multipart multiPart = new MimeMultipart("alternative");

MimeBodyPart textPart = new MimeBodyPart();
textPart.setText(text, "utf-8");

MimeBodyPart htmlPart = new MimeBodyPart();
htmlPart.setContent(html, "text/html; charset=utf-8");

multiPart.addBodyPart(textPart); 
multiPart.addBodyPart(htmlPart);
message.setContent(multiPart);

ByteArrayOutputStream output = new ByteArrayOutputStream();
message.writeTo(output);
String rawEmail = Base64.encodeBase64URLSafeString(output.toByteArray());

Message message = new Message();
message.setRaw(rawEmail);
message = service.users().messages().send(userId, message).execute();



回答2:


To add an update to above answer from Throlle. There were some differences in above and possibly with the later versions of gmail api

to send a message and follow their default provided standards for sending a standard email :

This is in grails but you can easily change for java, the controller stuff pre this html stuff can be found here. Maybe when I am finished with what I am doing and get a chance will update the github site with all these examples:

In controller:

  def sendHTMLEmail() {
        String emailBox='me@gmail.com'
        String to ='someuser@domain.com'
        String html="<html><body><table><tr><td><b>aa</b></td><td>bb</td></tr></table><h1>html content</h1></body></html>"
        MimeMessage content = gmailService.createHTMLEmail(to,emailBox,'gmail test','testing gmail via app',html)
        def message = gmailService.sendMessage(gmail,'me',content)
        render "=== ${message.id}"
}

In Service:

public static MimeMessage createHTMLEmail(String to, String from, String subject, String text, String html) {
        Properties props = new Properties()
        Session session = Session.getDefaultInstance(props, null)

        MimeMessage email = new MimeMessage(session)
        Multipart multiPart = new MimeMultipart("alternative")
        email.setFrom(new InternetAddress(from))
        email.addRecipient(javax.mail.Message.RecipientType.TO, new InternetAddress(to))
        email.setSubject(subject)

        MimeBodyPart textPart = new MimeBodyPart()
        textPart.setText(text, "utf-8")

        MimeBodyPart htmlPart = new MimeBodyPart()
        htmlPart.setContent(html, "text/html; charset=utf-8")

        multiPart.addBodyPart(textPart)
        multiPart.addBodyPart(htmlPart)
        email.setContent(multiPart)
        return email
    }

Then their standard provided sendMessage (below bits can be found on github link):

public static Message sendMessage(Gmail service,String userId,MimeMessage emailContent) throws MessagingException, IOException {
        try {
            Message message = createMessageWithEmail(emailContent)
            message = service.users().messages().send(userId, message).execute()
            return message
        } catch (Exception e) {
            //log.error "${e}"
        }
    }

and createMessageWithEmail

public static Message createMessageWithEmail(MimeMessage emailContent) throws MessagingException, IOException {
        ByteArrayOutputStream buffer = new ByteArrayOutputStream()
        emailContent.writeTo(buffer)
        byte[] bytes = buffer.toByteArray()
        String encodedEmail = Base64.encodeBase64URLSafeString(bytes)
        Message message = new Message()
        message.setRaw(encodedEmail)
        return message
    }


来源:https://stackoverflow.com/questions/34165219/send-html-email-with-plain-text-fallback-via-gmail-api

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!