Go-Filter-Bot / plugins /settings.go
Thaimozhi's picture
fix: auto index fixed
d492361
Raw History Blame Contribute Delete
9.33 kB
// Dynamic bot settings panel β€” toggle all settings from within the bot.
// No more .env edits needed! All changes are saved to MongoDB and cached in memory.
package plugins
import (
"fmt"
"regexp"
"strconv"
"strings"
"github.com/Jisin0/Go-Filter-Bot/database"
"github.com/Jisin0/Go-Filter-Bot/utils"
"github.com/PaulSonOfLars/gotgbot/v2"
"github.com/PaulSonOfLars/gotgbot/v2/ext"
)
var cbSettingsRegex = regexp.MustCompile(`settings\((.+)\)`)
func boolEmoji(v bool) string {
if v {
return "βœ…"
}
return "❌"
}
// buildSettingsMarkup generates the inline keyboard for the settings panel.
func buildSettingsMarkup(s database.BotSettings) gotgbot.InlineKeyboardMarkup {
return gotgbot.InlineKeyboardMarkup{
InlineKeyboard: [][]gotgbot.InlineKeyboardButton{
{
{Text: fmt.Sprintf("%s Multi Filter", boolEmoji(s.MultiFilter)), CallbackData: "settings(toggle_multi_filter)"},
},
{
{Text: fmt.Sprintf("%s Search as Button", boolEmoji(s.SearchAsButton)), CallbackData: "settings(toggle_search_button)"},
},
{
{Text: fmt.Sprintf("⏱ Auto Delete: %dm", s.AutoDelete), CallbackData: "settings(auto_delete)"},
},
{
{Text: "πŸ”— Shortener URL", CallbackData: "settings(shortener_url)"},
{Text: "πŸ”‘ Shortener API", CallbackData: "settings(shortener_api)"},
},
{
{Text: fmt.Sprintf("πŸ“’ Force-Sub (%d ch)", len(s.ForceSubChats)), CallbackData: "settings(fsub_info)"},
{Text: fmt.Sprintf("πŸ“ Index (%d ch)", len(s.IndexChannels)), CallbackData: "settings(index_info)"},
},
{
{Text: fmt.Sprintf("πŸ‘‘ Admins (%d dynamic)", len(s.DynamicAdmins)), CallbackData: "settings(admin_info)"},
},
{
{Text: "πŸ”„ Refresh", CallbackData: "settings(refresh)"},
{Text: "βœ– Close", CallbackData: "close"},
},
},
}
}
// buildSettingsText generates the main settings panel text.
func buildSettingsText(s database.BotSettings) string {
shortURL := s.ShortenerURL
if shortURL == "" {
shortURL = "<i>Not Set</i>"
}
shortAPI := "β€’β€’β€’β€’β€’β€’"
if s.ShortenerAPI == "" {
shortAPI = "<i>Not Set</i>"
}
fsubList := "<i>None</i>"
if len(s.ForceSubChats) > 0 {
parts := make([]string, len(s.ForceSubChats))
for i, c := range s.ForceSubChats {
parts[i] = fmt.Sprintf("<code>%d</code>", c)
}
fsubList = strings.Join(parts, ", ")
}
indexList := "<i>None</i>"
if len(s.IndexChannels) > 0 {
parts := make([]string, len(s.IndexChannels))
for i, c := range s.IndexChannels {
parts[i] = fmt.Sprintf("<code>%d</code>", c)
}
indexList = strings.Join(parts, ", ")
}
return fmt.Sprintf(`<b>βš™οΈ Bᴏᴛ SᴇᴛᴛΙͺΙ΄Ι’s Pα΄€Ι΄α΄‡ΚŸ</b>
<b>Multi Filter :</b> %s
<b>Search Mode :</b> %s
<b>Auto Delete :</b> %d minutes
<b>Shortener URL :</b> %s
<b>Shortener API :</b> %s
<b>Force-Sub :</b> %s
<b>Auto-Index :</b> %s
<b>Dynamic Admins :</b> %d
<i>Tap the buttons below to change settings.</i>
<i>Changes take effect immediately β€” no restart needed!</i>`,
boolEmoji(s.MultiFilter),
func() string {
if s.SearchAsButton {
return "Button"
}
return "Hyperlink"
}(),
s.AutoDelete,
shortURL,
shortAPI,
fsubList,
indexList,
len(s.DynamicAdmins),
)
}
// Settings handles the /settings command.
//
//nolint:errcheck
func Settings(bot *gotgbot.Bot, ctx *ext.Context) error {
if !utils.IsAdmin(ctx.EffectiveUser.Id) {
ctx.EffectiveMessage.Reply(bot, "β›” Only bot admins can use this command!", &gotgbot.SendMessageOpts{})
return nil
}
s := database.GetBotSettings()
_, err := ctx.Message.Reply(bot, buildSettingsText(s), &gotgbot.SendMessageOpts{
ParseMode: gotgbot.ParseModeHTML,
ReplyMarkup: buildSettingsMarkup(s),
})
if err != nil {
fmt.Printf("settings: %v\n", err)
}
return nil
}
// CbSettings handles all settings callbacks.
//
//nolint:errcheck
func CbSettings(bot *gotgbot.Bot, ctx *ext.Context) error {
update := ctx.CallbackQuery
if !utils.IsAdmin(update.From.Id) {
update.Answer(bot, &gotgbot.AnswerCallbackQueryOpts{Text: "β›” Only bot admins can change settings!", ShowAlert: true})
return nil
}
match := cbSettingsRegex.FindStringSubmatch(update.Data)
if len(match) < 2 {
return nil
}
action := match[1]
s := database.GetBotSettings()
switch action {
case "toggle_multi_filter":
DB.SetBotSetting("multi_filter", !s.MultiFilter)
update.Answer(bot, &gotgbot.AnswerCallbackQueryOpts{
Text: fmt.Sprintf("Multi Filter: %s", boolEmoji(!s.MultiFilter)),
})
case "toggle_search_button":
DB.SetBotSetting("search_as_button", !s.SearchAsButton)
update.Answer(bot, &gotgbot.AnswerCallbackQueryOpts{
Text: fmt.Sprintf("Search as Button: %s", boolEmoji(!s.SearchAsButton)),
})
case "auto_delete":
// Cycle through: 0 β†’ 5 β†’ 10 β†’ 30 β†’ 60 β†’ 0
var next int64
switch {
case s.AutoDelete == 0:
next = 5
case s.AutoDelete < 10:
next = 10
case s.AutoDelete < 30:
next = 30
case s.AutoDelete < 60:
next = 60
default:
next = 0
}
DB.SetBotSetting("auto_delete", next)
if next == 0 {
update.Answer(bot, &gotgbot.AnswerCallbackQueryOpts{Text: "Auto Delete: OFF"})
} else {
update.Answer(bot, &gotgbot.AnswerCallbackQueryOpts{Text: fmt.Sprintf("Auto Delete: %d minutes", next)})
}
case "shortener_url":
update.Answer(bot, &gotgbot.AnswerCallbackQueryOpts{})
// Ask in PM β€” works from both group and PM contexts
pmChat := &gotgbot.Chat{Id: update.From.Id, Type: gotgbot.ChatTypePrivate}
m := utils.Ask(bot, "πŸ“ Send the new <b>Shortener URL</b>\n\nExample: <code>fpshortner.in</code>\n\nSend <code>off</code> to disable.", pmChat, &update.From)
if m == nil {
return nil
}
val := strings.TrimSpace(m.Text)
if strings.ToLower(val) == "off" {
val = ""
}
DB.SetBotSetting("shortener_url", val)
if val == "" {
bot.SendMessage(update.From.Id, "βœ… Shortener URL disabled.", &gotgbot.SendMessageOpts{})
} else {
bot.SendMessage(update.From.Id, fmt.Sprintf("βœ… Shortener URL set to: <code>%s</code>", val), &gotgbot.SendMessageOpts{ParseMode: gotgbot.ParseModeHTML})
}
case "shortener_api":
update.Answer(bot, &gotgbot.AnswerCallbackQueryOpts{})
pmChat := &gotgbot.Chat{Id: update.From.Id, Type: gotgbot.ChatTypePrivate}
m := utils.Ask(bot, "πŸ“ Send the new <b>Shortener API Key</b>\n\nSend <code>off</code> to disable.", pmChat, &update.From)
if m == nil {
return nil
}
val := strings.TrimSpace(m.Text)
if strings.ToLower(val) == "off" {
val = ""
}
DB.SetBotSetting("shortener_api", val)
if val == "" {
bot.SendMessage(update.From.Id, "βœ… Shortener API disabled.", &gotgbot.SendMessageOpts{})
} else {
bot.SendMessage(update.From.Id, "βœ… Shortener API Key updated!", &gotgbot.SendMessageOpts{})
}
case "fsub_info":
text := "Use <code>/addfsub &lt;channel_id&gt;</code> to add\nUse <code>/delfsub &lt;channel_id&gt;</code> to remove\nUse <code>/fsub</code> to list"
update.Answer(bot, &gotgbot.AnswerCallbackQueryOpts{Text: "Manage with /addfsub, /delfsub, /fsub", ShowAlert: true})
msg, ok := update.Message.(*gotgbot.Message)
if !ok {
return nil
}
bot.SendMessage(msg.Chat.Id, text, &gotgbot.SendMessageOpts{ParseMode: gotgbot.ParseModeHTML})
return nil
case "index_info":
text := "Use <code>/addindex &lt;channel_id&gt;</code> to add\nUse <code>/delindex &lt;channel_id&gt;</code> to remove\nUse <code>/bulkindex &lt;channel_id&gt; [from] [to]</code> for bulk indexing"
update.Answer(bot, &gotgbot.AnswerCallbackQueryOpts{Text: "Manage with /addindex, /delindex, /bulkindex", ShowAlert: true})
msg2, ok2 := update.Message.(*gotgbot.Message)
if !ok2 {
return nil
}
bot.SendMessage(msg2.Chat.Id, text, &gotgbot.SendMessageOpts{ParseMode: gotgbot.ParseModeHTML})
return nil
case "admin_info":
text := "Use <code>/addadmin &lt;user_id&gt;</code> to add a dynamic admin\nUse <code>/deladmin &lt;user_id&gt;</code> to remove\nUse <code>/admins</code> to list all admins"
update.Answer(bot, &gotgbot.AnswerCallbackQueryOpts{Text: "Manage with /addadmin, /deladmin, /admins", ShowAlert: true})
msg3, ok3 := update.Message.(*gotgbot.Message)
if !ok3 {
return nil
}
bot.SendMessage(msg3.Chat.Id, text, &gotgbot.SendMessageOpts{ParseMode: gotgbot.ParseModeHTML})
return nil
case "refresh":
DB.RefreshBotSettings()
update.Answer(bot, &gotgbot.AnswerCallbackQueryOpts{Text: "♻️ Settings refreshed!"})
default:
// Handle set_autodelete_<value> from potential custom input
if strings.HasPrefix(action, "set_autodelete_") {
valStr := strings.TrimPrefix(action, "set_autodelete_")
val, err := strconv.ParseInt(valStr, 10, 64)
if err == nil {
DB.SetBotSetting("auto_delete", val)
update.Answer(bot, &gotgbot.AnswerCallbackQueryOpts{Text: fmt.Sprintf("Auto Delete: %d min", val)})
}
}
}
// Refresh the settings panel with updated values
newS := database.GetBotSettings()
update.Message.EditText(bot, buildSettingsText(newS), &gotgbot.EditMessageTextOpts{
ParseMode: gotgbot.ParseModeHTML,
ReplyMarkup: buildSettingsMarkup(newS),
})
return nil
}
// CbClose handles the close button on settings and other panels.
//
//nolint:errcheck
func CbClose(bot *gotgbot.Bot, ctx *ext.Context) error {
ctx.CallbackQuery.Message.Delete(bot, nil)
ctx.CallbackQuery.Answer(bot, &gotgbot.AnswerCallbackQueryOpts{})
return nil
}