电报 API 返回 HTML 而不是 JSON

Telegram API returning HTML instead of JSON

我正在写一个电报机器人来报告 fail2ban 禁令。很简单很脏,草草写的,但是可以用来向单个电报用户报告任何消息:

var TelegramBot = require('node-telegram-bot-api');
var fs = require('fs');

var store = {
    get: function (key) {
        return fs.readFileSync(__dirname + '/' + key, { encoding: 'utf-8' });
    },

    set: function (key, value) {
        fs.writeFileSync(__dirname + '/' + key, value, { encoding: 'utf-8' });
    }
};

var token = store.get('token');
var args = process.argv.slice(2);

if (args.length == 0) {
    console.error('No mode specified');
    process.exit(0);
}

TelegramBot.prototype.unregisterText = function (regexp) {
    for (var i = 0; i < bot.textRegexpCallbacks.length; ++i) {
        if (bot.textRegexpCallbacks[i].regexp.toString() == regexp) {
            bot.textRegexpCallbacks.splice(i, 1);
            return;
        }           
    }
};

fs.appendFileSync(__dirname + '/logs', 
    '[' + (new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '')) + '] '
        + args.join(' ') + '\n', 
    { encoding: 'utf-8' });

switch (args[0]) {
    case 'setup':
        var bot = new TelegramBot(token, { polling: true });
        var step = 'none';

        bot.onText(/\/setup/, function (msg, match) {
            var fromId = msg.from.id;
            step = 'setup-started';
            bot.sendMessage(fromId, 'Starting setup. Please enter the verification key.');

            bot.onText(/(.+)/, function (msg, match) {
                if (step == 'setup-started') {
                    var key = match[1];
                    var verification = store.get('key');
                    if (key == verification) {
                        store.set('owner', msg.from.id);
                        step = 'verified';
                        bot.sendMessage(msg.from.id, 'Correct. Setup complete.');
                    } else {
                        step = 'none';
                        bot.unregisterText(/(.+)/);
                        bot.sendMessage(msg.from.id, 'Wrong. Setup aborted.');
                    }
                }
            });
        });

        break;

    case 'report':
        var bot = new TelegramBot(token, { polling: false });
        var owner = store.get('owner');
        var subject = args[1];

        if (subject == 'message') {
            var message = args.slice(2).join(' ');
            bot.sendMessage(owner, message);
        } else if (subject == 'file') {
            var content = fs.readFileSync(args[2], { encoding: 'utf-8' });
            bot.sendMessage(owner, content);
        }

        break;

    default:
        console.error('Unrecognized mode', args[0]);
        break;
}

在我的开发机器上运行良好。我调用:

node bot.js report message whatever message i want

而且我在电报上正确收到了 "whatever message i want"。然而,一旦我在我的 digitalocean vps 上提交它,它就不再有效了。原来是电报库的问题:

Unhandled rejection Error: Error parsing Telegram response: <!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Bots: An introduction for developers</title>
    ...

显然 returns 一个 html 页面而不是 json...我也尝试联系相同的端点 (api.telegram.org/bothash/sendMessage)在我的 vps 上卷曲并返回 json(带有错误消息,因为我没有发送任何参数,但仍然 json)。

我不明白为什么会这样。有帮助吗?

您的 VPN 上似乎没有带有令牌的文件,或者令牌不正确。

大家可以自行查看:

当您向 api.telegram.org/{token}/sendMessage 发出请求并且 {token} 不正确时,它会将您重定向到 this page,它以您在您的问题。

因此您必须调试 store.getstore.get 函数的行为以及文件和令牌,以确保您使用的是正确的。

此外,我建议在使用任何其他 Telegram API 方法之前先 运行 bot.getMe() 以确保您指定了正确的机器人令牌。