Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ tmp
**/.env*

**/*_templ.go

.claude
6 changes: 3 additions & 3 deletions atlas.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ env "local" {
src = var.sources

migration {
dir = "file://internal/database/migrations"
dir = "file://internal/database/migrations?format=golang-migrate"
}

url = var.database_url
Expand All @@ -39,9 +39,9 @@ env "migrate" {
]

migration {
dir = "file:///migrations"
dir = "file:///migrations?format=golang-migrate"
}
tx-mode = "all"

url = var.database_url
}
}
74 changes: 74 additions & 0 deletions cmd/discord/commands/public/automod.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package public

import (
"context"
"fmt"
"time"

"github.com/bwmarrin/discordgo"
"github.com/cufee/aftermath/cmd/discord/common"
"github.com/cufee/aftermath/cmd/discord/rest"
"github.com/cufee/aftermath/internal/constants"
"github.com/cufee/aftermath/internal/database"
"github.com/cufee/aftermath/internal/log"
)

var AutomodDeleteMessageTimeout = time.Second * 30

func AutomodHandler(helpImage []byte) common.EventHandler[discordgo.MessageCreate] {
return common.EventHandler[discordgo.MessageCreate]{
Match: func(db database.Client, s *discordgo.Session, event *discordgo.MessageCreate) bool {
// only apply to the primary guild
if event.GuildID != constants.DiscordPrimaryGuildID {
return false
}
// ignore bot messages
if event.Author == nil || event.Author.Bot {
return false
}
// check if the user is verified
ctx, cancel := context.WithTimeout(context.Background(), time.Second*2)
defer cancel()

user, err := db.GetUserByID(ctx, event.Author.ID)
if err != nil {
// user doesn't exist in our database, they are not verified
return true
}
return !user.AutomodVerified
},
Handle: func(ctx common.Context, event *discordgo.MessageCreate) error {
// delete the user's message
err := ctx.Rest().DeleteMessage(ctx.Ctx(), event.ChannelID, event.ID)
if err != nil {
log.Err(err).Str("channelID", event.ChannelID).Str("messageID", event.ID).Msg("automod: failed to delete message from unverified user")
// continue to send explainer even if deletion fails
}

// send an explainer message with the help image
content := fmt.Sprintf(ctx.Localize("automod_unverified_user_message_deleted_fmt"), event.Author.ID)
msg, err := ctx.Rest().CreateMessage(ctx.Ctx(), event.ChannelID, discordgo.MessageSend{
Content: content,
}, []rest.File{{Data: helpImage, Name: "how_to_use_aftermath.png"}})
if err != nil {
log.Err(err).Str("channelID", event.ChannelID).Str("userID", event.Author.ID).Msg("automod: failed to send explainer message")
return nil
}

// delete the explainer after a timeout
go func() {
time.Sleep(AutomodDeleteMessageTimeout)

delCtx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()

err := ctx.Rest().DeleteMessage(delCtx, event.ChannelID, msg.ID)
if err != nil {
log.Err(err).Str("channelID", event.ChannelID).Str("messageID", msg.ID).Msg("automod: failed to delete explainer message")
}
}()

return nil
},
}
}
11 changes: 11 additions & 0 deletions cmd/discord/middleware/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"time"

"github.com/cufee/aftermath/cmd/discord/common"
"github.com/cufee/aftermath/internal/log"
"github.com/cufee/aftermath/internal/permissions"
)

Expand All @@ -30,3 +31,13 @@ func ExpireAfter(expiration time.Time) MiddlewareFunc {
return next
}
}

func MarkUsersVerified() MiddlewareFunc {
return func(ctx common.Context, next func(common.Context) error) func(common.Context) error {
if !ctx.User().AutomodVerified {
err := ctx.Core().Database().UpdateUserAutomodVerified(ctx.Ctx(), ctx.User().ID, true)
log.Err(err).Stack().Str("userID", ctx.User().ID).Msg("failed to mark user as automod verified")
}
return next
}
}
Empty file modified database-restore.sh
100644 → 100755
Empty file.
6 changes: 3 additions & 3 deletions docker-compose.base.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ services:
build:
context: .
dockerfile: Dockerfile.migrate
command: migrate apply --dir "file:///migrations" --tx-mode all --url "${DATABASE_URL}"
command: migrate apply --dir "file:///migrations?format=golang-migrate" --tx-mode all --url "${DATABASE_URL}"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
deploy:
Expand All @@ -40,7 +40,7 @@ services:
memory: 2048m
limits:
memory: 2048m

aftermath-backup-base:
image: ghcr.io/cufee/aftermath-backup:${ENVIRONMENT}
build:
Expand All @@ -52,7 +52,7 @@ services:
memory: 2048m
limits:
memory: 2048m

aftermath-service-base:
pull_policy: always
image: ghcr.io/cufee/aftermath:${ENVIRONMENT}
Expand Down
1 change: 1 addition & 0 deletions internal/constants/discord.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ var (
DiscordBotUserID = MustGetEnv("BOT_USER_ID")
DiscordBotInviteURL = MustGetEnv("BOT_INVITE_LINK")
DiscordPrimaryGuildInviteURL = MustGetEnv("PRIMARY_GUILD_INVITE_LINK")
DiscordPrimaryGuildID = MustGetEnv("DISCORD_PRIMARY_GUILD_ID")
)

var (
Expand Down
2 changes: 2 additions & 0 deletions internal/database/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ type UsersClient interface {

CreateUserSubscription(ctx context.Context, subscription models.UserSubscription) (models.UserSubscription, error)
UpdateUserSubscription(ctx context.Context, id string, subscription models.UserSubscription) (models.UserSubscription, error)

UpdateUserAutomodVerified(ctx context.Context, id string, verified bool) error
}

type SnapshotsClient interface {
Expand Down
26 changes: 0 additions & 26 deletions internal/database/gen/public/model/account_snapshots.go

This file was deleted.

24 changes: 0 additions & 24 deletions internal/database/gen/public/model/accounts.go

This file was deleted.

21 changes: 0 additions & 21 deletions internal/database/gen/public/model/app_configurations.go

This file was deleted.

21 changes: 0 additions & 21 deletions internal/database/gen/public/model/application_commands.go

This file was deleted.

27 changes: 0 additions & 27 deletions internal/database/gen/public/model/atlas_schema_revisions.go

This file was deleted.

23 changes: 0 additions & 23 deletions internal/database/gen/public/model/auth_nonces.go

This file was deleted.

22 changes: 0 additions & 22 deletions internal/database/gen/public/model/clans.go

This file was deleted.

27 changes: 0 additions & 27 deletions internal/database/gen/public/model/cron_tasks.go

This file was deleted.

24 changes: 0 additions & 24 deletions internal/database/gen/public/model/discord_interactions.go

This file was deleted.

Loading
Loading