google - API de Gmail: 400 solicitudes incorrectas al intentar enviar un correo electrónico(código PHP)
google gmail oauth api (5)
Creo que te estás olvidando de asignar $client_id
a tu variable $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.'';
Esperaba que el código de abajo enviara un correo electrónico, pero solo recibo esto:
Se produjo un error: Error al llamar a POST https://www.googleapis.com/gmail/v1/users/me/messages/send : (400) Solicitud incorrecta
Obtuve un 200 OK
usando la Consola de desarrolladores de Google here en la parte inferior. ¿Alguna ayuda?
$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();
}
EDITAR:
Este es el objeto de solicitud. Incluye los datos de respuesta también:
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
Este es un ejemplo completo de trabajo , solo asegúrese de cambiar toda la información apropiada y use PHPMailer para formatear un correo válido.
<?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'', ''[email protected]''); //email of sender
define(''TO'', ''[email protected]'');//email of receiver
$client_email = ''[email protected]'';
$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);
?>
Finalmente conseguí enviar correos con tu código:
Creo que has malinterpretado un poco la API de GMail.
Para usarlo, debes autenticarte en la API. Para hacer esto, hay dos formas:
- use OAuth: el servidor redirige al usuario a los servidores de google, donde pueden iniciar sesión, otorgar permiso a su aplicación y devolverle un token
- Cuentas de servicio. Estos son un poco más complicados:
- Primero, tendrás que configurar una aplicación (hecho)
- En segundo lugar, tendrás que configurar una cuenta de servicio. Así es como tu aplicación se autentica en google. Lo has hecho, y el certificado que tienes contiene la clave privada para autenticarse.
- tercero, el usuario debe otorgar acceso a su aplicación para actuar en nombre de ellos. Este es el punto que aún no has hecho.
Entonces, lo que estás intentando actualmente es enviar correos desde la cuenta de servicio, pero esta no es una cuenta de GMail.
La Consola de desarrollador usa el método OAuth, por lo que no hay problema para intentarlo.
Tenga en cuenta también que: con las cuentas de correo electrónico normales de GMail, no puede usar las "cuentas de servicio". Tendrás que usar OAuth. Para utilizar las cuentas de servicio, debe ser un cliente de Google Apps.
No convertiré la autorización de OAuth aquí, porque es completamente diferente, y hay muchos ejemplos por ahí.
Para otorgar permisos a su cuenta de servicio para enviar correos electrónicos en nombre de sus cuentas de GMails / Google Apps, siga este documento . Para One or More API Scopes
, deberá ingresar 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
.
Una vez que haya configurado esto, es posible enviar correos, solo modifique el código de la siguiente manera:
$results = $service->users_messages->send("me", $msg);
no funcionará, porque ''yo'' hace referencia a la cuenta de servicio, que no puede enviar correo (ver arriba). Reemplazarme con el ID de usuario (dirección de correo) de la cuenta desde la que se deben enviar los correos:
$results = $service->users_messages->send("[email protected]", $msg);
Entonces, tendrás que añadir
$cred->sub = ''[email protected]'';
abajo
$cred = new /Google_Auth_AssertionCredentials(
$service_account_name,
array(''https://www.googleapis.com/auth/gmail.send'', ''https://www.googleapis.com/auth/gmail.compose''),
$key
);
Tenga en cuenta que $message
debería ser $msg
en el try...catch
-Block.
A continuación, encontrará el código completo de trabajo para mí:
<?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();
}
Si queda alguna pregunta, no dude en preguntar!
Una cosa que necesitaba para que funcionara mi cliente de cuenta de servicio que no era obvio era agregar esto:
// you MUST do this to avoid 400 error
$user_to_impersonate = ''[email protected]'';
$client->setSubject($user_to_impersonate);
Utilice URL Endocde en cadena y url.
Este error es espacio en url.