Skip to content
This repository has been archived by the owner on Nov 7, 2023. It is now read-only.

Update dependency telegraf to v4 #21

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Conversation

renovate[bot]
Copy link

@renovate renovate bot commented Jan 24, 2021

Mend Renovate

This PR contains the following updates:

Package Change Age Adoption Passing Confidence
telegraf (source) ^3.38.0 -> ^4.0.0 age adoption passing confidence

Release Notes

telegraf/telegraf

v4.12.2

Compare Source

  • Fix: session reference counter had defaulted to 0, therefore permanently being cached and never being cleaned up — this has been fixed.

v4.12.1

Compare Source

  • Fix: bot.command did not match bot usernames if the registered username was not lowercased (#​1809)

v4.12.0

Compare Source

Normally the most exciting features of a new release would be support for the latest Bot API. But in this update, it's session! This has been in the works for many months, and we're happy to bring it to you this release!

🔒 Stable and safe session

Some of you may know that builtin session has been deprecated for quite a while. This was motivated by the fact that session is prone to race-conditions (#​1372). This left the community in a grey area where they continued to use session despite the deprecation, since no clear alternative was provided. Added to this was the fact that there were no official database-backed sessions, and all unofficial async session middleware were affected by #​1372.

This release finally addresses both of these long-running issues.

🏃🏼 No more race conditions

#​1713 provides a reference-counted implementation resistant to race conditions. Session is now no longer deprecated, and can be used safely!

Note: You should read more about how to safely use session in the docs repo.

™️ Official database adapters are here!

We're also happy to announce a revamped @telegraf/session—this provides official store implementations for database-backed sessions via Redis, MongoDB, MySQL, MariaDB, PostgreSQL, and SQLite. Just install the drivers necessary for your database, and off you go! Since this package now only provides a store implementation, it's usable with builtin session, and effectively makes all implementations have the same safety as the core package. Check it out!

🆗 Default session

Additionally, session now accepts a defaultSession parameter. You no longer need a hacky middleware to do ctx.session ??= { count }.

// 🤢 Old way
bot.use(session());
bot.use((ctx, next) => {
  ctx.session ??= { count: 0 };
  return next();
});

// 😁 New way ✅
bot.use(session({ defaultSession: () => ({ count: 0 }) }));
🔺 Bot API 6.5 support
  • Updated Typegram, added the following Markup.button helpers to request a user or chat:
  • Markup.button.userRequest
  • Markup.button.botRequest
  • Markup.button.groupRequest
  • Markup.button.channelRequest
  • Telegram::setChatPermissions and Context::setChatPermissions accept a new parameter for { use_independent_chat_permissions?: boolean } as documented in the API.
🔺 Bot API 6.4 support
  • Updated Typegram, added the following new methods to class Telegram and Context:
  • editGeneralForumTopic
  • closeGeneralForumTopic
  • reopenGeneralForumTopic
  • hideGeneralForumTopic
  • unhideGeneralForumTopic
  • Context::sendChatAction will automatically infer message_thread_id for topic messages.
  • Fix for 'this' Context of type 'NarrowedContext' is not assignable to method's 'this' of type 'Context<Update>'.
⚡️ RegExp support for commands!

Another long-standing problem was the lack of support for RegExp or case-insensitive command matching. This is here now:

bot.command("hello", ctx => ctx.reply("You sent a case-sensitive /hello"));
bot.command(/^hello$/i, ctx => ctx.reply("You sent a case-insensitive /hELLo"));
✍️ fmt helpers
  • New join fmt helper to combine dynamic arrays into a single FmtString.
import { fmt, bold, join } from "telegraf/format";

// elsewhere
bot.command("/fruits", async ctx => {
  const array = ["Oranges", "Apples", "Grapes"];
  const fruitList = join(array.map(fruit => bold(fruit)), "\n");
  const msg = fmt`Fruits to buy:\n${fruitList}`;
  await ctx.sendMessage(msg);
});
  • Fixed various bugs in fmt helpers, so things like bold(italic("telegraf")) will now work as expected.
🌀 Persistent chat actions

ctx.sendChatAction is used to send a "typing", or "uploading photo" status while your bot is working on something. But this is cleared after 5 seconds. If you have a longer process, you may want to keep calling sendChatAction in a loop. This new feature adds an API to help with this:

bot.command('/video', async ctx => {
  // starts sending upload_video action
  await ctx.persistentChatAction("upload_video", async () => {
    const data = await getLargeVideoSomehow();
    await ctx.sendVideo(Input.fromBuffer(data));
  }); // all done, stops sending upload_video
});

Thanks to @​orimiles5 for raising this pull request (#​1804).

Follow Telegraf_JS to receive these updates in Telegram. If you have feedback about this update, please share with us on @​TelegrafJSChat!

v4.11.2

Compare Source

  • Fixed types for sendMediaGroup to accept StreamFile.
  • Only send message_thread_id if is_topic_message is true.
    Telegram sends message_thread_id for reply messages, even if the group doesn't have topics. This caused the bot to throw when ctx.reply was used against reply messages in non-forums.

v4.11.1

Compare Source

  • Fixed an issue where TypeScript was not able to import "telegraf/filters". Top-level filters.{js|d.ts} were missing in package.json "files" array.

v4.11.0

Compare Source

🔺 Bot API 6.3 support
  • Updated to Typegram 4.1.0 and added the following new methods to Telegram class:
    • createForumTopic
    • editForumTopic
    • closeForumTopic
    • reopenForumTopic
    • deleteForumTopic
    • unpinAllForumTopicMessages
    • getForumTopicIconStickers
  • Added new method shorthands to Context; add message_thread_id implicitly to Context::send* methods.
✨ Filters! ✨

We've added a new powerful feature called filters! Here's how to use them.

// import our filters
import { message, editedMessage, channelPost, editedChannelPost, callbackQuery } from "telegraf/filters";
// you can also use require, like this:
// const { message, editedMessage, channelPost, editedChannelPost, callbackQuery } = require("telegraf/filters");

const bot = new Telegraf(token);

bot.on(message("text"), ctx => {
  // this is a text message update
  // ctx.message.text
});

bot.on(channelPost("video"), ctx => {
  // this is a video channel post update
  // ctx.channelPost.video
});

bot.on(callbackQuery("game_short_name"), ctx => {
  // this is a callback_query game update
  // ctx.callbackQuery.game_short_name
});

This unlocks the ability to filter for very specific update types previously not possible! This is only an initial release, and filters will become even more powerful in future updates.

All filters are also usable from a new method, ctx.has. This is very useful if you want to filter within a handler. For example:

// handles all updates
bot.use(ctx => {
  if (ctx.has(message("text"))) {
    // handles only text messages
    // ctx.message.text;
  } else {
    // handles all other updates
  }
});

Like bot.on, ctx.has also supports an array of update types and filters, even mixed:

// match a message update or a callbackQuery with data present
bot.on(["message", callbackQuery("data")], handler);

if (ctx.has(["message", callbackQuery("data")])) {
  // ctx.update is a message update or a callbackQuery with data present
};
⚠️ Deprecating `bot.on` and `Composer::on` with message types!

As of this release, filtering by message type using bot.on() (for example: "text", "photo", etc.) is deprecated. Don't panic, though! Your existing bots will continue to work, but whenever you can, you must update your message type filters to use the above filters before v5. This is fairly easy to do, like this:

- bot.on("text", handler);
+ bot.on(message("text"), handler);

The deprecated message type behaviour will be removed in v5.

You might be happy, or fairly upset about this development. But it was important we made this decision. For a long time, Telegraf has supported filtering by both update type and message type.

This meant you could use bot.on("message"), or bot.on("text") (text here is a message type, and not an update type, so this was really making sure that update.message.text existed). However, when polls were introduced, this caused a conflict. bot.on("poll") would match both update.poll (update about stopped polls sent by the bot) and update.message.poll (a message that is a native poll). At type-level, both objects will show as available, which was wrong.

Besides, this type of filters really limited how far we could go with Telegraf. That's why we introduced filters, which are way more powerful and flexible!

⚠️ An important reminder

A few updates back, in 4.9.0, we added ctx.send* methods to replace ctx.reply* methods. This is because in v5 the behaviour of ctx.reply* will be to actually reply to the current message, instead of only sending a message.

To start using this behaviour right away, we had also introduced a middleware. We recommend you start using this, so that you're prepared for v5, which is brewing very soon!

import { useNewReplies } from "telegraf/future";

// this will enable ctx.reply throughout the bot to automatically reply to current message
// use ctx.sendMessage and friends to send a message without replying
bot.use(useNewReplies());
Other changes
  • bot.launch is now catchable (#​1657)

    Polling errors were previously uncatchable in Telegraf. They are now. Simply attach a catch to bot.launch:

    bot.launch().catch(e => {
    // polling has errored
    });
    
    // You an also use await and try/catch if you're using ESM

    Three things to remember:

    • In case you're using bot.launch in webhook mode, it will immediately resolve after setWebhook completes.
    • This now means that bot.launch in polling mode will not resolve immediately. Instead, it will resolve after bot.stop(), or reject when there's a polling error.
    • The bot will not continue running after it errors, even if the error is caught. Before you create a new bot instance and launch it, consider that this error is fatal for a serious reason (for example: network is down, or bot token is incorrect). You may not want to attempt a restart when this happens.

    We previously did not want fatal errors to be caught, since it gives the impression that it's a handleable error. However, being able to catch this is useful when you launch multiple bots in the same process, and one of them failing doesn't need to bring down the process.

    Use this feature with care. :)

  • Format helpers ("telegraf/format") now use template string substitution instead of naively using +=. (Discussion)

Follow Telegraf_JS to receive these updates in Telegram. If you have feedback about this update, please share with us on @​TelegrafJSChat!

v4.10.0

Compare Source

  • Brand new formatting helpers! No more awkward escaping.

    import { fmt, bold, italics, mention } from "telegraf/format";
    
    ctx.reply(fmt`
    Ground control to ${mention("Major Tom", 10000000)}
    ${bold`Lock your Soyuz hatch`} and ${italic`put your helmet on`}
    ${link("David Bowie", "https://en.wikipedia.org/wiki/David_Bowie")}
    `);

    This also just works with captions!

    ctx.replyWithPhoto(
      file.id,
      { caption: fmt`${bold`File name:`} ${file.name}` },
    );
  • Added Input helpers to create the InputFile object.

    import { Telegraf, Input } from "telegraf";
    const bot = new Telegraf(token);
    
    bot.telegram.sendVideo(chatId, Input.fromLocalFile("../assets/cats.mp4"));
    
    bot.telegram.sendDocument(chatId, Input.fromBuffer(buf));
    
    bot.command("cat", ctx => {
      ctx.sendPhoto(Input.fromURL("https://funny-cats.example/cats.jpg"))
    });

    This helps clear the confusion many users have about InputFile.

  • Deprecated ctx.replyWithMarkdown; prefer MarkdownV2 as Telegram recommends.

  • Deprecated ctx.replyWithChatAction; use identical method ctx.sendChatAction instead.

  • bot.launch()'s webhook options now accepts certificate for self-signed certs.

  • Fix bot crashes if updateHandler throws (#​1709)

v4.9.2

Compare Source

  • Fixed bad shorthand for ctx.replyWithVideo (#​1687)

v4.9.1

Compare Source

  • Updated typegram to v3.11.0.

v4.9.0

Compare Source

You can now follow Telegraf releases on Telegram

  • Added support for Bot API 6.1, and API 6.2.
  • Easier Webhooks! Added Telegraf::createWebhook which calls setWebhook, and returns Express-style middleware. [Example]
  • New docs! at feathers-studio/telegraf-docs. All examples were moved there and updated to full TS and ESM.
  • More type exports: Experimental export of internal types (such as the Extra* types) now found as: import type { Convenience } from "telegraf/types" (#​1659)
  • Actual replies: New middleware: import { useNewReplies } from telegraf/future that changes the behaviour of Context::reply* methods to actually reply to the context message. This will be the default in v5.
  • Added Context::sendMessage and Context:sendWith* methods to replace the old Context::reply and Context::replyWith* methods.
  • Updated Telegraf binary! Supports ESM modules, new command-line options --method and --data to call API methods from the command-line.

v4.8.6

Compare Source

v4.8.5

Compare Source

  • Fix: Add exports.import to be able to import Telegraf in Node16+ mode

v4.8.4

Compare Source

  • Adds exports: { types, require } for TypeScript's "module": "Node16". Fixes: #​1629, Ref: Handbook

v4.8.3

Compare Source

  • Deprecate ctx.tg; use ctx.telegram instead
  • Retry on 429 flood waits (fixes #​1563)
  • Export type MiddlewareObj

v4.8.2

Compare Source

  • accept testEnv as an option to Telegraf / Client

v4.8.1

Compare Source

  • fix: added a dummy types.js so importing "telegraf/types" does not cause an eslint import resolution error

v4.8.0

Compare Source

  • Upgrade to typegram@3.9.0; Bot API 6.0 and Web App support
  • Added Markup.button.webApp helper
  • Added ctx.webAppData shorthand to retrieve web_app_data more ergonomically
  • Update minimist to latest, resolves a vulnerability
  • ⚠️ Experimental!: typegram & telegraf types exported as telegraf/types to be imported directly without relying on a separate dependency on typegram. The export interface is not stable. It may change at a later date. Feedback welcome

v4.7.0

Compare Source

Features:

  • Upgrade to typegram@3.8.0 and Bot API 5.7 support.
  • All dependencies updated, audit warnings resolved.

Fixes:

  • fix: BREAKING! ctx.approveChatJoinRequest and ctx.declineChatJoinRequest now implicitly use ctx.chat.id instead of expecting chatId as first parameter.

v4.6.0

Compare Source

  • Bot API 5.6 support
  • New Composer.spoiler and Composer#spoiler methods.

v4.5.2

Compare Source

  • BREAKING: banChatSenderChat and unbanChatSenderChat now infer this.chat.id instead of taking it as first parameter.

v4.5.1

Compare Source

  • Support Bot API 5.4 and 5.5
  • Deprecate kickChatMember in favour of banChatMember
  • fixed doc build in CI

v4.4.2

Compare Source

v4.4.1

Compare Source

v4.4.0: v4.4

Compare Source

v4.3.0: v4.3

Compare Source

I have no more features planned, except #​1267 for v5.0.

v4.2.1

Compare Source

v4.2.0

Compare Source

v4.1.2

Compare Source

v4.1.1

Compare Source

v4.1.0: v4.1

Compare Source

  • Deprecate session (#​1373)
  • Add dropPendingUpdates to Telegraf::launch (#​1366)
  • feat(client): add apiMode option (#​1334)
  • New exports:
    • deunionize,
    • NarrowedContext,
    • Telegram,
    • TelegramError

v4.0.3

Compare Source

v4.0.2

Compare Source

v4.0.1

Compare Source

v4.0.0: v4.0

Compare Source

Changelog Telegraf 4.0

General

  • Port to TypeScript
  • Update to Bot API 5.0
  • Scenes now live in their own namespace called Scenes
  • Allow cancelling requests via AbortController
  • Add attachmentAgent option to provide an agent that is used for fetching files from the web before they are sent to Telegram (previously done through the same agent as used to connect to Telegram itself)

Apart from updating Telegraf to full Telegram Bot API 5.0 support, the most significant improvement is that we now have a code base that is written 100 % in TypeScript, which more or less required a rewrite of the complete library.
Previously, the library was written in JavaScript and had a few type annotations to the side, but they were often incorrect or missing.

In working on the 4.0 release, we created type coverage of the complete Telegram Bot API.
The benefit is that your editor can now autocomplete accross every single field in every single method or entity.
Those who ever tried it out can confirm that this improves the development experience by an order of magnitude.

Note that this update brings 9 months worth of improvements, so while we did our best to summarise all important changes, it's possible that we forgot some!

Composer

  • Add Composer.guard
  • Deprecate static Composer.mount, prefer static Composer.on
  • Make Composer.entity and Composer.match private
  • Remove Composer.catchAll and Composer.safePassThru
  • Catch errors of both branches of Composer.fork
  • Listen to forwards using on('forward_date'), no longer on('forward')

Context

  • Make ctx.botInfo required, i.e. is is always available
  • Make ctx.state readonly
  • Add ctx.senderChat, ctx.unpinAllChatMessages, and ctx.copyMessage
  • ctx.deleteMessage no longer works for edited messages, channel posts, or edited channel posts
  • Remove ctx.updateSubTypes

Extra

Extra is removed entirely, see #​1076.
You can now just specify any options directly, without having to create an Extra instance before.

Markup

Markup is largely reworked.
Please check out the new documentation about Markup, this is much easier than trying to understand the differences between the old and the new version.
The TypeScript autocompletion should help you a lot in case you have to change something about your code.

The main thing to watch out for is that all buttons (keyboard buttons and inline buttons) are now created via Markup.button.url and its siblings, no longer via Markup.urlButton.

The integration with Extra is removed.

Session

Remove the ability to specify a custom property on the context object under which the session lives, in other words, the session data can only be available under ctx.session.
Note that this also applies to scene sessions, they now exclusively live under ctx.scene.session.

When no session data is stored, ctx.session is now undefined instead of {}.

Telegraf

Bots should now always be started using bot.launch with the corresponding configuration for either long polling (default) or webhooks.

  • startPolling and startWebhook are now private
  • TimeoutError is now thrown if update takes longer than handlerTimeout to process
  • handlerTimeout defaults to 90 seconds
  • stop returns void and takes reason instead of callback as as an argument
  • channelMode is removed
Polling
  • Remove retryAfter option (used in an error case), always using 5 seconds now
  • Remove timeout option, always using 50 seconds now
  • Remove limit option, always fetching 100 updates now
  • Remove stopCallback option

Common typing issues

Naturally, if your editor validates your code against the TypeScript types, you may find a few bugs here and there that you were not aware of.
Here are a few things you might come across and that we'd like to explain.

Property X is not available for messages, callback queries, etc

This happens in various different forms, one example is this:

bot.on("message", (ctx) => {
  const text = ctx.message.text;
  //                       ^ error here!
  // Property 'text' does not exist on type ...
});

We are listening for messages here, but not all messages are text messages!
As a result, the text property might be absent, for example for photo messages.

Here is how you solve it:

bot.on("message", (ctx) => {
  if ("text" in message) {
    // now we know that we have a text message!
    const text = ctx.message.text; // works!
    console.log(text);
  }
});

Remember that you can always just do this instead:

bot.on("text", (ctx) => {
  // we already know that we have a text message!
  const text = ctx.message.text; // works!
  console.log(text);
});
Cannot access ctx.session or ctx.scene or ctx.wizard type

If you are using sessions, scenes, wizards, or even yet another of the many modules that work with Telegraf, you have to define your own context object.
This context object must specify which types your middleware registers on the context.
We cannot infer this automatically.

This is best explained by an example bot.

Here is one that's relevant: https://github.com/telegraf/telegraf/blob/develop/docs/examples/example-bot.ts

Scenes have various examples here: https://github.com/telegraf/telegraf/tree/develop/docs/examples/scenes

I see a really complicated type error message!

Middleware in Telegraf is very flexible, so we have to do some really fancy stuff under the hood when we infer the types for you.
Whenever you type bot.on(['callback_query', 'text'], (ctx) => ctx.|, and autocomplete shows up, we have to look at the first argument of bot.on, iterate through the array, look at each string in it, and then do a type transformation on the complete Bot API surface to filter out which options are even available on the relevant context objects at this point.
All of this computation happens on the type level.
(Fun fact: in the first iteration of this feature it took up to 20 seconds for autocomplete to show up.)

The point is: types are hard.
It was our main priority to make the types correct, and then we focused on making the type inference fast.
We would love to make TypeScript print more readable type errors, and we are actively looking trying a few things to do this without too much black magic.

Until then, don't give up!
Here's what you can do:

  1. Remember that most type errors come from typos in variable names or other tiny mistakes.
    Double check this first, the problem may be simpler than you thought.
  2. Even complex error messages have parts in them that you understand!
    Look out for these parts, they often help to fix the problem.
  3. The community can help you.
    Don't hesitate to share a code snippet in the Telegram group.
    You are probably not the only one with this problem.

Configuration

📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR has been generated by Mend Renovate. View repository job log here.

@renovate
Copy link
Author

renovate bot commented Mar 24, 2023

Edited/Blocked Notification

Renovate will not automatically rebase this PR, because it does not recognize the last commit author and assumes somebody else may have edited the PR.

You can manually request rebase by checking the rebase/retry box above.

Warning: custom changes will be lost.

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

Successfully merging this pull request may close these issues.

None yet

1 participant