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

使用twitter-v2.js发送回复时遭遇401 Unauthorized错误求助

Twitter机器人回复401 Unauthorized错误的修复方案

核心问题分析

你遇到的401错误最可能是因为回复推文未@原作者,Twitter API v2强制要求回复内容必须包含被回复推文的作者用户名,否则会直接拒绝请求。此外还有几处代码细节和配置需要核对。

具体修复步骤

1. 回复文本必须包含原作者@用户名

修改搜索请求以获取推文作者ID,再批量获取用户名,将其添加到回复内容中:

// 修改搜索请求,添加tweet.fields参数获取作者ID
const { data } = await Bot2.get('tweets/search/recent', {
    query: TWITTER_SEARCH_PHRASE,
    max_results: TWITTER_SEARCH_MAX_RESULTS,
    'tweet.fields': 'author_id'
});

// 批量获取所有推文作者的用户名,避免多次API请求
const authorIds = data.map(tweet => tweet.author_id);
const { data: users } = await Bot2.get('users', {
    ids: authorIds.join(',')
});
const userIdToName = {};
users.forEach(user => {
    userIdToName[user.id] = user.username;
});

// 生成带@作者的回复文本
var authorUsername = userIdToName[data[i].author_id];
var textToReply = `Hey @${authorUsername} ${TWEETS_TO_REPLY[Math.floor(Math.random()*TWEETS_TO_REPLY.length)]}`;

2. 确认OAuth 1.0a凭证有效性

  • 再次核对TWITTER_ACCESS_TOKEN和TWITTER_ACCESS_TOKEN_SECRET:这两个凭证必须来自已授权你的应用获取读写权限的用户,不是应用级Bearer Token对应的凭证。
  • 登录Twitter开发者平台,确认你的应用权限确实设置为「读写」,且用户授权流程已完整执行(access token是通过OAuth授权流程生成的,不是仅创建应用时的密钥)。

3. 修正代码中的同步文件读取错误

fs.readFileSync是同步方法,不需要加await,否则会导致不必要的Promise等待:

// 错误写法
// var fileData = await fs.readFileSync(DB_FILE, 'utf8');

// 正确写法
var fileData = fs.readFileSync(DB_FILE, 'utf8');

4. 可选:明确指定API版本

部分版本的twitter-v2库需要明确指定API版本,可修改Bot实例初始化代码:

var Bot = new Twitter({
    consumer_key: TWITTER_CONSUMER_KEY,
    consumer_secret: TWITTER_CONSUMER_SECRET,
    access_token_key: TWITTER_ACCESS_TOKEN,
    access_token_secret: TWITTER_ACCESS_TOKEN_SECRET,
    version: '2' // 明确指定使用API v2
});

完整修改后的关键代码片段

async function BotStart() {
    console.log("> Twitter bot is running (" + Date() + ")...")

    // 搜索推文并获取作者ID
    const { data } = await Bot2.get('tweets/search/recent', {
        query: TWITTER_SEARCH_PHRASE,
        max_results: TWITTER_SEARCH_MAX_RESULTS,
        'tweet.fields': 'author_id'
    });

    console.log(data);

    // 处理本地数据库文件
    var bot_db = [];
    if (!fs.existsSync(DB_FILE)) {
        fs.closeSync(fs.openSync(DB_FILE, 'w'));
    }
    var fileData = fs.readFileSync(DB_FILE, 'utf8');
    fileData = fileData.trim();
    if (fileData !== "") {
        bot_db = fileData.split("\n");
    }

    var processed_tweets = [];

    // 批量获取作者用户名
    const authorIds = data.map(tweet => tweet.author_id);
    const { data: users } = await Bot2.get('users', {
        ids: authorIds.join(',')
    });
    const userIdToName = {};
    users.forEach(user => {
        userIdToName[user.id] = user.username;
    });

    // 遍历处理推文
    for (var i = 0; i < data.length; i++) {
        var id = data[i].id;
        if (bot_db.indexOf(id) === -1) {
            processed_tweets.push(id);

            // 记录已处理推文ID
            fs.appendFile(DB_FILE, id + "\n", function (err) {
                if (err) {
                    console.log("写入数据库文件失败: " + DB_FILE);
                } else {
                    console.log("已处理推文ID: " + id);
                }
            });

            // 生成回复内容并发送
            var authorUsername = userIdToName[data[i].author_id];
            var textToReply = `Hey @${authorUsername} ${TWEETS_TO_REPLY[Math.floor(Math.random()*TWEETS_TO_REPLY.length)]}`;
            try {
                var replyData = await Bot.post('tweets', { text: textToReply, in_reply_to_tweet_id: id });
                console.log("回复成功: " + textToReply);
            } catch (error) {
                console.log("回复错误详情: ", error);
            }
        }
    }

    // 输出处理结果
    if (processed_tweets.length > 0) {
        console.log("> 本次处理推文ID列表: " + processed_tweets);
    } else {
        console.log("> 本次无新推文需要处理。");
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 13:52:00