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

使用App Scripts调用Gemini API时持续出现InvalidSignature错误求助

Gemini API调用出现InvalidSignature错误的排查与修复

问题描述

我尝试使用App Scripts调用Gemini API,但始终收到InvalidSignature错误提示。所用代码是根据Gemini官方文档中的Python代码转换而来的私有API调用实现。

原代码

function createHeaders(payload) {
  var geminiApiKey = API_KEY
  var geminiApiSecret = SECRET_KEY
  var encodedApiSecret = Utilities.newBlob(geminiApiSecret, 'UTF-8').getBytes()

  var payloadNonce = new Date().getTime() / 1000;
  payload["nonce"] = Math.round(payloadNonce);

  var encodedPayload = Utilities.newBlob(JSON.stringify(payload), 'UTF-8').getBytes()
  var b64 = Utilities.base64Encode(encodedPayload) //string

  var signature = Utilities.computeHmacSignature(
    Utilities.MacAlgorithm.HMAC_SHA_384,
    b64,
    geminiApiKeyAuditor 
  ) //bytes

  return {
    "Content-Type": "text/plain",
    "X-GEMINI-APIKEY": geminiApiKeyAuditor,
    "X-GEMINI-PAYLOAD": b64,
    "X-GEMINI-SIGNATURE": Utilities.base64Encode(signature), //string
    "Cache-Control": "no-cache"
  };
}

function fetchGeminiData() {
  var baseUrl = "https://api.gemini.com";
  var url = baseUrl + "/v1/mytrades";

  var payload = {
    "request": "/v1/mytrades"
  };

  var headers = createHeaders(payload);
  var options = {
    "method": "post",
    "headers": headers,
  };

  var response = UrlFetchApp.fetch(url, options);
  var responseData = response.getContentText();
  var jsonResponse = JSON.parse(responseData);
  Logger.log(jsonResponse);
}

错误信息

Exception: Request failed for https://api.gemini.com returned code 400. Truncated server response: {"result":"error","reason":"InvalidSignature","message":"InvalidSignature"}

问题排查与修复

1. 变量名错误(核心问题)

代码中多处使用了未定义的geminiApiKeyAuditor,这是导致签名验证失败的主要原因:

  • 计算HMAC签名时,第三个参数应该是API密钥的字节数组(encodedApiSecret),而非错误的geminiApiKeyAuditor
  • 请求头中的X-GEMINI-APIKEY应该是你的实际API密钥(geminiApiKey),而非geminiApiKeyAuditor

2. Nonce唯一性问题

原代码中对时间戳除以1000后取整,可能导致短时间内请求的nonce重复,触发签名验证失败。建议直接使用毫秒级时间戳作为nonce,确保每次请求的nonce唯一:

payload["nonce"] = new Date().getTime();

3. 修复后的完整代码

function createHeaders(payload) {
  var geminiApiKey = API_KEY; // 确保已正确定义你的API密钥
  var geminiApiSecret = SECRET_KEY; // 确保已正确定义你的密钥
  var encodedApiSecret = Utilities.newBlob(geminiApiSecret, 'UTF-8').getBytes();

  // 使用毫秒级时间戳作为nonce,保证唯一性
  payload["nonce"] = new Date().getTime();

  var encodedPayload = Utilities.newBlob(JSON.stringify(payload), 'UTF-8').getBytes();
  var b64 = Utilities.base64Encode(encodedPayload);

  var signature = Utilities.computeHmacSignature(
    Utilities.MacAlgorithm.HMAC_SHA_384,
    b64,
    encodedApiSecret
  );

  return {
    "Content-Type": "text/plain",
    "X-GEMINI-APIKEY": geminiApiKey,
    "X-GEMINI-PAYLOAD": b64,
    "X-GEMINI-SIGNATURE": Utilities.base64Encode(signature),
    "Cache-Control": "no-cache"
  };
}

function fetchGeminiData() {
  var baseUrl = "https://api.gemini.com";
  var url = baseUrl + "/v1/mytrades";

  var payload = {
    "request": "/v1/mytrades"
  };

  var headers = createHeaders(payload);
  var options = {
    "method": "post",
    "headers": headers,
    "muteHttpExceptions": true // 可选,便于查看完整错误响应内容
  };

  var response = UrlFetchApp.fetch(url, options);
  var responseData = response.getContentText();
  var jsonResponse = JSON.parse(responseData);
  Logger.log(jsonResponse);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 17:00:38