PHP中Gmail API的Send/Get接口实现及现有代码优化咨询
Gmail API PHP Guzzle 调用指南
一、获取单封邮件(users.messages.get)
参数说明
access_token: 授权令牌,必填email_address: 目标用户邮箱,可使用me指代当前授权用户message_id: 要获取的邮件ID,从list接口返回结果中获取
Guzzle调用示例
use GuzzleHttp\Client; public function getEmail($access_token, $email_address, $message_id) { $client = new Client(); $uri = "https://gmail.googleapis.com/gmail/v1/users/{$email_address}/messages/{$message_id}"; // 可选:指定返回格式,默认full,可选metadata/raw/minimal $query = ['format' => 'full']; $response = $client->request('GET', $uri, [ 'headers' => [ 'Authorization' => "Bearer {$access_token}", 'Accept' => 'application/json' ], 'query' => $query ]); return json_decode($response->getBody()->getContents(), true); }
二、发送邮件(users.messages.send)
发送邮件分普通无附件和带附件两种场景,核心是构造符合RFC 2822规范的邮件内容,再进行base64url编码。
1. 普通无附件发送
参数说明
access_token: 授权令牌,必填email_address: 发件人邮箱(或me)raw_content: 符合RFC 2822的邮件原文,示例格式:From: 发件人 <sender@example.com> To: 收件人 <recipient@example.com> Subject: 邮件标题 Content-Type: text/plain; charset="UTF-8" 邮件正文内容
Guzzle调用示例
use GuzzleHttp\Client; public function sendPlainEmail($access_token, $email_address, $raw_content) { // 转换为base64url编码(Gmail要求的编码格式) $raw_base64 = rtrim(strtr(base64_encode($raw_content), '+/', '-_'), '='); $client = new Client(); $uri = "https://gmail.googleapis.com/gmail/v1/users/{$email_address}/messages/send"; $response = $client->request('POST', $uri, [ 'headers' => [ 'Authorization' => "Bearer {$access_token}", 'Content-Type' => 'application/json' ], 'json' => [ 'raw' => $raw_base64 ] ]); return json_decode($response->getBody()->getContents(), true); }
2. 带附件发送
带附件需使用上传接口,且邮件内容要构造为multipart/mixed格式的RFC 2822内容,同时指定uploadType=multipart参数。
参数说明
- 除上述参数外,需构造包含附件的
multipart/mixed格式邮件原文 - 接口URI需添加
uploadType=multipart查询参数
Guzzle调用示例
use GuzzleHttp\Client; public function sendEmailWithAttachment($access_token, $email_address, $multipart_content) { $raw_base64 = rtrim(strtr(base64_encode($multipart_content), '+/', '-_'), '='); $client = new Client(); $uri = "https://gmail.googleapis.com/upload/gmail/v1/users/{$email_address}/messages/send?uploadType=multipart"; $response = $client->request('POST', $uri, [ 'headers' => [ 'Authorization' => "Bearer {$access_token}", 'Content-Type' => 'application/json' ], 'json' => [ 'raw' => $raw_base64 ] ]); return json_decode($response->getBody()->getContents(), true); }
注:
multipart_content需按MIME规范构造,包含正文、附件的独立部分,用自定义边界分隔符区分各块内容。
三、原emailSend函数优化指导
原函数存在几个关键问题,以下是修正后的版本及说明:
问题分析
- 使用
form_params传递参数错误:Gmail send接口要求请求体为JSON格式,而非表单提交 - 带附件场景缺失
uploadType参数:上传接口必须添加?uploadType=multipart才能正确处理附件 - 逻辑无问题,但参数传递方式不符合接口要求
修正后的函数
use GuzzleHttp\Client; public function emailSend($access_token, $data, $email_address, $attach_status) { // 确保$data是完整的RFC 2822格式邮件内容,转换为base64url编码 $raw_base64 = rtrim(strtr(base64_encode($data), '+/', '-_'), '='); $client = new Client(); // 基础接口地址 $uri = "https://gmail.googleapis.com/gmail/v1/users/{$email_address}/messages/send"; // 带附件时切换到上传接口并添加必要参数 if ($attach_status == 1) { $uri = "https://gmail.googleapis.com/upload/gmail/v1/users/{$email_address}/messages/send?uploadType=multipart"; } $params = [ 'headers' => [ 'Authorization' => "Bearer {$access_token}", 'Content-Type' => 'application/json', 'Accept' => 'application/json' ], 'json' => [ // 替换form_params为json,匹配接口要求的请求格式 'raw' => $raw_base64 ] ]; $response = $client->request('POST', $uri, $params); return json_decode($response->getBody()->getContents(), true); }
调用注意事项
$data必须是完整的RFC 2822格式邮件内容,包含发件人、收件人、主题、正文(带附件时需包含附件MIME块)- 使用
me作为$email_address时,需确保access_token对应的授权用户为目标邮箱账号
内容的提问来源于stack exchange,提问作者codewiz
相关产品推荐
相关产品推荐

