Mailgun and OpenInsight: Checking Bounced Messages
This blog post demonstrates an easy way to utilize Mailgun for checking bounced email messages sent through the Mailgun managed email service. With a few bits of information from your free Mailgun account you can begin checking if your messages were delivered. This blog post continues where Mailgun and OpenInsight: Getting Started ended so if you're not familiar with Mailgun or why it's incredibly useful I encourage you to review the post before continuing on.
Required Information
Before beginning this process you'll need some test data and account information. We'll walk through it step by step.
- Generate a bounced message by sending email through mailgun to a non-existent email account. In my example I'll use the address ivannabreak@congruityservice.com.
Tip: You can use the example program from the getting started blog post or use any email client with your mailgun account information to generate the bounced message.
- Use the mailserver logs screen in the Mailgun control panel to verify the email bounced. The image below shows recent mail log entries for openinsight.congruityservice.com and the bounced test message for ivannabreak@congruityservice.com.
If you don't see the log entry for your bounced message be sure the correct domain was selected.
- Go to the main Mailgun control panel screen and note the API Key and domain name. You'll need the information later. The API key is secret and should be protected just as you would a password. The image below shows where the API key and domain name are located.
We now have all the information needed to check for bounced messages from within OpenInsight code.
Example Code
Create a new stored procedure based on the following program. You'll need to change the following variables and replace each with your information from the previous section:
- CheckAddressBounced
- APIKey
- APIDomain
See the variable comments for more information.
Function mailgun_check_bounce(params) /************************************************************************************************ * Name : MAILGUN_CHECK_BOUNCE * * Description: Simple example problem to query the MailGun email server to check for if the * specified email address bounced and get the reason why. * Program demonstrates the use of WinHTTP COM Object and JSON values. * * Example use only. Requires configuration of static variables for example. * Set CheckAddressBounced, APIKey, APIDomain before use. * * Parameters: * none * * Returns: * none * * History (Date, Initials, Notes) * 08/20/14 JAB Jared Bratu, Congruity Service * ************************************************************************************************/ Declare Function RTI_JSON Equ MAILGUN_ADDRESS_NOT_FOUND$ To "Address not found in bounces table" Equ MAILGUN_AUTH_FORBIDDEN$ To "Forbidden" Equ TRUE$ To 1 Equ FALSE$ To 0 *Address to check. Check if email sent to this address bounced. CheckAddressBounced = 'ivannabreak@congruityservice.com' *The mailgun private API Key available on the control panel APIKey = "key-replacewithyourapikey" ;* Replace with your key APIUserName = "api" ;*This should always be 'api' as per mailgun docs *The mailgun account domain the CheckAddresBounce address was sent through APIDomain = "openinsight.congruityservice.com" ;* Replace with your domain *Construct the API URL call according to the MailGun docs *http://documentation.mailgun.com/api-bounces.html#bounces APIUrl = "https://api.mailgun.net/v2/" : APIDomain : "/bounces/" : CheckAddressBounced *Break to debug on error DebugOnError = TRUE$ LOG = "Checking if " : CheckAddressBounced : " bounced." Gosub mcbSetLog *Construct an HTTP request and set the Open parameters *http://msdn.microsoft.com/en-us/library/windows/desktop/aa383989(v=vs.85).aspx oleObj = OleCreateInstance('WinHttp.WinHttpRequest.5.1') oleResult = OleCallMethod(oleObj, "Open", 'GET', APIUrl, 0) mcbStep = "Setting WinHTTP Open Parms" mcbStatus = OleStatus() ; Gosub mcbCheckStatus *Optional - Setup timeout methods for resolving DNS and server response *http://msdn.microsoft.com/en-us/library/windows/desktop/aa384061(v=vs.85).aspx mcbStatus = OleCallMethod(oleObj, "SetTimeouts", 30000,15000,15000,15000) ;* All times in ms mcbStep = "Setting timeout values" mcbStatus = OleStatus() ; Gosub mcbCheckStatus *Specify the username and password to authenticate with the API as oleResult = OleCallMethod(oleObj, "SetCredentials", APIUserName, APIKey, 0) status = OleStatus() mcbStep = "Setting user and pass" mcbStatus = OleStatus() ; Gosub mcbCheckStatus *Execute the API request call *Blocks until Timeout reached or response received oleResult = OleCallMethod(oleObj, 'SEND') mcbStep = "Executing request" mcbStatus = OleStatus() ; Gosub mcbCheckStatus *Get the response value or error value ResponseRAW = OleGetProperty(oleObj, 'ResponseText') mcbStep = "Reading ResponseText" mcbStatus = OleStatus() ; Gosub mcbCheckStatus *If authentication fails we don't get a JSON object If ResponseRAW EQ MAILGUN_AUTH_FORBIDDEN$ Then LOG = "Unrecoverable authentication error" Gosub mcbSetLog End Else bounce = '' *Branch will set bounce to true of bounced or false if not bounced Gosub mcbProcessResponse End If Unassigned(bounce) Then *Fatal error, couldn't determine bounce status *Check mcbLog variable for details debug End Else If bounce = TRUE$ Then *Message bounced *see mcbLog variable for details End Else *Message did not bounce End End debug Return * *End MAILGUN_CHECK_BOUNCE * * * Branch handles a successful API call. * * Requires: * ResponseRAW * * Returns: * Bounce * mcbProcessResponse: *Turn the raw response into a JSON object for manipulation RetObj = RTI_JSON(ResponseRAW, 'Parse') ResponseMessage = RTI_JSON(RetObj, "GetValue", "message") If ResponseMessage EQ MAILGUN_ADDRESS_NOT_FOUND$ Then bounce = FALSE$ mcbLog = "Address " : CheckAddressBounced : " did not bounce" Gosub mcbSetLog End Else bounce = TRUE$ RetObjValues = RTI_JSON(RetObj, "GetObject", "bounce") bounce_code = RTI_JSON(RetObjValues, 'GetValue', 'code') bounce_error = RTI_JSON(RetObjValues, 'GetValue', 'error') bounce_address = RTI_JSON(RetObjValues, 'GetValue', 'address') mcbLog = "Address " : bounce_address : " bounced with error " : bounce_code : ". Error: " : bounce_error Gosub mcbSetLog End Return;*etiwagapomd * * Branch to log errors into LOG * mcbCheckStatus: *mcb = MailGun Check Bounce If mcbStatus then Log = mcbStep : ' code: ': mcbStatus * If we want to break on error then * reference the error variables for easy access If DebugOnError EQ TRUE$ Then LOG_ALL = mcbLog LOG_LAST = Log debug End Gosub mcbSetLog End Return ;*etiwagapomd * * Simple concatenation or logging function. * mcbSetLog: If Unassigned(mcbLog) Then mcbLog = LOG End Else mcbLog<-1> = LOG End Return ;*etiwagapomd
If the program variables are assigned correctly and the test succeeds it should break to the debugger and in variable mcbLog<1> contain:
Address ivannabreak@congruityservice.com bounced with error 550. Error: 550 Requested action not taken: mailbox unavailable
This demonstrates that OpenInsight was able to query the Mailgun service using the web API to check if email sent to a particular address was delivered or not. More information about the API is available at the Mailgun Bounce documentation page.
The next blog entry in this series will document parts of the test program since the code will be the basis for all remaining postings in the rest of this series. Like any eager developer, I want to invest a minimal amount of effort to see a result before I commit to diving in to the details. Those details are coming.
Leave a comment