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

使用JavaScript无法将Clockify数据拉取至Google表格,求排查

问题排查与修正:Clockify数据同步到Google Sheets失败

核心错误点分析

  • 请求头结构错误:你嵌套了两层headers,UrlFetchApp要求headers是请求配置的顶级属性,嵌套会导致API无法识别你的密钥。
  • URL参数转义错误:URL里的&是HTML转义字符,在JavaScript模板字符串中应该直接用&,否则参数无法被正确解析。
  • 缺失错误处理:没有捕获请求失败的场景(比如密钥无效、Workspace ID错误),无法定位具体问题。
  • 潜在数据结构风险:假设data.timeEntries一定存在,若API返回空数据或结构变化会直接报错。

修正后的代码

function getClockifyReport() {
  // 修正请求头结构:去掉嵌套的headers层级
  const options = {
    headers: {
      "X-Api-Key": "你的实际API密钥",
      "content-type": "application/json"
    }
  };
  
  const workspaceId = "你的实际Workspace ID";
  
  // 修正URL参数:将&替换为&
  const url = `https://reports.api.clockify.me/v1/workspaces/${workspaceId}/reports/detailed?userGroupIds=all&projectIds=all&clientIds=all&billable=null&invoiced=null&approved=null&sortByDate=null&sortAscending=null&page=1&pageSize=50&considerDurationFormat=null&roundingMinutes=null&formatted=false`;

  try {
    // 添加错误捕获
    const response = UrlFetchApp.fetch(url, options);
    // 检查响应状态码
    if (response.getResponseCode() !== 200) {
      throw new Error(`API请求失败,状态码:${response.getResponseCode()},响应内容:${response.getContentText()}`);
    }
    
    const data = JSON.parse(response.getContentText());
    
    // 检查timeEntries是否存在
    if (!data.timeEntries || !Array.isArray(data.timeEntries)) {
      throw new Error("API返回数据格式异常,未找到timeEntries数组");
    }
    
    const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet 1");
    if (!sheet) {
      throw new Error("未找到名为'Sheet 1'的工作表");
    }
    
    sheet.clear();
    // 先准备所有数据再批量写入,比多次appendRow更高效
    const rows = [["Description", "Start Time", "End Time", "Duration", "User", "Client", "Project"]];
    
    data.timeEntries.forEach((entry) => {
      // 处理可能的空值,避免报错
      rows.push([
        entry.description || "",
        entry.timeInterval?.start || "",
        entry.timeInterval?.end || "",
        entry.timeInterval?.duration || "",
        entry.user?.name || "",
        entry.client?.name || "",
        entry.project?.name || ""
      ]);
    });
    
    // 批量写入数据
    if (rows.length > 1) {
      sheet.getRange(1, 1, rows.length, rows[0].length).setValues(rows);
    }
  } catch (error) {
    // 输出错误信息到日志,方便排查
    console.error("同步失败:", error.message);
    // 也可以在表格中显示错误
    const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet 1");
    if (sheet) {
      sheet.clear();
      sheet.appendRow(["同步错误:", error.message]);
    }
  }
}

额外验证步骤

  • 确认X-Api-Key是从Clockify账户设置中获取的有效密钥,且该密钥拥有对应Workspace的报表访问权限。
  • 确认workspaceId正确,可从Clockify workspace设置页面获取。
  • 运行脚本后查看Apps Script的日志(查看>日志),根据错误提示进一步排查。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 10:12:58