This is the second in a series of articles on using the Gmail API from FileMaker. The first article has some background on this approach as well as instructions for authenticating to the Gmail API and sending HTML emails. Please review that article here if you haven’t already. Additionally, there’s a great post by dbservices on integrating Gmail with FileMaker that lead to these articles and should be checked out as well.

As with the first article, all of these examples use the native Insert From URL script step so there won’t be any plug-ins required, and since the Insert From URL is supported in all aspects of the FileMaker platform, these techniques can be adapted to work on the Server, Go, FileMaker Cloud, and WebDirect. These techniques require FileMaker 16 or higher as they use the advanced cURL options introduced in that version.

In this article, we’re looking at sending large, multiple attachments via Gmail. Here’s a video overview along with a new free example file below.


FileMaker Gmail Integration: Example File

Please download the example file FM2Gmail v1.21 for a working demo. This new version adds the ability to send attachments and replaces v1.1 from the previous article. File updated July 19th, 2019.

FileMaker Gmail Integration

FM2Gmail Example File v1.2

Sending an Email with Attachments from FileMaker

Before we can send anything, we do need to authenticate our app with Google. Please refer to our previous article’s section on Getting Started / Authentication if you need to review these steps. Once we’re all authenticated, we can compose a new e-mail with attachments. You’ll notice in the new example file that the compose window has a new paper clip button for adding attachments. This button brings up a Card window which we can use to drag attachments in, add individual attachments and import entire folders of images or text files.

FileMaker Email Attachments

Adding Attachments To Your Email

As you can see from the above screenshot, we’ve added 24 images totaling 33.8MB. The 33.8MB represents their size when encoded into base64: that’s a little bit bigger than the binary size, but this Gmail API technique allows for sending up to 35MB so this email should send with no issues.

Resumable Uploads

Even with a good connection, uploading 33.8MB can take a few moments, so what if you’re on an unstable or slow connection, e.g. you’re on FileMaker Go with only 3G? One of the great options the Gmail API provides is a resumable upload, where if you lose your connection you can pick up where you left off without starting having to start from scratch. In our example file, if you lose the connection, or terminate the upload, the email stays in the outbox with a warning beside it.

Resume Uploads to the Gmail API with FIleMaker

Incomplete Uploads Are Orange With A Warning Icon


When we click on that email, we see that the upload is 43% complete and we have a Resume button available.

Compose Email with Attachments in FileMaker

Incomplete Uploads Can Be Resumed


We can then Resume the upload and have it pick up right where it left off. We can lose our connection and resume the upload as many times as needed for up to a week until it’s completed. When the upload is complete, the e-mail is sent.

HTML Emails from FileMaker in Gmail

24 Attachments Received


Under The Hood

The following steps all happen as part of the script Send Email – Resumable in our example file, so you can examine and step through that script to follow along with what we’re discussing below.

Initiating A Resumable Upload

To initiate a Resumable Upload we need to perform two requests. The first request is a POST that, if successful, returns a unique URL that we’ll use for the initial upload and any subsequent attempts that may be needed if the connection is lost.

For this POST, we’re going to use the following URL.

We then want to specify the following cURL headers (double brackets indicate a variable value to be inserted).

As the Content-Type header above indicates, the POST is expecting a JSON body which would contain any metadata we wanted to include with the upload. We’ll be looking at metadata in a future article, but for now, there’s no body in the POST. If there is no body, we do need to specify the Content-Length header as zero or we’ll get an error. Also, if there’s no body in the request, POST needs to be explicitly called as a cURL option or it’s assumed it’s a GET, so we want to add the following cURL option.

We also need to specify a variable for the response headers as the response itself will have no actual content and the URL we’re after will be in the headers.

If our POST is successful, then we get a response header called Location which will contain a URL that looks like the below.

Inserting The Attachments

Now that we have this unique URL, we’ll save it to the email record and then build the email body with its attachments. The first part of this process is identical to the example in our previous article and all happens in the subscript Create RFC2822 Form which produces text like this.

Once this part of the email form is built, the attachments are inserted between the final boundaries. Each of the attachments needs its own headers and is then inserted as base64, so the bottom of the form looks like this.

Now we can begin our upload by doing a PUT request to our unique URL.

Uploading The Email

For this PUT we need to specify the following cURL headers

We also need to specify that this is a PUT and specify our body and a variable for the response headers.

if the PUT is successful, then we get a simple JSON response like this, which we’ll save to our email record indicating that it was sent successfully.

Resuming The Upload

To resume a failed upload, the first step is to do perform a PUT on our unique URL with no body in the request. This will tell us how much has already been uploaded and where we can resume. For this request, we want to specify the following cURL headers.

The */* in the above header indicates we don’t know how much has been indicated, or how big out actual request is. We also need to indicate explicitly that this is a PUT and a variable for the response headers as there will be no content in the response and we’ll get the amount uploaded from these headers.

If the PUT is successful we’ll get the amount uploaded in the Content-Range response header. The bytes here actually represent the characters that we’ve already uploaded so we can remove that number of characters from the beginning of the body and then perform another PUT with this smaller body. We’ll also specify the position to start from in the Content-Range header, which is the uploaded amount plus one. We can repeat the process as many times as needed until the entire upload is complete. These subsequent PUTs require the following headers.

and as above we need to specify this is a PUT and pass the request body and a variable for our response header.

When the request is finally complete we get the simple JSON response indicating a successful download and can save the id and thread id to our email record as we did in the example from our first example, and that’s it!


In addition to the HTML ability that we discussed in our first article, the Gmail API’s attachment management can extend FileMaker’s email capabilities well beyond what the Send Mail script step can offer. Two features stand out.

1. The Resumable Upload

FileMaker GO has powerful tools for capturing large amounts of data in a variety of file formats, so it’s essential that those mobile users have confidence that the data they’re sending won’t be lost and can be sent later when they have a better connection. The resumable upload can provide that when a reliable internet connection is not available. Potentially, users can be sending large emails from FileMaker GO with a FileMaker Server receiving them and processing the attachments accordingly.

2. Multiple Attachments

FileMaker 17 has introduced the ability to send multiple attachments with the native Send Mail script step. However, the Send Mail step requires that the attachments are exported to a system directory and then that path is referenced via a FileMaker variable. This means that existing container data can’t be sent via the server as the Export Field Contents script step is not supported there. Since the Gmail method uses base64 for the attachments, these can be inserted into the email body directly from the containers allowing us to send them from Server, Cloud, and WebDirect.

Here’s the next article in the series:

Integrating FileMaker and Gmail Part 3 – Working With Threads

Tagged with →  

16 Responses to Integrating FileMaker and Gmail Part 2 – Sending Attachments

  1. Paul Jansen says:


    Great article. My experience with FileMaker base64 encoding has been that when decoded at the other end. meta data such as location information is missing from the image. Have you been able to avoid the loss of this data.

    • Jason Young says:

      Hi Paul,
      Thank you for the kind words. I’m not seeing that here. I compared the GetContainerAttribute() results before and after sending and I’m not seeing any metadata loss there, including lat &lng. This example does use Base64RFCEncode( 4648, ) for the encoding, so I’m not sure if that’s related.

  2. Ash says:

    This is an amazing article! Our email provider is office365 and looking through their documentation, although a tad different their API would work similarly to this, I now have another project to add to the list! great work!! , Im interested to know if you plan on writing an article about receiving emails into filemaker, We programed an email gateway to insert emails into filemaker, but if there is a way todo it nativley then thats great!

    • Jason Young says:

      Hi Ashly,

      Thank you for the kind words. We do plan on publishing another article (soon) on working with threads, which will cover receiving e-mails in specific threads. For a more general approach to receiving I would check out the work done by dbservices. I think they did a great job covering that and I wouldn’t have much to add there. The link is below:


  3. Mark says:

    Jason, I have implemented successfully your integration of gmail into my filemaker 16 application and all was working great. Then, Google recently changed their API validation requirements and while I can authenticate, my new clients cannot. I have gone back to the API console and tried to figure out what I need to do to be verified by google, but I really don’t know what I am doing. Can you help or point me in the right direction?

    • Jason Young says:

      Hi Mark,
      Verification is only required for public apps that you plan on distributing, so you create an app as a user in the same google group as your customer, and set it to internal (not public) on the Credentials / OAuth Consent Screen, then the users in that group should be able to authenticate to it without having to go through the verification process.

      Here’s some documentation on this along with the verification steps if you need to go that route:

      If you do need to go through the verification I would get assistance from whoever manages your customer’s domain as they will be required to complete those steps.

      I hope that helps and keep us posted.

      • Mark says:

        Thank you very much, I’ll give it a try. It certainly seems like a better way to go.

      • Mark says:

        Hi Jason,
        I did as you suggested and created the credentials under my clients Google organization. Now the authentication is granted and their email address appears on the Home layout. However, when I send an email I get an 1631 error. Any thoughts?

        • Mark says:

          I tested FM2GMAIL part 1 and FM2GMAIL Fresh part 3 using my same credentials and part 1 sent the email, but FM2GMAIL Fresh part 3 produced the 1631 error. Hope this helps.

          • Jason Young says:

            Hi Mark,
            Right, Google has made a change that was causing the FileMaker script Request Resumable Upload URL to not retrieve the PUT URL correctly. I’ve updated the example files for this post and the next one. You should be able to copy the changes to the Request Resumable Upload URL script (at the bottom) to your file. That should take care of it.
            My Best,

        • Mark says:

          Jason, the new version works great – I can’t thank you enough. My best!

  4. Justin Vuono says:

    Hi Jason, I had this implementation working smoothly for weeks – then suddenly I’m getting Error 1630 – it looks like it is not pulling any of the Google info. I tested just on the download fiel as well using the same creds and same issue. I’ve made no changes to anything, it just stopped working. I cleared the tokens and reset, still no luck. Any ideas?

    • Jason Young says:

      Hi Justin,
      Yes, Google made a change. I’ve updated the example file for this and the next blog post with a fix. The script Request Resumable Upload URL needs to be updated at the bottom per this new example file. That should take care of it.
      My best,

  5. Will this accept camera input on FileMaker Go?

    • Jason Young says:

      Hi Jerry,
      Yes, once you have it in a container field in Go, you can send it.
      The demo file uses desktop examples, but you could modify those to Insert From Device to populate the containers with the camera.

Leave a Reply

Your email address will not be published. Required fields are marked *

Share →
DayBack Calendar
DayBack's 30-day trial is unlocked so you can customize it and integrate it with your files.
Download DayBack and we'll send you a couple short emails with tips on how to modify it and use some of the coolest features.
Thank you! Please download: DayBack Calendar
Need More?
SeedCode tips & example files in your inbox
Need More?
SeedCode tips & example files in your inbox
Want More?
Be the first to see articles and tips like these
Download TimeZync and we'll send you a couple short emails with tips syncing your FileMaker Go files.
Thank you! Please download: TimeZync
Want More?
Be the first to see articles and tips like these