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

集成Google Calendar实现客户预约:服务账户与OAuth问题求助

会议预约系统Google Calendar集成解决方案

一、服务账户调用API返回空列表问题解决

1. 获取服务账户邮箱

在Google Cloud控制台进入IAM与管理员 > 服务账户,找到你的服务账户,复制其邮箱(格式:xxx@项目ID.iam.gserviceaccount.com)。

2. 共享日历至服务账户

打开Google Calendar网页版:

  • 找到目标日历,点击右侧「⋮」选择「设置和共享」;
  • 滚动到「共享特定人员」区域,点击「添加人员」;
  • 粘贴服务账户邮箱,权限根据需求选择「查看所有详情」或「更改和管理事件」,点击「发送」。

3. 修正API调用逻辑

调用API时必须指定具体日历ID:

  • 主日历ID为你的个人邮箱;
  • 其他日历的ID在「设置和共享」页面的「日历ID」字段获取。
    示例调用events.list接口的参数(PHP):
$calendar_id = 'your-personal-email@example.com'; // 替换为实际日历ID
$api_url = "https://www.googleapis.com/calendar/v3/calendars/{$calendar_id}/events";

二、OAuth流程创建活动的完整实现

你提供的代码仅生成授权URL,完整OAuth2流程需三步:

1. 获取授权码

用户访问你生成的$login_url完成授权后,会跳转到CLIENT_REDIRECT_URL,URL参数中包含code,需捕获该参数。

2. 交换获取访问令牌

用授权码向Google令牌接口发送POST请求,获取access_token和refresh_token:

$token_url = 'https://oauth2.googleapis.com/token';
$post_fields = http_build_query([
    'code' => $_GET['code'],
    'client_id' => CLIENT_ID,
    'client_secret' => CLIENT_SECRET,
    'redirect_uri' => CLIENT_REDIRECT_URL,
    'grant_type' => 'authorization_code'
]);

$ch = curl_init($token_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);

// 保存refresh_token到数据库,用于后续令牌刷新
$refresh_token = $response['refresh_token'];

3. 使用令牌创建活动

通过access_token调用events.insert接口创建会议:

$calendar_id = 'your-calendar-id@example.com';
$event_url = "https://www.googleapis.com/calendar/v3/calendars/{$calendar_id}/events";

$event_data = json_encode([
    'summary' => '客户预约会议',
    'start' => ['dateTime' => '2024-05-20T10:00:00+08:00'],
    'end' => ['dateTime' => '2024-05-20T11:00:00+08:00'],
    'attendees' => [['email' => 'customer@example.com']]
]);

$ch = curl_init($event_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $event_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Authorization: Bearer {$response['access_token']}",
    'Content-Type: application/json'
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);

4. 离线令牌刷新

当access_token过期(有效期约1小时),用保存的refresh_token重新获取:

$refresh_url = 'https://oauth2.googleapis.com/token';
$refresh_fields = http_build_query([
    'refresh_token' => $refresh_token,
    'client_id' => CLIENT_ID,
    'client_secret' => CLIENT_SECRET,
    'grant_type' => 'refresh_token'
]);

// 发送POST请求逻辑同步骤2,获取新的access_token

三、方案选择建议

  • 服务账户:适合无用户交互的后台操作(如批量同步空闲时段),需确保日历共享配置正确;
  • OAuth2:适合需要用户授权的场景(如客户自主预约),必须完成完整授权流程才能调用API操作日历。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 11:10:37