检索单个/多个附件Gmail API PHP


Retrieve single/multiple attachments Gmail API PHP

我正在尝试使用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();
            }
          }

@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编码数据。

我想你到目前为止已经解决了这个问题,但我在谷歌的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是我们上面得到的partId数组):

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/>';
    }
}

当用户打开附件时。hp:

$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创建了一个包装器,所以如果你觉得它有用,在这里-https://packagist.org/packages/adevait/gmail-wrapper.