Changes in BehaviourBuilder triggers and new FSM extension

Changes in BehaviourBuilder triggers and new FSM extension

InsanusMokrassar

First of all, lets meet: I am maintainer of TelegramBotAPI. It is a framework which allow you to use telegram bots almost everywhere where you are able to run Kotlin (currently excluding native, but I hope it will be changed with Kotlin Native release).

Some time ago I've created BehaviourBuilder . It is DSL where you may simply add reactions for your bot and ask to wait some data from user/chat/channel. How currently it looks like:

But there is a small problem: user may send something between receiving of /start and our waiting calls. In that case we will loose user messages a,d ask him to send data again (or even do not react on his messages after our message). Why that happens? the reason is related to the mechanism of SharedFlow work. In two words, this flow will eliminate any data after emitting to all subscribers, even in case when there is no any subscribers.

For the solving of this problem was created AccumulatorFlow. This flow will store all data which still not handled. That means, that in case we will use that flow instead of shared in context of onCommand, all updates in context of onCommand will be received one-by-one until there is anybody who received that data and handled it successfuly.

So, what about FSM?

Since 0.36.0has been added new package: dev.inmo:tgbotapi.behaviour_builder.fsm. It is an extension on top of behaviour builder with built-in finite state machine. That was made for the same reason with the creating of AccumulatorFlow: in context of chain we always must be sure that updates between steps didn't missed. Lets see the example:

Here we have one state handler, which ask user to send some text and in case when user has sent done text, chain will be completed (null returned). Otherwise, user will get back his text with note about saving and asked again about new text. The main point here is that between steps will not be lost any update.

But previously we could use default state machine from microutils

Yes, but there was one big problem: your updates have been lost between waiting operations.

Report Page