BLazzeD21 / Node.js-ChatGPT-Bot

СhatGPT bot for telegram written on node.js
https://t.me/GPTHelperChat_bot
MIT License
9 stars 3 forks source link

The bot is not async #4

Closed BLazzeD21 closed 11 months ago

BLazzeD21 commented 11 months ago

The bot does not work async, how can you either implement threads for different users or make it async?

The bot implements routers, but it's workaround:

index.js:

import {startHandler} from './handlers/userHandlers.js';

bot.command('start', startHandler(sessions));

handlers/userHandlers.js:

export const startHandler = (sessions) => {
  return async (ctx) => {
    const sessionId = ctx.message.chat.id;
    sessions[sessionId] = createInitialSession();
    await ctx.reply(LEXICON_EN['start'], menuKeyboard);
  };
};
impuLssse commented 11 months ago

что значит работает не асинхронно? напиши какое поведение получаешь и какое хочешь что такое sessions и LEXICON_EN, menuKeyboard

MKRhere commented 11 months ago

The simple answer is just use webhook mode. In polling mode, the bot fetches up to 100 pending updates and waits for all of them to finish processing before fetching the next batch. In webhook mode, the bot receives one update per chat until you finish processing, regardless of how many chats there are.

BLazzeD21 commented 11 months ago

LEXICON - это просто словарь со всеми репликами бота. sessions - сonst sessions = {}; из index.js menuKeyboard - клавиатура с изображения

Обработчик с командой start приведен для примера того, как обрабатывается команда в боте. Проблема заключается в том, что при использовании команд бота, которые обращаются к openai API, он не может обрабатывать другие команды ни от одного пользователя. Бот буквально зависает на одном пользователи и одном запросе.

image

impuLssse commented 11 months ago

LEXICON - это просто словарь со всеми репликами бота. sessions - сonst sessions = {}; из index.js menuKeyboard - клавиатура с изображения

Обработчик с командой start приведен для примера того, как обрабатывается команда в боте. Проблема заключается в том, что при использовании команд бота, которые обращаются к openai API, он не может обрабатывать другие команды ни от одного пользователя. Бот буквально зависает на одном пользователи и одном запросе.

image

сделай замыкающую функцию внутри, которая будет не блочить твой поток (почитай что такое замыкания в Js) либо есть еще 1 вариант, через rxjs сделать подписку на получение сообщение, и пока он обрабатывает твое сообщение, у тебя будет 1 текст, а когда придет ответ ты сможешь изменить сообщение на сообщение с ответом, либо отослать новое

MKRhere commented 11 months ago

If you need it to respond to the same chat even while processing, you just need to unhandle the promise that takes time. For example:

getLLMAnswer().then(async response => {
  await ctx.sendMessage(response);
}).catch(errorHandler);

You should not wait this. This method will cause three things you should be careful about:

  1. Errors will no longer be caught by Telegraf because it's an unhandled promise. You should catch them yourself as shown above.
  2. session will close while your unhandled promise is processing. You should not try to access or write to ctx.session in the .then callback.
  3. Telegraf will no longer limit how many requests you're handling in these unhandled promises. You should use a ratelimit plugin if needed.
BLazzeD21 commented 11 months ago

If you need it to respond to the same chat even while processing, you just need to unhandle the promise that takes time. For example:

getLLMAnswer().then(async response => {
  await ctx.sendMessage(response);
}).catch(errorHandler);

You should not wait this. This method will cause three things you should be careful about:

  1. Errors will no longer be caught by Telegraf because it's an unhandled promise. You should catch them yourself as shown above.
  2. session will close while your unhandled promise is processing. You should not try to access or write to ctx.session in the .then callback.
  3. Telegraf will no longer limit how many requests you're handling in these unhandled promises. You should use a ratelimit plugin if needed.

I'm a little confused on how to apply this to my main handlers...

https://github.com/BLazzeD21/Node.js-ChatGPT-Bot/blob/master/src/handlers/openaiHandlers.js

MKRhere commented 11 months ago

For example:

openai.getImage(...).then(async image => {
  if (imageUrl == '400') {
  // ...test of the logic for this handler
}).catch(errorHandler);

Notice I'm not awaiting openai.getImage.

BLazzeD21 commented 11 months ago

Thank you all very much for your help! The last solution worked!