首页 > 解决方案 > 是否可以在其他用户中创建谷歌日历事件而不是添加与会者

问题描述

我正在使用 PHP 创建一个谷歌日历事件并添加参与者,但我想直接在用户的日历中创建、更新、删除事件。

下面是我的 PHP 代码,它可以很好地在我的 gmail clanedar 中插入添加事件,但我无法将事件添加到其他用户的日历中。

 <?php 
require  'google/vendor/autoload.php';

function getClient()
{
$client = new Google_Client();
$client->setApplicationName('Google Calendar API PHP Quickstart');
$client->setScopes(Google_Service_Calendar::CALENDAR);
$client->setAuthConfig('credentials.json');
$client->setAccessType('offline');
$client->setPrompt('select_account consent');
$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();

$event = new Google_Service_Calendar_Event(array(
'summary' => 'Google I/O 2015',
'location' => '800 Howard St., San Francisco, CA 94103',
'description' => 'A chance to hear more about Google\'s developer products.',
'start' => array(
'dateTime' => '2021-05-29T09:00:00-07:00',
'timeZone' => 'America/Los_Angeles',
),
'end' => array(
'dateTime' => '2021-05-29T17:00:00-07:00',
'timeZone' => 'America/Los_Angeles',
),
'recurrence' => array(
'RRULE:FREQ=DAILY;COUNT=1'
),
'attendees' => array(
array('email' => 'example1@gmail.com'),
array('email' => 'example2@gmail.com'),
),
'reminders' => array(
'useDefault' => FALSE,
'overrides' => array(
  array('method' => 'email', 'minutes' => 24 * 60),
  array('method' => 'popup', 'minutes' => 10),
),
),
));

 $calendarId = 'primary';
 $event = $service->events->insert($calendarId, $event);
 printf('Event created: %s\n', $event->htmlLink);

我想将事件直接添加到 example1 和 example2 谷歌日历。有可能的 ?。提前致谢

标签: phpcalendargoogle-calendar-api

解决方案


我有一种感觉,你可能只是从某个地方复制了这段代码,并没有完全理解它在做什么。

谁,什么,在哪里?

当您的代码第一次运行时。用户将看到一个网页,要求他们同意您的应用程序访问他们的数据。

一旦用户同意,您的活动将被插入到该用户的主日历中。

$calendarId = 'primary';

所有用户都有一个设置为主要日历的日历,此外他们可以创建不同的日历,但您已选择将其插入到他们的主要日历中。

因此,该事件将被插入到进行身份验证的用户的主日历中。

谁是用户。

您的代码正在请求称为脱机访问的内容。

$client->setAccessType('offline');

这意味着您要求用户让您在他们不在时访问他们的日历。或离线。例如,如果您想自动将事件添加到用户日历以进行会议或其他事情,这将起作用。

它实际上所做的是向您返回一个 refreshToken,刷新令牌是 Oauth2 的东西,它使您能够在需要访问用户数据时请求新的访问令牌,这是他们的日历。使用刷新令牌,您可以执行以下操作,这将导致客户端为自己加载新的访问令牌。

$client->fetchAccessTokenWithRefreshToken([refreshtoken]);

你确实在某种程度上正在做这件事。

问题是,您需要让每个您希望访问其日历的用户至少授权您的应用程序一次,并将刷新令牌保存在数据库或某种文件中,以便跟踪哪个刷新令牌属于哪个用户。

目前您的代码仅存储一个用户

$tokenPath = 'token.json';
if (file_exists($tokenPath)) {
    $accessToken = json_decode(file_get_contents($tokenPath), true);
    $client->setAccessToken($accessToken);
}

.....

 // Save the token to a file.
    if (!file_exists(dirname($tokenPath))) {
        mkdir(dirname($tokenPath), 0700, true);
    }

您的代码第一次运行它会请求访问,然后它将保存令牌文件而不定义它是哪个用户,然后它将从现在开始加载该文件。您当前的代码是单用户。如果您希望其他用户运行您的应用程序,那么您需要更改此内容,以便您可以存储他们的刷新令牌并写入他们的日历。


推荐阅读