Google's GMail API download attachments
Firstly we need to get the data from the attachment object:
$attachmentObj = $service->users_messages_attachments->get($emailAccount, $messageId, $attachmentId);
$data = $attachmentObj->getData(); //Get data from attachment object
Then before writing to file, convert the data to standard RFC 4648 base64-encoding:
$data = strtr($data, array('-' => '+', '_' => '/'));
$myfile = fopen("excel.xlsx", "w+");;
fwrite($myfile, base64_decode($data));
fclose($myfile);
It now works!
function getAttachment($messageId, $partId, $userId)
{
try {
$client = getClient();
$gmail = new Google_Service_Gmail($client);
$message = $gmail->users_messages->get($userId, $messageId);
$message_payload_details = $message->getPayload()->getParts();
$attachmentDetails = array();
$attachmentDetails['attachmentId'] = $message_payload_details[$partId]['body']['attachmentId'];
$attachmentDetails['headers'] = $message_payload_details[$partId]['headers'];
$attachment = $gmail->users_messages_attachments->get($userId, $messageId, $attachmentDetails['attachmentId']);
$attachmentDetails['data'] = $attachment->data;
return ['status' => true, 'data' => $attachmentDetails];
} catch (\Google_Service_Exception $e) {
return ['status' => false, 'message' => $e->getMessage()];
}
}
function base64_to_jpeg($base64_string, $content_type) {
$find = ["_","-"]; $replace = ["/","+"];
$base64_string = str_replace($find,$replace,$base64_string);
$url_str = 'data:'.$content_type.','.$base64_string;
$base64_string = "url(".$url_str.")";
$data = explode(',', $base64_string);
return base64_decode( $data[ 1 ] );
}
// Get the API client and construct the service object.
$client = getClient();
$service = new Google_Service_Gmail($client);
$opt_param = array();
$opt_param['labelIds'] = 'INBOX';
$opt_param['maxResults'] = 1;
$messages = $service->users_messages->listUsersMessages($userId, $opt_param);
foreach ($messages as $message_thread) {
$message = $service->users_messages->get($userId, $message_thread['id']);
$message_parts = $message->getPayload()->getParts();
$files = array();
$attachId = $message_parts[1]['body']['attachmentId'];
$attach = $service->users_messages_attachments->get($userId, $message['id'], $attachId);
foreach ($message_parts as $key => $value) {
if ( isset($value->body->attachmentId) && !isset($value->body->data)) {
array_push($files, $value['partId']);
}
}
}
if(isset($_GET['messageId']) && $_GET['part_id']){ // This is After Clicking an Attachment
$attachment = getAttachment($_GET['messageId'], $_GET['part_id'], $userId);
$content_type = "";
foreach ($attachment['data']['headers'] as $key => $value) {
if($value->name == 'Content-Type'){ $content_type = $value->value; }
header($value->name.':'.$value->value);
}
$content_type_val = current(explode("/",$content_type));
$media_types = ["video", "image", "application"];
if(in_array($content_type_val, $media_types )){
echo base64_to_jpeg($attachment['data']['data'], $content_type); // Only for Image files
} else {
echo base64_decode($attachment['data']['data']); // Other than Image Files
}
} else { // Listing All Attachments
if(!empty($files)) {
foreach ($files as $key => $value) {
echo '<a target="_blank" href="index.php?messageId='.$message['id'].'&part_id='.$value.'">Attachment '.($key+1).'</a><br/>';
}
}
}