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

如何实现Google日历与应用内日历的同步?附代码片段

嘿,看你已经在尝试把Google日历整合到自己的日历应用里了,我帮你把这段代码补全并优化,确保能顺利实现用户同步Google日历事件到应用内的功能~

完整的Google日历事件同步实现代码
<!-- 加载Google API客户端库 -->
<script async defer src="https://apis.google.com/js/api.js" 
        onload="this.onload=function(){};handleClientLoad()" 
        onreadystatechange="if (this.readyState === 'complete') this.onload()">
</script>

<!-- 授权控制按钮 -->
<button id="authorize-button" style="display: none;">授权访问Google日历</button>
<button id="signout-button" style="display: none;">退出登录</button>

<script>
  // 替换成你在Google Cloud控制台获取的配置信息
  const CLIENT_ID = '你的OAuth客户端ID';
  const API_KEY = '你的API密钥';
  // 只读权限(适合仅同步查看),如需修改日历事件请改用'https://www.googleapis.com/auth/calendar'
  const SCOPES = 'https://www.googleapis.com/auth/calendar.readonly';

  let tokenClient;
  let gapiInited = false;
  let gisInited = false;

  // 加载API客户端与认证模块
  function handleClientLoad() {
    gapi.load('client', initializeGapiClient);
    initTokenClient();
  }

  // 初始化GAPI客户端
  async function initializeGapiClient() {
    await gapi.client.init({
      apiKey: API_KEY,
      // Google日历API的发现文档地址
      discoveryDocs: ["https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest"],
    });
    gapiInited = true;
    maybeEnableButtons();
  }

  // 初始化Token客户端(处理OAuth授权)
  function initTokenClient() {
    tokenClient = google.accounts.oauth2.initTokenClient({
      client_id: CLIENT_ID,
      scope: SCOPES,
      callback: '', // 后续动态设置回调
    });
    gisInited = true;
    maybeEnableButtons();
  }

  // 当API与授权模块都就绪时显示按钮
  function maybeEnableButtons() {
    if (gapiInited && gisInited) {
      document.getElementById('authorize-button').style.display = 'block';
    }
  }

  // 处理授权按钮点击
  function handleAuthClick() {
    tokenClient.callback = async (resp) => {
      if (resp.error !== undefined) {
        throw resp;
      }
      // 授权成功后更新按钮状态
      document.getElementById('signout-button').style.display = 'block';
      document.getElementById('authorize-button').innerText = '已授权';
      // 开始同步事件
      await listUpcomingEvents();
    };

    if (gapi.client.getToken() === null) {
      // 无令牌时请求用户授权
      tokenClient.requestAccessToken({prompt: 'consent'});
    } else {
      // 已有令牌时刷新权限
      tokenClient.requestAccessToken({prompt: ''});
    }
  }

  // 处理退出登录
  function handleSignoutClick() {
    const token = gapi.client.getToken();
    if (token !== null) {
      google.accounts.oauth2.revoke(token.access_token);
      gapi.client.setToken('');
      // 重置按钮状态
      document.getElementById('authorize-button').innerText = '授权访问Google日历';
      document.getElementById('signout-button').style.display = 'none';
      // 清空应用内同步的事件
      clearSyncedEvents();
    }
  }

  // 获取Google日历的即将到来事件并同步到应用内
  async function listUpcomingEvents() {
    try {
      const response = await gapi.client.calendar.events.list({
        'calendarId': 'primary', // 同步用户的主日历,也可指定其他日历ID
        'timeMin': (new Date()).toISOString(), // 仅同步当前时间之后的事件
        'showDeleted': false,
        'singleEvents': true, // 将重复事件拆分为单个条目
        'maxResults': 10, // 限制同步的事件数量,可按需调整
        'orderBy': 'startTime' // 按开始时间排序
      });

      const events = response.result.items;
      if (!events || events.length === 0) {
        console.log('未找到即将到来的事件');
        return;
      }

      // 同步事件到你的应用日历 - 请自定义此处逻辑
      syncEventsToAppCalendar(events);
    } catch (err) {
      console.error('获取事件失败:', err);
      return;
    }
  }

  // 自定义:将Google日历事件转换为应用内格式并同步
  function syncEventsToAppCalendar(events) {
    events.forEach(event => {
      // 处理事件的开始/结束时间(区分全天事件和定时事件)
      const start = event.start.dateTime || event.start.date;
      const end = event.end.dateTime || event.end.date;
      console.log(`同步事件:${event.summary} - 开始:${start},结束:${end}`);
      // 在这里添加你的代码,将事件插入到应用的日历存储或界面中
    });
  }

  // 自定义:清空应用内的同步事件
  function clearSyncedEvents() {
    // 添加你的代码,清除应用内已同步的Google日历事件
    console.log('已清除同步的Google日历事件');
  }

  // 绑定按钮点击事件
  document.getElementById('authorize-button').addEventListener('click', handleAuthClick);
  document.getElementById('signout-button').addEventListener('click', handleSignoutClick);
</script>
关键说明与注意事项
  • Google Cloud控制台配置:你需要先在Google Cloud控制台创建项目,启用「Calendar API」,然后创建OAuth 2.0客户端ID,并配置允许的JavaScript来源(你的应用域名),否则授权会失败。
  • 权限范围选择:使用calendar.readonly足够实现同步查看的需求,如果需要让用户在你的应用内修改Google日历事件,再改用calendar权限,但注意该权限需要通过Google的审核。
  • 事件同步逻辑:syncEventsToAppCalendar是核心自定义函数,你需要根据自己应用的日历数据结构,把Google返回的事件字段(标题、时间、描述等)转换成应用能识别的格式,再插入到存储或界面中。
  • 令牌安全:代码中处理了令牌的获取、刷新和撤销,确保用户退出时能完全移除授权权限,保护用户隐私。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:29:44