By Daniel Wood, 21 March 2014
Sending Email from FileMaker is a common feature these days. With the Send Mail script step this has made it even easier as you can either send via an SMTP server or your Mail Client. While good, these methods do have restrictions such as a one attachment limit and no HTML support if using via SMTP server. Also if sending via your Email client then it becomes difficult to capture sent mail in your system and not all mail clients work the same.
Developers have aimed to circumvent these issues by using FileMaker Email plugins capable of HTML and multiple attachments among other things. Plugins are a good alternative but require some setup and configuration of SMTP details, authentication, and are at the mercy of firewalls and other restrictions that may prevent Email from being sent.
Mandrill is different. It is basically the E-Mail sending side of MailChimp that has been spawned off to become its own site. Because of this, Mandrill also offers a wide range of features that you would expect from an Email campaign management site such as tracking of Email opens and clicks, full statistics on mail sent, bounce management, as well as a raft of other customisable settings.
You can use Mandrill to send Email via standard SMTP, or via their API. Even if you wish to use it just via SMTP alone it makes sense. The Mandrill SMTP credentials are reliable, secure, and work anywhere (subject to firewall restrictions of course). In addition, you get all the benefits of comprehensive email tracking and settings to help customise the experience.
In this article we will be covering sending Email via Mandrill by using their API. The benefit of this method is the Emails are sent using an HTTP POST request on port 80 so unless you work for a totalitarian company which has blocked the internets then you should be guaranteed that your Emails will send every time.
No catch I promise! I may sound like I work for Mandrill but my enthusiasm is based solely on using Mandrill now on 4 separate projects and having great success on all of them. Best of all Mandrill is free (now I have your attention!). With a free account you are given a starting limit of 12,000 Emails per month, with an hourly limit of 250.
Mandrill works using algorithms that fairly allocate Email send capacity based on the type and quantity of Email that you send. If you are sending legitimate Email and not spam then you will begin to notice your daily and hourly limits increase over time - though for most FileMaker solutions these starting limits are more than enough.
Go to http://www.mandrillapp.com and sign up for a new account. Account setup is really easy - all you need is a unique Email address and password. If you intend to use it for multiple solutions then it would be good practice to create a new account per solution - 12,000 emails per day sounds like a lot but you don't want to run out. Accounts are also free so there is no reason not to.
All Email you intend to send via the API must be sent with an API Key. The key identifies which account is sending the Email. Once logged into your account select SMTP and API Credentials from the settings menu. Here you can create as many API keys as you wish for various purposes. You will also find the SMTP credentials if you prefer to use those.
Mandrill is packed with configuration settings and tools for managing sent mail. These include things such as click tracking, blacklists, whitelists, custom metadata and webhooks to name a few. We won't go into depth on these here, but we will cover a couple of useful settings found in the Sending Options area.
From this point on we are going to refer to the Mandrill example file that is included with this article.
There are 3 key pieces of Mandrill information that you need to put into your FileMaker solution:
All of the URLs and request formats for the API can be found in the documentation here. We will be sending requests using JSON format, so we use the .json endpoint to the URL - however other formats are available such as XML and PHP.
You can hard-code the above directly into your send scripts, but a better way is to store them in global fields so they can be used system-wide and can be easily modified if required.
The next step is to transform your request template into an actual request that can be sent to the API. You will see in the screenshot above that our request template has some place-holder data in it at various points, eg. SENDERNAME, SUBJECT, and MESSAGE.
How you record that information in the database we will leave entirely up to you. For our example file we have an Email table onto which we will capture this information. For attachments we have a related Attachments table where each record stores an attachment in a container. It is then simply a case of substituting out our placeholders for actual data. To do this we have created a couple of helpful custom functions.
This custom function takes a number of parameters, each corresponding to something we will substitute into the request. We are also passing the request template as the first parameter, however if you wish it may be easier to include the template within the custom function, particularly if you only intend to use one template for the entire solution. The function is basically a glorified substitute command, but it does a couple of required things:
EDIT: Thank you to Tim Dietrich, Stephen Dolenski and Michael Gaslowitz who all pointed out we also need to escape other characters in the request so as not to break it!
You don't really need to concern yourself with how this function works, however it is such a cool function function it deserves some mention!
Custom functions can accept a container field as a parameter. However you cannot pass them a list of containers as the List() function is for strings only. We could define 1 parameter per attachment but that is really bad as a) we don't know how many attachments we will have, and b) if we have none or one then we have to define blank for all the other attachment parameters. So how do we process multiple container attachments with a single parameter?
The answer to this came from this Soliant Consulting article written by the very smart Wim Decorte. He noticed that a parameter to a custom function has a dual nature - you can either treat it as a normal value, OR you can treat it as a reference to a value. Basically, if we treat it as a reference then we can use it in conjunction with recursion and the GetNthRecord function to recurse through multiple related attachment containers and process each one. We are making use of the dual nature of the parameter, using it as a both a value and a reference. I think this is one of the coolest untapped features of custom functions!
Attachments are converted into Base64 and along with a file name and mime type are put into the correct request format.
I won't go into any more detail than that, feel free to dig deeper into how it works, and definitely check out Wim's great article on the topic.
This is the easiest part. Now that we have our request generated from the custom function, all that is left to do is send it to the API to send the Email.
The Insert from URL script step may be able to be used to send the request. At the point of writing this, I am still working on determining whether this is possible, and seeking the help of fellow developers in getting this working with this script step. In FileMaker Pro 13, the step does support HTTP POST, but I'm still working on getting the syntax correct for sending. For now, we are going to use the BaseElements plugin to send the request. Thank you to Michael Gaslowitz for pointing out that Insert from URL does support HTTP POST.
The example file comes pre-packaged with the excellent and free BaseElements plugin from Goya Pty Ltd. This should auto-install on startup and prior to sending Email if not already installed. We use this plugin because not only does it have a working mac and windows version but it also has a 64-bit windows version compatible with FileMaker Server 12 and 13 for server-side sending.
Because plugins do not work on iOS you have a couple of options - one is to have FileMaker Server carry out the sending by using the Perform on Server script step. If your solution is not hosted then you can use the native FileMaker Send Mail script step and use the Mandrill SMTP credentials instead of the API. We are also working on getting the Insert from URL step working (see above).
Sending the request is now really easy and is a single function call:
BE_HTTP_POST ( $URL ; $Request )
Where $URL is the API endpoint for sending an email, and $Request is your completed request. Sending of a standard Email without attachments should take less than a second, and a little longer for attachments.
After sending the request, the API will send you a response that contains useful information. A typical response will look something like this:
[<br />{"email":"daniel@weetbicks.com",<br /> "status":"sent","_id":<br /> "d54bb019417c491eb01fc8578c4641a5",<br /> "reject_reason":null}<br />]<br />
This is a JSON array of values of the following:
We have included this custom function to help you easily obtain a specified parameter from the response. Pass this function the response, along with either the parameter keyword (or associated number) to retrieve the value. This is useful if you wish to run a test condition as to whether the email sent or failed.
We hope this article has given you a good overview of Mandrill, what it is and what its benefits are. Integrating Mandrill with FileMaker is dead simple. It avoids a lot of potential SMTP related issues such as firewall restrictions, Outlook Exchange problems, or simply increasing usage of your own SMTP server. It also contains a wealth of settings and tracking options for marketing/campaign related emails. We haven't even touched upon the comprehensive online dashboard for tracking sent email statistics, but it's all there for you to explore. Have fun!
Please find attached an example file. This file is provided to help you fully understand what is going on in this article. Note that FileMaker 13 is required to view this example file. The file also contains links to the Mandrill API documentation and website, as well as the custom functions mentioned in the article.
UPDATE:The example file has been updated on 23rd March with the following changes:
Something to say? Post a comment...
Comments
Matt Petrowsky 29/03/2014 1:34pm (11 years ago)
Just have to say.... AWESOME write up and execution here. Big time saver! Thanks to all for hacking it out.
Daniel Wood 27/03/2014 9:37am (11 years ago)
Michael as I mentioned in my email but will reiterate here - you are a legeeeeeend!!!! I'll get the example file updated soon to include this method for sending and update the article also, thank you so much!
Michael Sloper 27/03/2014 9:09am (11 years ago)
Thanks Daniel! Not only is this a nice example for sending mail but also a great example for working with JSON and a REST API.
To get it to work with filemaker's insert from url, you have to change the parameters from JSON to name=value&name2=value2. In this case the JSON is using objects but we can serialize the objects using arrays in our url.
So change the Mandrill Request Template to :
key=«APIKEY»&
message[html]=«MESSAGE»&
message[subject]=«SUBJECT»&
message[from_email]=«SENDEREMAIL»&
message[from_name]=«SENDERNAME»&
message[to][0][email]=«RECIPIENTEMAIL»&
message[to][0][name]=«RECIPIENTNAME»&
message[to][0][type]=to&
async=true&
«ATTACHMENTS»
The same works for the attachments but this has to be changed in the custom function:
"message[attachments][0][type]="& MimeType & "&" &
"message[attachments][0][name]=" & FileName & "&" &
"message[attachments][0][content]="& Substitute ( Base64Encode ( thisAttachment ) ; [ Char ( 13 ) ; "" ] ; [ Char ( 10 ) ; "" ] ) & "\\"" &
(I hard coded the 0 index of the array so this would have to change for sending multiple attachments.)
Change the API URL to:
httpspost://mandrillapp.com/api/1.0/messages/send.json
Swap the set field script step in the send mail script for insert from url:
Settings::Mandrill Send Message URL & "?" & Emails::Mandrill Request
Thanks again!
-Michael
Stephen Dolenski 23/03/2014 12:13pm (11 years ago)
One thing to configure is your DNS records as recommended by mandrill the SPF and DKIM entries so that mandrill can send in your behalf and so that your mail isn't seen as spam.
Daniel Wood 23/03/2014 11:57am (11 years ago)
Also Daniel, I looked at your module for JSON but am not sure it is properly suited for this solution. I'm trying to keep the functions in this as simple to integrate as possible, and was not sure what was relevant in your JSON file. However I have taken your advice and escaped all the characters you mentioned, thanks!
Daniel Wood 23/03/2014 11:56am (11 years ago)
A new copy of the example file is up with some changes (refer to the article for the changes). I've also removed a paragraph about Insert from URL not working in 13, and replaced it with a paragraph that we are trying to get it working. I have been unsuccessful so far getting it working but my knowledge on using it properly is limited so I've contacted a couple of people who know far more about it than me to see if they can offer any advice, hope to find out next week. In the meantime if anyone wants to have a crack at trying to get this working with "Insert from URL" I would appreciate it, thanks!
Daniel Wood 23/03/2014 10:00am (11 years ago)
Cheers for the comment Daniel, I am going to check out your module and see if I can incorporate it to make the JSON request more bugproof. Crispin I am also going to do some testing and see if I can get it working with Insert from URL for you, I'll hopefully post an update to the article with a new demo file soon. Cheers!
Crispin Hodges 23/03/2014 8:44am (11 years ago)
The demo works really well.
Thanks for sharing it with the community. I do hope you get a chance to update it to use FileMaker 13 POST (and if you have time include Stephens CF). It will be wonderful to have it will work in Go and WebDirect.
Daniel Smith 23/03/2014 5:49am (11 years ago)
Thanks for the great article; I think I'm going to try Mandrill now.
Your custom function for creating JSON will work in most cases, but technically speaking, you have not escaped all characters that must be escaped, you missed: reverse solidus, backspace, formfeed, newline, and horizontal tab.
Another way to create the JSON and ready the response would be to use the JSON module I wrote: http://www.modularfilemaker.org/2013/08/json/
Stephen Dolenski 22/03/2014 1:04pm (11 years ago)
Daniel this is brilliant.
I modified your CF to trim all header fields and filter out any returns - i suppose that could be expanded to include additional illegal characters.
But was able to solved one issue why one record wouldn't send and one did - an errant return in the subject field.
(<strong>note:</strong> angle brackets replaced with stars to have this post properly).
<pre>Let ([
_null = "";
HTML = If ( Left ( message ; 6 ) = "*HTML*" ; 1 ; "" )
];
Substitute (
request ;
[ "**APIKEY**" ; Trim( Substitute ( apikey ; Char(13) ; _null )) ] ;
[ "**SENDERNAME**" ; Trim( Substitute ( sendername ; ["\\"" ; "\\\\\\"" ]; [Char(13) ; _null ] ) ) ] ;
[ "**SENDEREMAIL**" ; Trim( Substitute ( senderemail ; ["\\"" ; "\\\\\\""]; [Char(13) ; _null ] ) ) ] ;
[ "**RECIPIENTNAME**" ; Trim( Substitute ( recipientname ;[ "\\"" ; "\\\\\\"" ]; [Char(13) ; _null ]) ) ] ;
[ "**RECIPIENTEMAIL**" ; Trim( Substitute ( recipientemail ;[ "\\"" ; "\\\\\\"" ]; [Char(13) ; _null ]) ) ] ;
[ "**SUBJECT**" ; Trim( Substitute ( subject ; ["\\"" ; "\\\\\\""] ; [Char(13) ; _null ] )) ] ;
[ "**MESSAGE**" ; Trim( Substitute ( If ( HTML = 1 ; message ; GetAsCSS ( message & "¶¶" ) ) ; "\\"" ; "\\\\\\"" )) ] ;
[ "**ATTACHMENTS**" ; mandrill_attachmentCode ( attachments ; 1 ) ]
)
)</pre>
Michael Gaslowitz 22/03/2014 9:04am (11 years ago)
Yes, it was introduced in FileMaker 13, and it's compatible with server, web publishing, and iOS.
Daniel Wood 22/03/2014 8:04am (11 years ago)
Hi Michael, thank you for the comment and for alerting me to this fact! I didn't realise that it supported POST, was this introduced in 13? I have updated this part of the article to point out this fact, and will look at getting a revised demo file up soon. Thanks!
Michael Gaslowitz 22/03/2014 6:08am (11 years ago)
Really nice solution, and FileMaker 13 does support httppost and httpspost with the 'Insert From URL' script step:
http://help.filemaker.com/app/answers/detail/a_id/11626/~/support-for-http-post-operations-in-filemaker-pro
« previous 1 2 3 4 5
No one has commented on this page yet.
RSS feed for comments on this page | RSS feed for all comments