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

Google Calendar API技术问题:维持用户认证与事件转任务

解决Google Calendar API的两个问题:认证维持与事件创建优化

让我一步步帮你搞定这两个问题:


1. 维持/自动重新加载用户认证

你当前的代码只处理了首次授权的access token存储,但access token通常只有1小时有效期,过期后就会失效,而且没用到offline模式获取的refresh token来自动刷新——这就是令牌失效、需要手动重连的核心原因。

修改你的首页认证代码,加入自动刷新逻辑:

session_start(); // 务必放在代码最开头,保证session正常工作

$client = new Google_Client();
$client->setAuthConfig('client_secret.json');
$client->addScope(Google_Service_Calendar::CALENDAR);
$client->setRedirectUri($monsite);
$client->setAccessType('offline'); // 这个配置要保留,用来获取refresh token
$client->setIncludeGrantedScopes(true);

// 处理授权回调的code
if (isset($_GET['code'])) {
  $client->authenticate($_GET['code']);
  // 保存完整的token数据(包含refresh token)到session
  $tokenData = $client->getAccessToken();
  $_SESSION['oauth'] = $tokenData;
  // 授权完成后重定向回首页,避免重复处理code参数
  header('Location: ' . filter_var($monsite, FILTER_SANITIZE_URL));
  die();
}

// 检查并加载session中的token
if (isset($_SESSION['oauth'])) {
  $client->setAccessToken($_SESSION['oauth']);
  
  // 自动检测token是否过期,用refresh token刷新
  if ($client->isAccessTokenExpired()) {
    if ($refreshToken = $client->getRefreshToken()) {
      $newToken = $client->fetchAccessTokenWithRefreshToken($refreshToken);
      $client->setAccessToken($newToken);
      // 更新session里的token数据
      $_SESSION['oauth'] = $newToken;
    } else {
      // 没有refresh token,只能重新引导用户授权
      $authUrl = $client->createAuthUrl();
      header('Location: ' . filter_var($authUrl, FILTER_SANITIZE_URL));
      die();
    }
  }
} else {
  // 没有有效token,跳转授权页面
  $authUrl = $client->createAuthUrl();
  header('Location: ' . filter_var($authUrl, FILTER_SANITIZE_URL));
  die();
}

关键优化点:

  • 保存完整的token数据到session,不要只存access token,这样refresh token会被保留下来
  • 用isAccessTokenExpired()自动检测token过期,通过refresh token静默刷新,无需用户手动重连
  • 授权后重定向回首页,避免用户刷新页面时重复处理code参数

2. 直接插入日历事件(无需来宾邀请,通知创建者)

你之前的代码设置了attendees,这会触发Google Calendar给来宾发邀请,需要对方确认。要实现“直接插入事件、无需询问”的需求,只需要去掉attendees参数,同时可以添加提醒确保创建者收到通知。

方案1:创建普通日历事件(无邀请,带提醒)

修改你的事件创建代码:

// 注意:这里的$client变量名和Google_Client实例冲突了,建议改成$clientName这类名称
$event = new Google_Service_Calendar_Event(array(
  'summary' => $clientName . " / " . $contrat,
  'location' => $adresse,
  'description' => $desc,
  'start' => array(
    'dateTime' => $start,
    'timeZone' => 'Europe/Paris',
  ),
  'end' => array(
    'dateTime' => $end,
    'timeZone' => 'Europe/Paris',
  ),
  // 去掉attendees参数,不再发送邀请
  // 添加自定义提醒,确保创建者收到通知
  'reminders' => array(
    'useDefault' => false,
    'overrides' => array(
      array('method' => 'email', 'minutes' => 60), // 事件前1小时发邮件提醒
      array('method' => 'popup', 'minutes' => 15), // 事件前15分钟弹出提醒
    ),
  ),
));

// 插入到当前用户的主日历
$calendarId = 'primary';
$createdEvent = $service->events->insert($calendarId, $event);

方案2:如果是要创建Google Tasks(而非日历事件)

如果你说的“转为任务”是指Google Tasks(不是日历事件),需要切换到Google Tasks API:

  1. 先在Google Cloud控制台启用Google Tasks API
  2. 调整scope和创建代码:
// 在认证部分添加Tasks的scope
$client->addScope(Google_Service_Tasks::TASKS);

// 创建Task
$service = new Google_Service_Tasks($client);
$task = new Google_Service_Tasks_Task(array(
  'title' => $clientName . " / " . $contrat,
  'notes' => $desc,
  'due' => $start, // 格式需为RFC3339,比如"2024-05-20T14:00:00Z"
));

// 插入到默认任务列表
$taskListId = '@default';
$createdTask = $service->tasks->insert($taskListId, $task);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:17:45