correos - phpmailer gmail
No se puede obtener el cuerpo del correo electrónico con la API de PHP de Gmail (6)
Tengo problemas con la API de PHP de Gmail.
¡Quiero recuperar el contenido del cuerpo de los correos electrónicos, pero puedo recuperarlo solo para los correos electrónicos que tienen archivos adjuntos! Mi pregunta es por qué
Aquí está mi código hasta ahora:
// 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;
}
}
La segunda opción para recuperar contenido que conozco es mediante el uso del fragmento ubicado en la parte Encabezados , pero solo recupera los 50 primeros caracteres, lo que no es muy útil.
Una solución simple y robusta
No estaba satisfecho con las otras respuestas porque todas son defectuosas (elaboración en spoiler), y algunas son largas y están mezcladas con características que el autor de la pregunta (y yo) no buscó.
Para advertirle sobre posibles problemas en otras respuestas:
sin respaldo de texto sin formato
o no tratar con el cuerpo del mensaje falsy : la cadena ''0'' (es poco probable que suceda, pero no demasiado improbable)
o falta una búsqueda lo suficientemente profunda a través de la estructura de árbol de carga útil
Así que pensé que ahorraría a otros el problema y compartiría mi código (probado en toda mi bandeja de entrada).
// input: the message object (not the payload!)
// output: html or plain text
function msg_body($msg) {
$body = msg_body_recursive($msg->payload);
return array_key_exists(''html'', $body) ? $body[''html''] : $body[''plain''];
}
function msg_body_recursive($part) {
if($part->mimeType == ''text/html'') {
return [''html'' => decodeBody($part->body->data)];
} else if($part->mimeType == ''text/plain'') {
return [''plain'' => decodeBody($part->body->data)];
} else if($part->parts) {
$return = [];
foreach($part->parts as $sub_part) {
$result = msg_body_recursive($sub_part);
$return = array_merge($return, $result);
if(array_key_exists(''html'', $return))
break;
}
return $return;
}
return [];
}
function decodeBody($encoded) {
$sanitizedData = strtr($encoded,''-_'', ''+/'');
return base64_decode($sanitizedData);
}
Como una mejora adicional, el código debe ser recursivo, también debe cargar el mensaje en formato "completo" para extraer el cuerpo. Debajo de tres funciones puedes poner en tu propia clase.
private function decodeBody($body) {
$rawData = $body;
$sanitizedData = strtr($rawData,''-_'', ''+/'');
$decodedMessage = base64_decode($sanitizedData);
if(!$decodedMessage)
return false;
return $decodedMessage;
}
private function decodeParts($parts)
{
foreach ($parts as $part)
{
if ($part->getMimeType() === ''text/html'' && $part->getBody())
if ($result = $this->decodeBody($part->getBody()->getData()))
return $result;
}
foreach ($parts as $part)
{
if ($result = $this->decodeParts($part->getParts()))
return $result;
}
}
/**
* @param Google_Service_Gmail_Message $message
* @return bool|null|string
*/
public function getMessageBody($message)
{
$payload = $message->getPayload();
if ($result = $this->decodeBody($payload->getBody()->getData()))
return $result;
return $this->decodeParts($payload->getParts());
}
Escribí este código como una mejora de la respuesta de @ ya que filtra la respuesta html correctamente.
<?php
ini_set("display_errors", 1);
ini_set("track_errors", 1);
ini_set("html_errors", 1);
error_reporting(E_ALL);
require_once __DIR__ . ''/vendor/autoload.php'';
session_start();
function decodeBody($body) {
$rawData = $body;
$sanitizedData = strtr($rawData,''-_'', ''+/'');
$decodedMessage = base64_decode($sanitizedData);
if(!$decodedMessage){
$decodedMessage = FALSE;
}
return $decodedMessage;
}
function fetchMails($gmail, $q) {
try{
$list = $gmail->users_messages->listUsersMessages(''me'', array(''q'' => $q));
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''] && $part[''mimeType''] == ''text/html'') {
$FOUND_BODY = decodeBody($part[''body'']->data);
break;
}
}
} if(!$FOUND_BODY) {
foreach ($parts as $part) {
// 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 . " <br> <br> <br> *-*-*- " . $FOUND_BODY);
}
if ($list->getNextPageToken() != null) {
$pageToken = $list->getNextPageToken();
$list = $gmail->users_messages->listUsersMessages(''me'', array(''pageToken'' => $pageToken));
} else {
break;
}
}
} catch (Exception $e) {
echo $e->getMessage();
}
}
$client = new Google_Client();
$client->setAuthConfig(''client_secrets.json'');
$client->addScope(Google_Service_Gmail::GMAIL_READONLY);
if (isset($_SESSION[''access_token'']) && $_SESSION[''access_token'']) {
$client->setAccessToken($_SESSION[''access_token'']);
$gmail = new Google_Service_Gmail($client);
$q = '' after:2016/11/7'';
fetchMails($gmail, $q);
} else {
$redirect_uri = ''http://'' . $_SERVER[''HTTP_HOST''] . ''/gmail-api/oauth2callback.php'';
header(''Location: '' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
Hagamos un pequeño experimento. Me he enviado dos mensajes a mí mismo. Uno con un archivo adjunto y otro sin él.
Solicitud:
GET https://www.googleapis.com/gmail/v1/users/me/messages?maxResults=2
Respuesta:
{
"messages": [
{
"id": "14fe21fd6b3fb46f",
"threadId": "14fe21fd6b3fb46f"
},
{
"id": "14fe21f9341ed73c",
"threadId": "14fe21f9341ed73c"
}
],
"nextPageToken": "08943597140129624594",
"resultSizeEstimate": 3
}
Solo pido la carga útil, ya que ahí es donde están todas las partes relevantes:
fields = payload
GET https://www.googleapis.com/gmail/v1/users/me/messages/14fe21fd6b3fb46f?fields=payload
GET https://www.googleapis.com/gmail/v1/users/me/messages/14fe21f9341ed73c?fields=payload
Correo sin adjunto:
{
"payload": {
"parts": [
{
"partId": "0",
"mimeType": "text/plain",
"filename": "",
"headers": [
{
"name": "Content-Type",
"value": "text/plain; charset=UTF-8"
}
],
"body": {
"size": 22,
"data": "aGVjaz8gTm8gYXR0YWNobWVudD8NCg=="
}
},
{
"partId": "1",
"mimeType": "text/html",
"filename": "",
"headers": [
{
"name": "Content-Type",
"value": "text/html; charset=UTF-8"
}
],
"body": {
"size": 43,
"data": "PGRpdiBkaXI9Imx0ciI-aGVjaz8gTm8gYXR0YWNobWVudD88L2Rpdj4NCg=="
}
}
]
}
}
Correo con archivo adjunto:
{
"payload": {
"parts": [
{
"mimeType": "multipart/alternative",
"filename": "",
"headers": [
{
"name": "Content-Type",
"value": "multipart/alternative; boundary=001a1142e23c551e8e05200b4be0"
}
],
"body": {
"size": 0
},
"parts": [
{
"partId": "0.0",
"mimeType": "text/plain",
"filename": "",
"headers": [
{
"name": "Content-Type",
"value": "text/plain; charset=UTF-8"
}
],
"body": {
"size": 9,
"data": "V293IG1hbg0K"
}
},
{
"partId": "0.1",
"mimeType": "text/html",
"filename": "",
"headers": [
{
"name": "Content-Type",
"value": "text/html; charset=UTF-8"
}
],
"body": {
"size": 30,
"data": "PGRpdiBkaXI9Imx0ciI-V293IG1hbjwvZGl2Pg0K"
}
}
]
},
{
"partId": "1",
"mimeType": "image/jpeg",
"filename": "feelthebern.jpg",
"headers": [
{
"name": "Content-Type",
"value": "image/jpeg; name=/"feelthebern.jpg/""
},
{
"name": "Content-Disposition",
"value": "attachment; filename=/"feelthebern.jpg/""
},
{
"name": "Content-Transfer-Encoding",
"value": "base64"
},
{
"name": "X-Attachment-Id",
"value": "f_ieq3ev0i0"
}
],
"body": {
"attachmentId": "ANGjdJ_2xG3WOiLh6MbUdYy4vo2VhV2kOso5AyuJW3333rbmk8BIE1GJHIOXkNIVGiphP3fGe7iuIl_MGzXBGNGvNslwlz8hOkvJZg2DaasVZsdVFT_5JGvJOLefgaSL4hqKJgtzOZG9K1XSMrRQAtz2V0NX7puPdXDU4gvalSuMRGwBhr_oDSfx2xljHEbGG6I4VLeLZfrzGGKW7BF-GO_FUxzJR8SizRYqIhgZNA6PfRGyOhf1s7bAPNW3M9KqWRgaK07WTOYl7DzW4hpNBPA4jrl7tgsssExHpfviFL7yL52lxsmbsiLe81Z5UoM",
"size": 100446
}
}
]
}
}
Estas respuestas corresponden a las
$parts
en su código.
Como puede ver, si tiene suerte,
$parts[0][''body'']->data
le dará lo que desea, pero la mayoría de las veces no lo hará.
Generalmente hay dos enfoques para este problema. Podrías implementar el siguiente algoritmo (eres mucho mejor en PHP que en mí, pero este es el resumen general):
-
Atraviese
payload.parts
y compruebe si contiene unapart
que tenga el cuerpo que estaba buscando (ya seatext/plain
otext/html
). Si es así, ha terminado con su búsqueda. Si estaba analizando un correo como el anterior sin adjunto, esto sería suficiente. -
Vuelva a realizar el paso 1, pero esta vez con las
parts
encuentran dentro de lasparts
que acaba de verificar, de forma recursiva. Eventualmente encontrarás tupart
. Si estaba analizando un correo como el de arriba con un archivo adjunto, eventualmente encontraría subody
.
El algoritmo podría parecerse a lo siguiente (ejemplo en JavaScript):
var response = {
"payload": {
"parts": [
{
"mimeType": "multipart/alternative",
"filename": "",
"headers": [
{
"name": "Content-Type",
"value": "multipart/alternative; boundary=001a1142e23c551e8e05200b4be0"
}
],
"body": {
"size": 0
},
"parts": [
{
"partId": "0.0",
"mimeType": "text/plain",
"filename": "",
"headers": [
{
"name": "Content-Type",
"value": "text/plain; charset=UTF-8"
}
],
"body": {
"size": 9,
"data": "V293IG1hbg0K"
}
},
{
"partId": "0.1",
"mimeType": "text/html",
"filename": "",
"headers": [
{
"name": "Content-Type",
"value": "text/html; charset=UTF-8"
}
],
"body": {
"size": 30,
"data": "PGRpdiBkaXI9Imx0ciI-V293IG1hbjwvZGl2Pg0K"
}
}
]
},
{
"partId": "1",
"mimeType": "image/jpeg",
"filename": "feelthebern.jpg",
"headers": [
{
"name": "Content-Type",
"value": "image/jpeg; name=/"feelthebern.jpg/""
},
{
"name": "Content-Disposition",
"value": "attachment; filename=/"feelthebern.jpg/""
},
{
"name": "Content-Transfer-Encoding",
"value": "base64"
},
{
"name": "X-Attachment-Id",
"value": "f_ieq3ev0i0"
}
],
"body": {
"attachmentId": "ANGjdJ_2xG3WOiLh6MbUdYy4vo2VhV2kOso5AyuJW3333rbmk8BIE1GJHIOXkNIVGiphP3fGe7iuIl_MGzXBGNGvNslwlz8hOkvJZg2DaasVZsdVFT_5JGvJOLefgaSL4hqKJgtzOZG9K1XSMrRQAtz2V0NX7puPdXDU4gvalSuMRGwBhr_oDSfx2xljHEbGG6I4VLeLZfrzGGKW7BF-GO_FUxzJR8SizRYqIhgZNA6PfRGyOhf1s7bAPNW3M9KqWRgaK07WTOYl7DzW4hpNBPA4jrl7tgsssExHpfviFL7yL52lxsmbsiLe81Z5UoM",
"size": 100446
}
}
]
}
};
// In e.g. a plain text message, the payload is the only part.
var parts = [response.payload];
while (parts.length) {
var part = parts.shift();
if (part.parts) {
parts = parts.concat(part.parts);
}
if(part.mimeType === ''text/html'') {
var decodedPart = decodeURIComponent(escape(atob(part.body.data.replace(//-/g, ''+'').replace(//_/g, ''/''))));
console.log(decodedPart);
}
}
La opción mucho más fácil es obtener los datos sin procesar del correo y dejar que una biblioteca ya escrita haga el trabajo por usted:
Solicitud:
format = raw
fields = raw
GET https://www.googleapis.com/gmail/v1/users/me/messages/14fe21fd6b3fb46f?format=raw&fields=raw
Respuesta:
{
"raw": "TUlNRS1WZXJzaW9uOiAxLjANClJlY2VpdmVkOiBieSAxMC4yOC45OS4xOTYgd2l0aCBIVFRQOyBGcmksIDE4IFNlcCAyMDE1IDEzOjIzOjAxIC0wNzAwIChQRFQpDQpEYXRlOiBGcmksIDE4IFNlcCAyMDE1IDIyOjIzOjAxICswMjAwDQpEZWxpdmVyZWQtVG86IGVtdGhvbGluQGdtYWlsLmNvbQ0KTWVzc2FnZS1JRDogPENBRHNaTFJ5eGk2UGt0MHZnUS1iZHd1N2FNLWNHRmZKcEwrRHYyb3ZKOGp4SGN4VWhfQUBtYWlsLmdtYWlsLmNvbT4NClN1YmplY3Q6IFdoYXQgZGENCkZyb206IEVtaWwgVGhvbGluIDxlbXRob2xpbkBnbWFpbC5jb20-DQpUbzogRW1pbCBUaG9saW4gPGVtdGhvbGluQGdtYWlsLmNvbT4NCkNvbnRlbnQtVHlwZTogbXVsdGlwYXJ0L2FsdGVybmF0aXZlOyBib3VuZGFyeT0wMDFhMTE0NjhmMTY1YzUwNDUwNTIwMGI0YzYxDQoNCi0tMDAxYTExNDY4ZjE2NWM1MDQ1MDUyMDBiNGM2MQ0KQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFyc2V0PVVURi04DQoNCmhlY2s_IE5vIGF0dGFjaG1lbnQ_DQoNCi0tMDAxYTExNDY4ZjE2NWM1MDQ1MDUyMDBiNGM2MQ0KQ29udGVudC1UeXBlOiB0ZXh0L2h0bWw7IGNoYXJzZXQ9VVRGLTgNCg0KPGRpdiBkaXI9Imx0ciI-aGVjaz8gTm8gYXR0YWNobWVudD88L2Rpdj4NCg0KLS0wMDFhMTE0NjhmMTY1YzUwNDUwNTIwMGI0YzYxLS0="
}
El mayor inconveniente del segundo método es que si obtiene el mensaje sin procesar, descargará todos los datos adjuntos de inmediato, lo que podría ser una gran cantidad de datos para su caso de uso.
No soy bueno en PHP, ¡pero this parece prometedor si quieres elegir la segunda solución! ¡Buena suerte!
Para aquellos que estén interesados, mejoré enormemente mi última respuesta, ¡haciendo que funcione con texto / html (y respaldo a texto / plano si es necesario) y transformando las imágenes como archivos adjuntos de base64 que se cargarán automáticamente cuando se impriman como HTML completo!
El código no es perfecto en absoluto y es demasiado largo para explicarlo en detalle, pero está funcionando para mí.
Siéntase libre de tomarlo y adaptarlo (quizás corregirlo / mejorarlo si es necesario).
// 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();
$parts = $payload->getParts();
// With no attachment, the payload might be directly in the body, encoded.
$body = $payload->getBody();
$FOUND_BODY = FALSE;
// If we didn''t find a body, let''s look for the parts
if(!$FOUND_BODY) {
foreach ($parts as $part) {
if($part[''parts''] && !$FOUND_BODY) {
foreach ($part[''parts''] as $p) {
if($p[''parts''] && count($p[''parts'']) > 0){
foreach ($p[''parts''] as $y) {
if(($y[''mimeType''] === ''text/html'') && $y[''body'']) {
$FOUND_BODY = decodeBody($y[''body'']->data);
break;
}
}
} else if(($p[''mimeType''] === ''text/html'') && $p[''body'']) {
$FOUND_BODY = decodeBody($p[''body'']->data);
break;
}
}
}
if($FOUND_BODY) {
break;
}
}
}
// let''s save all the images linked to the mail''s body:
if($FOUND_BODY && count($parts) > 1){
$images_linked = array();
foreach ($parts as $part) {
if($part[''filename'']){
array_push($images_linked, $part);
} else{
if($part[''parts'']) {
foreach ($part[''parts''] as $p) {
if($p[''parts''] && count($p[''parts'']) > 0){
foreach ($p[''parts''] as $y) {
if(($y[''mimeType''] === ''text/html'') && $y[''body'']) {
array_push($images_linked, $y);
}
}
} else if(($p[''mimeType''] !== ''text/html'') && $p[''body'']) {
array_push($images_linked, $p);
}
}
}
}
}
// special case for the wdcid...
preg_match_all(''/wdcid(.*)"/Uims'', $FOUND_BODY, $wdmatches);
if(count($wdmatches)) {
$z = 0;
foreach($wdmatches[0] as $match) {
$z++;
if($z > 9){
$FOUND_BODY = str_replace($match, ''image0'' . $z . ''@'', $FOUND_BODY);
} else {
$FOUND_BODY = str_replace($match, ''image00'' . $z . ''@'', $FOUND_BODY);
}
}
}
preg_match_all(''/src="cid:(.*)"/Uims'', $FOUND_BODY, $matches);
if(count($matches)) {
$search = array();
$replace = array();
// let''s trasnform the CIDs as base64 attachements
foreach($matches[1] as $match) {
foreach($images_linked as $img_linked) {
foreach($img_linked[''headers''] as $img_lnk) {
if( $img_lnk[''name''] === ''Content-ID'' || $img_lnk[''name''] === ''Content-Id'' || $img_lnk[''name''] === ''X-Attachment-Id''){
if ($match === str_replace(''>'', '''', str_replace(''<'', '''', $img_lnk->value))
|| explode("@", $match)[0] === explode(".", $img_linked->filename)[0]
|| explode("@", $match)[0] === $img_linked->filename){
$search = "src=/"cid:$match/"";
$mimetype = $img_linked->mimeType;
$attachment = $gmail->users_messages_attachments->get(''me'', $mlist->id, $img_linked[''body'']->attachmentId);
$data64 = strtr($attachment->getData(), array(''-'' => ''+'', ''_'' => ''/''));
$replace = "src=/"data:" . $mimetype . ";base64," . $data64 . "/"";
$FOUND_BODY = str_replace($search, $replace, $FOUND_BODY);
}
}
}
}
}
}
}
// If we didn''t find the body in the last parts,
// let''s loop for the first parts (text-html only)
if(!$FOUND_BODY) {
foreach ($parts as $part) {
if($part[''body''] && $part[''mimeType''] === ''text/html'') {
$FOUND_BODY = decodeBody($part[''body'']->data);
break;
}
}
}
// With no attachment, the payload might be directly in the body, encoded.
if(!$FOUND_BODY) {
$FOUND_BODY = decodeBody($body[''data'']);
}
// Last try: if we didn''t find the body in the last parts,
// let''s loop for the first parts (text-plain only)
if(!$FOUND_BODY) {
foreach ($parts as $part) {
if($part[''body'']) {
$FOUND_BODY = decodeBody($part[''body'']->data);
break;
}
}
}
if(!$FOUND_BODY) {
$FOUND_BODY = ''(No message)'';
}
// 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();
}
Salud.
ACTUALIZACIÓN: es posible que desee consultar mi segunda respuesta debajo de esta para obtener un código más completo.
Finalmente, trabajé hoy, así que aquí está la respuesta del código completo para encontrar el cuerpo, gracias a @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();
}
Como puede ver, mi problema era que, a veces, el cuerpo no se puede encontrar en la carga útil-> partes, sino directamente en la carga útil-> cuerpo . (Además, agrego el bucle para varias partes).
Espero que esto ayude a alguien más.