1
votes

I've a calendar plugin working with my WordPress and I want to integrate Google Calendar API to Create, Read, Update, Delete Google Calendar Events. This is the process I followed.

I've created a function inside different Calendar plugin Class, that I got from the Google Calendar API documentation (https://developers.google.com/calendar/quickstart/php):

function getClient() {
        try{
            $client = new Google_Client();
            $client->setApplicationName('Google Calendar API');
            $client->setScopes(Google_Service_Calendar::CALENDAR);
            $client->setAuthConfig(AEC_PATH .'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);
            } else {
                print 'Access Token not generated!!';
            }

            // 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;
        } catch(Exception $e) {
            print_r($e->getMessage());
        }

Now I've added an action hook in constructor to initialize this function.

add_action('init', array($this, 'getClient'));

Now I'm calling this function getClient() in another function to call at particular time interval.

try{
            // Get the API client and construct the service object.
            $client = $this->getClient();
            $service = new Google_Service_Calendar($client);
            $calendarId = '<Google_Calendar_ID>';

            $event = new Google_Service_Calendar_Event(array(
                'summary' => $input->title,
                'location' => $input->address.''.$input->city.''.$input->state.''.$input->country.''.$input->zip,
                'description' => $input->description,
                'start' => array(
                    'dateTime' => '2019-09-22T09:00:00-07:00'
                ),
                'end' => array(
                    'dateTime' => '2019-09-22T17:00:00-07:00'
                ),
                'reminders' => array(
                    'useDefault' => FALSE,
                    'overrides' => array(
                    array('method' => 'email', 'minutes' => 24 * 60),
                    array('method' => 'popup', 'minutes' => 10),
                    ),
                ),
            ));

            $event = $service->events->insert($calendarId, $event);
            echo "--Google Event Created-->";
            print_r($event);
        } catch(Exception $e) {
            print_r($e->getMessage());
        }

Instead of new event created to my Google Calendar I'm getting an authorization error.

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "insufficientPermissions",
    "message": "Insufficient Permission: Request had insufficient authentication scopes."
   }
  ],
  "code": 403,
  "message": "Insufficient Permission: Request had insufficient authentication scopes."
 }

Could you please help me in understanding why I'm getting this error and how can I resolve it ?

2

2 Answers

0
votes

delete your token.pickle file, then run your script

SCOPES = ['https://www.googleapis.com/auth/calendar.readonly']

change to

SCOPES = ['https://www.googleapis.com/auth/calendar']
0
votes

This error is due a stale credentials, not an error in your code. To solve the situation you will have to delete the file named token.json and execute the code. You will be prompted to accept your app again with new scopes. If it is still failing, I recommend deleting both token.json and credentials.json; the latter for being corrupted.

If that didn't work, please check that your scope is written exactly the same as it appears on Authorizing requests with OAuth 2.0 and repeat the procedure.