I've changed it a bit as I wanted it purely script based, so I'm not submitting a PR.
I've added attachment saving with "attachmentpath" and "generateuniquefilenames" attributes, folder sorting, and a couple other things.
Grab what you want.
variables.connection = "";
variables.attachmentpath = "";
variables.generateuniquefilenames = false;
public function init(){
return this;
}
public function connect(
required string username,
required string password,
required string server,
required boolean secure = false,
required numeric timeout = 60,
required numeric port = 143
){
var clsSession = createObject("Java", "javax.mail.Session");
var objProperties = createObject("Java", "java.util.Properties");
var objStore = createObject("Java", "javax.mail.Store");
var oTimeout = arguments.timeout * 1000;
objProperties.init();
objProperties.put("mail.store.protocol", arguments.secure ? 'imaps' : 'imap');
objProperties.put("mail.imap.port", JavaCast( "int", arguments.port ) );
objProperties.put("mail.imap.connectiontimeout", oTimeout);
objProperties.put("mail.imap.timeout", oTimeout);
objProperties.put("mail.imap.ssl.enable", JavaCast( "boolean", arguments.secure ) );
objSession = clsSession.getInstance(objProperties);
objStore = objSession.getStore();
objStore.connect( arguments.server, arguments.username, arguments.password );
variables.connection = objStore;
}
public function close() {
variables.connection.close();
}
public function getHeaderOnly( string folder = "INBOX", startRow = 1, maxRows, uid, messageNumber ){
var list = getMessages(arguments);
return list;
}
public function getAll( string folder = "INBOX", startRow = 1, maxRows, uid, messageNumber, attachmentpath = "", generateuniquefilenames = false) {
variables.attachmentpath = arguments.attachmentpath;
variables.generateuniquefilenames = arguments.generateuniquefilenames;
var list = getMessages(arguments, true);
return list;
}
public function ListAllFolders( string folder, boolean recurse = false ){
var folders = getFolders( arguments.folder, JavaCast( "boolean", arguments.recurse ) );
var columns = "fullname,name, new, unread, totalmessages, parent, sortfolder";
var list = QueryNew(columns);
var listSorted = new Query();
var sortIndex = 10;
loop from="1" to="#ArrayLen(folders)#" step="1" index="index"{
if( folders[index].getType() != 2 ){
sortIndex = 10;
queryAddRow(list);
querySetCell(list, "fullname", folders[index].getFullName());
querySetCell(list, "name", folders[index].getName());
querySetCell(list, "new", folders[index].getNewMessageCount());
querySetCell(list, "parent", folders[index].getParent().getName());
querySetCell(list, "unread", folders[index].getUnreadMessageCount());
querySetCell(list, "totalmessages", folders[index].getMessageCount());
if (folders[index].getFullName() == "inbox") sortIndex = 1;
else if (folders[index].getFullName() == "drafts") sortIndex = 2;
else if (folders[index].getFullName() == "sent") sortIndex = 3;
else if (folders[index].getFullName() == "junk") sortIndex = 4;
else if (folders[index].getFullName() == "trash") sortIndex = 5;
querySetCell(list, "sortfolder", sortIndex );
}
}
listSorted.setDBType('query');
listSorted.setAttributes(qryimap=list);
listSorted.setSQL('select * from qryimap order by sortfolder');
return listSorted.execute().getResult();
}
public function markRead( string folder ){
var flag = CreateObject("Java", "javax.mail.Flags$Flag");
var objFolder = getFolder( arguments.folder );
objFolder.open( objFolder.READ_WRITE );
var messages = objFolder.getMessages();
loop from="1" to="#ArrayLen( messages )#" step="1" index="index"{
messages[index].setFlag(flag.SEEN, true);
}
objFolder.close(true);
return messages;
}
public function delete( string folder ){
var flag = CreateObject("Java", "javax.mail.Flags$Flag");
var objFolder = getFolder( arguments.folder );
objFolder.open( objFolder.READ_WRITE );
var messages = objFolder.getMessages();
loop from="1" to="#ArrayLen( messages )#" step="1" index="index"{
messages[index].setFlag(flag.DELETED, true);
}
objFolder.close(true);
return messages;
}
public function moveMail( required string newFolder, required string messageNumber, string folder ){
var objFolder = getFolder( arguments.folder );
var objNewFolder = getFolder( arguments.newFolder );
objFolder.open( objFolder.READ_WRITE );
var messages = objFolder.getMessages( JavaCast( "int[]", ListToArray(arguments.messageNumber)) );
objFolder.copyMessages( messages, objNewFolder );
objFolder.close(true);
return messages;
}
public function createFolder( required string folder ){
var objFolder = getFolder( arguments.folder );
objFolder.create( 3 );
return objFolder;
}
public function renameFolder( required string folder, required string newFolder ){
var objFolder = getFolder( arguments.folder );
var objNewFolder = getFolder( arguments.newFolder );
objFolder.renameTo( objNewFolder );
return objFolder;
}
public function deleteFolder( required string folder ){
var objFolder = getFolder( arguments.folder );
objFolder.delete( true );
}
private function getFolder( required string folder ){
if( !len( arguments.folder ) ){
arguments.folder = "INBOX";
}
var folder = variables.connection.getFolder( arguments.folder );
return folder;
}
private function getFolders( string folder, boolean recurse = false ){
if( !len(trim(arguments.folder)) ){
var folders = arguments.recurse ? variables.connection.getDefaultFolder().list("*") : variables.connection.getDefaultFolder().list();
}else{
var folders = arguments.recurse ? variables.connection.getFolder( arguments.folder ).list("*") : variables.connection.getFolder( arguments.folder ).list();
}
return folders;
}
private function openFolder( string folder ){
if( !structKeyExists( arguments, "folder" ) ){
var objFolder = variables.connection.getDefaultFolder();
}else{
var objFolder = variables.connection.getFolder( arguments.folder );
}
objFolder.open( objFolder.READ_ONLY );
return objFolder;
}
private function createQuery( required messages, required string columns, required boolean all=false ){
var flag = CreateObject("Java", "javax.mail.Flags$Flag");
var recipient = CreateObject("Java", "javax.mail.Message$RecipientType");
var list = QueryNew( arguments.columns );
loop from="1" to="#ArrayLen( messages )#" step="1" index="index"{
if( isNull(messages[index]) ){
continue;
}
queryAddRow(list);
querySetCell( list, "answered", messages[index].isSet(flag.ANSWERED) );
if( arguments.all ) querySetCell( list, "attachmentfiles", getFileName( messages[index] ) );
if( arguments.all ) querySetCell( list, "attachments", hasAttachments( messages[index] ) );
if( arguments.all ) querySetCell( list, "body", getHtmlBody( messages[index] ) );
querySetCell( list, "cc", IsArray( messages[index].getRecipients( recipient.CC ) ) ? ArrayToList(messages[index].getRecipients( recipient.TO )) : "" );
querySetCell( list, "deleted", messages[index].isSet(flag.DELETED) );
querySetCell( list, "draft", messages[index].isSet(flag.DRAFT) );
querySetCell( list, "flagged", messages[index].isSet(flag.FLAGGED) );
querySetCell( list, "from", messages[index].getSender().toString() );
querySetCell( list, "header", ArrayToList( createObject( "java", "java.util.Collections" ).list( messages[index].getAllHeaderLines() ) ) );
if( arguments.all ) querySetCell( list, "htmlbody", getHtmlBody( messages[index] ) );
querySetCell( list, "lines", messages[index].getLineCount() );
querySetCell( list, "messageid", messages[index].getMessageID() );
querySetCell( list, "messagenumber", messages[index].getMessageNumber() );
querySetCell( list, "recent", messages[index].isSet(flag.RECENT) );
querySetCell( list, "replyto", ArrayToList(messages[index].getReplyTo()) );
querySetCell( list, "rxddate", messages[index].getReceivedDate() );
querySetCell( list, "seen", messages[index].isSet(flag.SEEN) );
querySetCell( list, "sentDate", messages[index].getSentDate() );
querySetCell( list, "size", messages[index].getSize() );
querySetCell( list, "subject", messages[index].getSubject() );
if( arguments.all ) querySetCell( list, "textbody", getText( messages[index] ) );
querySetCell( list, "to", IsArray( messages[index].getRecipients( recipient.TO ) ) ? ArrayToList(messages[index].getRecipients( recipient.TO )) : messages[index].getRecipients( recipient.TO ) );
querySetCell( list, "uid", messages[index].getFolder().getUID( messages[index] ) );
if( arguments.all ) querySetCell( list, "user", messages[index].isSet(flag.USER) );
}
return list;
}
private function savePartAttachment( required messagepart ){
var fileCheckCount = 1;
if ((compareNoCase( arguments.messagepart.getDisposition(), arguments.messagepart.ATTACHMENT ) || compareNoCase( arguments.messagepart.getDisposition(), arguments.messagepart.INLINE ) ) and len(trim(arguments.messagepart.getFileName())) ) {
if (!len(trim(variables.attachmentpath))) throw "Need attachmentpath in order to save attachments.";
var saveFileAs = trim(arguments.messagepart.getFileName());
if (variables.generateuniquefilenames) {
var fileExt = trim(listLast(saveFileAs, "."));
if (trim(listFirst(saveFileAs, ".")) eq "" or fileExt eq "" or REFindNoCase("[^a-z0-9-_ \.]", saveFileAs)) throw "File name is suspicious.";
while ( fileExists(variables.attachmentpath & saveFileAs) ) {
saveFileAs = trim(arguments.messagepart.getFileName());
saveFileAs = REReplaceNoCase(saveFileAs, "\.#fileExt#$", "") & "-#fileCheckCount++#." & fileExt;
}
}
arguments.messagepart.saveFile( variables.attachmentpath & saveFileAs );
return variables.attachmentpath & saveFileAs;
}
return "";
}
private function getFileName( required message ){
if( !hasAttachments(arguments.message) ) {
return "";
}
var fileName = [];
var savedAttachment = "";
var multiPart = arguments.message.getContent();
for ( i=0; i LT multiPart.getCount(); i++ ) {
var bodyPart = multiPart.getBodyPart( i );
if ( bodyPart.isMimeType( "multipart/*" ) ) {
for ( fa=0; fa LT bodyPart.getContent().getCount(); fa++ ) {
var attachPart = bodyPart.getContent().getBodyPart(fa);
savedAttachment = savePartAttachment( attachPart );
if (savedAttachment neq "") fileName.append( savedAttachment );
}
}
else {
savedAttachment = savePartAttachment( bodyPart );
if (savedAttachment neq "") fileName.append( savedAttachment );
}
}
return fileName.toList(chr(9));
}
private function getText( required message ){
if ( arguments.message.isMimeType( "multipart/*" ) ) {
var multiPart = arguments.message.getContent();
for ( i=0; i LT multiPart.getCount(); i++ ) {
var bodyPart = multiPart.getBodyPart( i );
if( bodyPart.isMimeType("text/plain") ){
return bodyPart.getContent();
}
}
}
}
private function getHtmlBody( required message ){
if ( arguments.message.isMimeType( "multipart/*" ) ) {
var multiPart = arguments.message.getContent();
for ( i=0; i LT multiPart.getCount(); i++ ) {
var bodyPart = multiPart.getBodyPart( i );
if ( bodyPart.isMimeType( "text/html" ) ) {
return bodyPart.getContent();
}
}
}
return "";
}
boolean function hasAttachments( message ){
if ( arguments.message.isMimeType( "multipart/*" ) ) {
var multiPart = arguments.message.getContent();
for ( i=0; i LT multiPart.getCount(); i++ ) {
var bodyPart = multiPart.getBodyPart( i );
if (compareNoCase( bodyPart.getDisposition(), bodyPart.ATTACHMENT ) || compareNoCase( bodyPart.getDisposition(), bodyPart.INLINE ) ) {
return true;
}
}
}
return false;
}
public any function getMessages( struct attr, boolean getAll = false ) {
var messages = [];
var columns = "answered, cc, deleted, draft, flagged, from, header, lines, messageid,
messagenumber, recent, replyto, rxddate, seen, sentDate, size, subject, to, uid";
var objFolder = getFolder( arguments.attr.folder );
objFolder.open( objFolder.READ_ONLY );
if( structKeyExists( arguments.attr, "uid" ) and len(trim(arguments.attr.uid)) ) {
var messages = objFolder.getMessagesByUID( listToArray(arguments.attr.uid) );
}elseif( structKeyExists( arguments.attr, "messageNumber") and len(trim(arguments.attr.messageNumber)) ){
var messages = objFolder.getMessage( arguments.attr.messageNumber );
}elseif( !structKeyExists( arguments.attr, "maxRows") or (objFolder.getMessageCount() lt arguments.attr.startRow)){
var messages = objFolder.getMessages();
}else{
var messages = objFolder.getMessages( arguments.attr.startRow, arguments.attr.startRow + arguments.attr.maxRows - 1 );
}
if( arguments.getAll ){
columns = ListAppend( columns, "attachmentfiles, attachments, body, htmlbody, textbody, user", "," );
}
var list = createQuery( messages, columns, arguments.getAll );
objFolder.close( false );
return list;
}