SUPPORT.TWILIO.COM END OF LIFE NOTICE: This site, support.twilio.com, is scheduled to go End of Life on February 27, 2024. All Twilio Support content has been migrated to help.twilio.com, where you can continue to find helpful Support articles, API docs, and Twilio blog content, and escalate your issues to our Support team. We encourage you to update your bookmarks and begin using the new site today for all your Twilio Support needs.

Why Are HTML Tags Rendered as Plain Text and How Do You Send Formatted HTML Emails in Flex?

Question

Why are HTML tags rendered as raw plain text in outbound emails sent via the backend Twilio Conversations REST API, and how can I send HTML-formatted emails on the Conversations email channel?

 

Product

Twilio Conversations Classic - Twilio Flex

 

Answer

Passing an HTML string directly into the standard body parameter of the Conversations API (client.conversations.v1.conversations(sid).messages.create) causes Twilio to deliver the content as plain text, displaying raw HTML tags in the recipient's inbox.

To send formatted HTML emails via the Conversations API, you must upload the HTML content as a media asset to the Media Content Service (MCS) with Category=body and attach the returned MediaSid when creating the message:

  1. Upload the HTML Body to the Media Content Service (MCS)

Send an HTTP POST request to the MCS endpoint, setting Category=body as a query parameter and Content-Type: text/html in the header

 

async function uploadBody(html, contentType) {
  const url = `https://mcs.${MCS_REGION}.twilio.com/v1/Services/${CONVERSATIONS_SERVICE_SID}/Media?Category=body`;

  const response = await fetch(url, {
    method: "POST",
    headers: {
      Authorization: authHeader(),
      "Content-Type": contentType,
    },
    body: html,
  });

  if (!response.ok) {
    throw new Error(`Media upload failed (${response.status}): ${await response.text()}`);
  }

  const media = await response.json();
  return media.sid;
}
 
 // Upload HTML content 
 const htmlMediaSid = await uploadBody(htmlContent, "text/html");

 

  1. (Optional) Upload a Plain-Text fallback to MCS to include a plain-text alternative alongside the HTML email
// Upload plain text fallback content 
const textMediaSid = await uploadBody(plainTextContent, "text/plain");

 

  1. Create the Conversation Message with MediaSid(s) 
async function createMessage(mediaSids, subjectText) {
  const url = `https://conversations.twilio.com/v1/Conversations/${CONVERSATION_SID}/Messages`;

  const params = new URLSearchParams();
  mediaSids.forEach((sid) => params.append("MediaSid", sid));
  if (subjectText) {
    params.append("Subject", subjectText);
  }

  const response = await fetch(url, {
    method: "POST",
    headers: {
      Authorization: authHeader(),
      "Content-Type": "application/x-www-form-urlencoded",
    },
    body: params,
  });

  if (!response.ok) {
    throw new Error(`Message create failed (${response.status}): ${await response.text()}`);
  }

  return response.json();
} 

// Create message attached with MediaSid(s) 
const message = await createMessage([htmlMediaSid], "My Email Subject");

 

Additional Information 

Setting `Category=body` during the MCS upload is required so Twilio renders the content directly as the email body rather than sending it as a file attachment.

Email in Flex

Have more questions? Submit a request
Powered by Zendesk