更新我的G Suite域中用户的签名

时间:2016-12-05 11:05:49

标签: php gmail-api service-accounts google-api-explorer

我的目标是更新我的域中的所有用户电子邮件签名。

我已经设置了一个具有域范围委派权限的服务帐户。 但是我坚持这个错误:

{
 "error": {
  "errors": [
   {\n
    "domain": "global",
    "reason": "failedPrecondition",
    "message": "Bad Request"
   }
  ],
  "code": 400,
  "message": "Bad Request"
 }
}

我使用的请求与API资源管理器执行的请求相同。所以它应该很好地形成......

在API资源管理器中,它也没有正常工作,我有这个答案:

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "forbidden",
    "message": "Delegation denied for vivien@mydomain.com"
   }
  ],
  "code": 403,
  "message": "Delegation denied for vivien@mydomain.com"
 }
}

似乎我有许可问题,但我无法弄清楚原因。

以下是我的PHP测试代码:

 public function updateSignAction(){

    putenv('GOOGLE_APPLICATION_CREDENTIALS='.$this->get('kernel')->getRootDir().'/../app/Resources/files/mydomain.json');

    $client = new \Google_Client();
    $client->useApplicationDefaultCredentials();
    $client->setApplicationName("demo");
    $client->addScope([
        "https://www.googleapis.com/auth/gmail.settings.basic",
        "https://www.googleapis.com/auth/gmail.settings.sharing"
    ]);
    //$client->setSubject('vivien@mydomain.com');
    $httpClient = $client->authorize();

    $response = $httpClient->put(
       'https://www.googleapis.com/gmail/v1/users/vivien@mydomain.com/settings/sendAs/test',
       [
            'json' => [
                'signature' => "test-via-api"
            ]
        ]
    );

    return $this->render('AdminBundle:GoogleApi:user/update.html.twig', array(
        'response' => $response->getBody()->getContents(),
    ));
}

1 个答案:

答案 0 :(得分:0)

您必须对API进行身份验证。要做到这一点,有两种方法:

  • 使用OAuth - 服务器将用户重定向到谷歌的服务器,他们可以登录,为您的应用授予权限,并将令牌传回给您
  • 服务帐户。这些有点复杂:
  • 首先,您必须设置应用(已完成)
  • 其次,您必须设置服务帐户。这是您的应用验证谷歌的方式。您已完成此操作,并且您获得的证书包含用于身份验证的私钥
  • 第三,用户需要授予您的应用程序访问权限以代表他们行事。这是你还没有完成的一点。

所以您目前正在尝试的是从服务帐户发送邮件,但这不是Gmail帐户。

请注意:使用常规GMail帐户,您无法使用“服务帐户”。您必须使用OAuth。要使用服务帐户,您需要成为Google Apps客户。

要授予您的服务帐户权限以代表您的GMails / Google Apps帐户发送邮件,请关注this document。对于一个或多个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

设置好后,可以发送邮件,只需修改代码如下:

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

不会工作,因为' me'引用服务帐户,不能发送邮件(见上文)。将me替换为应从中发送邮件的帐户的用户ID(邮件地址)。

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

然后,您需要添加

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

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

<?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");

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

if ($client->getAuth()->isAccessTokenExpired()) {
  $client->getAuth()->refreshTokenWithAssertion($cred);
}

 $mime = "*censored*";

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

如果还有任何问题,请随时提问!