Using the Email Inbound Adapter
This topic describes the default behavior of the email inbound adapter (EnsLib.EMail.InboundAdapterOpens in a new tab) so that the production can send and receive email and describes how to use this adapter in your productions. You should be familiar with the requirements and limitations of the SMTP or POP3 server with which you are working.
Overall Behavior
First, it is useful to understand the details that you specify for the adapter. The EnsLib.EMail.InboundAdapterOpens in a new tab class provides runtime settings that you use to specify items like the following:
-
The POP3 server to use and login details for the mailbox from which to read messages
-
Matching criteria that indicate the messages of interest
-
A polling interval, which controls how frequently the adapter checks for new input
In general, the inbound email adapter (EnsLib.EMail.InboundAdapterOpens in a new tab) periodically checks the mailbox, finds matches, sends the messages (as instances of %Net.MailMessageOpens in a new tab) to the associated business service, and deletes the messages from the email server. The business service, which you create and configure, uses these messages and communicates with the rest of the production. The following figure shows the overall flow:
More specifically:
-
The adapter regularly executes its OnTask() method, which connects to the POP3 server and logs on, using a specific username and password. The polling interval is determined by the CallInterval setting.
-
The adapter looks at all the messages in this mailbox and compares them against the match criteria.
-
When the adapter finds a message that meets the criteria, it does the following:
-
The adapter creates an instance of the %Net.MailMessageOpens in a new tab class and puts the email data into it.
-
The adapter calls the internal ProcessInput() method of the associated business service class, passing the %Net.MailMessageOpens in a new tab instance as input.
-
The adapter deletes the mail message from the server.
-
-
The internal ProcessInput() method of the business service class executes. This method performs basic production tasks such as maintaining internal information as needed by all business services. You do not customize or override this method, which your business service class inherits.
-
The ProcessInput() method then calls your custom OnProcessInput() method, passing the %Net.MailMessageOpens in a new tab instance as input. The requirements for this method are described later in Implementing the OnProcessInput() Method.
The response message follows the same path, in reverse.
Creating a Business Service to Use the Email Inbound Adapter
To use this adapter in your production, create a new business service class as described here. Later, add it to your production and configure it. You must also create appropriate message classes, if none yet exist. See Defining Messages.
The following list describes the basic requirements of the business service class:
-
Your business service class should extend Ens.BusinessServiceOpens in a new tab.
-
In your class, the ADAPTER parameter should equal EnsLib.EMail.InboundAdapterOpens in a new tab.
-
Your class should implement the OnProcessInput() method, as described in Implementing the OnProcessInput() Method.
-
For other options and general information, see Defining a Business Service Class.
The following example shows the general structure that you need:
Class EEMA.EmailService Extends Ens.BusinessService
{
Parameter ADAPTER = "EnsLib.EMail.InboundAdapter";
Method OnProcessInput(pInput As %Net.MailMessage,
pOutput As %RegisteredObject) As %Status
{
set tsc=$$$OK
//your code here
Quit tsc
}
}
Implementing the OnProcessInput() Method
Within your custom business service class, your OnProcessInput() method should have the following signature:
Method OnProcessInput(pInput As %Net.MailMessage,
pOutput As %RegisteredObject) As %Status
Here pInput is the email message object that the adapter will send to this business service; this is an instance of %Net.MailMessageOpens in a new tab. Also, pOutput is the generic output argument required in the method signature.
The OnProcessInput() method should do some or all of the following:
-
Examine the email message and decide how to use it.
Email messages can have a variety of different structures, which would need different handling. You may want to start by making sure that the message has the structure you expect. That is, you would check whether it is a multipart message and whether the parts are binary. For more information, see Using Email Messages.
-
Once you are sure of the message structure, use the other properties of %Net.MailMessageOpens in a new tab to access the message body or any headers. See Using Email Messages.
-
Create an instance of the request message, which will be the message that your business service sends.
For information on creating message classes, see Defining Messages.
-
For the request message, set its properties as appropriate, using values in the email message.
-
Call a suitable method of the business service to send the request to some destination within the production. Specifically, call SendRequestSync(), SendRequestAsync(), or (less common) SendDeferredResponse(). For details, see Sending Request Messages.
Each of these methods returns a status (specifically, an instance of %StatusOpens in a new tab).
-
Make sure that you set the output argument (pOutput). Typically you set this equal to the response message that you have received. This step is required.
-
Return an appropriate status. This step is required.
The following shows a simple example:
Method OnProcessInput(pInput As %Net.MailMessage,
pOutput As %RegisteredObject) As %Status
{
//Check if mail message has multiple parts
Set multi=pInput.IsMultiPart
If multi
{$$$TRACE("This message has multiple parts; not expected")
Quit $$$ERROR($$$GeneralError,"Message has multiple parts")
}
//Check if mail message is binary
Set bin=pInput.IsBinary
If bin
{$$$TRACE("This message is binary; not expected")
Quit $$$ERROR($$$GeneralError,"Message is binary")
}
//Check if mail message is HTML
Set html=pInput.IsHTML
If html
{$$$TRACE("This message is HTML not expected")
Quit $$$ERROR($$$GeneralError,"Message is HTML")
}
//now safe to get text of message
Set pReq=##class(EEMA.EmailContents).%New()
Set pReq.MessageText=pInput.TextData
Set tSc=..SendRequestSync("EEMA.EmailProcessor",pReq,.pResp)
Set pOutput=pResp
Quit tSc
}
Using Email Messages
As noted earlier, after you retrieve an email message (%Net.MailMessageOpens in a new tab), you generally start by determining what kind of message it is and how to read it; that is, whether it is a multipart message and whether the parts are binary.
In this step, you can use the ContentType property, which is equivalent to the Content-Type property. Or you can use the IsBinary, IsHTML, and IsMultiPart properties, which indirectly provide the same information as ContentType.
If the message is a multipart message, each part is an instance of %Net.MailMessagePartOpens in a new tab.
A message has message headers; each part of the message can also have message headers. You can access the headers via various properties of %Net.MailMessageOpens in a new tab and %Net.MailMessagePartOpens in a new tab.
Message Contents
Once you know what the general message structure is, use the following techniques to retrieve the contents:
-
For a multipart message, use the Parts property, which is an array of the parts. Use the Count() method to get the number of parts. Use the GetAt() method to retrieve a given part; the key for each part is an integer, starting with 1 for the first part.
-
For a binary message (or message part), use the BinaryData property.
-
For a text message (or message part), use the TextData property.
-
If IsHTML is 0, the TextData property is an ordinary text string.
-
If IsHTML is 1, the TextData property is an HTML text string.
-
Note that the email client that sends a message determines any wrapping in the message. The mail server has no control over this; nor does InterSystems IRIS.
Message Headers
The message itself and each part of the message has a set of headers.
The %Net.MailMessageOpens in a new tab class provides properties that give you the most commonly used headers.
-
To—The list of email addresses to which this message was sent. This property is a standard InterSystems IRIS list; to work with it, you use the standard list methods: Insert(), GetAt(), RemoveAt(), Count(), and Clear().
-
From—The email address from which this message was sent.
-
Date—The date of this message.
-
Subject—A string containing the subject for this message.
-
Sender—The actual sender of the message.
-
Cc—The list of carbon copy addresses to which this message was sent.
-
Bcc—The list of blind carbon copy addresses to which this message was sent. If the receiver of the message was on the blind carbon copy list, this property contains the address of the receiver; otherwise, it is null.
Both %Net.MailMessageOpens in a new tab and %Net.MailMessagePartOpens in a new tab provide the following properties, which give you other headers:
-
ContentType—The Content-Type header of the message or message part.
-
ContentTransferEncoding—The Content-Transfer-Encoding header of the message or message part.
-
Headers—A multidimensional array that gives access to any additional headers.
Also, you can use the GetAttribute() method. Given a header name and an attribute, this method returns the value of that attribute.
Other Message Information
The following properties and methods provide additional information about the message:
-
The MessageSize property indicates the total length of the message, apart from any attached email messages.
-
The GetLocalDateTime() method returns the date and time when the message was retrieved, converted to local time in $HOROLOG format.
-
The GetUTCDateTime() method returns the date and time when the message was retrieved, converted to UTC in $HOROLOG format.
-
The GetUTCSeconds() method returns the date and time when the message was retrieved, in seconds since 12/31/1840.
-
The HToSeconds() class method converts a date/time in $HOROLOG format to seconds since 12/31/1840.
-
The SecondsToH() class method converts seconds since 12/31/1840 to a date/time in $HOROLOG format.
Adding and Configuring the Business Service
To add your business service to a production, use the Management Portal to do the following:
-
Add an instance of your custom business service class to the production.
-
Enable the business service.
-
Configure the adapter to access a POP3 mail server and download messages. Specifically:
-
Specify a POP3 mail server and login details needed to access a mailbox
-
Use Call Interv\al to specify how often the adapter looks for email
-
-
Run the production.
Specifying How to Log in to a POP3 Server
Specify values for the following settings to indicate the POP3 server to log onto, as well as the security information to access a mailbox:
For example, you could use values like the following:
Setting | Value |
---|---|
POP3 Server | pop.hotpop.com |
POP3 Port | 110 |
Credentials | hotpop |
In this example, hotpop is the ID of the production credentials that consist of the username isctest@hotpop.com and the corresponding password.
Specifying the Messages to Retrieve
Specify values for the following settings to control which messages to retrieve. Only messages that match all the given criteria are used. The matching is case-sensitive.
If you change these criteria, the adapter will examine and possibly process messages that did not match the criteria before.