Skip to content
This repository has been archived by the owner on Jul 9, 2021. It is now read-only.

spam protection #170

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 39 additions & 32 deletions command/mute.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,47 @@ import (
"trup/db"

"github.com/bwmarrin/discordgo"
"github.com/dustin/go-humanize"
)

const muteUsage = "mute <@user> <duration> [reason]"

func MuteMember(env *Env, session *discordgo.Session, moderator *discordgo.User, userId string, duration time.Duration, reason string) error {
w := db.NewMute(env.Guild, moderator.ID, userId, reason, time.Now(), time.Now().Add(duration))
err := w.Save()
if err != nil {
return fmt.Errorf("Failed to save your mute. Error: %w", err)
}

err = session.GuildMemberRoleAdd(env.Guild, userId, env.RoleMute)
if err != nil {
return fmt.Errorf("Error adding role %w", err)
}

reasonText := ""
if reason != "" {
reasonText = " with reason: " + reason
}
durationText := humanize.RelTime(time.Now(), time.Now().Add(duration), "", "")
err = db.NewNote(moderator.ID, userId, "User was muted for "+durationText+reasonText, db.ManualNote).Save()
if err != nil {
return fmt.Errorf("Failed to set note about the user %w", err)
}

r := ""
if reason != "" {
r = " with reason: " + reason
}
if _, err = session.ChannelMessageSend(
env.ChannelModlog,
fmt.Sprintf("User <@%s> was muted by %s for %s%s.", userId, moderator.Username, durationText, r),
); err != nil {
log.Println("Failed to send mute message: " + err.Error())
}

return nil
}

func mute(ctx *Context, args []string) {
if len(args) < 3 {
ctx.Reply("Usage: " + muteUsage)
Expand All @@ -22,7 +59,6 @@ func mute(ctx *Context, args []string) {
user := m.User.ID
var (
duration = args[2]
start = time.Now()
reason = ""
)
if len(args) > 3 {
Expand All @@ -35,41 +71,12 @@ func mute(ctx *Context, args []string) {
return nil
}

end := start.Add(i)
w := db.NewMute(ctx.Message.GuildID, ctx.Message.Author.ID, user, reason, start, end)
err = w.Save()
if err != nil {
ctx.ReportError("Failed to save your mute", err)
if err := MuteMember(ctx.Env, ctx.Session, ctx.Message.Author, user, i, reason); err != nil {
ctx.Reply("Failed to mute user. Error: " + err.Error())
return nil
}

err = ctx.Session.GuildMemberRoleAdd(ctx.Message.GuildID, user, ctx.Env.RoleMute)
if err != nil {
ctx.ReportError("Error adding role", err)
return nil
}

reasonText := ""
if reason != "" {
reasonText = " with reason: " + reason
}
err = db.NewNote(ctx.Message.Author.ID, user, "User was muted for "+duration+reasonText, db.ManualNote).Save()
if err != nil {
ctx.ReportError("Failed to set note about the user", err)
}
ctx.Reply("User successfully muted. <a:police:749871644071165974>")

r := ""
if reason != "" {
r = " with reason: " + reason
}

if _, err = ctx.Session.ChannelMessageSend(
ctx.Env.ChannelModlog,
fmt.Sprintf("User <@%s> was muted by %s for %s%s.", user, ctx.Message.Author.Username, duration, r),
); err != nil {
log.Println("Failed to send mute message: " + err.Error())
}
return nil
})
if err != nil {
Expand Down
50 changes: 50 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
return
}

if wasDeleted := spamProtection(s, m.Message); wasDeleted {
return
}

cache.add(m.ID, *m.Message)

if wasDeleted := runMessageFilter(s, m.Message); wasDeleted {
Expand Down Expand Up @@ -501,3 +505,49 @@ func initializeRoles(s *discordgo.Session, r *discordgo.Ready) {
}
}
}

func spamProtection(s *discordgo.Session, m *discordgo.Message) (deleted bool) {
accountAge, err := discordgo.SnowflakeTimestamp(m.Author.ID)
if err != nil {
return
}
if time.Since(accountAge) > time.Hour*24 {
return
}

messageHasMention := len(m.Mentions) > 0
if !messageHasMention {
return
}

var sameMessages []discordgo.Message
for _, msg := range cache.m {
if msg.Author.ID != m.Author.ID || msg.ChannelID != m.ChannelID || msg.Content != m.Content {
continue
}

timestamp, err := msg.Timestamp.Parse()
if err != nil {
continue
}

if time.Since(timestamp) > time.Minute {
continue
}

sameMessages = append(sameMessages, msg)
}

if len(sameMessages) > 2 {
_, err := s.ChannelMessageSend(env.ChannelAutoMod, "Detected spam. Message: "+m.ID)
log.Println("spamProtection err:", err)
// err := command.MuteMember(&env, s, s.State.User, m.Author.ID, time.Minute*24, "Spam")
// if err != nil {
// log.Printf("Failed to mute spammer(ID: %s). Error: %v\n", m.Author.ID, err)
// return false
// }
// return true
}

return false
}