我尝试使用Gmail API PHP获取邮箱中所有附件的列表。我在某些时候陷入困境,但我无法确定何时。这是我用来获取消息内容的代码,当我尝试获取附件时它会以某种方式失败。
我想获取与“q”查询对应的所有邮件的文件名和附件ID。这是我的代码:
function atta($service, $userId, $expeditor)
{
try
{
unset($optParamsamz);
$optParamsamz = [];
$optParamsamz['maxResults'] = 10; // Return Only 5 Messages
$optParamsamz['q'] = "has:attachment larger_than:10000000 "; // Only show messages in Inbox
$messagesamz = $service->users_messages->listUsersMessages('me',$optParamsamz);
$listamz = $messagesamz->getMessages();
$idlist = array();
foreach ($listamz as $key => $value) {
$message = $service->users_messages->get('me', $value['id']);
$array_message = $message->getPayload();
print_r($array_message);
echo "<br><br>";
}
}
catch (Exception $e)
{
print 'An error occurred: ' . $e->getMessage();
}
}
答案 0 :(得分:2)
我认为你到目前为止已经解决了这个问题,但我在谷歌的API上挣扎了一段时间,当然,在这里寻求帮助,所以我想这个答案可以帮助别人。
您的代码看起来很好,因此我在尝试检索附件时获取消息详细信息之后会出现问题。在处理附件时我注意到的一个奇怪的事情是attachment_id不一致并且随着对消息细节的不同调用而改变,因此我决定使用part_id而不是更改。因此,在获得有效载荷后,我这样做:
$messageDetails = $message->getPayload();
foreach ($messageDetails['parts'] as $key => $value) {
if (!isset($value['body']['data'])) {
array_push($files, $value['partId']);
}
}
现在,您拥有部件的ID,包括邮件中的附件。接下来,您需要获取附件的所有可能详细信息,以便重建文件并启用下载。您需要的文件名和其他详细信息仅与邮件详细信息和附件数据一起返回,并作为附件详细信息的一部分返回。
我将getAttachment函数作为一个整体粘贴。
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()];
}
}
附件列表(你已经有$ messageId和$ files是我们上面得到的partIds数组):
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/>';
}
}
当用户打开attachment.php:
时$attachment = $msgs->getAttachment($_GET['messageId'],$_GET['part_id']);
foreach ($attachment['data']['headers'] as $key => $value) {
header($key.':'.$value);
}
echo $attachment['data']['data'];
这将根据附件详细信息设置标题,并以正确的格式下载文件。
他们的API非常简单,但他们没有提供足够的示例,因此很容易陷入困境。我知道我做了:)。为此,我为Gmail的API创建了一个包装器,如果您发现它有用,请在此处default value。
答案 1 :(得分:0)
上面@trajchevska的回答很有帮助,但不幸的是,在有效负载部分上进行迭代不会捕获某些附件,例如消息正文中的图像,这些附件是部分内部的一部分。要获得这些,您需要递归遍历各个部分。我正在这样做:
function getAttachments($message_id, $parts) {
$attachments = [];
foreach ($parts as $part) {
if (!empty($part->body->attachmentId)) {
$attachment = $this->service->users_messages_attachments->get('me', $message_id, $part->body->attachmentId);
$attachments[] = [
'filename' => $part->filename,
'mimeType' => $part->mimeType,
'data' => strtr($attachment->data, '-_', '+/')
];
} else if (!empty($part->parts)) {
$attachments = array_merge($attachments, $this->getAttachments($message_id, $part->parts));
}
}
return $attachments;
}
在上面的示例中,$this->service
是经过身份验证的Google_Service_Gmail()
实例(与问题中的相同)。上面的方法在您的类中被调用为:
$attachments = $this->getAttachments($message->id, $message->getPayload()->parts);
这将为您提供数组中的文件名,MIME类型和base64编码数据。