Golang 电报机器人

huangapple go评论115阅读模式
英文:

Golang Telegram Bot

问题

我正在使用telego编写一个机器人,但我不知道如何将有限状态机(FSM)实现到机器人中。在此之前,我使用Python的aiogram编写机器人,其中FSM已经内置。在Golang中如何实现呢?

这段代码是从官方文档https://github.com/mymmrac/telego 中获取的。

我搜索了一下,没有找到任何可以帮助我的东西。

英文:

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.

答案1

得分: -1

在Golang中,你可以通过定义状态和转换来实现一个有限状态机(FSM)来处理Telegram机器人中的不同用户交互。尽管你正在使用的telego库没有内置的FSM支持,但你可以使用简单的switch-case语句或使用一个状态管理包(如github.com/looplab/fsm)来自己实现它。

下面是一个使用github.com/looplab/fsm包和你现有的telego机器人代码实现FSM的简单示例:

首先,定义FSM的状态和事件。在这个示例中,我们创建一个简单的FSM来管理用户的注册过程:

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

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

然后,修改你的main函数来创建FSM并处理状态转换:

func main() {
    // ... 你现有的代码 ...

    // 创建一个新的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{},
    )

    // 开始处理更新
    bh.Start()

    // 处理更新并处理FSM的状态转换
    for update := range updates {
        switch {
        case th.CommandEqual("start")(update):
            // 开始注册过程
            if err := f.Event(EventStartRegistration); err != nil {
                fmt.Println("处理start_registration事件时出错:", err)
            }
            // 向用户回复欢迎消息或注册说明
        case update.Message != nil:
            switch f.Current() {
            case StateRegister:
                // 处理用户提交的详细信息并相应地更新FSM
                if err := f.Event(EventSubmitDetails); err != nil {
                    fmt.Println("处理submit_details事件时出错:", err)
                }
            case StateCompleted:
                // 注册过程已完成。在这里处理用户的交互。
                // 你可以使用另一个switch-case语句来根据当前状态处理不同的交互。
                // 例如:
                // if update.Message.Text == "some_command" {
                //     // 处理特定于已完成状态的命令
                // } else {
                //     // 对已完成状态的其他交互进行回复
                // }
            default:
                // 向用户回复"未知命令"消息
            }
        }
    }
}

在这个示例中,我们创建了一个基本的FSM来管理用户的注册过程。FSM从StateIdle开始,在收到/start命令时转换到StateRegister。用户提交详细信息后,它会保持在StateRegister状态,直到触发EventFinishRegistration事件,然后转换到StateCompleted。根据当前状态,你可以以不同的方式处理用户交互。

请注意,这只是一个简单的示例,根据你的具体用例,你可能需要定义更多的状态和事件,并添加额外的逻辑来处理每个状态下的用户交互。

确保阅读github.com/looplab/fsm包的文档以了解更高级的用法和功能。

英文:

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.

huangapple
  • 本文由 发表于 2023年7月26日 21:03:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/76771634.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定