mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-07-15 17:16:07 +00:00
fix(tgbot): stop auto-deleted messages from resetting wizard state
SendMsgToTgbotDeleteAfter spawns a goroutine that, after the display delay, deleted the transient message and then unconditionally cleared the chat's conversation state. Every caller that ends a wizard step already clears the state synchronously, so that call was redundant — and harmful: if within the delay the user advanced to the next step (a callback sets a fresh awaiting_* state), the late goroutine wiped it, and the user's next message fell through unrecognized, silently dropping their input. Move the delayed deletion into deleteMessageAfterDelay, which only removes the message and no longer touches the conversation state. Guard deleteMessageTgBot against a nil bot so the deletion path is unit-testable.
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
package tgbot
|
||||
|
||||
import "testing"
|
||||
|
||||
// A transient "delete after N seconds" message must not reset the conversation
|
||||
// state when its timer fires: the user may have advanced to the next wizard step
|
||||
// (setting a fresh state) within that window, and clearing it would silently
|
||||
// drop their next input.
|
||||
func TestDeleteMessageAfterDelayKeepsUserState(t *testing.T) {
|
||||
userStateMgr.reset()
|
||||
t.Cleanup(userStateMgr.reset)
|
||||
|
||||
const chatID = int64(4242)
|
||||
userStateMgr.set(chatID, "awaiting_comment")
|
||||
|
||||
tg := &Tgbot{}
|
||||
tg.deleteMessageAfterDelay(chatID, 1, 0)
|
||||
|
||||
if st, ok := userStateMgr.get(chatID); !ok || st != "awaiting_comment" {
|
||||
t.Fatalf("delayed message deletion cleared the conversation state: got (%q, %v), want (%q, true)", st, ok, "awaiting_comment")
|
||||
}
|
||||
}
|
||||
@@ -228,16 +228,25 @@ func (t *Tgbot) SendMsgToTgbotDeleteAfter(chatId int64, msg string, delayInSecon
|
||||
return
|
||||
}
|
||||
|
||||
// Delete the sent message after the specified number of seconds
|
||||
go func() {
|
||||
time.Sleep(time.Duration(delayInSeconds) * time.Second) // Wait for the specified delay
|
||||
t.deleteMessageTgBot(chatId, sentMsg.MessageID) // Delete the message
|
||||
userStateMgr.clear(chatId)
|
||||
}()
|
||||
// Delete the sent message after the specified number of seconds.
|
||||
go t.deleteMessageAfterDelay(chatId, sentMsg.MessageID, delayInSeconds)
|
||||
}
|
||||
|
||||
// deleteMessageAfterDelay waits delayInSeconds and then removes the message. It
|
||||
// deliberately does not touch the conversation state: every caller that ends a
|
||||
// wizard step already clears the state synchronously, and clearing it here — up
|
||||
// to several seconds later — would wipe a state the user set for the next step
|
||||
// in the meantime, silently dropping their following input.
|
||||
func (t *Tgbot) deleteMessageAfterDelay(chatId int64, messageID, delayInSeconds int) {
|
||||
time.Sleep(time.Duration(delayInSeconds) * time.Second)
|
||||
t.deleteMessageTgBot(chatId, messageID)
|
||||
}
|
||||
|
||||
// deleteMessageTgBot deletes a message from the chat.
|
||||
func (t *Tgbot) deleteMessageTgBot(chatId int64, messageID int) {
|
||||
if bot == nil {
|
||||
return
|
||||
}
|
||||
params := telego.DeleteMessageParams{
|
||||
ChatID: tu.ID(chatId),
|
||||
MessageID: messageID,
|
||||
|
||||
Reference in New Issue
Block a user