API Gmail: 400 плохих запросов при попытке отправить электронное письмо (код PHP)

Я ожидал, что код ниже отправит электронное письмо, но я получаю только следующее:

Произошла ошибка: Ошибка при вызове POST https://www.googleapis.com/gmail/v1/users/me/messages/send : (400) Неверный запрос

Я получаю 200 OK используя Google Developers Console здесь внизу. Любая помощь?

 $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(); } 

РЕДАКТИРОВАТЬ:

это объект запроса. Он также включает в себя данные ответа:

 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 

Solutions Collecting From Web of "API Gmail: 400 плохих запросов при попытке отправить электронное письмо (код PHP)"

наконец, получил, чтобы отправить Mails с вашим кодом:

Я думаю, вы неправильно поняли API GMail.

Чтобы использовать его, вы должны пройти аутентификацию в API. Для этого существует два способа:

  • использовать OAuth – Сервер перенаправляет пользователя на серверы Google, где они могут войти, предоставить разрешение вашему приложению и передать вам токен
  • Учетные записи служб. Это немного сложнее:
    • Во-первых, вам нужно будет настроить приложение (сделано)
    • во-вторых, вам придется настроить учетную запись службы. Таким образом ваше приложение аутентифицируется в Google. вы сделали это, и у имеющегося сертификата есть закрытый ключ для аутентификации
    • в-третьих, пользователь должен предоставить вашему приложению доступ к действию от их имени. Это тот момент, который вы еще не сделали.

Так что вы пытаетесь отправить почту из учетной записи службы, но это не учетная запись GMail.

Консоль разработчика использует метод OAuth, поэтому нет никаких проблем, чтобы попробовать это.

Также обратите внимание: с помощью обычных учетных записей GMail вы не можете использовать «Учетные записи службы». Вам нужно будет использовать OAuth. Чтобы использовать учетные записи служб, вы должны быть клиентом Google Apps.

Я не буду конвертировать авторизацию OAuth здесь, потому что это совершенно другое, и есть много примеров.

Чтобы предоставить разрешения вашей учетной записи службы для отправки писем от имени ваших аккаунтов GMail / Google Apps, следуйте этому документу . Для One or More API Scopes вам нужно будет ввести 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 .

После того, как вы настроите это, вы можете отправлять письма, просто измените код следующим образом:

 $results = $service->users_messages->send("me", $msg); 

не будет работать, потому что «я» ссылается на учетную запись службы, которая не может отправлять почту (см. выше). Замените me идентификатором пользователя (почтовым адресом) учетной записи, с которой следует отправлять почту:

 $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.

Ниже вы найдете полный рабочий код для меня:

 <?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(); } 

Если остались вопросы, не стесняйтесь спрашивать!

Единственное, что мне нужно было сделать, чтобы мой клиент учетной записи службы, который не был очевиден, заключался в следующем:

 // you MUST do this to avoid 400 error $user_to_impersonate = 'junk@example.net'; $client->setSubject($user_to_impersonate); 

Я думаю, вы забываете назначить $client_id своей переменной $client .

 $client = new Google_Client(); $client->setApplicationName('Gmail API test'); $client->setDeveloperKey('<YOUR_API_KEY>'); $client->setClientSecret('<YOUR_CLIENT_SECRET>'); $client->SetClientId('599901532082-js1r50n20q6n5mir9fo1g81qkj9kfn3j.apps.googleusercontent.com'); $client->setScopes(array('https://www.googleapis.com/auth/gmail.send')); $client->setAccessToken('{"access_token":"<YOUR_ACCESS_TOKEN>", "token_type":"Bearer"‌​,"expires_in":3600, "refresh_token":"<YOUR_REFRESH_TOKEN>","created":12344556}'); $service = new Google_Service_Gmail($client); $raw = "RnJvbTogSm9obiBEb2UgPHRpcmVuZ2FyZmlvQGdtYWlsLmVzPiANClRvOiBNYXJ5IFNtaXRoIDx0aXJlbmdhcmZpb0BnbWFpbC5jb20-IA0KU3ViamVjdDogU2F5aW5nIEhlbGxvIA0KRGF0ZTogRnJpLCAyMSBOb3YgMTk5NyAwOTo1NTowNiAtMDYwMCANCk1lc3NhZ2UtSUQ6IDwxMjM0QGxvY2FsLm1hY2hpbmUuZXhhbXBsZT4NCg0KVGhpcyBpcyBhIG1lc3NhZ2UganVzdCB0byBzYXkgaGVsbG8uIFNvLCAiSGVsbG8iLg=="; $msg = new Google_Service_Gmail_Message(); $msg->setRaw($raw); $results = $service->users_messages->send("me", $msg); print 'Message with ID: ' . $message->getId() . ' sent.'; 

Это полный рабочий пример , просто убедитесь, что вы изменили всю необходимую информацию и используете PHPMailer для форматирования действительной почты.

 <?php // this the link to gmail-api-client or whatever you have... require 'vendor/autoload.php'; // download PHPMailer // https://github.com/PHPMailer/PHPMailer and uncomment the line below. // require 'PHPMailer/PHPMailerAutoload.php'; define('FROM', 'aseptik@gmail.com'); //email of sender define('TO', 'XXXXXXX@XXXXX.com');//email of receiver $client_email = 'XXXXX@developer.gserviceaccount.com'; $private_key = file_get_contents('tmp/XXXXXXX.p12'); $scopes = array( 'https://www.googleapis.com/auth/gmail.send', 'https://www.googleapis.com/auth/gmail.compose' ); $credentials = new \Google_Auth_AssertionCredentials($client_email, $scopes, $private_key); $credentials->sub = FROM; $client = new Google_Client(); $client->setAssertionCredentials($credentials); if ($client->getAuth()->isAccessTokenExpired()) { $client->getAuth()->refreshTokenWithAssertion(); } function create_message() { $mail = new PHPMailer(); $mail->setFrom(FROM, 'John Doe 1'); $mail->addAddress(TO, 'John Doe 2'); $mail->Subject = 'Saying Hello'; $mail->Body = 'This is a message just to say hello. So, "Hello"'; $mail->preSend(); $mime = $mail->getSentMIMEMessage(); return urlsafe_b64encode($mime); } function sendMessage($service, $userId, $message) { try { $message = $service->users_messages->send($userId, $message); print 'Message with ID: ' . $message->getId() . ' sent.'; return $message; } catch(Exception $e) { print 'An error occurred: ' . $e->getMessage(); } } function urlsafe_b64encode($string) { $data = base64_encode($string); $data = str_replace(array('+','/','=') , array('-','_','') , $data); return $data; } $service = new \Google_Service_Gmail($client); $msg = new \Google_Service_Gmail_Message(); $msg->setRaw(create_message()); sendMessage($service, 'me', $msg); ?> 

используйте URL Endocde в строке и URL-адресе.

Эта ошибка является пространством в URL-адресе.