Files

172 lines
3.7 KiB
Go

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
}