首页 > 解决方案 > 无法在 Google 日历中为不同用户创建活动

问题描述

大家好。我希望你们都做得很好。

我知道这个问题已经被问过很多次了,但是那里提供的解决方案都不适合我。

我正在自定义 PHP 中实现谷歌日历 API。我遵循了谷歌提供的官方文档。我已经能够为特定用户创建和获取事件。

我最初的目标是让每个用户都可以在自己的日历上获取、创建、更新和删除事件。

这是我在代码中一直在做的事情。

这是 calendarSetting.php 文件。

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

function getClient()
{
    $client = new Google_Client();
    $client->setApplicationName('Google Calendar API PHP Quickstart');
    $client->setScopes(Google_Service_Calendar::CALENDAR);
    $client->setAuthConfig('client_secret.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;
}
?>

这是 createCalendar.php 文件

<?php

  require __DIR__ . '/vendor/autoload.php';
  include('calendarSetting.php');
  session_start();
  $appointment_id = $_SESSION['appointment_id'];
  $patient_fname = $_SESSION['patient_fname'];
  $patient_lname = $_SESSION['patient_lname'];
  $patient_phone = $_SESSION['patient_phone'];
  $schedule = $_SESSION['appointment_date'];
  $start_date = $_SESSION['start'];
  $end_date = $_SESSION['end'];
 
    $client = getClient();
    $service = new Google_Service_Calendar($client);
    $event = new Google_Service_Calendar_Event(array(
        'summary' => $patient_fname . ' ' . $patient_lname,
        'description' => $patient_fname . ' ' . ' ' . $patient_lname . ' ' . $patient_phone ,
        
        'start' => array(
          'dateTime' => $start_date.':00+05:00',
          'timeZone' => 'America/Los_Angeles',
        ),
        'end' => array(
          'dateTime' => $end_date.':00+05:00',
          'timeZone' => 'America/Los_Angeles',
        ),
        'recurrence' => array(
          'RRULE:FREQ=DAILY;COUNT=1'
        ),
        'attendees' => array(
          array('email' => 'abc1211@gmail.com')
        )
         
        
      ));
    
      $calendarId = 'user876@gmail.com';
      $event = $service->events->insert($calendarId, $event);
    printf('Event created');
    header('location: Doctor');


?>

这非常适合 $calendarId = 'user876@gmail.com';的用户。. 但是如果我更改用户,它会给我一个错误。

致命错误:未捕获的 Google\Service\Exception:{“错误”:{“错误”:[{“域”:“全局”、“原因”:“未找到”、“消息”:“未找到”}]、“ code": 404, "message": "Not Found" } } 在 F:\xampp\htdocs\bupa1\vendor\google\apiclient\src\Http\REST.php:128 堆栈跟踪:#0 F:\xampp\ htdocs\bupa1\vendor\google\apiclient\src\Http\REST.php(103): Google\Http\REST::decodeHttpResponse(Object(GuzzleHttp\Psr7\Response), Object(GuzzleHttp\Psr7\Request), 'Google_Service_ ...') #1 [内部函数]: Google\Http\REST::doExecute(Object(GuzzleHttp\Client), Object(GuzzleHttp\Psr7\Request), 'Google_Service_...') #2 F:\xampp \htdocs\bupa1\vendor\google\apiclient\src\Task\Runner.php(182): call_user_func_array(Array, Array) #3 F:\xampp\htdocs\bupa1\vendor\google\apiclient\src\Http\REST.php(66): Google\Task\Runner->run() #4 F:\xampp\htdocs\bupa1\vendor\google\apiclient \src\Client.php(898): Google\Http\REST::execute(Object(GuzzleHttp\Client), Object(GuzzleHttp\Psr7\Request), 'Google_Service_...', Array, NULL) #5 F: F:\xampp\htdocs\bupa1\vendor\google\apiclient\src\Http\REST.php 中的 \x 在第 128 行

我一直在试图弄清楚为什么会这样。到目前为止,我发现每次我向谷歌发送请求以创建事件时,我在calendarSetting.php 文件中的访问令牌都不会刷新。

现在我陷入了如何获取刷新令牌的问题,以便新用户也可以创建事件。

如果有人可以帮助解决这个问题,我将不胜感激。

谢谢

标签: phpapicalendargoogle-calendar-apirefresh-token

解决方案


您现在拥有的最终将成为单用户系统。如果该文件存在,那么其他人将不需要登录。如果您开始删除该文件,那么如果用户 1 仍在使用系统,那么他们将使用文件中的用户 2 令牌读取数据。

如果这是一个网络应用程序,您应该使用会话变量。

oauth2callback.php

require_once __DIR__ . '/vendor/autoload.php';
require_once __DIR__ . '/Oauth2Authentication.php';

// Start a session to persist credentials.
session_start();

// Handle authorization flow from the server.
if (! isset($_GET['code'])) {
    $client = buildClient();
    $auth_url = $client->createAuthUrl();
    header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
} else {
    $client = buildClient();
    $client->authenticate($_GET['code']); // Exchange the authencation code for a refresh token and access token.
    // Add access token and refresh token to seession.
    $_SESSION['access_token'] = $client->getAccessToken();
    $_SESSION['refresh_token'] = $client->getRefreshToken();    
    //Redirect back to main script
    $redirect_uri = str_replace("oauth2callback.php",$_SESSION['mainScript'],$client->getRedirectUri());    
    header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}

Oauth2Authentication.php

您应该检查此文件中所有代码的完整链接。请注意它如何将用户令牌存储在会话变量中,因此每个用户都有自己的令牌存储在其浏览器中。

function getOauth2Client() {
    try {
        
        $client = buildClient();
        
        // Set the refresh token on the client. 
        if (isset($_SESSION['refresh_token']) && $_SESSION['refresh_token']) {
            $client->refreshToken($_SESSION['refresh_token']);
        }
        
        // If the user has already authorized this app then get an access token
        // else redirect to ask the user to authorize access to Google Analytics.
        if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
            
            // Set the access token on the client.
            $client->setAccessToken($_SESSION['access_token']);                 
            
            // Refresh the access token if it's expired.
            if ($client->isAccessTokenExpired()) {              
                $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
                $client->setAccessToken($client->getAccessToken()); 
                $_SESSION['access_token'] = $client->getAccessToken();              
            }           
            return $client; 
        } else {
            // We do not have access request access.
            header('Location: ' . filter_var( $client->getRedirectUri(), FILTER_SANITIZE_URL));
        }
    } catch (Exception $e) {
        print "An error occurred: " . $e->getMessage();
    }
}

推荐阅读