Web Trenches

Connecting to Gmail using ColdFusion



Do you want to build an integrated ColdFusion interface to Gmail?  Using newbish's IMAP CFC client, it can be done.  It just needs a couple modifications to work with Gmail's SLL IMAP.  

Here's how…

1. Enable IMAP in your Gmail account
2. Download the IMAP CFC from SourceForge.
3. Make the following modifications to the imap.cfc

  • On line 7, add this… <cfset this.sslenabled = 0 />
  • At the end of the init() function, add this…
            <cfif isdefined("arguments.ssl")>
                <cfset this.sslenabled = 1 />
            </cfif>
  • Replace the GetStore() function with this one…
        <cffunction name="GetStore" access="private" output="No">
            <cftry>
            <cfset clsSession = createObject("Java", "javax.mail.Session")>
            <cfset objProperties = createObject("Java", "java.util.Properties")>
            <cfset objStore = createObject("Java", "javax.mail.Store")>
            <cfset Timeout = this.imapTimeout * 1000>
            <cfif this.sslenabled>
                <cfset protocol = "imaps">
            <cfelse>
                <cfset protocol = "imap">
            </cfif>
            <cfset objProperties.init()>
            <cfset objProperties.put("mail.store.protocol", protocol)>
            <cfset objProperties.put("mail.imap.port", this.imapPort)>
            <cfset objProperties.put("mail.imap.connectiontimeout", Timeout)>
            <cfset objProperties.put("mail.imap.timeout", Timeout)>
            <cfset objSession = clsSession.getInstance(objProperties)>
            <cfset objStore = objSession.getStore()>
            <cfset objStore.connect(this.imapServer, this.username, this.password)>
            <cfcatch type="any">
                You do not have a mail account or there was a problem authenticating.<cfabort>
            </cfcatch>
            </cftry>
            <cfreturn objStore>
        </cffunction>

You can now use the CFC library to interface with Gmail's IMAP.  Just make sure to pass the right arguments into the init function – The port has to be 993 for Gmail, and argument 6 should be a 1 (ssl enabled).  The CFC will still work for non-SSL IMAP calls if you want to use it. Just pass a 0 in argument 6.

Here's an example for Gmail…

<!— Written by Jason Quatrino, Hamilton College // —>
<cfset imapCFC = CreateObject("component","imap") />
<cfset imapInit = imapCFC.Init(username,password,"imap.gmail.com",993,15,1) /><!— add your own username/password —>
<!— determine which message ids to get —>
<cfset msgs = imapCFC.list("Inbox") />
<!— Return a query of messages —>
<cfdump var="#msgs#" />

If you have a TON of e-mail in your Gmail Inbox, you might want to modify this code before you run it.  Something like this… pass in just a few message IDs in the second argument of the list function.  I can share more code if people are interested, but I don't have permission from "newbish" to post the whole CFC.

49 Replies to “Connecting to Gmail using ColdFusion”

  1. Line 10 on my imap.cfc is a bunch of comments. The cfcomponent tag doesn’t start until line 68. Can you be more specific as to where the cfif isdefined(“arguments.ssl”) line is supposed to go?

    Does it go anywhere in the init function?

    thanks

  2. Ryan, I’m not sure where you got the copy of imap.cfc you are using, but the current version (1.0) does not have any comments at the top.

    Here’s a little more detail on locations.


    This goes in with the other cfset tags just after the opening cfcomponent tag.




    These lines should go at the end of the init function, just before the closing cffunction tag.

  3. I got my imap.cfc from here: http://www.opensourcecf.com/CFOpenMail/imapcfc_view.cfm

    Which appears to be completely different…

    Anyway I used the other one and now I’ve got it working – awesome! But it seems very slow… When I call list() it appears to get all the messages in the account! How can that be usable? I have 1000’s of messages in my gmail, don’t most people?

    thanks.

    (Arg – I’ve tried to post this three times now and can’t get past your captcha – you should try WordPress – 0 spam without captchas)

  4. Sorry about the captcha. I need to switch that out for something. When WordPress reprograms everything in CF, I will switch. πŸ™‚ For now, I can swap out the captcha for the built-in CF8 method – at some point.

    For your list problem, the solution is posted above.

    Run the count() function first to get the number of messages, then only retrieve the first X messages by using the list() function and passing in the message IDs.

  5. Sorry about the double post – I refreshed the page to see if you had responded, and it posted my comment again! (I could plug WordPress again because it won’t do that, but I won’t…)

    Ok – I didn’t think the count() method would work, because it just returns a count, not message IDs. Now I see that the message IDs are just incrementing numbers, so you can just fetch numbers within the range of 1 to count(). The message ids are not unique to a message – this is not good! There is no way to ensure integrity this way… it may be a problem with the imap protocol, I don’t know. But when you list out 100 messages, and the user clicks the delete icon next to message 55, you have no way of knowing if message 55 is still the same message it was when you loaded the list 2 minutes ago.

  6. Ryan – I understand your logic on this, but that is not how it works for us. I’ll get you more details after I dig in further, but I just ran a test in our portal, and it does delete the correct message even when a new message has arrived since page load.

  7. Thanks for the replies Michael.

    I don’t think there will be a problem deleting after new messages have come in, as you said. But there will be if any of the *older* messages are changed, like moved to a different folder or deleted (by another imap session). Probably an unlikely senario, but still – even POP uses unique message identifiers to prevent things like this from happening.

    Do you know if there is any documentation for imap.cfc? I’m having trouble, there aren’t even hints in the argument tags.

    For example, when I delete a message, what is the “value” argument for? Its required, but I don’t know what to pass in.

    Thanks.

  8. When I try to delete a message using the “delete” function, I get: “folder cannot contain messages”. I don’t get it, I’m not trying to delete a folder… at least I don’t think thats what this method is for, since it takes a MessageNumber as one of the arguments.

    Arg, Michael how do you use this thing without any documentation? Lots of trial and error? πŸ™‚

  9. I can’t get this to work. It get the spinning wheel of death. I have double and triple checked by username and password but i don’t get results nor an error page.

    Has this happened to anyone else?

  10. I can’t get this to work. It get the spinning wheel of death. I have double and triple checked by username and password but i don’t get results nor an error page.

    Has this happened to anyone else?

  11. Does anyone know how to get a list all folders in an IMAP-account using imap.cfc? Have tried just about every method and seen every error message possible.

    πŸ™‚

  12. Thank you so much for replying Jason.

    Tried that, but keep getting the Error: “folder cannot contain messages” on line 61 of imap.cfc when passing / as folder-argument to the function.

    πŸ™‚
    Christian

  13. Christian, try submitting the folderlist() method without any arguments. This will return all folders.

    Also, I believe that the folderlist() ‘folder’ argument should be a folder name, which likely explains the error you’ve described.

  14. Is there a way to fetch address book or contact list from gmail account? Anyone would like to comment on this. Thanks

  15. Hi Michael,
    Isn’t it right that this would be necessary to add to line 15?

    Also, your code mod above is returning the first ten messages in my inbox (from five years ago), not the ten most recent.
    Thanks for making this post! It’s already very useful for me.

  16. Try this for the most recent 10:


    imapCFC = CreateObject(“component”,”imap.imap”);
    imapInit = imapCFC.Init(“#mail_accts[i][“email”]#”,”#mail_accts[i][“pw”]#”,”imap.gmail.com”,993,15,1);

    foldername = “Inbox”;
    limit = “10”;
    msgIDs = “”;

    // Get a count of messages in the folder
    msgcount = imapCFC.count(foldername);

    // Determine how many messages to get
    if (msgcount LTE limit)
    from=1;
    else
    from=msgcount – limit;

    // Build list of message ids
    for(i=from;i lte msgcount;i=i+1)
    msgIDs = ListAppend(msgIDs,i);

    // Get headers for message id list
    msgs = imapCFC.list(foldername,msgIDs);


  17. This is not an error that is being displayed by imap.cfc. It must be coming from something external to the CFC. Check one of the following…

    1. IMAP is enabled in your Gmail account settings.
    2. The port you are using for IMAP is not blocked by your network or local firewall.

    Also, what version of CF are you running. This has only been tested with 7 and 8. I supposed it is possible that the underlying java libraries of older versions do not support imaps.

  18. My hosting provider says port 993 is blocked due to security reasons πŸ™ Is there anyway around this?

  19. I get the same messager “No provider for imaps ”
    ColdFusion 7 is running on localhost with no changes to the default setting. Firewall is off!

    Any suggestion?

  20. Two things to check…

    1. Make sure IMAP is enabled in your Gmail account, under Settings.

    2. As an experiment, try setting up a mail client on the server and checking your Gmail using IMAP. If that doesn’t work either, then something on your network is blocking the IMAP port or server.

    One additional note… soon-to-be released ColdFusion 9 has a CFIMAP tag and can be used to connect to Gmail.

  21. 1. IMAP is enabled in gmail. I can pick up mails using outlook express and IMAP.

    2.I dont understand what you mean by setting up a mail client on the server. Is this what we are trying to do in the first place?

    Network should be fine since outlook works from the same server(my laptop).

    Another thing, when I this.sslenabled=0, I never get any response, firefox shows “loading…” at page title forever. I get the error message “No provider for imaps ” when I this.sslenabled=1 immediately.

  22. @Amir – What type of server are you running this on? Windows/Linux/Mac? Are you able to remote into it and run a mail client at the desktop? This is the test I was referring to. If the mail client can connect from the server’s desktop, then ColdFusion should be able to as well.

    We have this CFC running, as above, on several Windows servers with CF7 or CF8. I have not tested it in other environments, so others in this comment thread may have to step in and let you know if that works. It SHOULD work, since it is just Java, but it has not been tested.

  23. Well this is very interesting indeed.Would love to read a little more of this. Great post. Thanks for the heads-up…This blog was very informative and knowledgeable

  24. Guys,

    I am having a problem when I use getFolderlist(),
    It goes on well until the getFolder() method is called from openFolder(), It gives me an error :

    The getFolder method was not found.
    Either there are no methods with the specified method name and argument types, or the getFolder method is overloaded with argument types that ColdFusion cannot decipher reliably. ColdFusion found 0 methods that matched the provided arguments. If this is a Java object and you verified that the method exists, you may need to use the javacast function to reduce ambiguity.

    Please Help!!

  25. If you cfdump the arguments.objStore variable in OpenFolder() what do you see? Is the getFolder method available?

    If the getFolder() method isn’t available you may be having problems with your objStore. Also, what is the name of the folder you’re trying to open? Any special characters?

  26. I just want to load only unread mail in inbox with the use on ‘listMessages’ Method, without loading all mail of inbox.

    Any solution??

  27. Nirav,

    I think you’ll want to run a query of queries against the result set from list() as follows:


    SELECT *
    FROM messages
    WHERE seen = 0

  28. Thanks Jason
    But it’s take more time when there are thousands of mails in the account and only few of them are unread. I don’t want to load all read mails.

    And also I can’t find the method for listing all folders, such as ‘listAllFolders’ method of cfimap tag.

  29. can someone help me?? I keep getting a Connection timed out: connect; nested exception is: java.net.ConnectException: Connection timed out: connect

    even try the pop3 but getting the same so Im assuming it must be my server?

  30. Pat, are you sure your connection information (server, username, password, and port are correct? You can also try increasing your timeout. It’s the 5th argument in the init(). If it’s an SSL connection, make sure the sixth argument is 1.

  31. The Imap.cfc for retriving the mails from IMAP mail account is taking more time if the inbox contains thousands of mails.
    Any method is there in the imap.cfc for retriving only un read mail headers
    How to reduce the time taken for reading the mail headers using Imap.cfc

    Thanking you

  32. I need to check gmail and forward to a tech support inbox as a scheduled job at regular intervals overnight. Can I use the cfc to do that with some tweaking or do I need another piece using cfmail? Suggestions are appreciated!

Leave a Reply

Your email address will not be published. Required fields are marked *