I assume you've solved this until now, but I was struggling with Google's API for a while and, of course, looked for help here, so I guess this answer could help others.
Your code looks fine, so I assume the problem is after getting the message details, when trying to retrieve the attachments. A weird thing I noticed when dealing with the attachments is that the attachment_id is not consistent and changes with different calls to the message details, so instead of using that as identifier, I decided to go with the part_id, which doesn't change. So, after getting the payload, I do this:
$messageDetails = $message->getPayload();
foreach ($messageDetails['parts'] as $key => $value) {
if (!isset($value['body']['data'])) {
array_push($files, $value['partId']);
}
}
Now, you have the ids of the parts including the attachments in your message. Next, you want to get all possible details for the attachments, so you can reconstruct the files and enable download. You'd need the filename and other details that are only returned with the message details and the attachment data, that is returned as part of the attachment details.
I'm pasting the getAttachment function as a whole.
public function getAttachment($messageId, $partId)
{
try {
$files = [];
$gmail = new Google_Service_Gmail($this->authenticate->getClient());
$attachmentDetails = $this->getAttachmentDetailsFromMessage($messageId, $partId);
$attachment = $gmail->users_messages_attachments->get($this->authenticate->getUserId(), $messageId, $attachmentDetails['attachmentId']);
if (!$attachmentDetails['status']) {
return $attachmentDetails;
}
$attachmentDetails['data'] = $this->base64UrlDecode($attachment->data);
return ['status' => true, 'data' => $attachmentDetails];
} catch (\Google_Service_Exception $e) {
return ['status' => false, 'message' => $e->getMessage()];
}
}
The list of attachments (you already have the $messageId and $files is the array of partIds we got above):
if(!empty($files)) {
foreach ($files as $key => $value) {
echo '<a target="_blank" href="attachment.php?messageId='.$messageId.'&part_id='.$value.'">Attachment '.($key+1).'</a><br/>';
}
}
And when the user opens the attachment.php:
$attachment = $msgs->getAttachment($_GET['messageId'],$_GET['part_id']);
foreach ($attachment['data']['headers'] as $key => $value) {
header($key.':'.$value);
}
echo $attachment['data']['data'];
This will set the headers based on the attachment details and download the file in the right format.
Their API is pretty straightforward but they don't provide enough examples, so it's easy to get stuck with something. I know I did :). Working on this, I created a wrapper for Gmail's API, so in case you find it useful, here - https://packagist.org/packages/adevait/gmail-wrapper.