Search code examples
gmailimapzend-mail

Gmail IMAP via php ouath2 Zend_Mail_Protocol_Imap - getting the X-GM-THRID


I'm accessing GMail via IMAP using OAuth2 authentication and Zend_Mail_Protocol_Imap.

It all works great.

What I need to do is present emails in thread form just like the GMail interface. Google make this really easy because they have an X-GM-THRID header that links a conversation with a 64-bit unsigned integer.

My problem is: when presented with a single email, how do I find out what X-GM-THRID it belongs to?

First off Google says that there is a server extension X-GM-EXT-1 which is active. You can check it is there using the CAPABILITY command (and I have).

All the information suggests that if this is active then the X-GM-THRID will simply be returned as a header, but it isn't.

Perhaps I need to ask Google to return it via the fetch command. Google does describe a simple fetch process here:

https://developers.google.com/google-apps/gmail/imap_extensions

My code is sending TAG5 FETCH 3673 (FLAGS RFC822.HEADER X-GM-THRID) but the headers do not include an entry for X-GM-THRID.

I've even simplified it to TAG6 FETCH 3673 (X-GM-THRID) to be exactly as described in the google example. In this case no headers are returned.

I'm not massively familiar with IMAP commands and I'm not sure if Zend_Mail_Protocol_Imap is abstracting some handling which means this header is being removed.

But I do know that this is driving me mad.

Am I missing something? Is it not a header?


Solution

  • Okay, so it looks like it is not a header. It is an attribute in the IMAP command and response.

    The standard fetch command sent by Zend_Mail_Protocol_Imap is "TAG5 FETCH 3673 (FLAGS RFC822.HEADER)"

    The code that handles the response only expects to be dealing with 'FLAGS' and 'RFC822.HEADER'. It passes this information to a Zend_Mail_Message object which extends Zend_Mail_Part.

    Zend_Mail_Part parses information about flag. It also parses the header.

    The additional 'X-GM-THRID' attribute that I added does actually get a response. but since it is not passed back to Zend_Mail_Message there is no way for me to use it. It gets lost in the ether (at around line 171 of Zend_Mail_Storage_Imap in my Zend Library to be exact).

    So I've hacked the core... Zend_Mail_Storage_Imap::getMessage now expects $data['X-GM-THRID'] and passes it to the constructor Zend_Mail_Part. And I now have a method Zend_Mail_Part::getXGmThrid which solves all my problems. I'll obviously refactor them into my own classes extending Zend_Mail_Storage_Imap and Zend_Mail_Part in the not too distant... but for now I know this works.