使用snoowrap调用Reddit API遇Invalid grant错误求助
解决Reddit API投稿的"Invalid grant"错误及API细节
一、Reddit 投稿链接的原生API参数细节
1. API路由
POST /r/{subreddit}/api/submit
将{subreddit}替换为目标子版块的名称(比如javascript)
2. 必须携带的请求头
Authorization: Bearer {access_token}:通过OAuth2流程获取的有效访问令牌User-Agent: {自定义用户代理字符串}:格式建议为平台/版本 应用名/版本,例如nodejs/18.17.0 my_link_share_bot/1.0,不能过于简略Content-Type: application/x-www-form-urlencoded:因为提交的是表单格式数据
3. 请求数据格式(表单键值对)
kind: "link":明确指定是链接类型的投稿title: "你的帖子标题":帖子的显示标题url: "https://example.com":要分享的目标链接sr: "{subreddit}":目标子版块名称,需和路由中的值一致api_type: "json":指定API返回JSON格式的响应
二、"Invalid grant"错误的排查与解决
即便你确认凭证无误,也可能因为以下原因触发该错误,按顺序排查:
- 确认应用类型为Script:在Reddit开发者后台创建应用时,必须选择
script类型,密码模式授权仅对该类型应用开放 - 检查两步验证状态:如果你的Reddit账号开启了两步验证,必须使用应用专用密码代替原账号密码
- 验证用户代理格式:过于简单的User-Agent(比如仅
nodejs)会被Reddit拦截,必须包含平台、应用信息 - 核对凭证细节:
- clientId是应用页面的
personal use script字符串(不是应用名称) - clientSecret是页面中
secret字段的完整字符串 - 用户名和密码要注意大小写、特殊字符,确保没有拼写错误
- clientId是应用页面的
- 手动测试令牌获取:用curl直接调用令牌接口验证问题是否出在凭证层面:
curl -X POST -d "grant_type=password&username=你的账号名&password=你的密码" -u "clientId:clientSecret" https://www.reddit.com/api/v1/access_token
如果该请求也返回invalid_grant,说明问题出在凭证或应用配置,和snoowrap无关
三、修正后的snoowrap代码示例
exports.redditPost = async (subreddit) => { // 调试用:打印关键配置(上线后删除) console.log('User Agent:', process.env.REDDIT_USER_AGENT); console.log('Client ID:', process.env.REDDIT_CLIENT_ID?.substring(0, 5) + '...'); const redditBot = new snoowrap({ userAgent: process.env.REDDIT_USER_AGENT, clientId: process.env.REDDIT_CLIENT_ID, clientSecret: process.env.REDDIT_CLIENT_SECRET, username: process.env.REDDIT_USERNAME, password: process.env.REDDIT_PASSWORD, requestDelay: 1000, // 添加请求延迟避免触发限流 retryErrorCodes: [500, 502, 503, 504] // 自动重试服务器错误 }); try { const post = await redditBot.getSubreddit(subreddit).submitLink({ title: 'Title of Post', url: 'https://example.com' }); console.log('投稿成功,帖子ID:', post.id); } catch (err) { console.error('投稿失败:', err.message); console.error('错误详情:', err.stack); } };
内容的提问来源于stack exchange,提问作者MandoMando
相关产品推荐
相关产品推荐

