You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Google服务账号(Server-to-Server)获取日历事件列表失败

问题排查与修复方案

你的代码核心问题在于误用了服务账号自身的primary日历——服务账号的主日历默认是空的,而你实际要访问的是目标用户/共享日历的事件,所以才会返回无结果。以下是具体修复步骤:

1. 替换目标日历ID

把代码里的$calendarId = 'primary';替换为你要访问的目标日历ID:

  • 个人日历:直接用目标用户的邮箱(比如xxx@gmail.com)
  • 共享日历:在日历设置里找到的唯一ID(格式类似abc123...@group.calendar.google.com)

2. 确认权限配置

再次确认服务账号邮箱(XXX@XXX.iam.gserviceaccount.com)已被添加到目标日历的权限列表中,权限级别至少设置为「查看所有事件」。

3. 清理冗余代码

服务端到服务端调用不需要会话支持,直接删除session_start();这行无用代码。

修改后的完整代码

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

putenv('GOOGLE_APPLICATION_CREDENTIALS=XXX.json');

$client = new Google\Client();
$client->useApplicationDefaultCredentials();
$client->addScope('https://www.googleapis.com/auth/calendar.events.readonly');

// 替换为你的目标日历ID
$calendarId = 'xxx@gmail.com'; 
$optParams = array(
    'maxResults' => 10,
    'orderBy' => 'startTime',
    'singleEvents' => TRUE,
    'timeMin' => date('c'),
);

$service = new Google_Service_Calendar($client);
try {
    $results = $service->events->listEvents($calendarId, $optParams);

    if (count($results->getItems()) == 0) {
        print "No upcoming events found.\n";
    } else {
        print "Upcoming events:\n";
        foreach ($results->getItems() as $event) {
            $start = $event->start->dateTime;
            if (empty($start)) {
                $start = $event->start->date;
            }
            printf("%s (%s)\n", $event->getSummary(), $start);
        }
    }
} catch (Exception $e) {
    // 捕获错误信息方便排查
    print "Error fetching events: " . $e->getMessage() . "\n";
}

额外排查点

  • 检查date('c')的时区是否与目标日历事件的时区一致,时区偏差可能导致过滤掉未来事件
  • 确认服务账号密钥文件(XXX.json)路径正确,且PHP进程有读取权限
  • 登录谷歌云控制台,确认Calendar API已启用且未触发调用限额

内容的提问来源于stack exchange,提问作者teo2600

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 10:15:08