After I found out that you cannot use a GMail account to monitor bounce backs with the CFMail FailTo attribute, I wanted to take a look at Postmark. Postmark is an API-based service that helps web applications send email and track bounce backs. The service charges for email delivery - $1.50 for every 1,000 emails; but, you get 1,000 free credits when you sign up (no billing information required), so I figured it would be worth trying.
In the following demo code, I'm gonna use CFHTTP to send an email to an invalid email address using Postmark.
As you can see, I first define my email settings in a ColdFusion structure. Then, when I invoke the Postmark API, I simply serialize the email settings using the serializeJSON() method and post the resultant JSON string as the CFHTTP body content. The Postmark API then returns a JSON response, which I can deserialize using deserializeJSON(). When we run the above code, we get the following API response:
Postmark has never seen that email address before - firstname.lastname@example.org - so it can offer us no insight at this time. As far as we know, Postmark has successfully sent out the given email. Of course, since we know that this email address is not valid, Postmark will eventually get a hard bounce back. Once Postmark has the hard bounce back on file, it can start to give us some more comprehensive feedback at "Send" time. If we wait a minute and re-execute the code above, we'll get the following output:
As you can see, the API call still executed without error; but, this time, Postmark knows that the given email address has previously caused a hard bounce back and will let us know that the given email address is not active. I am not 100% sure if this feedback is purely for user-insight; or, if it means that the given email was not sent.
Using the Postmark API to check for bounce backs is just as easy; all we need is the API key, some filtering, and the CFHTTP tag. It looks like Postmark keeps all bounce backs on file; as such, when you ask for bounce back information, you have to request it in a quasi-paginated manner using a page size and offset index. When doing so, the most recent bounce backs are listed first (offset zero).
In the following code, we are going to check to see if the above email address - email@example.com - caused a bounce back:
<!--- Get the bounce-back information from the PostMark server. When doing this, we have a number of possible filters. For our use, we're just gonna filters on email LIKE'ness. ---> <cfhttp result="get" method="get" url="http://api.postmarkapp.com/bounces"> <!--- Alert the server that the we can accept JSON as the type of data returned in the response. ---> <cfhttpparam type="header" name="accept" value="application/json" /> <!--- Define the API key to authorize post. ---> <cfhttpparam type="header" name="X-Postmark-Server-Token" value="#request.apiKey#" /> <!--- Pass in the email filter. Notice that we are filtering on the *partial* email address. You don't have to do this - you can use the full email address. ---> <cfhttpparam type="url" name="emailFilter" value="nat@natalie-gets-way-naughty" /> <!--- Pass in the number of bounce backs that we want to list (PostMark provides implicit pagination of all bounce-back records, starting with the most recent first). ---> <cfhttpparam type="url" name="count" value="1" /> <!--- Pass in the paging offset (which bounce back index will start the given page) - zero is the first page. ---> <cfhttpparam type="url" name="offset" value="0" /> </cfhttp> <!--- Deserialize the response JSON. This should give us a structure that contains the returned bounces plus the total number of bounces in the system (returned or otherwise) that match the given set of filtering criteria. ---> <cfset response = deserializeJSON( toString( get.fileContent ) ) /> <!--- Output the bounce back response. ---> <cfdump var="#response#" label="PostMark Bounce Backs" />
As you can see, I am searching for emails that are LIKE "nat@natalie-gets-way-naughty;" I left off the ".com" just to demonstrate that this filtering does not use exact text matching. As with the previous CFHTTP example, the request and response are both transferred in JSON format. When we get the Postmark API response, we need to deserialize the JSON string before we can use it. Running the above code, we get the following CFDump output:
As you can see, the email address we were searching for did, indeed, generate a hard bounce back.
The Postmark API seems like a very powerful and easy way to send emails and monitor their delivery status. I'm still feeling my way around parts of the bounce back API; but, the Postmark support staff has been both very fast at responding and very open to new ideas regarding their functionality.
Want to use code from this post? Check out the license.