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

如何在Gmail插件后端复用access token实现Gmail消息元数据查询

问题:迁移Gmail插件到Node.js后端时401认证错误的解决方法

原Apps Script实现

function buildAddOn(e) {
  var accessToken = e.messageMetadata.accessToken;
  GmailApp.setCurrentMessageAccessToken(accessToken);
  var messageId = e.messageMetadata.messageId;
  var message = GmailApp.getMessageById(messageId);
  ...
}

当前Node.js后端代码

import Hapi from "@hapi/hapi";
import { google } from "googleapis";

const port = 3023;

const init = async () => {
  const server = Hapi.server({
    port: port,
    host: "localhost",
  });

  server.route({
    method: "POST",
    path: "/",
    handler: async (request, h) => {

      const { payload } = request;
      const { gmail } = payload;

      const gmailAPI = google.gmail({
        version: "v1",
        headers: {
          // 这里想使用Gmail插件客户端传来的access token
          Authorization: `Bearer ${gmail.accessToken}`,
        },
      });

      try {
        // 获取插件激活时Gmail中当前打开邮件的信息
        const res = await gmailAPI.users.messages.get({
          userId: "me",
          id: gmail.messageId,
        });
        console.log(res.data);
      } catch (e) {
        console.log(e.response.data);
      }
    }
  });

  await server.start();
  console.log(`Server running on ${server.info.uri}`);
};

init();

Gmail客户端传来的Payload

{
  "commonEventObject": { "hostApp": "GMAIL", "platform": "WEB" },
  "gmail": {
    "messageId": "msg-f:1762895788594548046",
    "threadId": "thread-f:1762895788594548046",
    "accessToken": "XXXYYYZZZ" // 已脱敏
  },
  "authorizationEventObject": {
    "userOAuthToken": "GGGYYYJJJ", // 已脱敏
    "systemIdToken": "FFFHHHCCC" // 已脱敏
  }
}

错误信息

{
  "error": {
    "code": 401,
    "message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
    "errors": [ [Object] ],
    "status": "UNAUTHENTICATED"
  }
}

插件授权范围

"oauthScopes": [
  "https://www.googleapis.com/auth/gmail.addons.execute",
  "https://mail.google.com/",
  "https://www.googleapis.com/auth/gmail.metadata", 
  "https://www.googleapis.com/auth/gmail.readonly"
]

问题核心

原本在Apps Script中通过GmailApp.setCurrentMessageAccessToken(accessToken)可以获取当前打开邮件的元数据,现在迁移到Node.js后端(使用Google API Node.js客户端库),尝试用Gmail客户端传来的access token调用Gmail API时出现401认证错误,需要指导如何复现原功能。


解决方法

1. 正确配置客户端认证方式

Google API Node.js客户端库不支持手动在headers中添加Authorization,需通过OAuth2客户端配置认证信息:

// 替换原有的gmailAPI初始化代码
const oauth2Client = new google.auth.OAuth2();
oauth2Client.setCredentials({ access_token: gmail.accessToken });

const gmailAPI = google.gmail({
  version: "v1",
  auth: oauth2Client,
});

2. 转换messageId格式

Gmail客户端传来的messageId带有msg-f:前缀,需去除后才能用于API调用:

// 处理messageId,移除前缀
const pureMessageId = gmail.messageId.replace(/^msg-f:/, '');

// 调用API时使用处理后的ID
const res = await gmailAPI.users.messages.get({
  userId: "me",
  id: pureMessageId,
});

3. 验证access token权限

解码客户端传来的access token,确认其包含gmail.readonly或gmail.metadata等必要权限范围,若权限不足需调整插件的OAuth授权配置。

4. 检查token有效性

确认access token未过期,若已过期需触发插件的重新授权流程,获取新的有效token。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 07:22:49