FileMaker version 12 or higher.
When 360Plugins are intialized for the first time, they will automatically download all required support files
Drag the plugin from the MAC or WIN folder into your FileMaker extensions, and restart FileMaker.
If the plugin does not load correctly, please send an email to support@360works.com
Install plug-ins for use with WebDirect by dragging the appropriate plugin to FileMaker Server/Web Publishing/publishing-engine/cwpc/Plugins
You do not need to do this step unless you plan on using the plugin with Instant Web Publishing with FileMaker Server Advanced. You will need an Enterprise license to use this feature.
For installing into the Web Publishing Engine with FileMaker Server or FileMaker Server Advanced, drag the plugin from the MAC or WIN(.fmx) folder into the FileMaker Server/Web Publishing/publishing-engine/wpc/Plugins folder. If there is no Plugins folder inside the wpc folder, then create it manually. Restart FileMaker Web Publishing, and now the plugins should be ready to go.
The easiest way to test whether the plugin is working is to call the version function of the plugin, and display that on an IWP layout. If it shows "?", then the plugin is not working. If it shows a number, then the plugin has been installed successfully.
If you are using FileMaker Server 12.0v1, you can follow the same procedure as detailed above for custom web publishing. However, in FileMaker Server 12.0v2 and later, custom web publishing now runs as a 64-bit application and requires the 64-bit version of the plugin You will need an Enterprise license to use this feature.
For Mac, the single plug-in file in the MAC directory contains both 32-bit and 64-bit versions. For Windows, look for the plug-in that has the extension .fmx64 and use it in exclusively in custom web publishing.
To install 64-bit plug-ins, install either the .fmx64 or the .fmplugin to the following directory:
FileMaker Server / Web Publishing / publishing-engine / cwpc / Plugins
If it does not exist, create the Plugin folder manually. Restart FileMaker Web Publishing, and then you can then test a script that contains a plug-in and see if it returns the correct values.
You do not need to do this step unless you plan on using the plugin with scheduled script triggering. You will need an Enterprise license to use this feature.
360Works has created an AutoUpdate helper database which makes setting up AutoUpdate much easier. This file includes pre-configured plugin files which you can place on your server, and an AutoUpdate script for each of our plugins which you can paste into your own solution.
You can get the AutoUpdate360Works file here Follow the instructions included in the file to either host your own Auto Update server or pull the files from ours.
Plugins will run in demo mode until they are registered. While running in Demo mode, the product will run for 2 hours every time you launch FileMaker / FileMaker Server / FileMaker Web Publishing Engine. The 2 hour time limit will reset every time you relaunch FileMaker. There is no expiration date when Demo mode stops working. There are no feature differences between the Demo version and the licensed version.
Once you have purchased the plugin, you can register it with the license key. Once a valid license key is entered, the product will run for as long as FileMaker is running. After FileMaker starts up with the plugin installed, open FileMaker preferences, click on the Plug-ins tab, select the plugin from the list, and click the Configure button. Enter your license key and company name in this dialog. You will only need to do this once on a given machine. Alternately, you can use the registration function to register the plugin during a startup script.
Note: If you are running the plugin with FileMaker Server / FileMaker Web Publishing Engine, you must use the registration function to register the plugin, since there is no preferences dialog on FileMaker Server to enter the license key and company name. You will need to call the register function at the beginning of any script that is going to call plugin functions. This will ensure that you do not get demo mode errors.
We love to hear your suggestions for improving our products! If you are experiencing problems with this plugin, or have a feature request, or are happy with it, we'd appreciate hearing about it. Send us a message on our website, or email us!
When calling plugin functions as script steps, you will handle errors in the same manner you would any other FileMaker script step. Please see the FileMaker documentation for how to handle errors appropriately. Generally, if there is an error, our plugins will return an error code of 1552 when Get(LastError) is called. However, some plugin functions will return different error codes. If a function can return an error code other than a 1552, it will be documented with the description of the function below. In addition to the error code, you can also get the description of the error by calling Get(LastExternalErrorDetail)
You can also call our functions in a calculation dialog. In this case, error handling is done differently. If you decide to call plugin functions in a calculation dialog and you want to capture errors, see this page page for instruction on how to do so
Every program attempts to expand until it can read mail. Those programs which cannot so expand are replaced by ones which can.The 360Works Email Plugin offers the following advantages over FileMaker's built-in mail functionality:
-Jamie Zawinski's Law of Software Envelopment
EmailRegister( "mylicensekey", "My Company" )] EmailConnectSMTP( "mail.example.com" ) EmailQuickSend( Email::from ;// required "from" address Email::to ; // comma-separated list of addresses Email::subject ; // subject of the message Email::body ; // message body Email::attach) // path or URL or container to attach EmailDisconnectSending a plain-text email with one attachment:
EmailRegister("myLicenseKey"; "My Company") EmailConnectSMTP( "mail.example.com" ) EmailCreate( Email::from ; Email::to ; Email::subject ) EmailSetBody( Email::body ; "plain" ) EmailAttachFile( $attachment ) EmailSend EmailDisconnectSending an HTML-formatted email
EmailRegister("myLicenseKey"; "My Company") EmailConnectSMTP( "mail.example.com" ) EmailCreate( Email::from ; Email::to ; Email::subject ) EmailSetBody( Email::body ); "html" ) EmailSend EmailDisconnectHTML Generation The Email plugin cannot generate HTML so supplying the HTML for the email body will be up to you. If you already have the HTML, then all you need to do is paste it in a FileMaker field and reference it like the above example or hard code it directly into the function call. If you already have an HTML file, you can open it with a text editor like Sublime Text or NotePad++ and then copy the HTML into a FileMaker field. If the HTML file is hosted, you can use EmailSetBodyFile like so:
EmailRegister("myLicenseKey"; "My Company") EmailConnectSMTP( "mail.example.com" ) EmailCreate( Email::from ; Email::to ; Email::subject ) //set the second parameter in EmailSetBodyFile to true to embed resources EmailSetBodyFile( "http://SomeURLtoHTML.com/emailbody.html";true ) EmailSend EmailDisconnect
If you do not have HTML yet and do not know how to write it then you could use an HTML generator like the one located here. There are several editors available online and stand alone programs so find one you like. This one is just a simple WYSIWYG editor.
Sending a single message multiple times to different recipients can be done by creating a message using EmailCreate, then calling EmailRecipients and EmailSend multiple times. If you are sending large messages with attachments, this avoids the overhead of creating a separate message for each recipient.
You can also send a single message to multiple TO, CC, or BCC recipients by passing a comma-separated list of addresses. Note: Email is sent from whichever machine the plugin is being used on, be sure to open up port 25 for outgoing SMTP access on those machines.file:///path/to/attachment.jpg
).
//First connect to the SMTP server and create the message. EmailConnectSMTP( "mail.example.com" ) EmailCreate( Email::from ; Email::to ; Email::subject ) EmailSetBody( GetAsCSS( Email::body ); "html" ) Go To Record/Request [ First ] Loop Set Variable [ $setRecipients; Value: EmailRecipients [ Email::to ] ] Set Variable [ $msgSend; Value = EmailSend ] Go To Record/Request [ Next ; Exit After Last ] End Loop // We've sent the same message to all recipients. Now disconnect Set Variable [ $disconnect; Value: EmailDisconnect ]
Set Variable [$registerResult; Value: EmailRegister ( license ; company )] // check for registration success here Set Variable [$connectResult; Value: EmailConnectIMAP( server ; username ; password )] // check for connection success here Set Variable [$$importUrl; Value: EmailReadMessages ("mailbox=INBOX" ;"viewed=false" ;"max=25" ;"attachments=true")] // check for import success here If [$$importUrl = "ERROR"] Show Custom Dialog [EmailLastError] Exit Script End If // Import the email messages from the local XML file // which was created by the EmailReadMessages function Import records [$$importUrl ; Update Matching] // Now disconnect from the IMAP server Set Variable [ $disconnect; Value: EmailDisconnect ] If [$disconnect = "ERROR"] Show Custom Dialog [EmailLastError] Exit Script End If
Alternatively, you can process the Emails using EmailGetNextMessage. This is a requirement if you're running on FileMaker Server or via Web Direct/IWP/CWP since [Import XML]is not a web-safe script step. The general pattern looks like this:
Set Variable [$$importUrl; Value= EmailReadMessages ("mailbox=INBOX" ;"viewed=false" ;"max=25" ;"attachments=true")] // check for errors here Loop Exit Loop If [not EmailGetNextMessage] New Record/Request Set Field[ImportedMessage::date ; EmailReadMessageValue( "dateSent" )] Set Field[ImportedMessage::from ; EmailReadMessageValue( "from" )] Set Field[ImportedMessage::to ; EmailReadMessageValue( "to" )] Set Field[ImportedMessage::subject ; EmailReadMessageValue( "subject" )] Set Field[ImportedMessage::body ; EmailReadMessageValue( "body" )] Set Field[ImportedMessage::messageId ; EmailReadMessageValue( "messageId" )] End Loop
readonly=false
. Note: setting readonly=false
will
cause any fetched messages to be marked as "viewed"! Then iterate to a message using the EmailGetNextMessage function. Finally, use the EmailMessageSetFlag function to apply flags to a message
(such as deleted, flagged, viewed, etc).
viewed
(by
setting readonly=false
). Additionally, any messages from a certain address are marked as
deleted
:
Set Variable [ $result = EmailReadMessages( "viewed=false" ; "readonly=false" ) ] If [$result = "ERROR"] # Handle Error Here... End If Loop Exit Loop If [not EmailGetNextMessage] Set Variable[$result ; EmailMessageSetFlag("viewed") If [EmailReadMessageValue("from") = "deleteme@example.com"] Set Variable[$result ;Value: EmailMessageSetFlag("deleted") End If End Loop
Here is an example illustrating how a login script would work for Google. Office 365 is almost identical, just change the name of the function calls. It assumes there is a related table occurrence named 'currentUserRecord' where the login token for the current user can be read and written:
Set Variable[ $$state; Get( UUID ) ] Set Variable[ $loginUrl; EmailGoogleGetLoginUrl( currentUserRecord::OAuthToken; ""; ""; $$state ) ] If[ IsEmpty( $loginUrl ) ] #User tokens are still valid from last login; can auto-login without being prompted Set Field[ currentUser::OAuthToken; EmailGoogleConnect( $googleUsername, currentUserRecord::OAuthToken; ""; ""; $$state ) ] #Proceed to make normal calls to the plug-in to send and receive emails Else #Need to redirect user to loginUrl Open URL[ $loginUrl ] #After they login, they should click a button in FileMaker that runs the post-login script, below #You can also show a dialog to pause the script and wait for them to press continue, instead of running a separate script. End If
Post-login script. Make sure $$state is the same UUID that was passed into the EmailGoogleGetLoginUrl function
Set Field[ currentUser::OAuthToken; EmailGoogleConnect( $googleUsername, currentUserRecord::OAuthToken; ""; ""; $$state ) ] #Proceed to make normal calls to the plug-in to send and receive emails
EmailAttachFile("http://localhost:8080/SuperContainer/RawData/123");
EmailAttachFile("file:///path/to/invoice.pdf");
EmailAttachFile("/Macintosh HD/path/to/invoice.pdf");
EmailAttachFile(myTable::myContainerField);
/Volumes
to the supplied path, since FileMaker includes the hard drive name in paths. For example,
/MacintoshHD/Users/John Smith/Documents/
is converted to the file URL
file:///Volumes/MacintoshHD/Users/John Smith/Documents/
.
.pages
files, etc.
data
- a container, path to a file, or a URL pointing to a file to attach to the message.EmailCreate("to@example.com"; "from@example.com"; "My Newsletter") EmailSetBody( "<html><body><img src=\"cid:headergif123\">" & "This is an HTML message with embedded images
" & "<img src=\"cid:footergif456\">" & "</body></html>"; "html" ) EmailAttachFileInline( Globals::headerContainer ; "headergif123" ) EmailAttachFileInline( Globals::footerContainer ; "footergif456" ) EmailSend
cid:contentid
, where contentid
is an arbitrary unique string you create for each
inline attachment.
Your contentIds should be globally unique for a given image/file resource, as mail clients will use this to cache
the contents of the message.
You should only use letters and numbers for your content ids, some mail clients have trouble with other
characters.
data
- a path to a file, or a URL pointing to a file to attach to the message (see EmailAttachFile for
valid arguments).contentId
- contentId of the attachment.append
to true if doing this).
//Assumes the connection the SMTP server has already been established. EmailCreate( "from@example.com", "to@example.com", "A multipart message" ) EmailBCCRecipients(somebody@360works.com;true) EmailBCCRecipients(someOneElse@360works.com;true)//passing in false will overwrite the BCC recipients list EmailSetBody( GetAsCSS( Email::body ); "html" ) EmailSend
bcc_addresses
- comma-separated list of addressesappend
- whether to append the new addresses to existing ones, or overwrite them.searchString
each time. Once a message is sent,
the replaced values are reset to their original values.
This is useful if you are using EmailSetBodyFile to load static HTML content as the body part, but want
to insert dynamic content in the body. Or, if you are sending many emails and want to merge data into a static
body text field.
Text in the body field: Hello CUSTOMERNAME, your account ending in ACCOUNTLASTFOUR is past due. Please pay ACCOUNTBALANCE by DUEDATE or your account will be terminated EmailCreate(someOne@360works.com;someOneElse@360works.com;"Example Email") EmailSetBody(myTable::bodyField;"html")//also works with plain text EmailBodySubstitute("CUSTOMERNAME";Customer::Name) EmailBodySubstitute("ACCOUNTLASTFOUR";Customer::AccountLastFour) EmailBodySubstitute("ACCOUNTBALANCE";Customer::Balance) EmailBodySubstitute("DUEDATE";Customer::Due Date) EmailSend
searchString
- the text to replacereplaceString
- the replacement textappend
to true if doing this).
EmailCreate( "from@example.com", "to@example.com", "A multipart message" ) EmailCCRecipients(someOne@email.com;true) //appends address to CC list EmailCCRecipients(someOneElse@email.com, anotherOne@email.com;true) //appends addresses to CC list EmailSetBody( GetAsCSS( Email::body ); "html" ) EmailSend
EmailCCRecipients(someOne@email.com;false) //overwrites current CC list EmailCCRecipients(someOneElse@email.com;false) //overwrites previous call
cc_addresses
- comma-separated list of addressesappend
- whether to append the new addresses to existing ones, or overwrite them.
fileType
parameter, you can allow the user to just select files,
just select directories, or select both files and directories. The default behavior is to only allow file
selection.
Note: specifying a fileType of "directories" or "files + directories" will cause a non-native file dialog to be used on some platforms, as the native dialogs may not support directory selection.
initialPath
- optional path to set the initial dialog selection to. If empty, will default to the user's
home directory.fileType
- whether to allow ,,"files",
,, ,,"directories",
,, or both ,,"files +
directories",
title
- optional title string to display as the title of the FileChooser dialoghost_address
- the SMTP host address. This parameter may contain a port number using a colon syntax, e.g.
,,smtp.example.com:2525,
user
- The optional SMTP authentication usernamepassword
- The optional SMTP authentication passwordEmailConnectAmazon( "nf298nrc23r"; "208chr29-hrc-29hr1983f")
It's also possible to use Amazon SES via SMTP. In this case you would need to generate SMTP keys and use EmailConnectSMTP. Please note that these are different than the access key/secret keys created for this
function. See EmailConnectSMTP for a link to instructions on how to generate these keys.
EmailConnectPOP
) must be called before
reading email messages from the server. This establishes a connection to the email server. When you are finished
getting/sending email, it is a good idea to call EmailDisconnect to close the connection.
Here is an example of connecting to a regular mail server:
Set Variable[$result ; Value: EmailConnectIMAP("my_email_host" ;"username" ;"password")]
"ssl=1"
. If
you are connecting to GMail, SSL encryption is required. Here is an example of connecting to google mail (gmail)
with SSL encryption, and expunge set to true:
Set Variable[$result ; Value: EmailConnectIMAP("imap.gmail.com" ;"username" ;"password" ;"ssl=1" ;"expunge=true")]
true
to enable SSL encryption. Some mail services (like Gmail) require
this.true
or false
to determine whether flagging a
message for deletion permanently removes the message from your mail server. If unspecified, messages are only
removed/expunged if the server does not support deleted flags.if your IMAP server requires TLS pass in a 1 or true for the secureConnection parameter if calling the function as a script step. If called as a function pass in tls=1. If your IMAP server requires SSL, you will need to call the EmailConnectIMAP function in a calculation and set the parameter to ssl=1 or true
host
- the IMAP host address. This parameter may contain a port number using a colon syntax, e.g.
,,imap.example.com:2525,
username
- The authentication usernamepassword
- The authentication passwordargs
- Additional optional arguments (ssl, forceTrust, tls).EmailConnectIMAP
) must be called before
reading email messages from the server. This establishes a connection to the email server. When you are finished
getting/sending email, it is a good idea to call EmailDisconnect to close the connection.
Note: We strongly recommend using IMAP instead of POP with Gmail due to possible confusion over Gmail's
labels and tags.
Here is an example of connecting to a regular mail server:
Set Variable[$result; Value: EmailConnectPOP("my_email_host" ;"username" ;"password")]
"ssl=1"
. If
you are connecting to GMail, SSL encryption is required. Here is an example of connecting to google mail (gmail)
with SSL encryption:
Set Variable[$result ; Value: EmailConnectPOP("pop.gmail.com" ;"username" ;"password" ;"ssl=1")]
if your POP server requires TLS pass in a 1 or true for the secureConnection parameter. If your POP server requires SSL, you will need to call the EmailConnectPOP function in a calculation and set the parameter to ssl=1 or true
host
- the POP host address. This parameter may contain a port number using a colon syntax, e.g.
,,pop.example.com:2525,
username
- The authentication usernamepassword
- The authentication passwordargs
- Additional optional arguments (ssl, forceTrust, tls).Note for Gmail users: By default, Gmail will set the "from" address to the email address used with EmailConnectSMTP for all outbound messages. If you want to set the "from" address to a different email address, you must add the desired email address manually in Gmail Settings. Gmail also requires that you change the "allow less secure apps" to true in order to connect to it with 3rd party software. This setting can be changed in the Security section in account settings.
Here is an example of connecting to a regular mail server:Set Variable[$result ; Value: EmailConnectSMTP("my_email_host" ;"username" ;"password")]
"ssl=1"
. If you are connecting to
Gmail, SSL encryption is required. Here is an example of connecting to Gmail with SSL encryption:
Set Variable[$result; Value: EmailConnectSMTP("smtp.gmail.com:465" ;"username" ;"password" ;"ssl=1")]
if your SMTP server requires TLS pass in a 1 or true for the secureConnection parameter. If your SMTP server requires SSL, you will need to call the EmailConnectSMTP function in a calculation and set the parameter to ssl=1 or true
NOTE: If you are using access and secret keys, you should be using EmailConnectAmazon. If you want to use EmailConnectSMTP, you must use Amazon's SES SMTP interface which requires separate SMTP credentials. Instructions to generate those credentials can be found here. Example connecting to SES SMTP US East Endpoint
Set Variable[$connect; Value: EmailConnectSMTP("email-smtp.us-east-1.amazonaws.com";"SMTPaccessKey";"SMTPsecretKey";"tls=1")
host
- the SMTP host address. This parameter may contain a port number using a colon syntax, e.g.
,,smtp.example.com:2525,
username
- The optional SMTP authentication usernamepassword
- The optional SMTP authentication passwordargs
- Additional optional arguments (ssl=true, forceTrust=true, tls=true,
timeout=,<,<,seconds,>,>,).from
- the FROM address for the new message. Use "Name ,<,you@domain.com,>," for displaying the
name instead.to
- the TO address for the new messagesubject
- the SUBJECT of the new messageflags
- optional flags which control how messages are countedEmailReadMessages
function.
To use this function, first call EmailReadMessages
with the appropriate parameters.
Next, call EmailGetNextMessage
, which returns 1 or 0 depending on whether a message was loaded.
Finally, call EmailReadMessageValue
to get individual properties of the currently loaded message.
Call this function to retrieve inbound emails AFTER EmailGoogleGetLoginUrl, and after sending the user to the login URL (if a URL was returned by the that function), or immediately (if a blank result was returned by that function). After this function completes successfully, you should store the result in a user record for future logins, and then you can proceed to make normal function calls.
There is an OAuth example login process at the top part of this documentation.
username
- The email address of the Google account that will be connected totokenStore
- Every time this function is called, the result should be stored in the database and passed in as this parameter on the next call to this function.googleClientId
- The client_id from your Google developer account. This is optional and can be omitted, in which case the 360Works registered clientId will be used.googleClientSecret
- The client_secret from your Google developer account. This is optional and can be omitted, in which case the 360Works registered clientSecret will be used.state
- This should match the random UUID that was passed to the ,EmailGoogleGetLoginUrl, function.Call this function to send outbound emails AFTER EmailGoogleGetLoginUrl, and after sending the user to the login URL (if a URL was returned by the that function), or immediately (if a blank result was returned by that function). After this function completes successfully, you should store the result in a user record for future logins, and then you can proceed to make normal function calls.
There is an OAuth example login process at the top part of this documentation.
username
- The email address of the Google account that will be connected totokenStore
- Every time this function is called, the result should be stored in the database and passed in as this parameter on the next call to this function.googleClientId
- The client_id from your Google developer account. This is optional and can be omitted, in which case the 360Works registered clientId will be used.googleClientSecret
- The client_secret from your Google developer account. This is optional and can be omitted, in which case the 360Works registered clientSecret will be used.state
- This should match the random UUID that was passed to the ,EmailGoogleGetLoginUrl, function.
There is an OAuth example login process at the top part of this documentation.
tokenStore
- Can be empty the first time you call this. After a successful login, you should store the tokenStore returned from ,EmailGoogleConnect, and pass it in the next time this function is called. In most cases this will skip the need for the user to have to log in.googleClientId
- The client_id from your Google developer account. This is optional and can be omitted, in which case the 360Works registered clientId will be used.googleClientSecret
- The client_secret from your Google developer account. This is optional and can be omitted, in which case the 360Works registered clientSecret will be used.state
- A random UUID. Store this UUID so that it can be passed as a parameter to ,EmailGoogleConnect,. The state parameter is required if calling the function on FileMaker Server, or with a Perform Script on Server, but it is legal to leave the state parameter empty if the plugin is running on FileMaker Pro.Checks if the email plugin is connected to an inbound server
EmailConnectIMAP(....)//connect to IMAP Server Set Variable[$mailboxes;Value:EmailListMailboxes("INBOX";true)] //passing in true gets all sub-folders in INBOX
parent
- optional mailbox to traverse. If not specified/empty, the root mailbox is used.recursive
- optional parameter for whether to traverse sub-folders recursively. Default is false.readonly=false
to use this function.
The allowed flags are: POP vs
IMAP. POP accounts typically do not support persistent flags, so if you flag a message as
deleted
in a POP account, it will be permanently deleted when you
disconnect from the server.
flag
- one of the named flags to setvalue
- the optional value to set the flag to. Default is ,,0,
, (or ,,false,
,).To save a copy of an outgoing message in your "Sent" mailbox, you can do something like the following:
EmailCreate( "my@mydomain.com" ; "bob@example.com" ; "Moving a test message" ) EmailSetBody( "Hi Bob! I'm saving a copy of this in my 'Sent' folder" ) EmailSend EmailMoveCurrentMessage( "Sent" )
The above example assumes that you are already connected both to your IMAP server and your SMTP server.
First we create a message and set the message body. Next, we deliver the message by calling EmailSend. Finally, If the message was delivered successfully, we save it to the "Sent" folder on our IMAP mailbox.
To move existing messages on your IMAP mailbox, call
EmailMoveCurrentMessage
after fetching the message with EmailGetNextMessage. This will
copy the message to the destination mailbox, creating the mailbox if it doesn't exist. If the original mailbox
has
readonly=false
specified, the message is flagged for deletion from the original mailbox. This can
be useful for processing all messages in a certain folder, then moving them to a "processed" folder on the
mailserver, for example.
Set Variable [ $result = EmailReadMessages( "readonly=false" ) ] If [$result = "ERROR"] # Handle Error Here... End If Loop Exit Loop If [not EmailGetNextMessage] // PROCESS THE MESSAGE HERE... Set Variable [ $moveResult = EmailMoveCurrentMessage ("Processed") ] End Loop
readonly=false
is required
for the processed messages to be removed from the mailbox. If not specified, the messages will still remain in
the original mailbox.
folder
- the name of the folder to move the message toCall this function to retrieve inbound emails AFTER EmailOffice365GetLoginUrl, and after sending the user to the login URL (if a URL was returned by the that function), or immediately (if a blank result was returned by that function). After this function completes successfully, you should store the result in a user record for future logins, and then you can proceed to make normal function calls.
There is an OAuth example login process at the top part of this documentation.
username
- The email address of the Office 365 account that will be connected totokenStore
- Every time this function is called, the result should be stored in the database and passed in as this parameter on the next call to this function.office365ClientId
- The client_id from your Microsoft Azure Account. This is optional and can be omitted, in which case the 360Works registered clientId will be used.office365ClientSecret
- The client_secret from your Microsoft Azure Account. This is optional and can be omitted, in which case the 360Works registered clientSecret will be used.office365TenantId
- The Tenant ID associated to the application with client_id. This is optional and can be omitted, in which case no tenant ID will be used (tenant ID is not useful in most scenarios).state
- This should match the random UUID that was passed to the ,EmailOffice365GetLoginUrl, function.Call this function to send outbound emails AFTER EmailOffice365GetLoginUrl, and after sending the user to the login URL (if a URL was returned by the that function), or immediately (if a blank result was returned by that function). After this function completes successfully, you should store the result in a user record for future logins, and then you can proceed to make normal function calls.
There is an OAuth example login process at the top part of this documentation.
username
- The email address of the Office 365 account that will be connected totokenStore
- Every time this function is called, the result should be stored in the database and passed in as this parameter on the next call to this function.office365ClientId
- The client_id from your Microsoft Azure Account. This is optional and can be omitted, in which case the 360Works registered clientId will be used.office365ClientSecret
- The client_secret from your Microsoft Azure Account. This is optional and can be omitted, in which case the 360Works registered clientSecret will be used.office365TenantId
- The Tenant ID associated to the application with client_id. This is optional and can be omitted, in which case no tenant ID will be used (tenant ID is not useful in most scenarios).state
- This should match the random UUID that was passed to the ,EmailOffice365GetLoginUrl, function.
There is an OAuth example login process at the top part of this documentation.
tokenStore
- Can be empty the first time you call this. After a successful login, you should store the tokenStore returned from ,EmailOffice365Connect, and pass it in the next time this function is called. In most cases this will skip the need for the user to have to log in.office365ClientId
- The client_id from your Microsoft Azure Account. This is optional and can be omitted, in which case the 360Works registered clientId will be used.office365ClientSecret
- The client_secret from your Microsoft Azure Account. This is optional and can be omitted, in which case the 360Works registered clientSecret will be used.office365TenantId
- The Tenant ID associated to the application with client_id. This is optional and can be omitted, in which case no tenant ID will be used (tenant ID is not useful in most scenarios).state
- A random UUID. Store this UUID so that it can be passed as a parameter to ,EmailOffice365Connect,. The state parameter is required if calling the function on FileMaker Server, or with a Perform Script on Server, but it is legal to leave the state parameter empty if the plugin is running on FileMaker Pro.Possible URIs for adding an attachment are listed in the EmailAttachFile function.
from
- The ,",from,", email address. Use "Name ,<,you@domain.com,>, for displaying the
name instead.to
- A comma-separated list of ,",to,", email addressessubject
- The subject of the messagebody
- The message body. If the body starts with ,,<,html,
, it is assumed to be an
HTML-formatted message.attachment
- A container holding an attachment to include with the email, or a URL or path to a file to
attach.attachments=true
as a parameter to the EmailReadMessages function.
This function will retrieve attachment files only for paths generated by calling EmailReadMessages() with argument "attachments=true". Also, attachments will no longer be retrievable once the connection to the inbound server has been severed(e.g. calling EmailDisconnect).
After importing an email message into FileMaker, pass any attachment paths to this function to get container data
for the attachment path. For example, you might pass the following argument:
EmailReadAttachment( "/Macintosh HD/private/tmp/4545776.01203682301836.JavaMail.root@pluto.local/text.html" )
file:
, image:
, or any other prefix - just the
path.
This can also be a part of your email parsing loop by passing in the return of
EmailReadMessageValue("attachmentsAll")
EmailConnectIMAP(...)//connect to IMAP Server EmailReadMessages("attachments=true")//passing in false will still get a list of attachments but only file names no paths Set Variable[$count;Value:1] //variable to control exit loop condition Loop Exit Loop If [not EmailGetNextMessage] New Record/Request Set Variable[$attachList ; Value: EmailReadMessageValue( "attachmentsAll" )] //can also specify "attachmentsInline" or "attachments" Go to Layout["Attachments"; Animation:None] Loop Exit Loop If[ValueCount($attachments)< $count] New Record/Request Set Field[Attachments::Data; EmailReadAttachment(GetValue($attachList;$count)) Set Variable[$count; Value: $count+1] End Loop //do some more message parsing here End LoopNote: this function will actually work for any file, it doesn't need to be an email attachment.
path
- The path as returned in the email importsavePath
- An optional path parameter to save the attachment to a local folder instead of a container fieldkey
- The key to retrieveEmailGetNextMessage
function.
If there are multiple values for a key, each value will be on a separate line.
The parameter must be one of the following values (case-insensitive): attachments
parameter in EmailReadMessages
). Note:
inlined attachments are excluded from this list. Use attachmentsAll
to get all attachments
including inlined ones, or attachemntsINLINE
to get only inline attachments..htmlRaw
instead, or set
attachments=false
when fetching messages.)You can retrieve
any message header by using this function. For example, to get information about the mail application which sent
the message, you can use EmailReadMessageValue("header:X-Mailer")
. If a header has multiple values,
they will be returned as a return-separated list.
key
- The key to retrieve, must be one of the above listed keys.If an error occurs, this function will return "ERROR". Use the EmailLastError function to get more information about the error.
The Email plugin supports reading messages from POP and IMAP mailboxes. Typically, you're interested in only fetching new messages from your mailbox. There are several approaches to doing this.
Note: POP3 mail servers are not required to support UIDs. Please check with the server administrator about UID support.
IMAP and POP3 mailboxes assign each message a unique UID. When reading messages from an IMAP or POP3 mailbox, you can get the value for this UID with the following function:
Set Field[ImportedMessage::uid ; EmailReadMessageValue( "uid" ) ]
Go To Record/Request/Page [Last] Set Variable [ $result = EmailReadMessages ( "uid=" & ImportedMessage::uid ) ]
You can specify a filter option to only search for unread messages:
Set Variable [ $result = EmailReadMessages ("viewed=false" ;"readonly=false")
After fetching unread messages, you should then set the "viewed" flag to true
for each message,
so subsequent reads will skip these messages. This is outlined in the following section "Reading Individual
Messages"
Note: searching for unread messages will not work correctly if other email clients are accessing the same mailbox and marking messages as viewed.
This is similar to option 2, except you don't need to modify the
messages on the server. Simple count how many messages have been fetched from the mailbox, and pass a
skip
parameter to the EmailReadMessages
function whose value is this number.
Note: If messages are deleted from the mailbox, local messages should be deleted as well, so
the local count
matches the number of fetched messages on the server.
After successfully calling EmailReadMessages, you can iterate over the fetched messages using the EmailGetNextMessage function. This pattern typically looks like this:
Loop Exit Loop If [not EmailGetNextMessage] New Record/Request Set Field[ImportedMessage::from ; EmailReadMessageValue( "from" )] Set Field[ImportedMessage::to ; EmailReadMessageValue( "to" )] Set Field[ImportedMessage::subject ; EmailReadMessageValue( "subject" )] Set Field[ImportedMessage::body ; EmailReadMessageValue( "body" )] Set Field[ImportedMessage::messageId ; EmailReadMessageValue( "messageId" )] // OPTIONAL: mark this messages as "viewed" // You must pass readonly=false during EmailReadMessages to do this Set Variable[$result ; EmailMessageSetFlag("viewed")] End Loop
To import email data into FileMaker via XML, use the "Import Records"
script step, and specify an XML data source, passing the file URL returned from this function.
Use the
"messageId" field in the resulting XML as a match field when defining import options. Note: XML
import is not a web-safe script. Use the method described in "Reading Individual Messages" if your
script is running in IWP or on the server, or if you need to modify individual messages on the server.
key=value
arguments. You can specify any number of flags you wish. The following is a description of the available flags:
100,200
". Default is centered on-screen.INBOX
.true
, which enables attachment downloading. Setting
this to
false
will disable downloading attachments, which can be significantly faster. If attachment
downloading is disabled, you can still retrieve a list of the attachments in a message using the
EmailReadMessageValue ( "attachments" )
function. You can then re-read the message at a later time
to download the attachments. uid
is newer
than the one passed in. This is very useful for only fetching new messages from IMAP mailboxes. When looping
through new messages, call EmailReadMessageValue("uid")
on the last message and save this to a field
in your database. Then when fetching new messages, pass this uid
in as a filter argument. Only
newer messages will be returned. Note: if you specify this option and the mailbox is an IMAP
mailbox, some of the other search filters (skip, to, from, date) will be ignored.from
addressto
addresssubject
messageId.
Note: If the message is in a different folder/mailbox other than
inbox, you will need to specify the folder/mailbox by using the mailbox
parameter.body
true
to return only
previously viewed messages, false
to return only unread messages.true
to return only flagged messages, false
to
return only non-flagged messages.true
to return only deleted messages, false
to return only non-deleted messages The
default is false
, meaning deleted message will be excluded.1
to enable (e.g., "alternateDecoding=1"). The
alternate decoding method is disabled by defaulttrue
(read-only). If you plan on deleting, moving,
or flagging any messages, use false
in this parameter. Note: setting
readonly=false
will cause any fetched messages to be marked as "viewed"! For example, you might use the following to fetch the first 25 unread messages from your inbox, not downloading attachments:
EmailReadMessages("mailbox=INBOX" ;"attachments=false" ;"max=25";"viewed=false")
flags
- optional flags which control how messages are read.MBOX
file or raw message content file (.eml
),
and stores the parsed messages in an FMPXML file, suitable for import into FileMaker. In addition, you can use
the EmailGetNextMessage function after calling this to loop over the messages and programatically read
individual values using the EmailReadMessageValue
The following is a description of the available flags:
Note: this will disconnect from your current mail server if there is an active connection.
file
- path to an MBOX fileappend
to true if doing this).
EmailRecipients(someOne@email.com;true) EmailRecipients(someOneElse@email.com, anotherOne@email.com;true)//appends address to recipients list
EmailRecipients(someOne@email.com;false) //overwrites current recipient list EmailRecipients(someOneElse@email.com;false) //overwrites previous call
to_addresses
- comma-separated list of addressesappend
- whether to append the new addresses to existing ones, or overwrite them.licenseKey
- a valid license key string.registeredTo
- the company name for the license key used.emailAddress
- The user's email address to allow for support contactproblemDescription
- A description of the current issueaccessKey
- Your AWS access keysecretKey
- Your AWS secret keyrecipient
- Phone numbers to send the message tobody
- SMS Body. Some carriers may break long messages into separate, shorter messages.region
- Optional. AWS region from which the SMS message will send. Default is us-east-1
false
.100,200
". Default is centered on-screen.options
- optional parametersshowProgress
- Whether to show a progress bar. Default = ,,false,
progressLocation
- Location of the progress bar, e.g. ,",,100,200,
,"EmailCreate( "from@example.com", "to@example.com", "A multipart message" ) EmailSetBody( Email::body ; "plain" ) // this is used for mail clients which don't display HTML EmailSetBody( Email::HTMLbody ); "html" ) // HTML version with formatting EmailSend
body
- text to be displayed in the messagecontentType
- type of formatting used in the body, e.g. "plain", "html", "rtf".characterSet
- optional character settrue
as the embedResources
parameter, any images or
stylesheets referenced in the email message will be included as inline attachments in the email message. This
means that users will not need to load the resources from the central server, but it can increase the email
message size considerably.
If you pass false
as the embedResources
parameter, any referenced image URLs will be
rewritten as absolute URLs. This function also accepts .mhtml html archive files, which
have the advantage of already having all images embedded in the file. The embedResources
parameter
is always effectively true
for .mhtml files.
url
- URL to the HTML document.embedResources
- whether resources should be embedded in the HTML email or rewritten as absolute URLs.errorCapture
- set to true to suppress the default popups.EmailSetHeader( "reply-to" ; "reply@example.com" ) EmailSetHeader( "bcc" ; "blind@example.com" ) EmailSetHeader( "subject" ; "List of Example Headers" )
header
- the header namevalue
- the header valueEmailConnectSMTP(...)//Connect to SMTP server EmailCreate( "from@example.com", "to@example.com", "Multiple Subjects" ) EmailSetBody( Email::body; "html" )//body will be the same for all recipients Go to Record/Request/Page [First] Loop   EmailRecipients(Customer::EmailAddress) //not passing in true for append parameter overwrites recipients list   EmailSetSubject("Alert for:"& Customer::Name)   EmailSend Go to Record/Request/Page[Next;Exit after last: On] End Loop
subject
- the email message subjectemail
- one or more email addresses to validate (comma-separated).