使用服务帐户插入谷歌日历条目

我正在尝试使用服务帐户在 Google 日历上创建条目。我对此非常接近,但最后一行不起作用。当我让它运行时,我得到了一个。否则,程序可以毫无差错地运行,无论它的价值如何。500 Internal Service Error

文件内容可以在这里找到。我尝试调用的方法从该文件的第 1455 行开始。Calendar.phpinsert()

<?php

function calendarize ($title, $desc, $ev_date, $cal_id) {

    session_start();

    /************************************************
    Make an API request authenticated with a service
    account.
    ************************************************/
    set_include_path( '../google-api-php-client/src/');

    require_once 'Google/Client.php';
    require_once 'Google/Service/Calendar.php';

    // (not real keys)
    $client_id = '843319906820-jarm3f5ctbtjj9b7lp5qdcqal54p1he6.apps.googleusercontent.com';
    $service_account_name = '843319906820-jarm3f5ctbtjj7b7lp5qdcqal54p1he6@developer.gserviceaccount.com';
    $key_file_location = '../google-api-php-client/calendar-249226a7a27a.p12';

//    echo pageHeader("Service Account Access");
    if (!strlen($service_account_name) || !strlen($key_file_location))
        echo missingServiceAccountDetailsWarning();

    $client = new Google_Client();
    $client->setApplicationName("xxxx Add Google Calendar Entries");

    if (isset($_SESSION['service_token'])) {
        $client->setAccessToken($_SESSION['service_token']);
    }

    $key = file_get_contents($key_file_location);
    $cred = new Google_Auth_AssertionCredentials(
        $service_account_name, 
        array('https://www.googleapis.com/auth/calendar'), 
        $key
    );
    $client->setAssertionCredentials($cred);
    if($client->getAuth()->isAccessTokenExpired()) {
        $client->getAuth()->refreshTokenWithAssertion($cred);
    }
    $_SESSION['service_token'] = $client->getAccessToken();

    // Prior to this, the code has mostly come from Google's example
    //     google-api-php-client / examples / service-account.php
    // and relates to getting the access tokens. 

    // The rest of this is about setting up the calendar entry.
    //Set the Event data
    $event = new Google_Service_Calendar_Event();
    $event->setSummary($title);
    $event->setDescription($desc);

    $start = new Google_Service_Calendar_EventDateTime();
    $start->setDate($ev_date);
    $event->setStart($start);

    $end = new Google_Service_Calendar_EventDateTime();
    $end->setDate($ev_date);     
    $event->setEnd($end);

    $calendarService = new Google_Service_Calendar($client);
    $calendarList = $calendarService->calendarList;

    $events = $calendarService->events;

    // if I leave this line, my code won't crash (but it won't do anything, either)
    //echo "here"; die(); 

    $events.insert($cal_id, $event, false);
} 

?>

答案 1

我想通了。由于我没有看到任何将服务帐户与API v3一起使用的完整示例,因此我将发布我的完整解决方案以供参考。但是,除了实现代码之外,还需要执行一些操作:

1)您需要转到Google开发人员的控制台并将您的帐户标记为“服务帐户”。这将使其与 Web 应用程序区分开来。重要的区别在于,在添加事件之前,系统不会提示任何人登录到其帐户,因为该帐户将属于您的应用程序,而不是最终用户。有关详细信息,请参阅此文章,从第 5 页开始。

2)您需要创建公钥/私钥对。在开发人员的控制台中,单击“凭据”。在您的服务帐户下,单击“生成新的P12密钥”。您需要将其存储在某个地方。该文件位置将成为以下代码中的变量字符串。$key_file_location

3)同样从开发人员的控制台中,您需要启用API。在项目中,在左边距处可以看到 。选择该选项并找到 API。单击它,接受服务条款,并验证它现在是否显示在 下,状态为CalendarAPIsCalendarEnabled APIsOn

4)在您要添加活动的Google日历中,在设置下,点击日历设置,然后点击顶部的“共享此日历”。在“与特定人员共享”下的“人员”字段中,粘贴服务帐户凭据中的电子邮件地址。将权限设置更改为“对事件进行更改”。不要忘记保存更改。

然后,在某个地方实现此代码。

如果某些内容令人困惑或被遗漏,请发表评论。祝你好运!

<?php

function calendarize ($title, $desc, $ev_date, $cal_id) {

    session_start();

    /************************************************
    Make an API request authenticated with a service
    account.
    ************************************************/
    set_include_path( '../google-api-php-client/src/');

    require_once 'Google/Client.php';
    require_once 'Google/Service/Calendar.php';

    //obviously, insert your own credentials from the service account in the Google Developer's console
    $client_id = '843319906820-xxxxxxxxxxxxxxxxxxxdcqal54p1he6.apps.googleusercontent.com';
    $service_account_name = '843319906820-xxxxxxxxxxxxxxxxxxxdcqal54p1he6@developer.gserviceaccount.com';
    $key_file_location = '../google-api-php-client/calendar-xxxxxxxxxxxx.p12';

    if (!strlen($service_account_name) || !strlen($key_file_location))
        echo missingServiceAccountDetailsWarning();

    $client = new Google_Client();
    $client->setApplicationName("Whatever the name of your app is");

    if (isset($_SESSION['service_token'])) {
        $client->setAccessToken($_SESSION['service_token']);
    }

    $key = file_get_contents($key_file_location);
    $cred = new Google_Auth_AssertionCredentials(
        $service_account_name, 
        array('https://www.googleapis.com/auth/calendar'), 
        $key
    );
    $client->setAssertionCredentials($cred);
    if($client->getAuth()->isAccessTokenExpired()) {
        $client->getAuth()->refreshTokenWithAssertion($cred);
    }
    $_SESSION['service_token'] = $client->getAccessToken();

    $calendarService = new Google_Service_Calendar($client);
    $calendarList = $calendarService->calendarList;

    //Set the Event data
    $event = new Google_Service_Calendar_Event();
    $event->setSummary($title);
    $event->setDescription($desc);

    $start = new Google_Service_Calendar_EventDateTime();
    $start->setDateTime($ev_date);
    $event->setStart($start);

    $end = new Google_Service_Calendar_EventDateTime();
    $end->setDateTime($ev_date);
    $event->setEnd($end);

    $createdEvent = $calendarService->events->insert($cal_id, $event);

    echo $createdEvent->getId();
} 

?>

一些有用的资源:
Github 示例服务帐户
Google Developers Console 用于在 API v3
中插入事件 使用 OAuth 2.0 访问 Google API


答案 2

以下是Google API Client 2.0的方法

按照 Alex 的 Answer Go Google Developer 控制台创建服务帐户,但以 JSON 格式创建凭据

遵循Google API客户端升级指南,由作曲家安装并包含在

 require_once 'vendor/autoload.php';

按照 Alex 的回答转到 Google 日历,使用服务帐户 ID 共享日历

xxxxx@yyyy.iam.gserviceaccount.com 

将Ref.带到下面的编码,最重要的是日历ID应该是日历创建者的电子邮件,但不是主要的

<?php


require_once __DIR__.'/vendor/autoload.php';
   session_start();     


$client = new Google_Client();
$application_creds = __DIR__.'/secret.json';  //the Service Account generated cred in JSON
$credentials_file = file_exists($application_creds) ? $application_creds : false;
define("APP_NAME","Google Calendar API PHP");   //whatever
$client->setAuthConfig($credentials_file);
$client->setApplicationName(APP_NAME);
$client->addScope(Google_Service_Calendar::CALENDAR);
$client->addScope(Google_Service_Calendar::CALENDAR_READONLY);

//Setting Complete

//Go Google Calendar to set "Share with ..."  Created in Service Account (xxxxxxx@sustained-vine-198812.iam.gserviceaccount.com)

//Example of Use of API
$service = new Google_Service_Calendar($client);  


$calendarId = 'xxxx@gmail.com';   //NOT primary!! , but the email of calendar creator that you want to view
$optParams = array(
  'maxResults' => 10,
  'orderBy' => 'startTime',
  'singleEvents' => TRUE,
  'timeMin' => date('c'),
);
$results = $service->events->listEvents($calendarId, $optParams);

if (count($results->getItems()) == 0) {
  print "No upcoming events found.\n";
} else {
  echo "Upcoming events:";
  echo "<hr>";
  echo "<table>";
  foreach ($results->getItems() as $event) {
    $start = $event->start->dateTime;
    if (empty($start)) {
      $start = $event->start->date;
    }
    echo "<tr>";
    echo"<td>".$event->getSummary()."</td>";
    echo"<td>".$start."</td>";
    echo "</tr>";
  }
  echo "</table>";
}  

推荐