I'm having trouble with the Gmail PHP API.
I want to retrieve the body content of emails, but I can retrieve it only for emails which have attachments! My question is why?
Here's my code so far:
// Authentication things above... $client = getClient(); $gmail = new Google_Service_Gmail($client); $list = $gmail->users_messages->listUsersMessages('me', ['maxResults' => 1000]); while ($list->getMessages() != null) { foreach ($list->getMessages() as $mlist) { $message_id = $mlist->id; $optParamsGet2['format'] = 'full'; $single_message = $gmail->users_messages->get('me', $message_id, $optParamsGet2); $threadId = $single_message->getThreadId(); $payload = $single_message->getPayload(); $headers = $payload->getHeaders(); $parts = $payload->getParts(); //print_r($parts); PRINTS SOMETHING ONLY IF I HAVE ATTACHMENTS... $body = $parts[0]['body']; $rawData = $body->data; $sanitizedData = strtr($rawData,'-_', '+/'); $decodedMessage = base64_decode($sanitizedData); //should display my body content } if ($list->getNextPageToken() != null) { $pageToken = $list->getNextPageToken(); $list = $gmail->users_messages->listUsersMessages('me', ['pageToken' => $pageToken, 'maxResults' => 1000]); } else { break; } }
The second option to retrieve content that I know is by using the snippet located in the Headers part, but it only retrieves the 50 first characters or so, which isn't very useful.
The Gmail API is a RESTful API that can be used to access Gmail mailboxes and send mail. For most web applications the Gmail API is the best choice for authorized access to a user's Gmail data and is suitable for various applications, such as: Read-only mail extraction, indexing, and backup.
UPDATE: You might want to check my second answer below this one for a more complete code.
Finally, I worked today, so here's the complete code answer for finding the body - thanks to @Tholle:
// Authentication things above /* * Decode the body. * @param : encoded body - or null * @return : the body if found, else FALSE; */ function decodeBody($body) { $rawData = $body; $sanitizedData = strtr($rawData,'-_', '+/'); $decodedMessage = base64_decode($sanitizedData); if(!$decodedMessage){ $decodedMessage = FALSE; } return $decodedMessage; } $client = getClient(); $gmail = new Google_Service_Gmail($client); $list = $gmail->users_messages->listUsersMessages('me', ['maxResults' => 1000]); try{ while ($list->getMessages() != null) { foreach ($list->getMessages() as $mlist) { $message_id = $mlist->id; $optParamsGet2['format'] = 'full'; $single_message = $gmail->users_messages->get('me', $message_id, $optParamsGet2); $payload = $single_message->getPayload(); // With no attachment, the payload might be directly in the body, encoded. $body = $payload->getBody(); $FOUND_BODY = decodeBody($body['data']); // If we didn't find a body, let's look for the parts if(!$FOUND_BODY) { $parts = $payload->getParts(); foreach ($parts as $part) { if($part['body']) { $FOUND_BODY = decodeBody($part['body']->data); break; } // Last try: if we didn't find the body in the first parts, // let's loop into the parts of the parts (as @Tholle suggested). if($part['parts'] && !$FOUND_BODY) { foreach ($part['parts'] as $p) { // replace 'text/html' by 'text/plain' if you prefer if($p['mimeType'] === 'text/html' && $p['body']) { $FOUND_BODY = decodeBody($p['body']->data); break; } } } if($FOUND_BODY) { break; } } } // Finally, print the message ID and the body print_r($message_id . " : " . $FOUND_BODY); } if ($list->getNextPageToken() != null) { $pageToken = $list->getNextPageToken(); $list = $gmail->users_messages->listUsersMessages('me', ['pageToken' => $pageToken, 'maxResults' => 1000]); } else { break; } } } catch (Exception $e) { echo $e->getMessage(); }
As you can see, my problem was, sometimes the body cannot be found in the payload->parts but directly in the payload->body! (plus I add the loop for multiple parts).
Hope this helps somebody else.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With