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

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?

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.

Related

How do I use ResponseEntity<Mono<String>> to do a get call via webclient?

Documentaion says:-
ResponseEntity<Mono> or ResponseEntity<Flux> -- this makes the response status and headers known immediately while the body is provided asynchronously at a later point. Whether the body is Mono or Flux depends on how many values the response has.
My usecase is I want the headers right away so that I can do some processes while I wait for the body.
Can anyone help me with a method that would make use of this ?

Handling of List-Unsubscribe callbacks on server

When adding 'List-Unsubscribe' email headers, what kind of handling is required on the server-side for the callbacks?
It's possible to add both a mailto-link and a web-link to the header, in PHPMailer it could look like this:
$email->AddCustomHeader("List-Unsubscribe: <mailto:unsubscribe#example.com?subject=Unsubscribe>, <http://example.com/unsubscribe.php?unsubscribeid=$id>");
But does the mailto-address have to somehow automatically handle the unsubscription, or is it okay if the request just goes to an inbox that is frequently checked by a list administrator who manually processes the unsubscribe-requests?
And what about the web-link? Does it have to point to a script that will unsubscribe the recipient there and then, or can it just point to the webpage with an unsubscribe form?
You can handle this how you like, however, you should also be aware of the List-Unsubscribe-Post header (defined in RFC8058) too, as it makes you far less prone to accidental unsubscribes caused by mail scanners.
I'd really recommend processing these automatically. It's not that difficult. The URLs in list-unsubscribe should be entirely self-contained, that is, you should embed all the data you need (for example a hash of a unique user identifier, and a mailing list ID) into the URLs, so for HTTP you might use:
'<https://www.example.com/listunsub/' . $userid .'/' . $listid . '>'
You could configure a rewrite in your web server to map that URL pattern to appropriate vars in your PHP script and do the necessary database operations to remove them from the mailing list.
For email it's a bit different:
'<mailto:listunsub-' . userid . '-' . $listid . '#example.com .'>'
For this last format you would configure your mail server to spot the 'listunsub-' prefix and use that to pipe the message into a script which could extract the user and list IDs. Notice that you don't need a subject or a message body - the address itself contains all you need, and that means that a receiver doesn't have to write a message - their mail client can simply send an empty message to the address and you will have enough info to work with.

poplib mark as seen

I am using poplib in Python 3.3 to fetch emails from a gmail account and everything is working well, except that the mails are not marked as read after retrieving them with the retr() method, despite the fact that the documentation says "Retrieve whole message number which, and set its seen flag."
Here is the code:
pop = poplib.POP3_SSL("pop.gmail.com", "995")
pop.user("recent:mymail#gmail.com")
pop.pass_("mypassword")
numMessages = len(pop.list()[1])
for i in range(numMessages):
for j in pop.retr(i+1)[1]:
print(j)
pop.quit()
Am I doing something wrong or does the documentation lie? (or, did I just misinterpret it?)
The POP protocol has no concept of "read" or "unread" messages; the LIST command simply shows all existing messages. You may want to use another protocol, like IMAP, if the server supports it.
You could delete messages after successful retrieval, using the DELE command. Only after a successful QUIT command will the server actually delete them.

Post a text request in Casablanca (C++ REST SDK)

I am writing a client side code in Visual C++ 2012 using C++ Rest SDK (codename "Casablanca").
I have a client created and wish to POST a text string to the server. However, when I send the following code, it is compiling but not sending sending the request.
When I remove everything after "methods::POST" and send a blank post request, then it is sent and received by the server.
Can you please guide me where the problem is. The documentation related to this function is available on Casablanca Documentation.
pplx::task<http_response>resp = client.request(methods::POST,L"",L"This is the random text that I wish to send", L"text/plain");
I think the usage you give here looks correct.
Is your Casablanca the latest version ? Please check that out from here : http://casablanca.codeplex.com/
If you are sure your measurement is accurate, you may want to create a minimal repro and file a bug here : http://casablanca.codeplex.com/workitem/list/basic
I was having a similar problem, all my POSTs was arriving in blank on server , after a few hours work above it, i found a possible solution.
I changed the default content type to application/x-www-form-urlencoded and I started to pass the values like this Example data=text1&data2=text2
client.request(methods::POST,L"",L"data=text1&data2=text2", L"application/x-www-form-urlencoded");
The body parameter must be a json::value.
I cannot comment yet so I have to put my thoughts in an answer. I solved this problem like this: There is an overload of the request method that takes as a parameter the content type so that you do not have to change the code.
m_client->request(methods::POST, L"/statuses/update.json?" + url_encode(data),L"",L"application/x-www-form-urlencoded");
Obviously you would have to implement the url_encode method but that is not difficult. There is a pretty good implementation in "Cassablanca". A search on this site will alos turn up some good examples.

pyramid: constructe route_url without request object

I use yapps to generate a parser for a LaTex-ish language (for example to translate stuff like \begin{itemize} to the corresponding <ul>-Tags) within pyramid. One command (i.e. \ref{SOMEID}) should construct a route via a call of route_url (or route_path) and pass the id to it. Since this call happens deep in the code that was generated by yapps and the grammar that I defined, I don't see any possibility to pass a request object to it.
Is there some sort of global request object? Or, since I foresee that I shouldn't use it, is there a possibility to construct a route (that depends on a parameter) without a request object?
route_url requires both a request and a registry (request.registry). It generates urls relative to the request, and it accesses the list of all routes and other settings from the registry. Thus, you must generate a dummy request with parameters you care about. For example:
from pyramid.request import Request
request = Request.blank('/', base_url='https://example.com/prefix')
request.registry = config.registry
Now you can store this request anywhere, it's good to go representing everything about your site: the hostname/port (example.com:443), the prefix your app is mounted at (/prefix), the uri scheme (https).
If you need to get this deep down into your code you may have to make it a global or attach it to some context/registry that you have available, but what I've shown is how to make the request that you require.

Resources