为机器人使用 Telegraf webhook 时出现 404 错误
404 error using Telegraf webhook for a bot
我正在尝试让 Telegram 机器人正常工作,我正在使用 Telegraf.js。我通过使用默认的 Apache VirtualHost 向我的域名添加子域来设置 Webhook。
它基本上可以正常工作,但出于某种原因,我从 Telegram 的网络钩子 API 信息 (getWebhookInfo):
收到了 404 错误
{
"ok": true,
"result": {
"url": "https://subdomain.domain.tld/telegraf/<chain-of-64-letters-and-numbers>",
"has_custom_certificate": false,
"pending_update_count": 12,
"last_error_date": 1652692046,
"last_error_message": "Wrong response from the webhook: 404 Not Found",
"max_connections": 40,
"ip_address": "XX.XX.XX.XX"
}
}
我注意到后缀被附加是有原因的(我只提供子域 URL 而没有任何路径),它可能来自 Telegraf.js 但它似乎导致了404 错误。
我的代码:
const { Telegraf } = require("telegraf");
require("dotenv").config();
// Bot initialization
const token = process.env.API_KEY;
if (token === undefined) {
throw new Error("Token not defined!");
}
const bot = new Telegraf(token/*, {
telegram: {
apiRoot: "http://127.0.0.1:" // I'm planning to use tdlib/telegram-bot-api later on
}
}*/);
// Commands handling
bot.start(ctx => {
console.info("ok!");
ctx.reply("Hello from bot!");
});
bot.on("text", () => console.info("text received"));
bot.command("test", ctx => ctx.reply("Working!!"));
bot.command("quit", ctx => ctx.leaveChat());
// Bot launching
bot.launch({
webhook: {
domain: "https://subdomain.domain.tld",
port: 3000 // I've seen 3000 is frequently used so let's use that
}
}).then(
resolve => console.info(`Bot '${bot.botInfo.username}' (${bot.botInfo.id}) started successfully (${resolve || "OK"})`),
reject => console.info(`Bot '${bot.botInfo.username}' (${bot.botInfo.id}) failed to start: ${reject}`)
);
// Graceful stop handling
process.once("SIGINT", () => bot.stop("SIGINT"));
process.once("SIGTERM", () => bot.stop("SIGTERM"));
我的虚拟主机:
<VirtualHost *:443>
ServerName subdomain.domain.tld
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# Let's Encrypt
SSLCertificateFile /etc/letsencrypt/live/domain.tld-0001/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/domain.tld-0001/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
我做错了什么?
我忘记在我的 Apache VirtualHost
上添加 ProxyPass
:
<VirtualHost *:443>
ServerName subdomain.domain.tld
# Missing part
ProxyPreserveHost On
ProxyRequests Off
AllowEncodedSlashes NoDecode
SSLProxyEngine On
SSLProxyCheckPeerCN Off
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/
# End of missing part
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# Let's Encrypt
SSLCertificateFile /etc/letsencrypt/live/domain.tld-0001/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/domain.tld-0001/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
现在一切正常。
我正在尝试让 Telegram 机器人正常工作,我正在使用 Telegraf.js。我通过使用默认的 Apache VirtualHost 向我的域名添加子域来设置 Webhook。
它基本上可以正常工作,但出于某种原因,我从 Telegram 的网络钩子 API 信息 (getWebhookInfo):
{
"ok": true,
"result": {
"url": "https://subdomain.domain.tld/telegraf/<chain-of-64-letters-and-numbers>",
"has_custom_certificate": false,
"pending_update_count": 12,
"last_error_date": 1652692046,
"last_error_message": "Wrong response from the webhook: 404 Not Found",
"max_connections": 40,
"ip_address": "XX.XX.XX.XX"
}
}
我注意到后缀被附加是有原因的(我只提供子域 URL 而没有任何路径),它可能来自 Telegraf.js 但它似乎导致了404 错误。
我的代码:
const { Telegraf } = require("telegraf");
require("dotenv").config();
// Bot initialization
const token = process.env.API_KEY;
if (token === undefined) {
throw new Error("Token not defined!");
}
const bot = new Telegraf(token/*, {
telegram: {
apiRoot: "http://127.0.0.1:" // I'm planning to use tdlib/telegram-bot-api later on
}
}*/);
// Commands handling
bot.start(ctx => {
console.info("ok!");
ctx.reply("Hello from bot!");
});
bot.on("text", () => console.info("text received"));
bot.command("test", ctx => ctx.reply("Working!!"));
bot.command("quit", ctx => ctx.leaveChat());
// Bot launching
bot.launch({
webhook: {
domain: "https://subdomain.domain.tld",
port: 3000 // I've seen 3000 is frequently used so let's use that
}
}).then(
resolve => console.info(`Bot '${bot.botInfo.username}' (${bot.botInfo.id}) started successfully (${resolve || "OK"})`),
reject => console.info(`Bot '${bot.botInfo.username}' (${bot.botInfo.id}) failed to start: ${reject}`)
);
// Graceful stop handling
process.once("SIGINT", () => bot.stop("SIGINT"));
process.once("SIGTERM", () => bot.stop("SIGTERM"));
我的虚拟主机:
<VirtualHost *:443>
ServerName subdomain.domain.tld
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# Let's Encrypt
SSLCertificateFile /etc/letsencrypt/live/domain.tld-0001/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/domain.tld-0001/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
我做错了什么?
我忘记在我的 Apache VirtualHost
上添加 ProxyPass
:
<VirtualHost *:443>
ServerName subdomain.domain.tld
# Missing part
ProxyPreserveHost On
ProxyRequests Off
AllowEncodedSlashes NoDecode
SSLProxyEngine On
SSLProxyCheckPeerCN Off
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/
# End of missing part
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# Let's Encrypt
SSLCertificateFile /etc/letsencrypt/live/domain.tld-0001/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/domain.tld-0001/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
现在一切正常。