API Gmail: 400 mauvaise requête lors de l'envoi d'un e-mail (code PHP)

Je m'attendais à ce que le code ci-dessous envoie un email, mais je ne reçois que ceci:

une erreur s'est produite: erreur appelant POST https://www.googleapis.com/gmail/v1/users/me/messages/send: (400) mauvais Demande

je 200 OK utilisation de la Console des développeurs Google ici au fond. Toute aide?

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

}

EDIT:

c'est l'objet de la requête. Il inclut les données de réponse aussi:

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
19
demandé sur ziiweb 2015-09-15 19:53:03

5 réponses

enfin réussi à envoyer des Mails avec votre code:

je pense que vous avez un peu mal compris L'API GMail.

Pour l'utiliser, vous devez vous authentifier à l'API. Pour ce faire, il existe deux solutions:

  • utiliser OAuth - le serveur redirige l'utilisateur vers les serveurs de google, où ils peuvent se connecter, accorder la permission à votre application, et passer un token de retour à vous
  • Comptes De Service. Ce sont un peu plus compliqué:
    • tout d'Abord, vous aurez à l'installation d'une application (fait)
    • deuxièmement, vous devrez configurer un compte de service. C'est ainsi que votre application s'authentifie sur google. vous avez fait cela, et le certificat que vous avez contient la clé privée pour authentifier
    • troisièmement, l'utilisateur doit accorder votre demande d'accès à agir en leur nom. C'est le point que vous ne l'avez pas encore fait.

donc ce que vous essayez actuellement est de envoyer des mails depuis le compte service, mais c'est un compte GMail.

la Console du développeur utilise la méthode OAuth, donc il n'y a aucun problème pour essayer cela.

veuillez noter également: avec des comptes GMail réguliers, vous pouvez utilisez 'comptes de Service'. Vous devrez utiliser OAuth. Pour utiliser des comptes de Service, vous devez être un client Googleapps.

Je ne changerai pas D'autorisation ici, parce que c'est complètement différent, et il y a beaucoup exemples.

pour autoriser votre compte de Service à envoyer des mails au nom de vos comptes GMails/Googleapps, veuillez suivre ce document. One or More API Scopes, vous devrez entrer 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.

après avoir configuré ceci, il est possible d'envoyer des mails, il suffit de modifier le code comme suit:

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

ne fonctionnera pas, car ' me ' renvoie au compte de service, qui ne peut pas envoyer de courrier (voir surtout.) Remplacez me avec l'identifiant (adresse postale) du compte à partir duquel les courriers doivent être envoyés.:

$results = $service->users_messages->send("senders_mail@domain.com", $msg);

alors, vous devrez ajouter

$cred->sub = 'senders_mail@domain.com';

en dessous de

$cred = new \Google_Auth_AssertionCredentials(
  $service_account_name,
  array('https://www.googleapis.com/auth/gmail.send', 'https://www.googleapis.com/auth/gmail.compose'),
  $key
);

Veuillez également noter que $message doit être $msg dans le try...catch-Bloc.

ci-dessous, vous trouverez le code de travail complet pour moi:

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

S'il reste des questions, n'hésitez pas à les poser!

13
répondu tillz 2016-01-14 13:22:01

une chose qui n'était pas évidente était d'ajouter ceci:

// you MUST do this to avoid 400 error
$user_to_impersonate = 'junk@example.net';
$client->setSubject($user_to_impersonate);
3
répondu stu 2015-10-28 15:01:11

je pense que vous oubliez d'attribuer le $client_id pour votre $client variable.

$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.';
2
répondu Tholle 2015-09-18 10:23:17

C'est un exemple, assurez-vous de changer toutes les infos et utiliser PHPMailer pour formater un courrier valide.

<?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);
?>
2
répondu Luca Filosofi 2015-09-24 19:29:42

utilisez L'Endocde URL dans la chaîne et l'url.

Cette erreur est l'espace dans l'url.

1
répondu user3770797 2015-09-18 08:37:56