Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Awaiting for telegraf.launch() stops the code. #1749

Closed
GordiNoki opened this issue Nov 24, 2022 · 15 comments · Fixed by #1949
Closed

Awaiting for telegraf.launch() stops the code. #1749

GordiNoki opened this issue Nov 24, 2022 · 15 comments · Fixed by #1949

Comments

@GordiNoki
Copy link

GordiNoki commented Nov 24, 2022

Context

Trying to await for the bot to launch stops the code. I think this is done so that the code does not close after the bot is launched, but my code requires waiting for the bot to connect for the rest code to work. Is there any better way of doing so?
It worked before with older version of telegraf (4.10.0).

  • Telegraf.js Version: 4.11.2
  • Node.js Version: v18.0.0
  • Operating System: Windows 11

Minimal Example Code Reproducing the Issue

const config = require("./config.json");
const { Telegraf } = require("telegraf");

(async () => {
    const telegraf = new Telegraf(config.telegram.token);
    await telegraf.launch();
    console.log("Telegram started.");
})();

Expected Behavior

"Telegram started." in console.

Current Behavior

Nothing

Error Message and Logs (export DEBUG='telegraf:*')

  telegraf:main Created a `Telegraf` instance +0ms
  telegraf:main Connecting to Telegram +2ms
  telegraf:client HTTP call getMe {} +0ms
  telegraf:main Launching @<botname>_bot +443ms
  telegraf:client HTTP call deleteWebhook { drop_pending_updates: undefined } +442ms
  telegraf:main Bot started with long polling +85ms // Holds there cause of awaiting at telegraf.ts:267 line
  telegraf:polling Starting long polling +0ms
  telegraf:client HTTP call getUpdates { timeout: 50, offset: 0, allowed_updates: [] } +86ms
@GordiNoki
Copy link
Author

GordiNoki commented Nov 24, 2022

> npm install [email protected]

added 1 package, changed 1 package, and audited 109 packages in 2s

11 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
> node .\a.js         
  telegraf:main Created a `Telegraf` instance +0ms
  telegraf:main Connecting to Telegram +2ms
  telegraf:client HTTP call getMe {} +0ms
  telegraf:main Launching @<botname>_bot +460ms
  telegraf:client HTTP call deleteWebhook { drop_pending_updates: undefined } +460ms
  telegraf:polling Starting long polling +0ms
  telegraf:client HTTP call getUpdates { timeout: 50, offset: 0, allowed_updates: [] } +89ms
  telegraf:main Bot started with long polling +91ms
Telegram started.
> 

@MKRhere
Copy link
Member

MKRhere commented Nov 24, 2022

Thanks for opening this issue.

Since 4.11 (4.11.0 release notes: see "Other changes"), we made a choice to make bot.launch() throw error if long polling errors (related: #1657). This would unfortunately mean that the promise never resolves until the bot stops.

We're aware that although the previous behaviour was undocumented, many users have relied on it to get a "bot started" event. I'm holding off on "fixing" this prematurely by rolling back, so that we can still provide a way for errors to be caught. Meanwhile, you can do this:

const config = require("./config.json");
const { Telegraf } = require(https://github.com/telegraf/telegraf);

(async () => {
    const telegraf = new Telegraf(config.telegram.token);
    console.log("Telegram started.");
    await telegraf.launch();
})();

Note that awaiting bot.launch() is not strictly required unless you have a usecase where you need to catch errors. See the release notes for more details.

I'll leave this issue open until we've provided a new solution to both sides.

@MKRhere MKRhere pinned this issue Nov 24, 2022
@MKRhere
Copy link
Member

MKRhere commented Nov 25, 2022

You could also do this:

bot.botInfo = await bot.telegram.getMe();
console.log("Bot started");
bot.launch();

This will prevent launch() from calling getMe on its own, and has all the same guarantees pre-4.11.0 had.

@GordiNoki
Copy link
Author

Thanks! It works, but as you said, I won't close the problem until you come up with a better solution.

@BotFessor
Copy link

Thanks for pointing this out. I ran into a similar scenario and just omitted the await keyword

@RobinTail
Copy link

Having the same issue after upgrade.
launch should return Promise, but currently it never resolves.

@takeTrace
Copy link

You could also do this:

bot.botInfo = await bot.telegram.getMe();
console.log("Bot started");
bot.launch();

This will prevent launch() from calling getMe on its own, and has all the same guarantees pre-4.11.0 had.

not work for 4.12.2

@bladerunner2020
Copy link

Please update the documentation.
Spent quite a lot of time before found out that promise is never resolved by design...

@pavloging
Copy link

I solved the problem, for me this solution is suitable. [email protected]

const bot = new Telegraf(process.env.TOKEN);
bot.launch();
// Started message
if (bot) bot.telegram.getMe().then((res) => console.log(`Bot started on https://t.me/${res.username}`))

I hope, I solved your question.

@GordiNoki
Copy link
Author

I solved the problem, for me this solution is suitable. [email protected]

const bot = new Telegraf(process.env.TOKEN);
bot.launch();
// Started message
if (bot) bot.telegram.getMe().then((res) => console.log(`Bot started on https://t.me/${res.username}`))

I hope, I solved your question.

This is basically the same solution as @MKRhere provided year ago

IITII added a commit to IITII/tg_setu_bot that referenced this issue Dec 4, 2023
@IITII
Copy link

IITII commented Dec 5, 2023

I solved the problem, for me this solution is suitable. [email protected]

const bot = new Telegraf(process.env.TOKEN);
bot.launch();
// Started message
if (bot) bot.telegram.getMe().then((res) => console.log(`Bot started on https://t.me/${res.username}`))

I hope, I solved your question.

I don't think this works, my test failed at [email protected].
I forced the telegraf version to 4.10.0 after read the changelog. I will consider upgrading when this issue closed.

@arkbabayan21
Copy link

arkbabayan21 commented Jan 30, 2024

This worked for me

  bot.botInfo = await bot.telegram
    .getMe()
    .then(async (res) => {
      console.log(`${res.username} launched successfully`);
      await bot.launch();
    })
    .catch((error) => {
      throw new Error(`Failed to launch the bot: ${error.message}`);
    });

@MKRhere
Copy link
Member

MKRhere commented Feb 21, 2024

Here we go! #1949 adds a callback to bot.launch that is called when launching the bot.

bot.launch(() => console.log("Bot is starting!"));

If you pass LaunchOptions, the callback goes after the options.

bot.launch({ dropPendingUpdates: true }, () => console.log("Bot is starting!"));

This is available on npm as a release candidate: 4.16.0-rc.2. Stable release when #1949 is merged.

@mindrunner
Copy link

Here we go! #1949 adds a callback to bot.launch that is called when launching the bot.

bot.launch(() => console.log("Bot is starting!"));

If you pass LaunchOptions, the callback goes after the options.

bot.launch({ dropPendingUpdates: true }, () => console.log("Bot is starting!"));

This is available on npm as a release candidate: 4.16.0-rc.2. Stable release when #1949 is merged.

How does this solve the original issue? launch still blocks forever when being awaited which leaves a dangling promise.

@MKRhere
Copy link
Member

MKRhere commented Apr 4, 2024

@mindrunner

How does this solve the original issue? launch still blocks forever when being awaited which leaves a dangling promise.

bot.launch returning a long-lived promise is intentional, because it's the only place you can handle polling errors (which are generally fatal and the bot cannot continue, unlike handler errors). It allows #1657 to recover from errors gracefully, for when there are more than the single bot running in the process. The new launch callback solves the problem of wanting to log a message on bot start.

Read https://github.com/telegraf/telegraf/releases/tag/v4.11.0 for more details on why that change was made.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants