172 lines
3.7 KiB
Go
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
|
|
}
|