I have never done anything mail related with ColdFusion other than sending mail using ColdFusion's CFMail tag. After years of this, I think it's finally time to start making this a two way street - healthy relationships are all about give AND take. I want to start looking into ColdFusion's CFPOP tag to see how I can get mail off a server and thereby, open up an automated bidirectional line of communication using the pop mail server as the go-between.
Before I could even start looking into ColdFusion CFPop, I had to get a mail server that could handle non-SSL POP3 support. I can't use my gMail accounts because apparently they use SSL which ColdFusion cannot yet handle (as of CF8). So, I did a quick Google search for "Free Pop mail" and came across the site Lavabit. This site seems perfect for testing. Their FREE, basic account offers:
- Storage: 128 MB
- Advertising: No
- Virus Protection: Yes
- Statistical Spam Filter: No
- Incoming Message Limit: 1,024 messages/day
- Outgoing Message Limit: 256 messages/day
- Message Size Limit: 32 MB
This should be more than enough to provide the perfect ColdFusion CFPop testing environment. I would say the setup took about 2 minutes... and did I mention that the basic account is FREE :)
Once I got the mail server setup done, I had to start building my ColdFusion testing environment. I am going to keep this ultra simple while I get my bearings on how all the CFPop stuff works. I set up a simple ColdFusion Application.cfm template:
<!--- Set page settings. ---> <cfsetting showdebugoutput="false" requesttimeout="20" /> <!--- Create the POP server login information. Lavabit's UNSECURED POP3 port is 110. ---> <cfset REQUEST.Pop = StructNew() /> <cfset REQUEST.Pop.Server = "lavabit.com" /> <cfset REQUEST.Pop.Username = "bennadel" /> <cfset REQUEST.Pop.Password = "XXXXXXXX" /> <cfset REQUEST.Pop.Port = "110" />
Now, all of my testing code can use the centralized REQUEST.Pop configuration information.
Ok, so let's start taking a look at how ColdFusion's CFPop tag works. The CFPop tag has three actions:
GetHeaderOnly and GetAll both receive information from the POP mail server. The Delete action deletes a given message (or list of messages) from the mail server. The reason there are two "get" actions is for performance optimization. The GetHeaderOnly action gets information about the messages but leaves out the attachments and content information that can take more processing and transfer time:
<!--- Gather the email headers. ---> <cfpop action="getheaderonly" name="qHeader" <!--- Server configuration. ---> server="#REQUEST.Pop.Server#" port="#REQUEST.Pop.Port#" username="#REQUEST.Pop.Username#" password="#REQUEST.Pop.Password#" />
The email header information that comes back from the server is stored in a standard ColdFusion query object with the following columns:
The To, CC, From, ReplyTo, Subject, and Date fields are pretty self-explanatory. The Header field contains the email header information that seems to have a lot of routing and "behind the scenes" information. The MessageID is some sort of unique identifier that is parsed out of the Header data. The MessageNumber seems to be the sequential "order ID" of the message as it sits in the mail box. The UID seems to be a unique identifier for that message that can be used to filter all of the CFPop actions (GetHeaderOnly, GetAll, and Delete); apparently it is the header's X-UID field, but this field is not present in the Header data.
Note that I am saying "seems to be" on several of these values above because really, I am not 100% where these values come from. This is the first time I am looking into this CFPop stuff, so please don't take this with any sort of authority.
When you use the GetAll action:
<!--- Gather the entire email messages. ---> <cfpop action="getall" name="qMessage" <!--- Server configuration. ---> server="#REQUEST.Pop.Server#" port="#REQUEST.Pop.Port#" username="#REQUEST.Pop.Username#" password="#REQUEST.Pop.Password#" />
... ColdFusion retrieves all of the above columns plus the following additional content and attachment columns:
The TextBody and the HTMLBody fields contain data from the different parts of the message if different Content Types were supplied (think CFMailPart [type = text/plain or text/html]). Needless to say, Text/Plain goes into the TextBody field and the Text/HTML goes into the HTMLBody field. The Body field always contains the first content part found in the email message (in top-down order). The attachments is a tab delimited list of attached file names and the AttachmentFiles is a tab delimited list of file path corresponding to the file names (the files are downloaded to the ColdFusion server as part of the CFPop action when AttachmentPath is supplied in the CFPop tag). CIDs is a structure that contains the key-value pair data for the embedded images in an HTML email. I have not seen this in action yet, but from the looks of it, the key is the name of the image file and the value is the CID that it corresponds to.
Once we get the email messages from the POP server, we can delete them using the Delete action:
<!--- Delete the given email message. ---> <cfpop action="delete" uid="82379091" <!--- Server configuration. ---> server="#REQUEST.Pop.Server#" port="#REQUEST.Pop.Port#" username="#REQUEST.Pop.Username#" password="#REQUEST.Pop.Password#" />
As you can see here, I am filtering the delete action using the UID attribute. This UID attribute can contain a single value or a comma delimited list of values that correspond to the UID fields in the GetAll and GetHeaderOnly CFPop actions. If you do not supply some sort of filtering UID (exclude the UID attribute in the CFPop tag), then all of the emails on the server will be deleted.
Ok, so that's like a birds eye view of the ColdFusion CFPop tag. Please don't look at this as a tutorial; this was mostly a gathering of notes for myself. There is a lot that can be done here, but I think the premise is fairly simple. Now, I just need to come up with a really cool idea that will help me learn how to fully utilize this functionality. My first instinct is to integrate this with some SMS text messaging through the cellular email gateways... but that's another post, and another adventure.
Links for my future study:
Want to use code from this post? Check out the license.