PHP Google 服务帐户授权日历 API

PHP Google Service account auth Calendar API

我想从我的网站分享活动并将其添加到我自己的 google 日历中。 所以,我不想要 oauth 提示。因为访问我网站的用户也可以将活动添加到我的日历中。

我认为我做对了,但我有这个错误:Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested

因此,我不确定是否需要付费工作区帐户才能执行此操作。 如果不是,我不明白我哪里失败了?

这是我的代码:

$client = new Google\Client();

$client->setAuthConfig('./secret.json');
$client->setApplicationName('app name');
$client->addScope(Google\Service\Calendar::CALENDAR_EVENTS);
$client->setSubject('mail@gmail.com');
$client->setAccessType('offline');

$service = new Google\Service\Calendar($client);

$event = new Google\Service\Calendar\Event(array(
    'summary' => 'summary',
    'location' => 'street bla bla',
    'description' => 'first event',
    'start' => array(
        'dateTime' => '2021-11-30T10:00:00.000-05:00',
        'timeZone' => 'Europe/Brussels',
    ),
    'end' => array(
        'dateTime' => '2021-11-30T10:00:00.000-05:00',
        'timeZone' => 'Europe/Brussels',
    )
));

$service->events->insert('calendar_id', $event);

谢谢

问题是您正在尝试将主题或委托设置为普通的 Gmail 电子邮件地址 $client->setSubject('mail@gmail.com');

服务帐户只能与 Google 工作区域帐户一起使用,并且只有在您正确设置对域中用户的委派后才能使用。

很遗憾地告诉您,您将无法使用带有您的 gmail 电子邮件地址的服务帐户。

您可以做的是 运行 来自示例项目的代码,它使用已安装的应用程序并存储刷新令牌。此代码将是单个用户。您将不得不对其进行一些监控,因为刷新令牌可能会过期,尽管一旦您的项目设置为产品,它就不那么常见了。

require __DIR__ . '/vendor/autoload.php';

if (php_sapi_name() != 'cli') {
    throw new Exception('This application must be run on the command line.');
}

/**
 * Returns an authorized API client.
 * @return Google_Client the authorized client object
 */
function getClient()
{
    $client = new Google_Client();
    $client->setApplicationName('Google Calendar API PHP Quickstart');
    $client->setScopes(Google_Service_Calendar::CALENDAR_READONLY);
    $client->setAuthConfig('credentials.json');
    $client->setAccessType('offline');
    $client->setPrompt('select_account consent');

    // Load previously authorized token from a file, if it exists.
    // The file token.json stores the user's access and refresh tokens, and is
    // created automatically when the authorization flow completes for the first
    // time.
    $tokenPath = 'token.json';
    if (file_exists($tokenPath)) {
        $accessToken = json_decode(file_get_contents($tokenPath), true);
        $client->setAccessToken($accessToken);
    }

    // If there is no previous token or it's expired.
    if ($client->isAccessTokenExpired()) {
        // Refresh the token if possible, else fetch a new one.
        if ($client->getRefreshToken()) {
            $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
        } else {
            // Request authorization from the user.
            $authUrl = $client->createAuthUrl();
            printf("Open the following link in your browser:\n%s\n", $authUrl);
            print 'Enter verification code: ';
            $authCode = trim(fgets(STDIN));

            // Exchange authorization code for an access token.
            $accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
            $client->setAccessToken($accessToken);

            // Check to see if there was an error.
            if (array_key_exists('error', $accessToken)) {
                throw new Exception(join(', ', $accessToken));
            }
        }
        // Save the token to a file.
        if (!file_exists(dirname($tokenPath))) {
            mkdir(dirname($tokenPath), 0700, true);
        }
        file_put_contents($tokenPath, json_encode($client->getAccessToken()));
    }
    return $client;
}


// Get the API client and construct the service object.
$client = getClient();
$service = new Google_Service_Calendar($client);

// Print the next 10 events on the user's calendar.
$calendarId = 'primary';
$optParams = array(
  'maxResults' => 10,
  'orderBy' => 'startTime',
  'singleEvents' => true,
  'timeMin' => date('c'),
);
$results = $service->events->listEvents($calendarId, $optParams);
$events = $results->getItems();

if (empty($events)) {
    print "No upcoming events found.\n";
} else {
    print "Upcoming events:\n";
    foreach ($events as $event) {
        $start = $event->start->dateTime;
        if (empty($start)) {
            $start = $event->start->date;
        }
        printf("%s (%s)\n", $event->getSummary(), $start);
    }
}