feat: implement group filter management with caching and database integration
This commit is contained in:
@@ -0,0 +1,171 @@
|
||||
package group
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"neo/core"
|
||||
hc "neo/context"
|
||||
"neo/database"
|
||||
)
|
||||
|
||||
var (
|
||||
// filterCache stores group filters. Map of ChatJID string -> map of Key string -> Content string
|
||||
filterCache = make(map[string]map[string]string)
|
||||
cacheMu sync.RWMutex
|
||||
)
|
||||
|
||||
func init() {
|
||||
core.Default.Register(&core.Command{
|
||||
Name: "filter",
|
||||
Aliases: []string{"f"},
|
||||
Description: "Manage group filters",
|
||||
Category: "Group",
|
||||
Permissions: []core.Permission{core.PermissionGroupOnly},
|
||||
Run: HandleFilterCommand,
|
||||
})
|
||||
|
||||
// Register the middleware to catch incoming messages
|
||||
core.Default.Use(FilterMiddleware)
|
||||
}
|
||||
|
||||
// LoadCache loads all filters from DB into memory
|
||||
func LoadCache() {
|
||||
cacheMu.Lock()
|
||||
defer cacheMu.Unlock()
|
||||
|
||||
var filters []database.Filter
|
||||
database.DB.Find(&filters)
|
||||
|
||||
for _, f := range filters {
|
||||
if filterCache[f.GroupID] == nil {
|
||||
filterCache[f.GroupID] = make(map[string]string)
|
||||
}
|
||||
filterCache[f.GroupID][f.Key] = f.Content
|
||||
}
|
||||
}
|
||||
|
||||
func HandleFilterCommand(ctx *hc.Ctx) {
|
||||
args := ctx.Arguments()
|
||||
if len(args) < 1 {
|
||||
ctx.Reply("Usage:\n.filter add key|content\n.filter del key")
|
||||
return
|
||||
}
|
||||
|
||||
action := args[0]
|
||||
chatID := ctx.ChatJID().String()
|
||||
|
||||
switch action {
|
||||
case "add":
|
||||
fullArgs := ctx.FullArgs()
|
||||
// Remove the 'add ' prefix from full arguments string
|
||||
contentStart := strings.Index(fullArgs, "add") + 3
|
||||
if contentStart >= len(fullArgs) {
|
||||
ctx.Reply("Invalid format. Use: .filter add key|content")
|
||||
return
|
||||
}
|
||||
|
||||
payload := strings.TrimSpace(fullArgs[contentStart:])
|
||||
|
||||
parts := strings.SplitN(payload, "|", 2)
|
||||
if len(parts) < 2 {
|
||||
ctx.Reply("Invalid format. Use: .filter add key|content")
|
||||
return
|
||||
}
|
||||
|
||||
key := strings.ToLower(strings.TrimSpace(parts[0]))
|
||||
content := strings.TrimSpace(parts[1])
|
||||
|
||||
if key == "" || content == "" {
|
||||
ctx.Reply("Key or content cannot be empty.")
|
||||
return
|
||||
}
|
||||
|
||||
// Update DB
|
||||
var filter database.Filter
|
||||
result := database.DB.Where(database.Filter{Key: key, GroupID: chatID}).FirstOrCreate(&filter, database.Filter{
|
||||
Key: key,
|
||||
GroupID: chatID,
|
||||
Content: content,
|
||||
})
|
||||
|
||||
if result.RowsAffected == 0 {
|
||||
// Update if exists
|
||||
filter.Content = content
|
||||
database.DB.Save(&filter)
|
||||
}
|
||||
|
||||
// Update Cache
|
||||
cacheMu.Lock()
|
||||
if filterCache[chatID] == nil {
|
||||
filterCache[chatID] = make(map[string]string)
|
||||
}
|
||||
filterCache[chatID][key] = content
|
||||
cacheMu.Unlock()
|
||||
|
||||
ctx.Reply("Filter '" + key + "' added successfully.")
|
||||
|
||||
case "del":
|
||||
if len(args) < 2 {
|
||||
ctx.Reply("Usage: .filter del key")
|
||||
return
|
||||
}
|
||||
key := strings.ToLower(strings.Join(args[1:], " "))
|
||||
|
||||
// Delete from DB
|
||||
database.DB.Where(database.Filter{Key: key, GroupID: chatID}).Delete(&database.Filter{})
|
||||
|
||||
// Delete from cache
|
||||
cacheMu.Lock()
|
||||
if groupFilters, ok := filterCache[chatID]; ok {
|
||||
delete(groupFilters, key)
|
||||
}
|
||||
cacheMu.Unlock()
|
||||
|
||||
ctx.Reply("Filter '" + key + "' deleted successfully.")
|
||||
|
||||
default:
|
||||
ctx.Reply("Unknown action. Use add or del.")
|
||||
}
|
||||
}
|
||||
|
||||
func FilterMiddleware(ctx *hc.Ctx) bool {
|
||||
if !ctx.IsGroup() {
|
||||
return false
|
||||
}
|
||||
|
||||
// Get message text safely handling different message types similarly to core.go
|
||||
text := hc.ParseMessageText(ctx.Event())
|
||||
|
||||
if text == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
// Don't intercept normal commands
|
||||
prefixes := []string{"!", "/", "."}
|
||||
for _, p := range prefixes {
|
||||
if strings.HasPrefix(text, p) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
lowerText := strings.ToLower(strings.TrimSpace(text))
|
||||
chatID := ctx.ChatJID().String()
|
||||
|
||||
cacheMu.RLock()
|
||||
groupFilters, exists := filterCache[chatID]
|
||||
if !exists {
|
||||
cacheMu.RUnlock()
|
||||
return false
|
||||
}
|
||||
|
||||
content, hasFilter := groupFilters[lowerText]
|
||||
cacheMu.RUnlock()
|
||||
|
||||
if hasFilter {
|
||||
ctx.Reply(content)
|
||||
return true // Stop processing, we handled it
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package cmds
|
||||
import (
|
||||
_ "neo/cmds/download"
|
||||
_ "neo/cmds/general"
|
||||
_ "neo/cmds/group"
|
||||
_ "neo/cmds/media"
|
||||
_ "neo/cmds/misc"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user