// Using import statements instead of require
import express from "express";
import path, { dirname } from "path";
import { Telegraf, session } from "telegraf";
import { config } from "dotenv";
import { fileURLToPath } from "url";
import { PrismaClient } from "@prisma/client";
import { botSendMessage, sendServState, sendWPT } from "./helper_functions.js";
import ngrok from 'ngrok'
config();
// Using Prisma ORM
const prisma = new PrismaClient();
// Setup __dirname equivalent in ES module scope
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// Initialize dotenv
// Initialize Express
const expressApp = express();
const port = process.env.PORT || 3000;
// Middleware to serve static files
expressApp.use(express.static("static"));
expressApp.use(express.json());
// Initialize the bot
const bot = new Telegraf(process.env.BOT_TOKEN, { telegram: { webhookReply: false } });
bot.use(session())
// Start ngrok and set the webhook
(async function() {
try {
// Connect ngrok to the specified port
const url = await ngrok.connect(port);
const WEBHOOK_URL = `${url}/telegram-webhook`;
// Set the webhook for the bot
await bot.telegram.setWebhook(WEBHOOK_URL);
console.log(`Webhook set to ${WEBHOOK_URL}`);
// Webhook handler for incoming Telegram updates
expressApp.post('/telegram-webhook', (req, res) => {
bot.handleUpdate(req.body)
.then(() => {
if (!res.headersSent) {
res.sendStatus(200);
}
})
.catch((error) => {
console.error('Error in webhook handler:', error);
if (!res.headersSent) {
res.sendStatus(500);
}
});
});
// Root endpoint to serve the main page
expressApp.get("/", (req, res) => {
res.sendFile(path.join(__dirname, "/index.html"));
});
// Start the Express server
expressApp.listen(port, () => {
console.log(`Server running on port ${port}`);
});
} catch (err) {
console.error('Error setting up webhook or server:', err);
}
})();
bot.command("start", (ctx) => {
console.log(ctx.from);
console.log(ctx.session);
ctx.session.state = 'idle'
ctx.session.cur_command = null
botSendMessage(bot, ctx, "Hello there! I am the FM helper bot.")
});
这是我的机器人发送消息:
export function botSendMessage(bot, ctx, message){
bot.telegram.sendMessage(ctx.chat.id, `@${ctx.from.username}\n${message}`);
}
这是我的电报机器人代码片段,在我添加使用 session() 中间件之前一切正常。然而现在,每当我尝试 /start 命令时,我总是会遇到以下错误:
Error in webhook handler: TypeError: Cannot set properties of undefined (setting 'state')
at file:///C:/fm-telebot/index.js:134:21
at C:\fm-telebot\node_modules\telegraf\lib\composer.js:397:28
at C:\fm-telebot\node_modules\telegraf\lib\composer.js:165:111
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async execute (C:\fm-telebot\node_modules\telegraf\lib\composer.js:518:17)
at async C:\fm-telebot\node_modules\telegraf\lib\composer.js:519:21
at async execute (C:\fm-telebot\node_modules\telegraf\lib\composer.js:518:17)
at async C:\fm-telebot\node_modules\telegraf\lib\composer.js:519:21
at async C:\fm-telebot\node_modules\telegraf\lib\session.js:104:13
at async execute (C:\fm-telebot\node_modules\telegraf\lib\composer.js:518:17)
因为我在expressApp.post()中有一个catch块。当我在 /start 命令中控制台注销我的 ctx.session() 时,它只显示未定义。我尝试显式设置会话中间件的选项,但它也不起作用。我想我也在网上搜索过,但没有找到与我有太大相关性的帖子。 ClaudeAI也没能帮助找出错误。
如果有人有这方面的经验,关于我在哪里出错或如何解决这个错误(我正在考虑手动设置它,但这将需要我检查每个命令是否实例化会话,这确实很不方便,并且不受欢迎)
对我有用的是创建一个默认会话,如下所示:
bot.use(
session({
defaultSession: () => ({})
})
);
或者当有自定义上下文时(自定义上下文的文档):
interface MyContext<U extends Update = Update> extends Context<U> {
session: {
someRandomNumber: number
},
};
const bot = new Telegraf<MyContext>(process.env.BOT_TOKEN)
bot.use(
session({
defaultSession: () => ({
someRandomNumber: 0
})
})
);