Gmail API:尝试发送电子邮件时出现 400 个错误请求(PHP 代码)
我希望下面的代码能发送电子邮件,但我只收到了这个:
I expected the code below to send an email, but I'm only getting this:
发生错误:调用 POST 时出错https://www.googleapis.com/gmail/v1/users/me/messages/send: (400) 不好请求
An error occurred: Error calling POST https://www.googleapis.com/gmail/v1/users/me/messages/send: (400) Bad Request
我使用 Google Developers Console 200 OK=es">此处 在底部.有什么帮助吗?
I get a 200 OK
using the Google Developers Console here at the bottom. Any help?
$client_id = '599901532082-js1r50n20q6n5mir9fo1g81qkj9kfn3j.apps.googleusercontent.com';
$service_account_name = '599901532082-js1r50n20q6n5mir9fo1g81qkj9kfn3j@developer.gserviceaccount.com';
$key_file_location = '/tmp/APIProject-cb6558ba6435.p12';
$client = new Google_Client();
$client->setApplicationName("Client_Library_Examples");
$service = new Google_Service_Gmail($client);
if (isset($_SESSION['service_token'])) {
$client->setAccessToken($_SESSION['service_token']);
}
$key = file_get_contents($key_file_location);
$cred = new Google_Auth_AssertionCredentials(
$service_account_name,
array('https://www.googleapis.com/auth/gmail.send', 'https://www.googleapis.com/auth/gmail.compose'),
$key
);
$client->setAssertionCredentials($cred);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
}
//check if you want the validity of this string at: http://www.komeil.com/toolbox/base64decoder
//it is web safe base64 encoded email
$mime = "RnJvbTogSm9obiBEb2UgPHRpcmVuZ2FyZmlvQGdtYWlsLmVzPiANClRvOiBNYXJ5IFNtaXRoIDx0aXJlbmdhcmZpb0BnbWFpbC5jb20-IA0KU3ViamVjdDogU2F5aW5nIEhlbGxvIA0KRGF0ZTogRnJpLCAyMSBOb3YgMTk5NyAwOTo1NTowNiAtMDYwMCANCk1lc3NhZ2UtSUQ6IDwxMjM0QGxvY2FsLm1hY2hpbmUuZXhhbXBsZT4NCg0KVGhpcyBpcyBhIG1lc3NhZ2UganVzdCB0byBzYXkgaGVsbG8uIFNvLCAiSGVsbG8iLg==";
$service = new Google_Service_Gmail($client);
$msg = new Google_Service_Gmail_Message();
$msg->setRaw($mime);
try {
$results = $service->users_messages->send("me", $msg);
print 'Message with ID: ' . $message->getId() . ' sent.';
return $message;
} catch (Exception $e) {
print 'An error occurred: ' . $e->getMessage();
}
这是请求对象.它还包括响应数据:
this is the request object. It includes the response data also:
object(Google_Http_Request)[508]
private 'batchHeaders' =>
array (size=3)
'Content-Type' => string 'application/http' (length=16)
'Content-Transfer-Encoding' => string 'binary' (length=6)
'MIME-Version' => string '1.0' (length=3)
protected 'queryParams' =>
array (size=0)
empty
protected 'requestMethod' => string 'POST' (length=4)
protected 'requestHeaders' =>
array (size=3)
'content-type' => string 'application/json; charset=UTF-8' (length=31)
'authorization' => string 'Bearer ya29.8gEUMiBLfxS8OLdSmpiQ-EcumeATo2qFAfPtPqwTw9fQ2zVrfZaA1X5OLoBmQccrXr8V8g' (length=82)
'accept-encoding' => string 'gzip' (length=4)
protected 'baseComponent' => string 'https://www.googleapis.com' (length=26)
protected 'path' => string '/gmail/v1/users/me/messages/send' (length=32)
protected 'postBody' => string '{"raw":"RnJvbTogSm9obiBEb2UgPHRpcmVuZ2FyZmlvQGdtYWlsLmVzPg0KVG86IE1hcnkgU21pdGggPHRpcmVuZ2FyZmlvQGdtYWlsLmNvbT4NClN1YmplY3Q6IFNheWluZyBIZWxsbw0KDQpUaGlzIGlzIGEgbWVzc2FnZSBqdXN0IHRvIHNheSBoZWxsby4gU28sICdIZWxsbycu"}' (length=214)
protected 'userAgent' => string 'Client_Library_Examples google-api-php-client/1.0.6-beta (gzip)' (length=63)
protected 'canGzip' => boolean true
protected 'responseHttpCode' => null
protected 'responseHeaders' => null
protected 'responseBody' => null
protected 'expectedClass' => string 'Google_Service_Gmail_Message' (length=28)
public 'accessKey' => null
object(Google_Http_Request)[508]
private 'batchHeaders' =>
array (size=3)
'Content-Type' => string 'application/http' (length=16)
'Content-Transfer-Encoding' => string 'binary' (length=6)
'MIME-Version' => string '1.0' (length=3)
protected 'queryParams' =>
array (size=0)
empty
protected 'requestMethod' => string 'POST' (length=4)
protected 'requestHeaders' =>
array (size=4)
'content-type' => string 'application/json; charset=UTF-8' (length=31)
'authorization' => string 'Bearer ya29.8gEUM***fxS8OLdSmpiQ-EcumeATo2qFAfPtPqwTw9fQ2zVrfZaA1X5OLoBmQccrXr8V8g' (length=82)
'accept-encoding' => string 'gzip' (length=4)
'content-length' => int 214
protected 'baseComponent' => string 'https://www.googleapis.com' (length=26)
protected 'path' => string '/gmail/v1/users/me/messages/send' (length=32)
protected 'postBody' => string '{"raw":"RnJvbTogSm9obiBEb2UgPHRpcmVuZ2FyZmlvQGdtYWlsLmVzPg0KVG86IE1hcnkgU21pdGggPHRpcmVuZ2FyZmlvQGdtYWlsLmNvbT4NClN1YmplY3Q6IFNheWluZyBIZWxsbw0KDQpUaGlzIGlzIGEgbWVzc2FnZSBqdXN0IHRvIHNheSBoZWxsby4gU28sICdIZWxsbycu"}' (length=214)
protected 'userAgent' => string 'Client_Library_Examples google-api-php-client/1.0.6-beta (gzip)' (length=63)
protected 'canGzip' => boolean true
protected 'responseHttpCode' => int 400
protected 'responseHeaders' =>
array (size=13)
'vary' => string 'Origin
X-Origin' (length=15)
'content-type' => string 'application/json; charset=UTF-8' (length=31)
'content-encoding' => string 'gzip' (length=4)
'date' => string 'Fri, 18 Sep 2015 08:34:25 GMT' (length=29)
'expires' => string 'Fri, 18 Sep 2015 08:34:25 GMT' (length=29)
'cache-control' => string 'private, max-age=0' (length=18)
'x-content-type-options' => string 'nosniff' (length=7)
'x-frame-options' => string 'SAMEORIGIN' (length=10)
'x-xss-protection' => string '1; mode=block' (length=13)
'server' => string 'GSE' (length=3)
'alternate-protocol' => string '443:quic,p=1' (length=12)
'alt-svc' => string 'quic=":443"; p="1"; ma=604800' (length=29)
'transfer-encoding' => string 'chunked' (length=7)
protected 'responseBody' => string '{
"error": {
"errors": [
{
"domain": "global",
"reason": "failedPrecondition",
"message": "Bad Request"
}
],
"code": 400,
"message": "Bad Request"
}
}
' (length=179)
protected 'expectedClass' => string 'Google_Service_Gmail_Message' (length=28)
public 'accessKey' => null
推荐答案
终于可以用你的代码发送邮件了:
finally got to send Mails with your code:
我认为您对 GMail API 有点误解.
I think you have misunderstood the GMail API a little bit.
要使用它,您必须对 API 进行身份验证.为此,有两种方法:
To use it, you must authenticate to the API. To do this, there are two ways:
- 使用 OAuth - 服务器将用户重定向到 google 的服务器,在那里他们可以登录、授予您的应用程序权限并将令牌传回给您
- 服务帐户.这些有点复杂:
- 首先,您必须设置一个应用(完成)
- 其次,您必须设置一个服务帐户.这就是您的应用向 Google 进行身份验证的方式.你已经这样做了,你得到的证书包含用于认证的私钥
- 第三,用户需要授予您的应用程序访问权限以代表他们行事.这是您尚未完成的一点.
所以您当前尝试的是从服务帐户发送邮件,但这不是 GMail 帐户.
So what you're currently trying is to send mails from the service account, but this is not an GMail Account.
开发者控制台使用 OAuth 方法,所以尝试这个没有问题.
The Developer Console uses the OAuth method, so there's no problem to try this.
另请注意:对于常规 GMail 帐户,您不能使用服务帐户".您必须使用 OAuth.要使用服务帐户,您需要成为 Google Apps 客户.
Please also note: With regular GMail Accounts, you can not use 'Service Accounts'. You'll have to use OAuth. To use Service Accounts, you need to be a Google Apps customer.
我不会在这里讨论 OAuth 授权,因为它完全不同,并且有很多示例.
I won't conver OAuth authorization here, because it's completely different, and there are many examples out there.
要授予您的服务帐户权限以代表您的 GMails/Google Apps 帐户发送邮件,请按照本文档.对于
一个或多个 API 范围
,您必须输入https://mail.google.com/,https://www.googleapis.com/auth/gmail.modify,https://www.googleapis.com/auth/gmail.compose,https://www.googleapis.com/auth/gmail.send
.To grant your Service Account Permissions to send mails on behalf of your GMails/Google Apps accounts, please follow this document. For
One or More API Scopes
, you'll have to enterhttps://mail.google.com/,https://www.googleapis.com/auth/gmail.modify,https://www.googleapis.com/auth/gmail.compose,https://www.googleapis.com/auth/gmail.send
.设置好后就可以发送邮件了,修改代码如下:
After you've setup this, it's possible to send mails, just modify the code as follows:
$results = $service->users_messages->send("me", $msg);
不起作用,因为我"指的是无法发送邮件的服务帐户(见上文).将
me
替换为应该发送邮件的帐户的用户 ID(邮件地址).:won't work, because 'me' referrs to the service account, which can't send mail (see above). Replace
me
with the user id (mail-address) of the account from which the mails should be send.:$results = $service->users_messages->send("senders_mail@domain.com", $msg);
然后,您需要添加
$cred->sub = 'senders_mail@domain.com';
下面
$cred = new Google_Auth_AssertionCredentials( $service_account_name, array('https://www.googleapis.com/auth/gmail.send', 'https://www.googleapis.com/auth/gmail.compose'), $key );
还请注意,
$message
应该是$msg
在try...catch
-Block 中.Please also note that
$message
should be$msg
in thetry...catch
-Block.在下面,您将找到适合我的完整的工作代码:
Below, you'll find the the complete, working code for me:
<?php require_once realpath(dirname(__FILE__) . '/../src/Google/autoload.php'); $client_id = '*censored*.apps.googleusercontent.com'; $service_account_name = '*censored*@developer.gserviceaccount.com'; $key_file_location = '/tmp/apiKey.p12'; $userid_from='*censored*'; $client = new Google_Client(); $client->setApplicationName("Client_Library_Examples"); //hmmm, really don't know whether these lines are necessary if (isset($_SESSION['service_token'])) { $client->setAccessToken($_SESSION['service_token']); } $key = file_get_contents($key_file_location); $cred = new Google_Auth_AssertionCredentials( $service_account_name, array('https://www.googleapis.com/auth/gmail.send', 'https://www.googleapis.com/auth/gmail.compose', 'https://www.googleapis.com/auth/gmail.modify','https://www.googleapis.com/auth/gmail.readonly'), $key ); $cred->sub=$userid_from; //<-- Important! $client->setAssertionCredentials($cred); if ($client->getAuth()->isAccessTokenExpired()) { $client->getAuth()->refreshTokenWithAssertion($cred); } //check if you want the validity of this string at: http://www.komeil.com/toolbox/base64decoder //it is web safe base64 encoded email $mime = "*censored*, same content as you posted, but another recipient ;-)"; $service = new Google_Service_Gmail($client); $msg = new Google_Service_Gmail_Message(); $msg->setRaw($mime); try { $results = $service->users_messages->send($userid_from, $msg); print 'Message with ID: ' . $results->id . ' sent.'; } catch (Exception $e) { print 'An error occurred: ' . $e->getMessage(); }
如果还有什么问题,欢迎随时提问!
If there are any questions left, feel free to ask!
相关文章