Native HTML Email in Claris® FileMaker®

Claris FileMaker has built-in methods to send email in HTML format, using SMTP protocols. I’ll cover what this means, how to use this functionality, and use FileMaker to send basic HTML email.


Email is one of the simplest tools used to communicate and send information. Just open an email client, write a message and press a button to virtually send a letter or message to a recipient.

Sometimes, in addition to simple text, we want to enrich our emails with graphical content and attachments, making it more useful for those who receive it or giving a more cohesive image to your brand. This requires HTML, making it not as simple to build and send emails this way.

Claris FileMaker + HTML Email + SMTP

Claris FileMaker has built-in methods to send email in HTML format, using SMTP protocols. I’ll cover what this means, how to use this functionality, and use FileMaker to send basic HTML email that looks like this:

In FileMaker 17, without plugins, it was only possible to send email in plain text format, using the SMTP server sending options that were available in the “Send Mail” instruction.

FileMaker 18 and 19 support protocols available via the “InsertFromURL” instruction, enriched by adding the SMTP and SMTPS protocols (among others).

Note: The approach for sending email via SMTP has changed a bit in recent years. Sending email directly using SMTP/SMTPs and basic authentication, e.g. via Google or Microsoft/Azure, might not be supported, at least without a few additional steps:

I’d also recommend you consider using a 3rd-party service (like Mandrill, AWS SES or SendGrid) if planning to send a high volume of email.

The Beauty of InsertFromURL

The protocols supported by the “InsertFromURL” instruction allow you to interact differently with an SMTP server by extending what was previously not possible with the “Send Mail” command: sending emails in HTML format.

To create an email that respects these characteristics, it is necessary to respect some rules of composition  of the message that you want to send via “InsertFromURL” (using FileMaker).The email or the body of the call must be composed following the MIME-Version 1.0 standard. To help you better understand how to implement it, I’ll explain in detail below.

Notes on HTML Style

In this brief guide, I will not explain how to style an email template using HTML. Elsewhere, online, you can surely find many ideas on how to design an excellent and attractive email template.

The only advice I’d like to give you is to insert the images used in the composition of your template directly into the body of the mail (using base64 encoding):

<img src="data:base64,iVBORw0K…" />

Template Mail

First of all, it is necessary to prepare a textual model of the body of our email with some placeholders {{value}} which we will replace dynamically before sending.

Attention! This is not the real email that the user sees, but a series of instructions that will be interpreted by our SMTP server to correctly send the email to the recipient.

From: {{from}}
To: {{to}}
Cc: {{cc}}
Subject: {{subject}}
X-Mailer: FileMaker 18
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="{{hash}}"
Content-Transfer-Encoding: base64

--{{hash}}
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: base64

{{HTMLMessage}}

--{{hash}}
Content-Type: {{mimeType}}
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename= "{{fileName}}"

{{attachment}}

--{{hash}}--

Sender, recipient and subject

In the first lines of our model, we will have to replace the placeholders with the information of the sender, as well as who should receive the email.

From: {{from}}
To: {{to}}
Cc: {{cc}}
Subject: {{subject}}

To make it simple, I will use the calculation “Substitute” to which I will transfer my variables ($fromName, $from, $to, $cc and $subject:

Substitute ( $template_content;
  ["{{from}}"; $fromName & " <" & $from & ">"];
  ["{{to}}"; $to & " <" & $to & ">"];
  ["{{cc}}"; If ( not IsEmpty ( $cc); "<" & $cc& ">")];
  ["{{subject}}"; $subject]
)

Headers

Among the headers of our model we have to insert the following information:

X-Mailer: FileMaker 19
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="{{hash}}"
Content-Transfer-Encoding: base64

Important: the value of {{hash}} must be generated at the beginning and then replaced in all parts of our template. In this case, I used the following formula to generate a unique random string for my email ($hash):

Lower ( Substitute ( Get ( UUID ); "-"; "" ) )

And as previously indicated, I used the “Substitute” command to dynamically replace its value:

Substitute ( $template_content;
  ["{{hash}}"; $hash]
)

Body

In the body of our model, we can now insert the real body of our email, as well as every attachment and every structure we want to send.

To correctly enter this information we must respect the following logic:

For HTML content:

--{{hash}}
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: base64

{{HTMLMessage}}

The initial statement — {{hash}} indicates a new block of content that follows a specific content type (in this case text/html) and a transfer method (base64).

The value of {{HTMLMessage}}, will be the real email template in HTML format.

As always, it will use the “Substitute” command to dynamically replace its value within our model:

Substitute ( $template_content;
  ["{{hash}}"; $hash];
  ["{{HTMLMessage}}"; Base64EncodeRFC ( 2045; $HTMLMessage )]
)

Note: for the HTML body I chose to base its content on base64!

For the attachments:

--{{hash}}
Content-Type: {{mimeType}}
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename= "{{fileName}}"

{{attachment}}

The initial instruction — {{hash}} indicates a new block of content that follows a specific content type (in this case it has to be determined based on the type of file we are attaching), a transfer method (base64), the name of the file being sent and finally our file {{attachment}}.

As always I will use the “Substitute” command to dynamically replace its value within our model:

Substitute ( $template_content;
  ["{{hash}}"; $hash];
  ["{{mimeType}}"; $mimeType];
  ["{{fileName}}"; $fileName];
  ["{{attachment}}"; Base64EncodeRFC ( 2045; $attachment)]
)

Note: for the attachment I have again chosen to base its content in base64!

To get the file name, I used the statement:

GetContainerAttribute ( Table::container_field; "filename" )

To obtain the related mime-type I have created a pair of custom functions (GetMimeType and GetFileExtension) that help to get the correct value in relation to the extension of the file that you want to attach.

Let (
[
  ~extension = "." & extension;
  ~result =
  Case (
   ~extension = ".gif"; "image/gif";
   ~extension = ".htm"; "text/html";
   ~extension = ".html"; "text/html";
   ~extension = ".ics"; "text/calendar";
   ~extension = ".log"; "text/plain";
   ~extension = ".jpeg"; "image/jpeg";

...
GetMimeType ( GetFileExtension ( fileName ) )

Repeat these steps described above for each attachment that you want to insert in the email (use a “Loop” to simplify this activity).

Footer

To complete our model, just insert a simple final instruction (note the opening and closing characters -):

--{{hash}}--

And again, I have used the “Substitute” command to dynamically replace its value:

Substitute ( $template_content;
  ["{{hash}}"; $hash]
)

Template ready to use

Et voilà! The result of the model with all the values replaced will have a structure similar to the one you see below (with the expected parts, replaced by our FileMaker script).

In this test, in addition to the body of the email in HTML format, I have attached 4 files: a text document, an Excel file, a zip archive, and an image.

From: Fabio Bosisio <my_email@beezwax.net>
To: my_team @beezwax.net <my_team@beezwax.net>
Cc: <my_boss@beezwax.net>
Subject: Mail in HTML with multi-attachments
X-Mailer: FileMaker 19
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="6dfceaf6898944dfa794717a50817ce8"
Content-Transfer-Encoding: base64

--6dfceaf6898944dfa794717a50817ce8
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: base64

PCFkb2N0eXBlIGh0bWw+DTxodG1sPg0NPGhlYWQ+DSAgICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIg
Y29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoIiAvPg0gICAgPG1ldGEgaHR0cC1lcXVpdj0iQ29u
... (too long removed)


--6dfceaf6898944dfa794717a50817ce8
Content-Type: text/plain
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename= "my_file.txt"

VGhpcyBpcyBhIHRleHQgZmlsZS4uLg==


--6dfceaf6898944dfa794717a50817ce8
Content-Type: application/zip
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename= "my_archive.zip"

UEsDBBQACAAIAOSWqk4AAAAAAAAAAAAAAAALABAAbXlfZmlsZS50eHRVWAwAVQHWXEwB1lz1ARQA
C8nILFYAokSFktSKEoW0zJxUPT09AFBLBwhYB9WLFgAAABYAAABQSwMECgAAAAAA7JaqTgAAAAAA
... (too long removed)

--6dfceaf6898944dfa794717a50817ce8
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename= "mime.xlsx"

UEsDBBQABgAIAAAAIQBi7p1oXgEAAJAEAAATAAgCW0NvbnRlbnRfVHlwZXNdLnhtbCCiBAIooAAC
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
... (too long removed)

--6dfceaf6898944dfa794717a50817ce8
Content-Type: image/jpeg
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename= "image.jpeg"

/9j/4AAQSkZJRgABAQEASABIAAD/4gxYSUNDX1BST0ZJTEUAAQEAAAxITGlubwIQAABtbnRyUkdC
IFhZWiAHzgACAAkABgAxAABhY3NwTVNGVAAAAABJRUMgc1JHQgAAAAAAAAAAAAAAAAAA9tYAAQAA
... (too long removed)

--6dfceaf6898944dfa794717a50817ce8--

Now… send the email

The last important step that remains before we can send our email is to configure the SMTP options provided by our email provider.

Since the email must be sent via “InsertFromURL” it is necessary to configure the cURL options needed for the correct routing of the message:

--connect-timeout 30
-v
--mail-from my_email@beezwax.net
--mail-rcpt my_team@beezwax.net
--mail-rcpt my_boss@beezwax.net
--user my_smtp_username:my_smtp_password
--upload-file $message
--ssl-reqd

Also in this case I dynamically replaced the indispensable values to send the email.

Important to note are the –mail-from and –mail-rcpt flags (which can be repeated if you want to insert a list of recipients) and the –user flag containing the authentication credentials to our SMTP server.

Our model ($message) will instead be managed with the flag –upload-file

Note: In the “InsertFromURL” instruction, you must indicate as the URL the complete address of our mail server including protocol and port, but in our case we use a communication based on SSL, so the protocol chosen is SMTPS and port 456.

smtps://my_smtp_server.beezwax.net:456

Conclusion

Thanks to the power of Claris FileMaker, it is possible to send emails (with few tricks) directly from our applications, in order to make communications to customers more attractive and impactful.

One more thing

Do you know that this functionality, combined with the FileMaker Data API, allows you to create a new mode of interaction between you and your customers?

Imagine an email in HTML format with a link that calls a web service that uses the Data API to trigger an event or create a record in your database. A typical use case is the submission of a report which asks your customer to give a confirmation. Now you only need one link in your summary email to allow the customer to do this, quickly and easily.

Demo: Native HTML E-Mail In FileMaker 18 (and 19!)

If something is not clear in this post, please download the demo file I created to help you practice and learn.

Leave a Reply