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:
- 先在Google Cloud控制台启用Google Tasks API
- 调整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
相关产品推荐
相关产品推荐

