Skip to content

Commit

Permalink
Merge branch 'release/3.4.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
j4rv committed Apr 9, 2024
2 parents 1324c77 + d444c02 commit 6ab0197
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 15 deletions.
42 changes: 31 additions & 11 deletions cmd/jarvbot/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func onMessageCreated(ctx context.Context) func(ds *discordgo.Session, mc *disco
// the command key must be lowercased
var commands = map[string]command{
// public
"!version": simpleTextResponse("v3.3.3"),
"!version": simpleTextResponse("v3.4.0"),
"!source": simpleTextResponse("Source code: https://github.com/j4rv/discord-bot"),
"!genshindailycheckin": answerGenshinDailyCheckIn,
"!genshindailycheckinstop": answerGenshinDailyCheckInStop,
Expand All @@ -67,15 +67,16 @@ var commands = map[string]command{
"!sniper_shoot": notSpammable(answerSniperShoot),
"!pp": notSpammable(answerPP),
// only available for discord mods
"!roleids": modOnly(answerRoleIDs),
"!react4roles": modOnly(answerMakeReact4RolesMsg),
"!addcommand": modOnly(answerAddCommand),
"!removecommand": modOnly(answerRemoveCommand),
"!roleids": guildOnly((answerRoleIDs)),
"!react4roles": guildOnly((answerMakeReact4RolesMsg)),
"!addcommand": guildOnly((answerAddCommand)),
"!removecommand": guildOnly((answerRemoveCommand)),
"!listcommands": modOnly(answerListCommands),
"!allowspamming": modOnly(answerAllowSpamming),
"!preventspamming": modOnly(answerPreventSpamming),
"!setcustomtimeoutrole": modOnly(answerSetCustomTimeoutRole),
"!announcehere": modOnly(answerAnnounceHere),
"!allowspamming": guildOnly(modOnly(answerAllowSpamming)),
"!preventspamming": guildOnly(modOnly(answerPreventSpamming)),
"!setcustomtimeoutrole": guildOnly(modOnly(answerSetCustomTimeoutRole)),
"!announcehere": guildOnly(modOnly(answerAnnounceHere)),
"!messagelogs": guildOnly(modOnly(answerMessageLogs)),
// only available for the bot owner
"!addglobalcommand": adminOnly(answerAddGlobalCommand),
"!removeglobalcommand": adminOnly(answerRemoveGlobalCommand),
Expand Down Expand Up @@ -220,13 +221,22 @@ func answerAnnounceHere(ds *discordgo.Session, mc *discordgo.MessageCreate, ctx
return err == nil
}

func answerMessageLogs(ds *discordgo.Session, mc *discordgo.MessageCreate, ctx context.Context) bool {
err := serverDS.setServerProperty(mc.GuildID, serverPropMessageLogs, mc.ChannelID)
notifyIfErr("answerMessageLogs", err, ds)
if err == nil {
ds.ChannelMessageSend(mc.ChannelID, "Okay! Will send message logs in this channel")
}
return err == nil
}

// ---------- Simple command stuff ----------

func answerAddCommand(ds *discordgo.Session, mc *discordgo.MessageCreate, ctx context.Context) bool {
commandBody := commandPrefixRegex.ReplaceAllString(mc.Content, "")
key := strings.TrimSpace(commandPrefixRegex.FindString(commandBody))
if key == "" {
ds.ChannelMessageSend(mc.ChannelID, errorMessage("Could not get the key from the command body"))
ds.ChannelMessageSend(mc.ChannelID, diff("Could not get the key from the command body", "- "))
return false
}
response := commandPrefixRegex.ReplaceAllString(commandBody, "")
Expand All @@ -242,7 +252,7 @@ func answerAddGlobalCommand(ds *discordgo.Session, mc *discordgo.MessageCreate,
commandBody := commandPrefixRegex.ReplaceAllString(mc.Content, "")
key := strings.TrimSpace(commandPrefixRegex.FindString(commandBody))
if key == "" {
ds.ChannelMessageSend(mc.ChannelID, errorMessage("Could not get the key from the command body"))
ds.ChannelMessageSend(mc.ChannelID, diff("Could not get the key from the command body", "- "))
return false
}
response := commandPrefixRegex.ReplaceAllString(commandBody, "")
Expand Down Expand Up @@ -365,6 +375,16 @@ func modOnly(wrapped command) command {
}
}

func guildOnly(wrapped command) command {
return func(ds *discordgo.Session, mc *discordgo.MessageCreate, ctx context.Context) bool {
if mc.GuildID == globalGuildID {
ds.ChannelMessageSend(mc.ChannelID, notAGuildMessage)
return false
}
return wrapped(ds, mc, ctx)
}
}

func notSpammable(wrapped command) command {
return func(ds *discordgo.Session, mc *discordgo.MessageCreate, ctx context.Context) bool {
if !isAdmin(mc.Author.ID) {
Expand Down
7 changes: 7 additions & 0 deletions cmd/jarvbot/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,15 @@ var warnMessageMinLength = 1
var warnMessageMaxLength = 320

const avatarTargetSize = "1024"
const maxMessageCount = 25

// https://discord.com/branding
const colorYellow = 0xFEE75C
const colorRed = 0xED4245

const serverPropCustomTimeoutRoleName = "custom_timeout_role_name"
const serverPropAnnounceHere = "announce_here"
const serverPropMessageLogs = "message_logs"

const defaultTimeoutRoleName = "Shadow Realm"
const shootMisfireChance = 0.2
Expand All @@ -38,6 +44,7 @@ const react4RolesCRON = "0 0 * * 6"
// Messages
const userMustBeAdminMessage = "Only the bot's admin can do that"
const userMustBeModMessage = "Only a mod can do that"
const notAGuildMessage = "This command can only be used on a server"
const commandReceivedMessage = "Gotcha!"
const commandSuccessMessage = "Successfully donette!"
const commandWithTwoArgumentsError = "Something went wrong, please make sure to use the command with the following format: '!command (...) (...)'"
Expand Down
16 changes: 12 additions & 4 deletions cmd/jarvbot/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"log"
"os"
"os/signal"
"strings"
"syscall"

"github.com/bwmarrin/discordgo"
Expand Down Expand Up @@ -75,6 +76,8 @@ func initDiscordSession() *discordgo.Session {
backgroundCtx := context.Background()

ds.AddHandler(onMessageCreated(backgroundCtx))
ds.AddHandler(onMessageUpdated(backgroundCtx))
ds.AddHandler(onMessageDeleted(backgroundCtx))
ds.AddHandler(onMessageReacted(backgroundCtx))
ds.AddHandler(onMessageUnreacted(backgroundCtx))

Expand All @@ -83,6 +86,7 @@ func initDiscordSession() *discordgo.Session {
ds.Identify.Intents |= discordgo.IntentGuildMessages
ds.Identify.Intents |= discordgo.IntentGuildMessageReactions
ds.Identify.Intents |= discordgo.IntentDirectMessages
ds.State.MaxMessageCount = maxMessageCount

// Open a websocket connection to Discord and begin listening.
err = ds.Open()
Expand Down Expand Up @@ -161,15 +165,19 @@ func initSlashCommands(ds *discordgo.Session) func() {
}
}

// for single line strings only!
func errorMessage(body string) string {
return "```diff\n- " + body + "\n```"
func diff(body, prefix string) string {
lines := strings.Split(body, "\n")
var formattedBody string
for _, line := range lines {
formattedBody += prefix + line + "\n"
}
return "```diff\n" + formattedBody + "```"
}

func notifyIfErr(context string, err error, ds *discordgo.Session) {
if err != nil {
msg := "ERROR [" + context + "]: " + err.Error()
log.Println(msg)
sendDirectMessage(adminID, errorMessage(msg), ds)
sendDirectMessage(adminID, diff(msg, "- "), ds)
}
}
78 changes: 78 additions & 0 deletions cmd/jarvbot/modding.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,57 @@ import (
"github.com/bwmarrin/discordgo"
)

func onMessageDeleted(ctx context.Context) func(ds *discordgo.Session, mc *discordgo.MessageDelete) {
return func(ds *discordgo.Session, mc *discordgo.MessageDelete) {
if mc.BeforeDelete != nil && mc.BeforeDelete.Author != nil {
// dont mind if the bot messages get deleted
if mc.BeforeDelete.Author.ID == ds.State.User.ID {
return
}

logsChannelID, err := serverDS.getServerProperty(mc.GuildID, serverPropMessageLogs)
if err != nil {
return
}
ds.ChannelMessageSendEmbed(
logsChannelID,
&discordgo.MessageEmbed{
Author: &discordgo.MessageEmbedAuthor{
Name: mc.BeforeDelete.Author.Username,
IconURL: mc.BeforeDelete.Author.AvatarURL(""),
},
Color: colorRed,
Title: "Message deleted",
Description: messageToString(mc.BeforeDelete),
},
)
}
}
}

func onMessageUpdated(ctx context.Context) func(ds *discordgo.Session, mc *discordgo.MessageUpdate) {
return func(ds *discordgo.Session, mc *discordgo.MessageUpdate) {
if mc.BeforeUpdate != nil && mc.Author != nil {
logsChannelID, err := serverDS.getServerProperty(mc.GuildID, serverPropMessageLogs)
if err != nil {
return
}
ds.ChannelMessageSendEmbed(
logsChannelID,
&discordgo.MessageEmbed{
Author: &discordgo.MessageEmbedAuthor{
Name: mc.Author.Username,
IconURL: mc.Author.AvatarURL(""),
},
Color: colorYellow,
Title: "Message edited",
Description: messageUpdatedToString(mc.BeforeUpdate, mc.Message),
},
)
}
}
}

type UserWarning struct {
ID int `db:"UserWarning"`
UserID string `db:"DiscordUserID"`
Expand Down Expand Up @@ -89,3 +140,30 @@ func answerWarnings(ds *discordgo.Session, ic *discordgo.InteractionCreate) {
fileRespond(ds, ic, "Damn that user has been warned a lot", fmt.Sprintf("%s_warnings.txt", user.Username), responseMsg)
}
}

func messageToString(m *discordgo.Message) string {
str := "In channel: <#" + m.ChannelID + ">"
if m.Author != nil {
str += "\nAuthor: " + m.Author.Mention()
}
if m.Content != "" {
str += "```" + m.Content + "```"
}
if m.Attachments != nil && len(m.Attachments) > 0 {
str += "\nAttachments:"
for _, a := range m.Attachments {
str += "\n" + a.URL
}
}
return str
}

func messageUpdatedToString(from, to *discordgo.Message) string {
str := "In channel: <#" + from.ChannelID + ">"
if from.Author != nil {
str += "\nAuthor: " + from.Author.Mention()
}
str += diff(from.Content, "- ")
str += diff(to.Content, "+ ")
return str
}

0 comments on commit 6ab0197

Please sign in to comment.