Refactor post handling and add command setup for Telegram bot
This commit is contained in:
@@ -55,7 +55,7 @@ func (b *Bot) setupRoutes() {
|
||||
|
||||
// Post flow
|
||||
adminOnly.Handle("/post", b.handlePost)
|
||||
adminOnly.Handle(tele.OnText, b.handleTextOrForwarded)
|
||||
adminOnly.Handle(tele.OnText, b.handleTextInput)
|
||||
|
||||
// Entry management
|
||||
adminOnly.Handle("/del", b.handleEntryDel)
|
||||
@@ -66,15 +66,41 @@ func (b *Bot) setupRoutes() {
|
||||
// TOC
|
||||
adminOnly.Handle("/refresh", b.handleRefresh)
|
||||
|
||||
// Admin management (super admin only)
|
||||
superAdminOnly := b.bot.Group()
|
||||
superAdminOnly.Use(b.SuperAdminMiddleware())
|
||||
superAdminOnly.Handle("/admin_add", b.handleAdminAdd)
|
||||
superAdminOnly.Handle("/admin_del", b.handleAdminDel)
|
||||
superAdminOnly.Handle("/admin_list", b.handleAdminList)
|
||||
|
||||
// Callbacks
|
||||
b.bot.Handle(tele.OnCallback, b.handleCallback)
|
||||
}
|
||||
|
||||
func (b *Bot) Start() {
|
||||
b.setCommands()
|
||||
log.Println("Bot started...")
|
||||
b.bot.Start()
|
||||
}
|
||||
|
||||
func (b *Bot) setCommands() {
|
||||
commands := []tele.Command{
|
||||
{Text: "post", Description: "投稿 - 添加频道内容到目录"},
|
||||
{Text: "list", Description: "列表 - 查看所有条目"},
|
||||
{Text: "cat_list", Description: "分类列表"},
|
||||
{Text: "cat_add", Description: "添加分类 <名称> [排序]"},
|
||||
{Text: "cat_del", Description: "删除分类 <名称>"},
|
||||
{Text: "del", Description: "删除条目 <ID>"},
|
||||
{Text: "edit", Description: "编辑标题 <ID> <新标题>"},
|
||||
{Text: "move", Description: "移动条目 <ID> <新分类>"},
|
||||
{Text: "refresh", Description: "刷新目录"},
|
||||
}
|
||||
|
||||
if err := b.bot.SetCommands(commands); err != nil {
|
||||
log.Printf("Failed to set commands: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Bot) Stop() {
|
||||
b.bot.Stop()
|
||||
b.toc.Stop()
|
||||
|
||||
89
internal/telegram/handlers_admin.go
Normal file
89
internal/telegram/handlers_admin.go
Normal file
@@ -0,0 +1,89 @@
|
||||
package telegram
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
tele "gopkg.in/telebot.v3"
|
||||
)
|
||||
|
||||
func (b *Bot) handleAdminAdd(c tele.Context) error {
|
||||
payload := strings.TrimSpace(c.Message().Payload)
|
||||
if payload == "" {
|
||||
return c.Reply("用法: /admin_add <用户ID>")
|
||||
}
|
||||
|
||||
userID, err := strconv.ParseInt(payload, 10, 64)
|
||||
if err != nil {
|
||||
return c.Reply("❌ 无效的用户ID")
|
||||
}
|
||||
|
||||
// 检查是否已是管理员
|
||||
if b.isAdmin(userID) {
|
||||
return c.Reply("⚠️ 该用户已是管理员")
|
||||
}
|
||||
|
||||
if err := b.storage.AddAdmin(userID); err != nil {
|
||||
return c.Reply(fmt.Sprintf("❌ 添加失败: %v", err))
|
||||
}
|
||||
|
||||
return c.Reply(fmt.Sprintf("✅ 已添加管理员: %d", userID))
|
||||
}
|
||||
|
||||
func (b *Bot) handleAdminDel(c tele.Context) error {
|
||||
payload := strings.TrimSpace(c.Message().Payload)
|
||||
if payload == "" {
|
||||
return c.Reply("用法: /admin_del <用户ID>")
|
||||
}
|
||||
|
||||
userID, err := strconv.ParseInt(payload, 10, 64)
|
||||
if err != nil {
|
||||
return c.Reply("❌ 无效的用户ID")
|
||||
}
|
||||
|
||||
// 不能删除超级管理员
|
||||
if b.cfg.IsSuperAdmin(userID) {
|
||||
return c.Reply("❌ 无法删除超级管理员(配置文件中的管理员)")
|
||||
}
|
||||
|
||||
if err := b.storage.RemoveAdmin(userID); err != nil {
|
||||
return c.Reply(fmt.Sprintf("❌ 删除失败: %v", err))
|
||||
}
|
||||
|
||||
return c.Reply(fmt.Sprintf("✅ 已移除管理员: %d", userID))
|
||||
}
|
||||
|
||||
func (b *Bot) handleAdminList(c tele.Context) error {
|
||||
// 配置文件中的超级管理员
|
||||
superAdmins := b.cfg.Admins
|
||||
|
||||
// 数据库中的动态管理员
|
||||
dbAdmins, err := b.storage.ListAdmins()
|
||||
if err != nil {
|
||||
return c.Reply(fmt.Sprintf("❌ 获取管理员列表失败: %v", err))
|
||||
}
|
||||
|
||||
var sb strings.Builder
|
||||
sb.WriteString("👑 **管理员列表**\n\n")
|
||||
|
||||
sb.WriteString("**超级管理员(配置文件):**\n")
|
||||
if len(superAdmins) == 0 {
|
||||
sb.WriteString(" _无_\n")
|
||||
} else {
|
||||
for _, id := range superAdmins {
|
||||
sb.WriteString(fmt.Sprintf(" • `%d`\n", id))
|
||||
}
|
||||
}
|
||||
|
||||
sb.WriteString("\n**动态管理员(数据库):**\n")
|
||||
if len(dbAdmins) == 0 {
|
||||
sb.WriteString(" _无_\n")
|
||||
} else {
|
||||
for _, id := range dbAdmins {
|
||||
sb.WriteString(fmt.Sprintf(" • `%d`\n", id))
|
||||
}
|
||||
}
|
||||
|
||||
return c.Reply(sb.String(), tele.ModeMarkdown)
|
||||
}
|
||||
@@ -12,20 +12,113 @@ import (
|
||||
const (
|
||||
cbPrefixCat = "cat:"
|
||||
cbPrefixConfirm = "confirm:"
|
||||
cbPrefixTitle = "title:"
|
||||
cbCancel = "cancel"
|
||||
)
|
||||
|
||||
func (b *Bot) handlePost(c tele.Context) error {
|
||||
msg := c.Message()
|
||||
payload := strings.TrimSpace(c.Message().Payload)
|
||||
|
||||
// 快捷方式: 回复消息 + /post <分类> /tt <标题>
|
||||
if msg.ReplyTo != nil && payload != "" {
|
||||
return b.handleQuickPost(c, msg.ReplyTo, payload)
|
||||
}
|
||||
|
||||
// 常规交互流程
|
||||
b.states.StartPost(c.Sender().ID)
|
||||
return c.Reply("📨 请转发一条来自目标频道的消息")
|
||||
return c.Reply("📨 请转发需要归档到目录的消息\n\n消息将被同步发送到频道并添加到目录\n\n💡 快捷方式: 回复消息并发送\n`/post <分类> /tt <标题>`", tele.ModeMarkdown)
|
||||
}
|
||||
|
||||
func (b *Bot) handleTextOrForwarded(c tele.Context) error {
|
||||
func (b *Bot) handleQuickPost(c tele.Context, replyMsg *tele.Message, payload string) error {
|
||||
// 解析: <分类> /tt <标题>
|
||||
parts := strings.SplitN(payload, "/tt", 2)
|
||||
category := strings.TrimSpace(parts[0])
|
||||
|
||||
var title string
|
||||
if len(parts) > 1 {
|
||||
title = strings.TrimSpace(parts[1])
|
||||
}
|
||||
|
||||
if category == "" {
|
||||
return c.Reply("❌ 用法: /post <分类> /tt <标题>\n例如: /post iOS /tt 某个APP推荐")
|
||||
}
|
||||
|
||||
// 验证分类存在
|
||||
if !b.storage.CategoryExists(category) {
|
||||
categories, _ := b.storage.ListCategories()
|
||||
var names []string
|
||||
for _, cat := range categories {
|
||||
names = append(names, cat.Name)
|
||||
}
|
||||
return c.Reply(fmt.Sprintf("❌ 分类 [%s] 不存在\n\n可用分类: %s", category, strings.Join(names, ", ")))
|
||||
}
|
||||
|
||||
// 标题: 优先使用指定标题,否则从回复消息提取
|
||||
if title == "" {
|
||||
title = extractTitle(replyMsg)
|
||||
}
|
||||
|
||||
// 构建链接
|
||||
link := buildMessageLinkFromReply(c.Message(), replyMsg)
|
||||
|
||||
// 创建条目
|
||||
entry, err := b.storage.CreateEntry(category, title, link)
|
||||
if err != nil {
|
||||
return c.Reply(fmt.Sprintf("❌ 保存失败: %v", err))
|
||||
}
|
||||
|
||||
b.toc.TriggerUpdate()
|
||||
|
||||
return c.Reply(fmt.Sprintf("✅ 已添加\n\nID: `%s`\n分类: %s\n标题: %s\n链接: %s",
|
||||
entry.ID, entry.Category, entry.Title, entry.Link), tele.ModeMarkdown)
|
||||
}
|
||||
|
||||
func buildMessageLinkFromReply(currentMsg, replyMsg *tele.Message) string {
|
||||
chat := currentMsg.Chat
|
||||
msgID := replyMsg.ID
|
||||
|
||||
if chat.Username != "" {
|
||||
return fmt.Sprintf("https://t.me/%s/%d", chat.Username, msgID)
|
||||
}
|
||||
|
||||
chatID := chat.ID
|
||||
if chatID < 0 {
|
||||
chatID = -chatID - 1000000000000
|
||||
}
|
||||
return fmt.Sprintf("https://t.me/c/%d/%d", chatID, msgID)
|
||||
}
|
||||
|
||||
func (b *Bot) handleTextInput(c tele.Context) error {
|
||||
msg := c.Message()
|
||||
if msg == nil || msg.OriginalChat == nil {
|
||||
if msg == nil {
|
||||
return nil
|
||||
}
|
||||
return b.handleForwarded(c)
|
||||
|
||||
// 只处理私聊消息,忽略群组对话
|
||||
if c.Chat().Type != tele.ChatPrivate {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 只处理有活跃投稿状态的用户
|
||||
state := b.states.Get(c.Sender().ID)
|
||||
if state == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 转发消息处理 (StepAwaitForward)
|
||||
// OriginalChat: 转发自频道/群组; OriginalSender: 转发自个人用户
|
||||
isForwarded := msg.OriginalChat != nil || msg.OriginalSender != nil
|
||||
if isForwarded && state.Step == StepAwaitForward {
|
||||
return b.handleForwarded(c)
|
||||
}
|
||||
|
||||
// 自定义标题输入 (StepAwaitTitle)
|
||||
if state.Step == StepAwaitTitle {
|
||||
return b.handleTitleInput(c)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Bot) handleForwarded(c tele.Context) error {
|
||||
@@ -39,8 +132,9 @@ func (b *Bot) handleForwarded(c tele.Context) error {
|
||||
}
|
||||
|
||||
msg := c.Message()
|
||||
if msg.OriginalChat == nil {
|
||||
return c.Reply("❌ 这不是一条转发消息,请转发频道消息")
|
||||
// 检查是否为转发消息(来自频道/群组或个人用户)
|
||||
if msg.OriginalChat == nil && msg.OriginalSender == nil {
|
||||
return c.Reply("❌ 这不是一条转发消息,请转发一条消息给我")
|
||||
}
|
||||
|
||||
b.states.SetForwarded(c.Sender().ID, msg)
|
||||
@@ -91,7 +185,8 @@ func (b *Bot) handleCallback(c tele.Context) error {
|
||||
return c.Respond(&tele.CallbackResponse{Text: "无权限"})
|
||||
}
|
||||
|
||||
data := c.Callback().Data
|
||||
// telebot v3 会在 data 前加 \f 前缀,需要去掉
|
||||
data := strings.TrimPrefix(c.Callback().Data, "\f")
|
||||
userID := c.Sender().ID
|
||||
|
||||
switch {
|
||||
@@ -102,6 +197,10 @@ func (b *Bot) handleCallback(c tele.Context) error {
|
||||
category := strings.TrimPrefix(data, cbPrefixCat)
|
||||
return b.handleCategoryCallback(c, userID, category)
|
||||
|
||||
case strings.HasPrefix(data, cbPrefixTitle):
|
||||
action := strings.TrimPrefix(data, cbPrefixTitle)
|
||||
return b.handleTitleCallback(c, userID, action)
|
||||
|
||||
case strings.HasPrefix(data, cbPrefixConfirm):
|
||||
action := strings.TrimPrefix(data, cbPrefixConfirm)
|
||||
return b.handleConfirmCallback(c, userID, action)
|
||||
@@ -116,6 +215,74 @@ func (b *Bot) handleCancelCallback(c tele.Context, userID int64) error {
|
||||
return c.Respond(&tele.CallbackResponse{Text: "已取消"})
|
||||
}
|
||||
|
||||
func (b *Bot) handleTitleCallback(c tele.Context, userID int64, action string) error {
|
||||
state := b.states.Get(userID)
|
||||
if state == nil || state.Step != StepAwaitTitle {
|
||||
return c.Respond(&tele.CallbackResponse{Text: "会话已过期"})
|
||||
}
|
||||
|
||||
if action == "default" {
|
||||
// 使用默认标题
|
||||
title := extractTitle(state.ForwardedMsg)
|
||||
b.states.SetTitle(userID, title)
|
||||
return b.showConfirmation(c, state, title)
|
||||
}
|
||||
|
||||
// 自定义标题 - 提示用户输入
|
||||
c.Edit("✏️ 请发送新标题:")
|
||||
return c.Respond()
|
||||
}
|
||||
|
||||
func (b *Bot) handleTitleInput(c tele.Context) error {
|
||||
state := b.states.Get(c.Sender().ID)
|
||||
if state == nil || state.Step != StepAwaitTitle {
|
||||
return nil
|
||||
}
|
||||
|
||||
title := strings.TrimSpace(c.Message().Text)
|
||||
if title == "" {
|
||||
return c.Reply("❌ 标题不能为空,请重新输入:")
|
||||
}
|
||||
|
||||
if len(title) > 50 {
|
||||
title = title[:47] + "..."
|
||||
}
|
||||
|
||||
b.states.SetTitle(c.Sender().ID, title)
|
||||
return b.showConfirmationMsg(c, state, title)
|
||||
}
|
||||
|
||||
func (b *Bot) showConfirmation(c tele.Context, state *PostState, title string) error {
|
||||
channelName := "未知频道"
|
||||
if state.ForwardedMsg.OriginalChat != nil {
|
||||
channelName = state.ForwardedMsg.OriginalChat.Title
|
||||
}
|
||||
|
||||
menu := &tele.ReplyMarkup{}
|
||||
confirmBtn := menu.Data("✅ 确认添加", cbPrefixConfirm+"yes")
|
||||
cancelBtn := menu.Data("❌ 取消", cbCancel)
|
||||
menu.Inline(menu.Row(confirmBtn, cancelBtn))
|
||||
|
||||
text := fmt.Sprintf("📋 确认添加?\n\n频道: %s\n分类: %s\n标题: %s", channelName, state.SelectedCat, title)
|
||||
c.Edit(text, menu)
|
||||
return c.Respond()
|
||||
}
|
||||
|
||||
func (b *Bot) showConfirmationMsg(c tele.Context, state *PostState, title string) error {
|
||||
channelName := "未知频道"
|
||||
if state.ForwardedMsg.OriginalChat != nil {
|
||||
channelName = state.ForwardedMsg.OriginalChat.Title
|
||||
}
|
||||
|
||||
menu := &tele.ReplyMarkup{}
|
||||
confirmBtn := menu.Data("✅ 确认添加", cbPrefixConfirm+"yes")
|
||||
cancelBtn := menu.Data("❌ 取消", cbCancel)
|
||||
menu.Inline(menu.Row(confirmBtn, cancelBtn))
|
||||
|
||||
text := fmt.Sprintf("📋 确认添加?\n\n频道: %s\n分类: %s\n标题: %s", channelName, state.SelectedCat, title)
|
||||
return c.Reply(text, menu)
|
||||
}
|
||||
|
||||
func (b *Bot) handleCategoryCallback(c tele.Context, userID int64, category string) error {
|
||||
state := b.states.Get(userID)
|
||||
if state == nil || state.Step != StepAwaitCategory {
|
||||
@@ -124,17 +291,20 @@ func (b *Bot) handleCategoryCallback(c tele.Context, userID int64, category stri
|
||||
|
||||
b.states.SetCategory(userID, category)
|
||||
|
||||
channelName := "未知频道"
|
||||
if state.ForwardedMsg.OriginalChat != nil {
|
||||
channelName = state.ForwardedMsg.OriginalChat.Title
|
||||
}
|
||||
// 提取默认标题
|
||||
defaultTitle := extractTitle(state.ForwardedMsg)
|
||||
|
||||
menu := &tele.ReplyMarkup{}
|
||||
confirmBtn := menu.Data("✅ 确认", cbPrefixConfirm+"yes")
|
||||
useDefaultBtn := menu.Data("✅ 使用此标题", cbPrefixTitle+"default")
|
||||
customBtn := menu.Data("✏️ 自定义标题", cbPrefixTitle+"custom")
|
||||
cancelBtn := menu.Data("❌ 取消", cbCancel)
|
||||
menu.Inline(menu.Row(confirmBtn, cancelBtn))
|
||||
menu.Inline(
|
||||
menu.Row(useDefaultBtn),
|
||||
menu.Row(customBtn),
|
||||
menu.Row(cancelBtn),
|
||||
)
|
||||
|
||||
text := fmt.Sprintf("📋 确认添加?\n\n频道: %s\n分类: %s", channelName, category)
|
||||
text := fmt.Sprintf("📝 确认标题\n\n分类: %s\n标题: %s\n\n使用此标题或自定义?", category, defaultTitle)
|
||||
c.Edit(text, menu)
|
||||
return c.Respond()
|
||||
}
|
||||
@@ -152,8 +322,18 @@ func (b *Bot) handleConfirmCallback(c tele.Context, userID int64, action string)
|
||||
defer b.states.Delete(userID)
|
||||
|
||||
msg := state.ForwardedMsg
|
||||
title := extractTitle(msg)
|
||||
link := buildMessageLink(msg)
|
||||
title := state.Title
|
||||
|
||||
// 复制消息内容发送到频道(非转发,可编辑)
|
||||
channel := &tele.Chat{ID: b.cfg.Channel.ID}
|
||||
channelMsg, err := b.sendMessageCopy(channel, msg)
|
||||
if err != nil {
|
||||
c.Edit(fmt.Sprintf("❌ 发送到频道失败: %v", err))
|
||||
return c.Respond(&tele.CallbackResponse{Text: "发送失败"})
|
||||
}
|
||||
|
||||
// 使用频道消息的链接
|
||||
link := buildChannelLink(b.cfg.Channel.ID, channelMsg.ID)
|
||||
|
||||
entry, err := b.storage.CreateEntry(state.SelectedCat, title, link)
|
||||
if err != nil {
|
||||
@@ -168,6 +348,66 @@ func (b *Bot) handleConfirmCallback(c tele.Context, userID int64, action string)
|
||||
return c.Respond(&tele.CallbackResponse{Text: "添加成功"})
|
||||
}
|
||||
|
||||
// sendMessageCopy 复制消息内容发送(非转发,可编辑)
|
||||
func (b *Bot) sendMessageCopy(to *tele.Chat, msg *tele.Message) (*tele.Message, error) {
|
||||
// 图片
|
||||
if msg.Photo != nil {
|
||||
photo := &tele.Photo{File: msg.Photo.File, Caption: msg.Caption}
|
||||
return b.bot.Send(to, photo, tele.ModeHTML)
|
||||
}
|
||||
|
||||
// 视频
|
||||
if msg.Video != nil {
|
||||
video := &tele.Video{File: msg.Video.File, Caption: msg.Caption}
|
||||
return b.bot.Send(to, video, tele.ModeHTML)
|
||||
}
|
||||
|
||||
// 文档
|
||||
if msg.Document != nil {
|
||||
doc := &tele.Document{File: msg.Document.File, Caption: msg.Caption}
|
||||
return b.bot.Send(to, doc, tele.ModeHTML)
|
||||
}
|
||||
|
||||
// 音频
|
||||
if msg.Audio != nil {
|
||||
audio := &tele.Audio{File: msg.Audio.File, Caption: msg.Caption}
|
||||
return b.bot.Send(to, audio, tele.ModeHTML)
|
||||
}
|
||||
|
||||
// 语音
|
||||
if msg.Voice != nil {
|
||||
voice := &tele.Voice{File: msg.Voice.File}
|
||||
return b.bot.Send(to, voice)
|
||||
}
|
||||
|
||||
// 贴纸
|
||||
if msg.Sticker != nil {
|
||||
sticker := &tele.Sticker{File: msg.Sticker.File}
|
||||
return b.bot.Send(to, sticker)
|
||||
}
|
||||
|
||||
// 动图
|
||||
if msg.Animation != nil {
|
||||
anim := &tele.Animation{File: msg.Animation.File, Caption: msg.Caption}
|
||||
return b.bot.Send(to, anim, tele.ModeHTML)
|
||||
}
|
||||
|
||||
// 纯文本
|
||||
if msg.Text != "" {
|
||||
return b.bot.Send(to, msg.Text, tele.ModeHTML, tele.NoPreview)
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("不支持的消息类型")
|
||||
}
|
||||
|
||||
func buildChannelLink(channelID int64, msgID int) string {
|
||||
chatID := channelID
|
||||
if chatID < 0 {
|
||||
chatID = -chatID - 1000000000000
|
||||
}
|
||||
return fmt.Sprintf("https://t.me/c/%d/%d", chatID, msgID)
|
||||
}
|
||||
|
||||
func extractTitle(msg *tele.Message) string {
|
||||
text := msg.Text
|
||||
if text == "" {
|
||||
|
||||
@@ -4,13 +4,40 @@ import (
|
||||
tele "gopkg.in/telebot.v3"
|
||||
)
|
||||
|
||||
// isAdmin 检查用户是否为管理员(配置文件或数据库)
|
||||
func (b *Bot) isAdmin(userID int64) bool {
|
||||
return b.cfg.IsAdmin(userID) || b.storage.IsAdmin(userID)
|
||||
}
|
||||
|
||||
func (b *Bot) AdminMiddleware() tele.MiddlewareFunc {
|
||||
return func(next tele.HandlerFunc) tele.HandlerFunc {
|
||||
return func(c tele.Context) error {
|
||||
if !b.cfg.IsAdmin(c.Sender().ID) {
|
||||
// 群组中的非命令消息,非管理员直接忽略不回复
|
||||
if c.Chat().Type != tele.ChatPrivate {
|
||||
msg := c.Message()
|
||||
if msg != nil && !msg.IsService() && (msg.Text == "" || msg.Text[0] != '/') {
|
||||
if !b.isAdmin(c.Sender().ID) {
|
||||
return nil // 静默忽略
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !b.isAdmin(c.Sender().ID) {
|
||||
return c.Reply("⛔ 无权限访问")
|
||||
}
|
||||
return next(c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SuperAdminMiddleware 超级管理员中间件(仅配置文件中的管理员)
|
||||
func (b *Bot) SuperAdminMiddleware() tele.MiddlewareFunc {
|
||||
return func(next tele.HandlerFunc) tele.HandlerFunc {
|
||||
return func(c tele.Context) error {
|
||||
if !b.cfg.IsSuperAdmin(c.Sender().ID) {
|
||||
return c.Reply("⛔ 需要超级管理员权限")
|
||||
}
|
||||
return next(c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ type PostStep int
|
||||
const (
|
||||
StepAwaitForward PostStep = iota
|
||||
StepAwaitCategory
|
||||
StepAwaitTitle
|
||||
StepAwaitConfirm
|
||||
)
|
||||
|
||||
@@ -19,6 +20,7 @@ type PostState struct {
|
||||
UserID int64
|
||||
ForwardedMsg *tele.Message
|
||||
SelectedCat string
|
||||
Title string
|
||||
Step PostStep
|
||||
CreatedAt time.Time
|
||||
}
|
||||
@@ -86,6 +88,20 @@ func (sm *StateManager) SetCategory(userID int64, category string) *PostState {
|
||||
}
|
||||
|
||||
state.SelectedCat = category
|
||||
state.Step = StepAwaitTitle
|
||||
return state
|
||||
}
|
||||
|
||||
func (sm *StateManager) SetTitle(userID int64, title string) *PostState {
|
||||
sm.mu.Lock()
|
||||
defer sm.mu.Unlock()
|
||||
|
||||
state := sm.states[userID]
|
||||
if state == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
state.Title = title
|
||||
state.Step = StepAwaitConfirm
|
||||
return state
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user