3

I'm writing a bot on telego, I don't understand how to implement fsm into the bot. Before that, I wrote bots in python aiogram where fsm was built in. How to do it in golang?

package main

import (
    "fmt"
    "os"

    "github.com/mymmrac/telego"
    th "github.com/mymmrac/telego/telegohandler"
    tu "github.com/mymmrac/telego/telegoutil"
)

func main() {
    botToken := os.Getenv("TOKEN")

    // Note: Please keep in mind that default logger may expose sensitive information,
    // use in development only
    bot, err := telego.NewBot(botToken, telego.WithDefaultDebugLogger())
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }

    // Get updates channel
    updates, _ := bot.UpdatesViaLongPolling(nil)

    // Create bot handler and specify from where to get updates
    bh, _ := th.NewBotHandler(bot, updates)

    // Stop handling updates
    defer bh.Stop()

    // Stop getting updates
    defer bot.StopLongPolling()

    // Register new handler with match on command `/start`
    bh.Handle(func(bot *telego.Bot, update telego.Update) {
        // Send message
        _, _ = bot.SendMessage(tu.Message(
            tu.ID(update.Message.Chat.ID),
            fmt.Sprintf("Hello %s!", update.Message.From.FirstName),
        ))
    }, th.CommandEqual("start"))

    // Register new handler with match on any command
    // Handlers will match only once and in order of registration,
    // so this handler will be called on any command except `/start` command
    bh.Handle(func(bot *telego.Bot, update telego.Update) {
        // Send message
        _, _ = bot.SendMessage(tu.Message(
            tu.ID(update.Message.Chat.ID),
            "Unknown command, use /start",
        ))
    }, th.AnyCommand())

    // Start handling updates
    bh.Start()
}

This code was taken from official documentation https://github.com/mymmrac/telego

I googled and didn't find anything that could help me.

John
  • 43
  • 2

1 Answers1

-1

In Golang, you can implement a finite state machine (FSM) in your Telegram bot by defining states and transitions for handling different user interactions. Although the telego library you are using doesn't have built-in support for FSM, you can implement it yourself using a simple switch-case statement or using a state management package like github.com/looplab/fsm.

Here's a simple example of how you can implement an FSM using the github.com/looplab/fsm package with your existing telego bot code:

Define the states and events for your FSM. In this example, let's create a simple FSM to manage the user's registration process:

const (
    StateIdle      = "idle"
    StateRegister  = "register"
    StateCompleted = "completed"
)

const (
    EventStartRegistration = "start_registration"
    EventSubmitDetails     = "submit_details"
    EventFinishRegistration = "finish_registration"
)

Modify your main function to create the FSM and handle state transitions:

func main() {
    // ... Your existing code ...

    // Create a new FSM
    f := fsm.NewFSM(
        StateIdle,
        fsm.Events{
            {Name: EventStartRegistration, Src: []string{StateIdle}, Dst: StateRegister},
            {Name: EventSubmitDetails, Src: []string{StateRegister}, Dst: StateRegister},
            {Name: EventFinishRegistration, Src: []string{StateRegister}, Dst: StateCompleted},
        },
        fsm.Callbacks{},
    )

    // Start handling updates
    bh.Start()

    // Process updates and handle FSM transitions
    for update := range updates {
        switch {
        case th.CommandEqual("start")(update):
            // Start registration process
            if err := f.Event(EventStartRegistration); err != nil {
                fmt.Println("Error processing start_registration event:", err)
            }
            // Respond to the user with a welcome message or instructions for registration
        case update.Message != nil:
            switch f.Current() {
            case StateRegister:
                // Process user's submitted details and update FSM accordingly
                if err := f.Event(EventSubmitDetails); err != nil {
                    fmt.Println("Error processing submit_details event:", err)
                }
            case StateCompleted:
                // The registration process is completed. Handle the user's interactions here.
                // You can use another switch-case statement to handle different interactions based on the current state.
                // For example:
                // if update.Message.Text == "some_command" {
                //     // Handle a command specific to the completed state
                // } else {
                //     // Respond to other interactions in the completed state
                // }
            default:
                // Respond to the user with an "Unknown command" message
            }
        }
    }
}

In this example, we created a basic FSM to manage the user's registration process. The FSM starts in the StateIdle, and when the /start command is received, it transitions to StateRegister. After the user submits their details, it remains in the StateRegister until the EventFinishRegistration event is triggered, transitioning to StateCompleted. Depending on the current state, you can handle user interactions differently.

Please note that this is a simple example, and depending on your specific use case, you may need to define more states and events and add additional logic to handle user interactions in each state.

Make sure to study the github.com/looplab/fsm package documentation for more advanced usage and features.

  • Thank you! i have readen framework, but as I understand you wrote the wrong code) Still a big thank you – John Jul 26 '23 at 16:30
  • 2
    This answer looks like ChatGPT – DavidW Jul 27 '23 at 12:45
  • 1
    @DavidW: Agreed. For the second-to-last paragraph, I got a similar response from [ChatGPT](https://meta.stackoverflow.com/questions/421831/) (using only the first paragraph of the question): *"This example is just a basic starting point. Depending on the complexity of your bot, you may need to expand the FSM to include more states and events. Additionally, you can add more logic to handle user inputs and bot responses."*. – Peter Mortensen Jul 28 '23 at 07:21
  • 1
    cont' - Note: ChatGPT uses (in this particular case at least) the abomination "Golang" from the prompt. It uses the correct [Go](https://en.wikipedia.org/wiki/Go_%28programming_language%29) if that is used in the prompt. Perhaps it thinks they are equally good, based on the training data? Or perhaps [the human annotators](https://www.theverge.com/features/23764584/ai-artificial-intelligence-data-notation-labor-scale-surge-remotasks-openai-chatbots) got it wrong. – Peter Mortensen Jul 28 '23 at 07:29