You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用google-api-php-client创建Workspace用户删除通知通道遇400错误

Google Workspace用户删除通知通道创建失败(400 Bad Request)

问题描述

需要创建通知通道,当Workspace用户被删除时,PHP应用能收到通知。调用Google Directory API的users->watch方法时抛出400 Bad Request错误,但用户插入等其他操作(如$this->dir->users->insert($user))正常执行。

代码实现

<?php

namespace App\Services;

use App\Models\Student;
use Exception;
use Google\Service\Directory\Channel;
use Illuminate\Support\Str;

class WorkspaceAdminService
{
    protected string $delegatedAdmin;
    protected string $appName;
    protected $scopes = array(
        \Google\Service\Directory::ADMIN_DIRECTORY_USER,
        \Google\Service\Directory::ADMIN_DIRECTORY_ORGUNIT,
    );
    protected $authJson;
    /**
     * @var \Google\Service\Directory  $dir
     **/
    protected $dir;

    public function __construct()
    {
        $authJson = resource_path('jsons/eservices-emails-creds.json');
        $this->appName = env("GOOGLE_APP_NAME");
        $this->delegatedAdmin = env("GOOGLE_DELEGATED_ADMIN");
        
        $googleClient = new \Google\Client();
        $googleClient->setApplicationName($this->appName);
        $googleClient->useApplicationDefaultCredentials();
        $googleClient->setAuthConfig($authJson);
        $googleClient->setSubject($this->delegatedAdmin);
        $googleClient->setScopes($this->scopes);
        $googleClient->setAccessType('offline');

        $this->dir = new \Google\Service\Directory($googleClient);
    }

   
    public function watch(string $url)
    {
        $channel = new Channel();

        $channel->setId(Str::uuid()->toString());
        $channel->setAddress($url);
        $channel->setType('web_hook');
        try {
            $this->dir->users->watch($channel, [
                'event' => 'delete',
            ]);

        } catch (Exception $e) {
            dd($e);
        }
    }
}

错误信息

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

解决方案

1. 补充Channel必填的过期参数

Google Directory API要求Channel对象必须包含expiration(毫秒级时间戳),最长有效期为30天,修改watch方法:

public function watch(string $url)
{
    $channel = new Channel();

    $channel->setId(Str::uuid()->toString());
    $channel->setAddress($url);
    $channel->setType('web_hook');
    // 设置30天后过期(转毫秒)
    $channel->setExpiration((time() + 30 * 24 * 60 * 60) * 1000);
    try {
        $this->dir->users->watch($channel, [
            'event' => 'delete',
        ]);

    } catch (Exception $e) {
        dd($e->getMessage(), $e->getResponse()->getBody()->getContents());
    }
}

2. 验证Webhook地址合规性

  • 必须是HTTPS协议的公网可访问地址,Google不支持HTTP地址
  • 地址不能带查询参数,需为直接路径(如https://your-domain.com/webhook/google-user-delete)
  • 确保地址能接收POST请求:Google创建通道时会发送验证请求,需返回200状态码确认

3. 检查权限与Scope

  • 确认委托管理员账号在Workspace控制台的角色中,包含管理API通知的权限
  • 若Scope常量存在问题,可替换为完整字符串:
    protected $scopes = array(
        "https://www.googleapis.com/auth/admin.directory.user",
        "https://www.googleapis.com/auth/admin.directory.orgunit",
    );
    

4. 调试详细错误信息

替换原dd($e)为以下代码,获取Google返回的具体错误描述:

dd($e->getMessage(), $e->getResponse()->getBody()->getContents());

内容的提问来源于stack exchange,提问作者MOHAMMAD RASIM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 07:28:18