14

The "Try it" part documentation allows me to play the API, and the field selector allow me to select a lot of fields, e.g. header, raw, etc. But none of them actually showed up when tried the API. The only thing I saw were still just the message ID and the thread ID.

https://developers.google.com/gmail/api/v1/reference/users/messages/list

E.g. The following:

GET https://www.googleapis.com/gmail/v1/users/{user_id}/messages?**fields=messages(historyId%2Cid%2Cpayload%2Craw%2CsizeEstimate%2Csnippet%2CthreadId)**&key={YOUR_API_KEY}

Returns:

{
 "messages": [
  {
   "id": "146da54fe3dc089e",
   "threadId": "146da54fe3dc089e"
  },
  {
   "id": "146da41d9486982f",
   "threadId": "146da41d9486982f"
  },
  ...
}

But I would expect the extra fields requested are returned too.

Is there a way to get this working? I know there is a separate method to get an individual message but like to get them batch if possible.

yuklai
  • 1,595
  • 1
  • 14
  • 26

2 Answers2

9

messages.list does not return much more than just the identifiers. not sure what the field selector is but i don't believe it's used.

however you can use a batched message.get to then retrieve many messages at once in a second call:

A batch request consists of multiple API calls combined into one HTTP request. This section describes the batch syntax in detail; later, there's an example.

Note: A set of n requests batched together counts toward your usage limit as n requests, not as one request. The batch request is taken apart into a set of requests before processing.

From: https://developers.google.com/storage/docs/json_api/v1/how-tos/batch

With the Gmail API and batch here're some sample code:

GTLBatchQuery *batchQuery = [GTLBatchQuery batchQuery];

[gmailMessageIds enumerateObjectsUsingBlock:^(NSNumber *messageId, NSUInteger idx, BOOL *stop) {
    GTLQueryGmail *query = [GTLQueryGmail queryForUsersMessagesGet];
    query.userId = self.account.email;
    query.identifier = [NSString stringWithFormat:@"%llx", [messageId unsignedLongLongValue]];
    query.format = kGTLGmailFormatRaw;

    [batchQuery addQuery:query];
}];


[self.gmailService executeQuery:batchQuery completionHandler:^(GTLServiceTicket *ticket, GTLBatchResult *result, NSError *error) {
    NSArray *gmailMessages = result.successes.allValues; // This is an array of GTLGmailMessage objects
    ... 
}];
yuklai
  • 1,595
  • 1
  • 14
  • 26
Eric D
  • 6,901
  • 1
  • 15
  • 26
  • Thanks for suggesting that! There seems to be one problem with this approach though. "Note: A set of n requests batched together counts toward your usage limit as n requests, not as one request. The batch request is taken apart into a set of requests before processing." Based on that by fetching 10 messages quickly (within 1 second) would have caused me to go over the 10 request per second limit. – yuklai Jun 27 '14 at 05:22
  • Did you actually try it and go over the 10 requests/second limit or are you merely speculating? I'd go and try it before you speculate. I don't believe that limit is applied at something as short as a 1 second granularity but rather average over a little bit longer window. Feel free to reply if I'm wrong. – Eric D Jun 27 '14 at 05:44
  • Fair enough. No I haven't tried the batch yet since I'm using iOS and there is no SDK yet for the gmail API. But I did try firing 50 requests asynchronously and it starts failing after ~10th. But I will try the batch and reply back. – yuklai Jun 27 '14 at 05:55
  • Hi fatshu, iOs libraries can be found here: https://code.google.com/p/google-api-objectivec-client/source/browse/#svn%2Ftrunk%2FSource%2FServices%2FGmail%2FGenerated Hopefully will get it sorted out to be linked from docs in next few hours. Is 50 requests asynchronously and failing after ~10h unexpected? I'm unclear what you're saying. What request throughput are you maintaining (50/second?)? What's the failure (e.g. 429)? – Eric D Jun 27 '14 at 15:22
  • Thanks, I saw the library after I replied last night and is going to integrate with it now. I was firing 50 asynchronously and some of them started to timeout (as reported by NSURLConnection). I'm doing a default list on messages (which returns 50 on the first page) and I'm firing get of these messages all asynchronously. And I started to see the connection timeout. But that's as far as I could tell last night. Will check in again after I finish integrating with the SDK and do some more experiment. – yuklai Jun 27 '14 at 17:13
  • 2
    Also note that now messages.get() and threads.get() both support format=METADATA and metadataHeaders=['from', 'to', 'subject', ...] params. so when you do do the second batched get() call you can request just the things you need which should make it faster/more efficient (and we'll be updating quota soon to reflect that). – Eric D Oct 24 '14 at 17:15
0

Upon browsing the Google documentation, using the messages.get section, I was able to return all of the field values via json using the method getMessage(...).

In the original request you are given the id and threadId. Using the id we are able to return all messages by doing something like so:

ListMessagesResponse mResponse =
            service.users().messages().list(user).execute();

// This will return the json listed with the field methods id and threadId.
List<Message> messages = mResponse.getMessages();

// Parse the response
if(message.size() == 0){...}
else {
  for(Message msg: messages)
    *.getMessage(service,user,msg.getId());
}

The above is not exact code but, should provide you with an idea of how to approach this problem.

coletrain
  • 2,809
  • 35
  • 43