如何不使用Google客户端库发起API请求?Deno环境Gmail API需求
用Deno通过Fetch调用Google Gmail API的方案
完全可以不依赖Google官方库,直接用Deno的原生fetch调用Gmail REST API,核心是手动完成OAuth2认证流程获取有效访问令牌。以下是具体实现步骤:
一、完成OAuth2认证(获取访问令牌)
Google API的认证核心是拿到带权限的access_token,分两种常见场景:
场景1:服务端无用户交互(适合后台分析任务)
如果你的分析任务不需要用户手动授权(比如访问企业邮箱的共享数据),可以用服务账号JWT认证:
- 在Google Cloud控制台创建服务账号,下载JSON格式的密钥文件
- 在Deno中手动生成JWT签名,然后请求令牌:
import { create } from "https://deno.land/x/djwt@v2.8/mod.ts"; import { parse } from "https://deno.land/std@0.200.0/json/mod.ts"; // 加载服务账号密钥 const serviceAccount = parse(await Deno.readTextFile("./service-account-key.json")); const now = Math.floor(Date.now() / 1000); // 构造JWT payload const payload = { iss: serviceAccount.client_email, scope: "https://www.googleapis.com/auth/gmail.readonly", aud: "https://oauth2.googleapis.com/token", exp: now + 3600, // 令牌有效期1小时 iat: now, }; // 用RS256算法签名JWT const jwt = await create( { alg: "RS256", typ: "JWT" }, payload, serviceAccount.private_key ); // 请求获取access_token const tokenResponse = await fetch("https://oauth2.googleapis.com/token", { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: new URLSearchParams({ grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer", assertion: jwt, }), }); const tokenData = await tokenResponse.json(); const accessToken = tokenData.access_token;
场景2:需要用户手动授权(访问个人邮箱)
如果需要访问用户个人邮箱,用授权码流程:
- 引导用户访问Google授权页面,获取授权码
- 用授权码交换access_token:
const clientId = "YOUR_CLIENT_ID"; const clientSecret = "YOUR_CLIENT_SECRET"; const redirectUri = "YOUR_REDIRECT_URI"; const authCode = "USER_AUTH_CODE"; const tokenResponse = await fetch("https://oauth2.googleapis.com/token", { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: new URLSearchParams({ client_id: clientId, client_secret: clientSecret, code: authCode, redirect_uri: redirectUri, grant_type: "authorization_code", }), }); const tokenData = await tokenResponse.json(); const accessToken = tokenData.access_token; // 可选:保存refresh_token用于后续刷新令牌
二、用Fetch调用Gmail API
拿到accessToken后,直接调用Gmail的REST端点即可,比如获取收件箱前10封邮件:
// 获取邮件列表 const messagesResponse = await fetch( "https://gmail.googleapis.com/gmail/v1/users/me/messages?maxResults=10", { headers: { Authorization: `Bearer ${accessToken}`, }, } ); const messagesData = await messagesResponse.json(); // 可选:获取单封邮件详情 if (messagesData.messages?.length) { const messageId = messagesData.messages[0].id; const messageResponse = await fetch( `https://gmail.googleapis.com/gmail/v1/users/me/messages/${messageId}`, { headers: { Authorization: `Bearer ${accessToken}` }, } ); const messageDetail = await messageResponse.json(); console.log(messageDetail); }
关键注意事项
- 确保在Google Cloud控制台启用了Gmail API
- 选择正确的权限范围:比如只读用
https://www.googleapis.com/auth/gmail.readonly,如需修改用更高级的权限 - 服务账号场景下,需要给服务账号授权对应的邮箱权限(在Google Workspace admin控制台完成)
不需要迁移到Node.js,Deno的fetch和crypto相关模块完全能覆盖需求,核心是手动实现OAuth2的令牌生成/交换流程。
内容的提问来源于stack exchange,提问作者Ammar Ahmed
相关产品推荐
相关产品推荐

