通过Google Apps Script调用Discord API获取频道时遇403错误(错误码1020)
问题重现
我用Google Apps Script编写了以下代码,尝试获取Discord服务器的频道列表:
var token = "MY_TOKEN" var url = "https://discord.com/api/v10/guilds/[GUILD_ID]/channels" var header = { Authorization: "Bot " + token } function myFunction(){ var params = { method: "get", headers: header, muteHttpExceptions: false } var response = UrlFetchApp.fetch(url,params) Logger.log(response.getContentText()) }
运行myFunction()时抛出错误:
Exception: Request failed for https://discord.com returned code 403. Truncated server response: error code: 1020 (use muteHttpExceptions option to examine full response)
将muteHttpExceptions设为true后,仅返回:
error code: 1020
已排查的信息:
- Bot已加入目标服务器,显示离线(不确定是否影响)
- Bot为私有类型
- Bot Token和服务器ID均确认正确
- 通过OAuth2生成邀请链接时,仅勾选
bot权限范围并赋予管理员权限;现在生成链接要求选择重定向URL,但下拉列表为空,无法生成新链接 - 调用
/users/@me/guilds接口正常,能返回包含目标服务器的数组:
[ { "id": "[GUILD_ID]", "name": "[GUILD_NAME]", "icon": null, "owner": false, "permissions": "4398046511103", "features": [ "APPLICATION_COMMAND_PERMISSIONS_V2" ] } ]
我怀疑是权限问题,但找不到排查方向。
问题根源
1020错误是Cloudflare的人机验证拦截,并非Discord的权限问题——你能正常调用/users/@me/guilds已经证明Token有效、Bot在服务器内且具备基础权限。Google Apps Script的请求来自共享IP池,这类IP常被Cloudflare标记为可疑流量,触发拦截机制。
另外,Bot离线状态不影响API调用,只要Token有效就能正常请求接口。
修复步骤
1. 添加合法的User-Agent请求头
Discord API要求请求携带明确的User-Agent,默认Google Apps Script的UA可能不被认可,补充后可降低被拦截概率:
var token = "MY_TOKEN" var url = "https://discord.com/api/v10/guilds/[GUILD_ID]/channels" var header = { Authorization: "Bot " + token, "User-Agent": "DiscordBot (你的应用名称, 版本号) GoogleAppsScript" // 替换为你的应用自定义信息 } function myFunction(){ var params = { method: "get", headers: header, muteHttpExceptions: true // 保持开启以便查看完整错误信息 } var response = UrlFetchApp.fetch(url,params) Logger.log(response.getContentText()) }
2. 解决OAuth2重定向URL问题
现在Discord要求所有OAuth2应用必须设置重定向URI,即使是生成Bot邀请链接也需要。你可以手动添加一个格式合法的URI(比如http://localhost):
- 进入Discord开发者门户 → 你的应用 → OAuth2 → 重定向URI
- 点击「添加重定向URI」,输入
http://localhost后保存 - 回到OAuth2 URL生成器,就能正常选择重定向URI并生成Bot邀请链接了
3. 备选方案:换用其他执行环境
如果添加UA后仍被拦截,可考虑将请求逻辑迁移到非共享IP的环境(比如Vercel/Netlify Serverless函数、自部署的Node.js服务),这类环境的IP被Cloudflare拦截的概率更低。
额外验证
可以用curl直接测试API请求,确认是否能正常返回频道列表:
curl -H "Authorization: Bot YOUR_TOKEN" -H "User-Agent: DiscordBot (你的应用名称, 版本号)" https://discord.com/api/v10/guilds/YOUR_GUILD_ID/channels
如果curl能正常返回,说明问题确实出在Google Apps Script的IP环境上。
内容的提问来源于stack exchange,提问作者Ersih Frans

