From 5976e1ad9ea56cea205ee0c9aa6dc0d694ec4e3a Mon Sep 17 00:00:00 2001 From: jonas747 Date: Mon, 23 Mar 2020 20:17:13 +0100 Subject: [PATCH] add proper analytics --- automod/automod_bot.go | 3 + automod_legacy/bot.go | 10 +- autorole/bot.go | 8 +- aylien/aylien.go | 2 +- cmd/yagpdb/main.go | 2 + commands/plugin_bot.go | 7 +- commands/yagcommmand.go | 7 ++ customcommands/bot.go | 5 +- logs/plugin_bot.go | 8 +- moderation/commands.go | 3 + moderation/plugin_bot.go | 2 +- notifications/plugin_bot.go | 9 ++ premium/plugin_bot.go | 2 +- reddit/bot.go | 2 +- reddit/redditbot.go | 4 + reminders/plugin_bot.go | 9 +- reputation/plugin_bot.go | 5 +- rolecommands/bot.go | 6 +- rolecommands/menu.go | 12 ++- rolecommands/rolecommands.go | 7 +- rsvp/plugin_bot.go | 16 +++- serverstats/plugin_bot.go | 2 +- soundboard/bot.go | 158 ++++++++++++++++--------------- stdcommands/stdcommands.go | 2 +- streaming/bot.go | 7 ++ tickets/tickets_commands.go | 5 + timezonecompanion/plugin_bot.go | 13 +-- twitter/feed.go | 3 + verification/verification_bot.go | 3 + verification/verification_web.go | 17 ++-- youtube/feed.go | 3 + 31 files changed, 220 insertions(+), 122 deletions(-) diff --git a/automod/automod_bot.go b/automod/automod_bot.go index 7f285d0447..b6612ad0b7 100644 --- a/automod/automod_bot.go +++ b/automod/automod_bot.go @@ -8,6 +8,7 @@ import ( "github.com/jonas747/discordgo" "github.com/jonas747/dstate" + "github.com/jonas747/yagpdb/analytics" "github.com/jonas747/yagpdb/automod/models" "github.com/jonas747/yagpdb/bot" "github.com/jonas747/yagpdb/bot/eventsystem" @@ -387,6 +388,8 @@ func (p *Plugin) RulesetRulesTriggeredCondsPassed(ruleset *ParsedRuleset, trigge loggedModels := make([]*models.AutomodTriggeredRule, len(triggeredRules)) + go analytics.RecordActiveUnit(ruleset.RSModel.GuildID, p, "rule_triggered") + // apply the effects for i, rule := range triggeredRules { ctxData.CurrentRule = rule diff --git a/automod_legacy/bot.go b/automod_legacy/bot.go index c9f6abbb48..4d8a911621 100644 --- a/automod_legacy/bot.go +++ b/automod_legacy/bot.go @@ -5,6 +5,7 @@ import ( "github.com/jonas747/discordgo" "github.com/jonas747/dstate" + "github.com/jonas747/yagpdb/analytics" "github.com/jonas747/yagpdb/bot" "github.com/jonas747/yagpdb/bot/eventsystem" "github.com/jonas747/yagpdb/commands" @@ -111,12 +112,14 @@ func CheckMessage(m *discordgo.Message) bool { rules := []Rule{config.Spam, config.Invite, config.Mention, config.Links, config.Words, config.Sites} + didCheck := false + // We gonna need to have this locked while we check for _, r := range rules { if r.ShouldIgnore(m, member) { continue } - + didCheck = true d, punishment, msg, err := r.Check(m, cs) if d { del = true @@ -140,9 +143,14 @@ func CheckMessage(m *discordgo.Message) bool { } if !del { + if didCheck { + go analytics.RecordActiveUnit(cs.Guild.ID, &Plugin{}, "checked") + } return false } + go analytics.RecordActiveUnit(cs.Guild.ID, &Plugin{}, "rule_triggered") + if punishMsg != "" { // Strip last newline punishMsg = punishMsg[:len(punishMsg)-1] diff --git a/autorole/bot.go b/autorole/bot.go index e111d386e1..8b724db724 100644 --- a/autorole/bot.go +++ b/autorole/bot.go @@ -11,6 +11,7 @@ import ( "github.com/jonas747/discordgo" "github.com/jonas747/dstate" "github.com/jonas747/retryableredis" + "github.com/jonas747/yagpdb/analytics" "github.com/jonas747/yagpdb/bot" "github.com/jonas747/yagpdb/bot/eventsystem" "github.com/jonas747/yagpdb/commands" @@ -26,7 +27,7 @@ var _ bot.BotStopperHandler = (*Plugin)(nil) var _ commands.CommandProvider = (*Plugin)(nil) func (p *Plugin) AddCommands() { - commands.AddRootCommands(roleCommands...) + commands.AddRootCommands(p, roleCommands...) } type assignRoleEventdata struct { @@ -330,6 +331,7 @@ func onMemberJoin(evt *eventsystem.EventData) (retry bool, err error) { if config.RequiredDuration < 1 && config.CanAssignTo(addEvt.Roles, time.Now()) { err = common.BotSession.GuildMemberRoleAdd(addEvt.GuildID, addEvt.User.ID, config.Role) + go analytics.RecordActiveUnit(addEvt.GuildID, &Plugin{}, "assigned_role") return bot.CheckDiscordErrRetry(err), err } @@ -527,6 +529,8 @@ func handleAssignRole(evt *scheduledEventsModels.ScheduledEvent, data interface{ return false, nil } + go analytics.RecordActiveUnit(evt.GuildID, &Plugin{}, "assigned_role") + err = common.BotSession.GuildMemberRoleAdd(evt.GuildID, dataCast.UserID, config.Role) return bot.CheckDiscordErrRetry(err), err } @@ -563,6 +567,8 @@ func handleGuildMemberUpdate(evt *eventsystem.EventData) (retry bool, err error) } } + go analytics.RecordActiveUnit(update.GuildID, &Plugin{}, "assigned_role") + // if we branched here then all the checks passed and they should be assigned the role err = common.BotSession.GuildMemberRoleAdd(update.GuildID, update.User.ID, config.Role) if err != nil { diff --git a/aylien/aylien.go b/aylien/aylien.go index 24eb3cc5fa..bdde83be71 100644 --- a/aylien/aylien.go +++ b/aylien/aylien.go @@ -58,7 +58,7 @@ func RegisterPlugin() { var _ commands.CommandProvider = (*Plugin)(nil) func (p *Plugin) AddCommands() { - commands.AddRootCommands(&commands.YAGCommand{ + commands.AddRootCommands(p, &commands.YAGCommand{ CmdCategory: commands.CategoryFun, Cooldown: 5, Name: "Sentiment", diff --git a/cmd/yagpdb/main.go b/cmd/yagpdb/main.go index def2d18943..5c4c58db57 100644 --- a/cmd/yagpdb/main.go +++ b/cmd/yagpdb/main.go @@ -1,6 +1,7 @@ package main import ( + "github.com/jonas747/yagpdb/analytics" "github.com/jonas747/yagpdb/common/run" // Core yagpdb packages @@ -50,6 +51,7 @@ func main() { paginatedmessages.RegisterPlugin() // Setup plugins + analytics.RegisterPlugin() safebrowsing.RegisterPlugin() discordlogger.Register() commands.RegisterPlugin() diff --git a/commands/plugin_bot.go b/commands/plugin_bot.go index da590c723e..fa03c23264 100644 --- a/commands/plugin_bot.go +++ b/commands/plugin_bot.go @@ -164,13 +164,16 @@ func FilterResp(in interface{}, guildID int64) interface{} { return in } -func AddRootCommands(cmds ...*YAGCommand) { +func AddRootCommands(p common.Plugin, cmds ...*YAGCommand) { for _, v := range cmds { + v.Plugin = p CommandSystem.Root.AddCommand(v, v.GetTrigger()) } } -func AddRootCommandsWithMiddlewares(middlewares []dcmd.MiddleWareFunc, cmds ...*YAGCommand) { + +func AddRootCommandsWithMiddlewares(p common.Plugin, middlewares []dcmd.MiddleWareFunc, cmds ...*YAGCommand) { for _, v := range cmds { + v.Plugin = p CommandSystem.Root.AddCommand(v, v.GetTrigger().SetMiddlewares(middlewares...)) } } diff --git a/commands/yagcommmand.go b/commands/yagcommmand.go index e62efc2317..84772c92a6 100644 --- a/commands/yagcommmand.go +++ b/commands/yagcommmand.go @@ -13,6 +13,7 @@ import ( "github.com/jonas747/discordgo" "github.com/jonas747/dstate" "github.com/jonas747/retryableredis" + "github.com/jonas747/yagpdb/analytics" "github.com/jonas747/yagpdb/bot" "github.com/jonas747/yagpdb/commands/models" "github.com/jonas747/yagpdb/common" @@ -114,6 +115,8 @@ type YAGCommand struct { // It returns a reply and an error // the reply can have a type of string, *MessageEmbed or error RunFunc dcmd.RunFunc + + Plugin common.Plugin } // CmdWithCategory puts the command in a category, mostly used for the help generation @@ -196,6 +199,10 @@ func (yc *YAGCommand) Run(data *dcmd.Data) (interface{}, error) { if err != nil { logger.WithError(err).Error("Failed setting cooldown") } + + if yc.Plugin != nil { + go analytics.RecordActiveUnit(data.Msg.GuildID, yc.Plugin, "cmd_executed_"+strings.ToLower(yc.Name)) + } } // set cmdErr to nil if this was a user error top stop it from being recorded and logged as an actual error diff --git a/customcommands/bot.go b/customcommands/bot.go index 1898c3d93b..aa37056b40 100644 --- a/customcommands/bot.go +++ b/customcommands/bot.go @@ -12,6 +12,7 @@ import ( "time" "unicode/utf8" + "github.com/jonas747/yagpdb/analytics" "github.com/jonas747/yagpdb/premium" "emperror.dev/errors" @@ -53,7 +54,7 @@ var _ bot.BotInitHandler = (*Plugin)(nil) var _ commands.CommandProvider = (*Plugin)(nil) func (p *Plugin) AddCommands() { - commands.AddRootCommands(cmdListCommands) + commands.AddRootCommands(p, cmdListCommands) } func (p *Plugin) BotInit() { @@ -590,6 +591,8 @@ func ExecuteCustomCommand(cmd *models.CustomCommand, tmplCtx *templates.Context) defer CCExecLock.Unlock(lockKey, lockHandle) + go analytics.RecordActiveUnit(cmd.GuildID, &Plugin{}, "executed_cc") + // pick a response and execute it f.Info("Custom command triggered") diff --git a/logs/plugin_bot.go b/logs/plugin_bot.go index fa0f985816..83e6c8495d 100644 --- a/logs/plugin_bot.go +++ b/logs/plugin_bot.go @@ -26,7 +26,7 @@ var _ bot.BotInitHandler = (*Plugin)(nil) var _ commands.CommandProvider = (*Plugin)(nil) func (p *Plugin) AddCommands() { - commands.AddRootCommands(cmdLogs, cmdWhois, cmdNicknames, cmdUsernames, cmdMigrate) + commands.AddRootCommands(p, cmdLogs, cmdWhois, cmdNicknames, cmdUsernames, cmdMigrate) } func (p *Plugin) BotInit() { @@ -86,7 +86,7 @@ var cmdWhois = &commands.YAGCommand{ if memberCPY != nil { member = memberCPY } - + if parsed.Args[0].Value != nil { member = parsed.Args[0].Value.(*dstate.MemberState) } @@ -116,7 +116,7 @@ var cmdWhois = &commands.YAGCommand{ if createdDurStr == "" { createdDurStr = "Less than an hour ago" } - + var memberStatus string state := [4]string{"Playing", "Streaming", "Listening", "Watching"} if !member.PresenceSet || member.PresenceGame == nil { @@ -128,7 +128,7 @@ var cmdWhois = &commands.YAGCommand{ memberStatus = fmt.Sprintf("%s: %s", state[member.PresenceGame.Type], member.PresenceGame.Name) } } - + embed := &discordgo.MessageEmbed{ Title: fmt.Sprintf("%s#%04d%s", member.Username, member.Discriminator, nick), Fields: []*discordgo.MessageEmbedField{ diff --git a/moderation/commands.go b/moderation/commands.go index 370156beb7..4182efd8b3 100644 --- a/moderation/commands.go +++ b/moderation/commands.go @@ -12,6 +12,7 @@ import ( "github.com/jonas747/dcmd" "github.com/jonas747/discordgo" "github.com/jonas747/dstate" + "github.com/jonas747/yagpdb/analytics" "github.com/jonas747/yagpdb/bot" "github.com/jonas747/yagpdb/bot/paginatedmessages" "github.com/jonas747/yagpdb/commands" @@ -89,6 +90,8 @@ func MBaseCmdSecond(cmdData *dcmd.Data, reason string, reasonArgOptional bool, n permsMet = true } + go analytics.RecordActiveUnit(cmdData.GS.ID, &Plugin{}, "executed_cmd_"+cmdName) + return oreason, nil } diff --git a/moderation/plugin_bot.go b/moderation/plugin_bot.go index b8e1cbb548..c4f99f4815 100644 --- a/moderation/plugin_bot.go +++ b/moderation/plugin_bot.go @@ -37,7 +37,7 @@ var _ bot.BotInitHandler = (*Plugin)(nil) var _ bot.ShardMigrationReceiver = (*Plugin)(nil) func (p *Plugin) AddCommands() { - commands.AddRootCommands(ModerationCommands...) + commands.AddRootCommands(p, ModerationCommands...) } func (p *Plugin) BotInit() { diff --git a/notifications/plugin_bot.go b/notifications/plugin_bot.go index fac63c8c59..def64a0d1d 100644 --- a/notifications/plugin_bot.go +++ b/notifications/plugin_bot.go @@ -8,6 +8,7 @@ import ( "emperror.dev/errors" "github.com/jonas747/discordgo" "github.com/jonas747/dstate" + "github.com/jonas747/yagpdb/analytics" "github.com/jonas747/yagpdb/bot" "github.com/jonas747/yagpdb/bot/eventsystem" "github.com/jonas747/yagpdb/common" @@ -60,6 +61,8 @@ func HandleGuildMemberAdd(evtData *eventsystem.EventData) (retry bool, err error Type: discordgo.ChannelTypeDM, } + go analytics.RecordActiveUnit(gs.ID, &Plugin{}, "posted_join_server_msg") + if sendTemplate(thinCState, config.JoinDMMsg, ms, "join dm", false) { return true, nil } @@ -72,6 +75,8 @@ func HandleGuildMemberAdd(evtData *eventsystem.EventData) (retry bool, err error return } + go analytics.RecordActiveUnit(gs.ID, &Plugin{}, "posted_join_server_dm") + chanMsg := config.JoinServerMsgs[rand.Intn(len(config.JoinServerMsgs))] if sendTemplate(channel, chanMsg, ms, "join server msg", config.CensorInvites) { return true, nil @@ -107,6 +112,8 @@ func HandleGuildMemberRemove(evt *eventsystem.EventData) (retry bool, err error) chanMsg := config.LeaveMsgs[rand.Intn(len(config.LeaveMsgs))] + go analytics.RecordActiveUnit(gs.ID, &Plugin{}, "posted_leave_server_msg") + if sendTemplate(channel, chanMsg, ms, "leave", config.CensorInvites) { return true, nil } @@ -196,6 +203,8 @@ func HandleChannelUpdate(evt *eventsystem.EventData) (retry bool, err error) { } } + go analytics.RecordActiveUnit(cu.GuildID, &Plugin{}, "posted_topic_change") + go func() { _, err := common.BotSession.ChannelMessageSend(topicChannel, fmt.Sprintf("Topic in channel <#%d> changed to **%s**", cu.ID, cu.Topic)) if err != nil { diff --git a/premium/plugin_bot.go b/premium/plugin_bot.go index 1e6f089f74..6ba05cda66 100644 --- a/premium/plugin_bot.go +++ b/premium/plugin_bot.go @@ -16,7 +16,7 @@ func (p *Plugin) BotInit() { } func (p *Plugin) AddCommands() { - commands.AddRootCommands(cmdGenerateCode) + commands.AddRootCommands(p, cmdGenerateCode) } const ( diff --git a/reddit/bot.go b/reddit/bot.go index e17bca718d..e5f0639d41 100644 --- a/reddit/bot.go +++ b/reddit/bot.go @@ -27,7 +27,7 @@ func (p *Plugin) RemoveGuild(g int64) error { } func (p *Plugin) AddCommands() { - commands.AddRootCommands(&commands.YAGCommand{ + commands.AddRootCommands(p, &commands.YAGCommand{ CmdCategory: commands.CategoryDebug, HideFromCommandsPage: true, Name: "testreddit", diff --git a/reddit/redditbot.go b/reddit/redditbot.go index 2abc4ad830..9d6cbb5ae1 100644 --- a/reddit/redditbot.go +++ b/reddit/redditbot.go @@ -12,6 +12,7 @@ import ( "github.com/jonas747/discordgo" "github.com/jonas747/go-reddit" + "github.com/jonas747/yagpdb/analytics" "github.com/jonas747/yagpdb/common" "github.com/jonas747/yagpdb/common/config" "github.com/jonas747/yagpdb/common/mqueue" @@ -186,7 +187,10 @@ func (p *PostHandlerImpl) handlePost(post *reddit.Link, filterGuild int64) error if common.Statsd != nil { go common.Statsd.Count("yagpdb.reddit.matches", 1, []string{"subreddit:" + post.Subreddit, "guild:" + strconv.FormatInt(item.GuildID, 10)}, 1) } + + go analytics.RecordActiveUnit(item.GuildID, &Plugin{}, "posted_reddit_message") } + return nil } diff --git a/reminders/plugin_bot.go b/reminders/plugin_bot.go index 24c45e57a4..ed0d11e35d 100644 --- a/reminders/plugin_bot.go +++ b/reminders/plugin_bot.go @@ -2,6 +2,10 @@ package reminders import ( "fmt" + "strconv" + "strings" + "time" + "github.com/jinzhu/gorm" "github.com/jonas747/dcmd" "github.com/jonas747/discordgo" @@ -10,9 +14,6 @@ import ( "github.com/jonas747/yagpdb/common" "github.com/jonas747/yagpdb/common/scheduledevents2" seventsmodels "github.com/jonas747/yagpdb/common/scheduledevents2/models" - "strconv" - "strings" - "time" ) var logger = common.GetPluginLogger(&Plugin{}) @@ -21,7 +22,7 @@ var _ bot.BotInitHandler = (*Plugin)(nil) var _ commands.CommandProvider = (*Plugin)(nil) func (p *Plugin) AddCommands() { - commands.AddRootCommands(cmds...) + commands.AddRootCommands(p, cmds...) } func (p *Plugin) BotInit() { diff --git a/reputation/plugin_bot.go b/reputation/plugin_bot.go index d3a91c84d3..2ca21294e4 100644 --- a/reputation/plugin_bot.go +++ b/reputation/plugin_bot.go @@ -6,6 +6,7 @@ import ( "strconv" "strings" + "github.com/jonas747/yagpdb/analytics" "github.com/jonas747/yagpdb/bot/paginatedmessages" "github.com/jonas747/dcmd" @@ -23,7 +24,7 @@ var _ bot.BotInitHandler = (*Plugin)(nil) var _ commands.CommandProvider = (*Plugin)(nil) func (p *Plugin) AddCommands() { - commands.AddRootCommands(cmds...) + commands.AddRootCommands(p, cmds...) } func (p *Plugin) BotInit() { @@ -78,6 +79,8 @@ func handleMessageCreate(evt *eventsystem.EventData) { return } + go analytics.RecordActiveUnit(msg.GuildID, &Plugin{}, "auto_add_rep") + content := fmt.Sprintf("Gave +1 %s to **%s**", conf.PointsName, who.Mention()) common.BotSession.ChannelMessageSend(msg.ChannelID, content) } diff --git a/rolecommands/bot.go b/rolecommands/bot.go index c7f3ee99e6..63d94a4971 100644 --- a/rolecommands/bot.go +++ b/rolecommands/bot.go @@ -3,9 +3,11 @@ package rolecommands import ( "context" "database/sql" + "github.com/jonas747/dcmd" "github.com/jonas747/discordgo" "github.com/jonas747/dstate" + "github.com/jonas747/yagpdb/analytics" "github.com/jonas747/yagpdb/bot/eventsystem" "github.com/jonas747/yagpdb/commands" "github.com/jonas747/yagpdb/common" @@ -26,7 +28,7 @@ func (p *Plugin) AddCommands() { EmbedColor: 0x42b9f4, } - commands.AddRootCommands( + commands.AddRootCommands(p, &commands.YAGCommand{ CmdCategory: commands.CategoryTool, Name: "Role", @@ -177,6 +179,8 @@ func CmdFuncRole(parsed *dcmd.Data) (interface{}, error) { return HumanizeAssignError(parsed.GS, err) } + go analytics.RecordActiveUnit(parsed.GS.ID, &Plugin{}, "cmd_used") + if given { return "Gave you the role!", nil } diff --git a/rolecommands/menu.go b/rolecommands/menu.go index e0556a1e2a..3378987266 100644 --- a/rolecommands/menu.go +++ b/rolecommands/menu.go @@ -3,11 +3,16 @@ package rolecommands import ( "context" "database/sql" - "emperror.dev/errors" "fmt" + "sort" + "sync" + "time" + + "emperror.dev/errors" "github.com/jonas747/dcmd" "github.com/jonas747/discordgo" "github.com/jonas747/dstate" + "github.com/jonas747/yagpdb/analytics" "github.com/jonas747/yagpdb/bot" "github.com/jonas747/yagpdb/bot/eventsystem" "github.com/jonas747/yagpdb/common" @@ -17,9 +22,6 @@ import ( "github.com/volatiletech/null" "github.com/volatiletech/sqlboiler/boil" "github.com/volatiletech/sqlboiler/queries/qm" - "sort" - "sync" - "time" ) func cmdFuncRoleMenuCreate(parsed *dcmd.Data) (interface{}, error) { @@ -442,6 +444,8 @@ func MemberChooseOption(ctx context.Context, rm *models.RoleMenu, gs *dstate.Gui } } + go analytics.RecordActiveUnit(gs.ID, &Plugin{}, "user_interacted_menu") + if rm.DisableSendDM { resp = "" } diff --git a/rolecommands/rolecommands.go b/rolecommands/rolecommands.go index 01ebbaddb7..9f28bef6de 100644 --- a/rolecommands/rolecommands.go +++ b/rolecommands/rolecommands.go @@ -6,6 +6,10 @@ package rolecommands import ( "context" "fmt" + "sort" + "strconv" + "time" + "github.com/jonas747/discordgo" "github.com/jonas747/dstate" "github.com/jonas747/yagpdb/bot" @@ -17,9 +21,6 @@ import ( "github.com/jonas747/yagpdb/web" "github.com/tidwall/buntdb" "github.com/volatiletech/sqlboiler/queries/qm" - "sort" - "strconv" - "time" ) type Plugin struct{} diff --git a/rsvp/plugin_bot.go b/rsvp/plugin_bot.go index af0145caf0..e3ed55cc34 100644 --- a/rsvp/plugin_bot.go +++ b/rsvp/plugin_bot.go @@ -4,6 +4,12 @@ import ( "context" "database/sql" "fmt" + "strconv" + "strings" + "sync" + "time" + "unicode/utf8" + "github.com/jonas747/dcmd" "github.com/jonas747/discordgo" "github.com/jonas747/dstate" @@ -17,11 +23,6 @@ import ( "github.com/jonas747/yagpdb/timezonecompanion" "github.com/volatiletech/sqlboiler/boil" "github.com/volatiletech/sqlboiler/queries/qm" - "strconv" - "strings" - "sync" - "time" - "unicode/utf8" ) var _ bot.BotInitHandler = (*Plugin)(nil) @@ -49,6 +50,7 @@ func (p *Plugin) AddCommands() { Name: "Create", Aliases: []string{"new", "make"}, Description: "Creates an event, You will be led through an interactive setup", + Plugin: p, RunFunc: func(parsed *dcmd.Data) (interface{}, error) { count, err := models.RSVPSessions(models.RSVPSessionWhere.GuildID.EQ(parsed.GS.ID)).CountG(parsed.Context()) @@ -96,6 +98,7 @@ func (p *Plugin) AddCommands() { CmdCategory: catEvents, Name: "Edit", Description: "Edits an event", + Plugin: p, RequireDiscordPerms: []int64{discordgo.PermissionManageServer, discordgo.PermissionManageMessages}, Arguments: []*dcmd.ArgDef{ &dcmd.ArgDef{Name: "ID", Type: dcmd.Int}, @@ -174,6 +177,7 @@ func (p *Plugin) AddCommands() { Aliases: []string{"ls"}, Description: "Lists all events in this server", RequireDiscordPerms: []int64{discordgo.PermissionManageServer, discordgo.PermissionManageMessages}, + Plugin: p, RunFunc: func(parsed *dcmd.Data) (interface{}, error) { events, err := models.RSVPSessions(models.RSVPSessionWhere.GuildID.EQ(parsed.GS.ID), qm.OrderBy("starts_at asc")).AllG(parsed.Context()) if err != nil { @@ -204,6 +208,7 @@ func (p *Plugin) AddCommands() { Description: "Deletes an event, specify the event ID of the event you wanna delete", RequireDiscordPerms: []int64{discordgo.PermissionManageServer, discordgo.PermissionManageMessages}, RequiredArgs: 1, + Plugin: p, Arguments: []*dcmd.ArgDef{ &dcmd.ArgDef{Name: "ID", Type: dcmd.Int}, }, @@ -237,6 +242,7 @@ func (p *Plugin) AddCommands() { Aliases: []string{"cancelsetup"}, Description: "Force cancels the current setup session in this channel", RequireDiscordPerms: []int64{discordgo.PermissionManageServer}, + Plugin: p, RunFunc: func(parsed *dcmd.Data) (interface{}, error) { p.setupSessionsMU.Lock() diff --git a/serverstats/plugin_bot.go b/serverstats/plugin_bot.go index c0dd2ff6b2..5ede54aabf 100644 --- a/serverstats/plugin_bot.go +++ b/serverstats/plugin_bot.go @@ -48,7 +48,7 @@ func (p *Plugin) BotInit() { } func (p *Plugin) AddCommands() { - commands.AddRootCommands(&commands.YAGCommand{ + commands.AddRootCommands(p, &commands.YAGCommand{ CustomEnabled: true, CmdCategory: commands.CategoryTool, Cooldown: 5, diff --git a/soundboard/bot.go b/soundboard/bot.go index c217a667cb..f3ccf1dc9b 100644 --- a/soundboard/bot.go +++ b/soundboard/bot.go @@ -1,99 +1,103 @@ package soundboard import ( + "strings" + "emperror.dev/errors" "github.com/jonas747/dcmd" "github.com/jonas747/dstate" + "github.com/jonas747/yagpdb/analytics" "github.com/jonas747/yagpdb/commands" "github.com/jonas747/yagpdb/soundboard/models" - "strings" ) func (p *Plugin) AddCommands() { - commands.AddRootCommands( - &commands.YAGCommand{ - CmdCategory: commands.CategoryFun, - Name: "Soundboard", - Aliases: []string{"sb"}, - Description: "Play, or list soundboard sounds", - Arguments: []*dcmd.ArgDef{ - &dcmd.ArgDef{Name: "Name", Type: dcmd.String}, - }, - RunFunc: func(data *dcmd.Data) (interface{}, error) { - sounds, err := GetSoundboardSounds(data.GS.ID, data.Context()) - if err != nil { - return nil, errors.WithMessage(err, "GetSoundboardSounds") - } - - // Get member from api or state - member := commands.ContextMS(data.Context()) - - if data.Args[0].Str() == "" { - return ListSounds(sounds, member), nil - } - - var sound *models.SoundboardSound - for _, v := range sounds { - if strings.EqualFold(v.Name, data.Args[0].Str()) { - sound = v - break + commands.AddRootCommands(p, + &commands.YAGCommand{ + CmdCategory: commands.CategoryFun, + Name: "Soundboard", + Aliases: []string{"sb"}, + Description: "Play, or list soundboard sounds", + Arguments: []*dcmd.ArgDef{ + &dcmd.ArgDef{Name: "Name", Type: dcmd.String}, + }, + RunFunc: func(data *dcmd.Data) (interface{}, error) { + sounds, err := GetSoundboardSounds(data.GS.ID, data.Context()) + if err != nil { + return nil, errors.WithMessage(err, "GetSoundboardSounds") } - } - - if sound == nil { - return "Sound not found, " + ListSounds(sounds, member), nil - } else if !CanPlaySound(sound, member.Roles) { - return "You can't play that sound, either you have a blacklisted role or missing a required role for this sound", nil - } - - status := TranscodingStatus(sound.Status) - if status != TranscodingStatusReady { - switch status { - case TranscodingStatusQueued: - return "This sound has yet to be transcoded, if it appear to be stuck in this state then contact support", nil - case TranscodingStatusFailedLong: - return "This sound is too long", nil - case TranscodingStatusFailedOther: - return "This sound failed transcoding, which means you linked or uploaded a invalid media file. You cannot link youtube videos or web pages, has to be direct links to a media file.", nil - case TranscodingStatusTranscoding: - return "This sound is in the process of being converted, please try again in a couple seconds...", nil + + // Get member from api or state + member := commands.ContextMS(data.Context()) + + if data.Args[0].Str() == "" { + return ListSounds(sounds, member), nil } - } - data.GS.RLock() - defer data.GS.RUnlock() + var sound *models.SoundboardSound + for _, v := range sounds { + if strings.EqualFold(v.Name, data.Args[0].Str()) { + sound = v + break + } + } - var voiceChannel int64 - vs := data.GS.VoiceState(false, data.Msg.Author.ID) - if vs != nil { - voiceChannel = vs.ChannelID - } + if sound == nil { + return "Sound not found, " + ListSounds(sounds, member), nil + } else if !CanPlaySound(sound, member.Roles) { + return "You can't play that sound, either you have a blacklisted role or missing a required role for this sound", nil + } - if voiceChannel == 0 { - return "You're not in a voice channel", nil - } + status := TranscodingStatus(sound.Status) + if status != TranscodingStatusReady { + switch status { + case TranscodingStatusQueued: + return "This sound has yet to be transcoded, if it appear to be stuck in this state then contact support", nil + case TranscodingStatusFailedLong: + return "This sound is too long", nil + case TranscodingStatusFailedOther: + return "This sound failed transcoding, which means you linked or uploaded a invalid media file. You cannot link youtube videos or web pages, has to be direct links to a media file.", nil + case TranscodingStatusTranscoding: + return "This sound is in the process of being converted, please try again in a couple seconds...", nil + } + } - if RequestPlaySound(data.GS.ID, voiceChannel, data.Msg.ChannelID, sound.ID) { - return "Queued up", nil - } + data.GS.RLock() + defer data.GS.RUnlock() - return "Playing it now", nil - }, - }, - - &commands.YAGCommand{ - CmdCategory: commands.CategoryFun, - Name: "SoundboardReset", - Aliases: []string{"sbclose", "sbReset"}, - Description: "Reset Soundboard Player", - RunFunc: func(data *dcmd.Data) (interface{}, error) { - response := resetPlayerServer(data.GS.ID) - if response != "" { - return response, nil - } - return "Reset Complete!", nil + var voiceChannel int64 + vs := data.GS.VoiceState(false, data.Msg.Author.ID) + if vs != nil { + voiceChannel = vs.ChannelID + } + + if voiceChannel == 0 { + return "You're not in a voice channel", nil + } + + go analytics.RecordActiveUnit(data.GS.ID, p, "playing sound") + + if RequestPlaySound(data.GS.ID, voiceChannel, data.Msg.ChannelID, sound.ID) { + return "Queued up", nil + } + + return "Playing it now", nil + }, }, - }) + + &commands.YAGCommand{ + CmdCategory: commands.CategoryFun, + Name: "SoundboardReset", + Aliases: []string{"sbclose", "sbReset"}, + Description: "Reset Soundboard Player", + RunFunc: func(data *dcmd.Data) (interface{}, error) { + response := resetPlayerServer(data.GS.ID) + if response != "" { + return response, nil + } + return "Reset Complete!", nil + }, + }) } func ListSounds(sounds []*models.SoundboardSound, ms *dstate.MemberState) string { diff --git a/stdcommands/stdcommands.go b/stdcommands/stdcommands.go index a6c86481da..16dd4c4df6 100644 --- a/stdcommands/stdcommands.go +++ b/stdcommands/stdcommands.go @@ -65,7 +65,7 @@ func (p *Plugin) PluginInfo() *common.PluginInfo { } func (p *Plugin) AddCommands() { - commands.AddRootCommands( + commands.AddRootCommands(p, // Info info.Command, invite.Command, diff --git a/streaming/bot.go b/streaming/bot.go index c7d52794c3..cf799514db 100644 --- a/streaming/bot.go +++ b/streaming/bot.go @@ -11,6 +11,7 @@ import ( "github.com/jonas747/discordgo" "github.com/jonas747/dstate" "github.com/jonas747/retryableredis" + "github.com/jonas747/yagpdb/analytics" "github.com/jonas747/yagpdb/bot" "github.com/jonas747/yagpdb/bot/eventsystem" "github.com/jonas747/yagpdb/common" @@ -414,6 +415,8 @@ func SendStreamingAnnouncement(config *Config, guild *dstate.GuildState, ms *dst return } + go analytics.RecordActiveUnit(guild.ID, &Plugin{}, "sent_streaming_announcement") + ctx := templates.NewContext(guild, nil, ms) ctx.Data["URL"] = ms.PresenceGame.URL ctx.Data["url"] = ms.PresenceGame.URL @@ -442,6 +445,8 @@ func GiveStreamingRole(guildID, memberID, streamingRole int64, currentUserRoles if !common.ContainsInt64Slice(currentUserRoles, streamingRole) { err = common.BotSession.GuildMemberRoleAdd(guildID, memberID, streamingRole) + go analytics.RecordActiveUnit(guildID, &Plugin{}, "assigned_streaming_role") + } if err != nil { @@ -463,6 +468,8 @@ func RemoveStreamingRole(guildID, memberID int64, streamingRole int64, currentRo return } + go analytics.RecordActiveUnit(guildID, &Plugin{}, "removed_streaming_role") + err := common.BotSession.GuildMemberRoleRemove(guildID, memberID, streamingRole) if err != nil { logger.WithError(err).WithField("guild", guildID).WithField("user", memberID).WithField("role", streamingRole).Error("Failed removing streaming role") diff --git a/tickets/tickets_commands.go b/tickets/tickets_commands.go index d05c754d0b..db8f7e233b 100644 --- a/tickets/tickets_commands.go +++ b/tickets/tickets_commands.go @@ -15,6 +15,7 @@ import ( "github.com/jonas747/dcmd" "github.com/jonas747/discordgo" "github.com/jonas747/dstate" + "github.com/jonas747/yagpdb/analytics" "github.com/jonas747/yagpdb/commands" "github.com/jonas747/yagpdb/common" "github.com/jonas747/yagpdb/common/templates" @@ -393,6 +394,10 @@ func (p *Plugin) AddCommands() { conf = &models.TicketConfig{} } + if conf.Enabled { + go analytics.RecordActiveUnit(data.GS.ID, &Plugin{}, "cmd_used") + } + activeTicket, err := models.Tickets(qm.Where("channel_id = ? AND guild_id = ?", data.CS.ID, data.GS.ID)).OneG(data.Context()) if err != nil && err != sql.ErrNoRows { return nil, err diff --git a/timezonecompanion/plugin_bot.go b/timezonecompanion/plugin_bot.go index 20c61aa43e..259e358cb7 100644 --- a/timezonecompanion/plugin_bot.go +++ b/timezonecompanion/plugin_bot.go @@ -4,6 +4,10 @@ import ( "context" "database/sql" "fmt" + "math" + "strings" + "time" + "github.com/jonas747/dcmd" "github.com/jonas747/discordgo" "github.com/jonas747/yagpdb/bot" @@ -13,9 +17,6 @@ import ( "github.com/jonas747/yagpdb/common" "github.com/jonas747/yagpdb/timezonecompanion/models" "github.com/volatiletech/sqlboiler/boil" - "math" - "strings" - "time" ) var _ bot.BotInitHandler = (*Plugin)(nil) @@ -26,7 +27,7 @@ func (p *Plugin) BotInit() { } func (p *Plugin) AddCommands() { - commands.AddRootCommands(&commands.YAGCommand{ + commands.AddRootCommands(p, &commands.YAGCommand{ CmdCategory: commands.CategoryTool, Name: "settimezone", Aliases: []string{"setz", "tzset"}, @@ -303,12 +304,12 @@ func (p *Plugin) handleMessageCreate(evt *eventsystem.EventData) { if m.GuildID == 0 { return } - + //Additional check to ensure not reacting to own message if m.Author.ID == common.BotUser.ID { return } - + result, err := p.DateParser.Parse(m.Content, time.Now()) if err != nil || result == nil { return diff --git a/twitter/feed.go b/twitter/feed.go index 1af0d9cd21..0a9afa8dce 100644 --- a/twitter/feed.go +++ b/twitter/feed.go @@ -10,6 +10,7 @@ import ( "github.com/dghubble/go-twitter/twitter" "github.com/jonas747/discordgo" + "github.com/jonas747/yagpdb/analytics" "github.com/jonas747/yagpdb/common" "github.com/jonas747/yagpdb/common/mqueue" "github.com/jonas747/yagpdb/feeds" @@ -177,6 +178,8 @@ OUTER: webhookUsername := t.User.ScreenName + " • YAGPDB" embed := createTweetEmbed(t) for _, v := range relevantFeeds { + go analytics.RecordActiveUnit(v.GuildID, p, "posted_twitter_message") + mqueue.QueueMessage(&mqueue.QueuedElement{ Source: "twitter", SourceID: strconv.FormatInt(v.ID, 10), diff --git a/verification/verification_bot.go b/verification/verification_bot.go index a66f66df61..da9c03eb4a 100644 --- a/verification/verification_bot.go +++ b/verification/verification_bot.go @@ -13,6 +13,7 @@ import ( "emperror.dev/errors" "github.com/jonas747/discordgo" "github.com/jonas747/dstate" + "github.com/jonas747/yagpdb/analytics" "github.com/jonas747/yagpdb/bot" "github.com/jonas747/yagpdb/bot/eventsystem" "github.com/jonas747/yagpdb/common" @@ -76,6 +77,8 @@ func (p *Plugin) handleMemberJoin(evt *eventsystem.EventData) { return } + go analytics.RecordActiveUnit(m.GuildID, p, "process_started") + go p.startVerificationProcess(conf, m.GuildID, m.User) } diff --git a/verification/verification_web.go b/verification/verification_web.go index a21f9b7ffc..5c46ca5197 100644 --- a/verification/verification_web.go +++ b/verification/verification_web.go @@ -4,6 +4,14 @@ import ( "database/sql" "encoding/json" "fmt" + "html" + "html/template" + "net/http" + "net/url" + "strconv" + "time" + + "github.com/jonas747/yagpdb/analytics" "github.com/jonas747/yagpdb/common" "github.com/jonas747/yagpdb/common/scheduledevents2" "github.com/jonas747/yagpdb/verification/models" @@ -13,12 +21,6 @@ import ( "github.com/volatiletech/null" "github.com/volatiletech/sqlboiler/boil" "goji.io/pat" - "html" - "html/template" - "net/http" - "net/url" - "strconv" - "time" ) type FormData struct { @@ -222,6 +224,9 @@ func (p *Plugin) handlePostVerifyPage(w http.ResponseWriter, r *http.Request) (w scheduledevents2.ScheduleEvent("verification_user_verified", g.ID, time.Now(), userID) verSession.SolvedAt = null.TimeFrom(time.Now()) verSession.UpdateG(ctx, boil.Infer()) + + go analytics.RecordActiveUnit(g.ID, p, "completed") + } else { templateData.AddAlerts(web.ErrorAlert("Invalid reCAPTCHA submission.")) } diff --git a/youtube/feed.go b/youtube/feed.go index cb7e268ba7..cca284c292 100644 --- a/youtube/feed.go +++ b/youtube/feed.go @@ -11,6 +11,7 @@ import ( "github.com/jinzhu/gorm" "github.com/jonas747/discordgo" "github.com/jonas747/retryableredis" + "github.com/jonas747/yagpdb/analytics" "github.com/jonas747/yagpdb/common" "github.com/jonas747/yagpdb/common/mqueue" "github.com/mediocregopher/radix/v3" @@ -348,6 +349,8 @@ func (p *Plugin) sendNewVidMessage(guild, discordChannel string, channelTitle st parseMentions = []discordgo.AllowedMentionType{discordgo.AllowedMentionTyeEveryone} } + go analytics.RecordActiveUnit(parsedGuild, p, "posted_youtube_message") + mqueue.QueueMessage(&mqueue.QueuedElement{ Guild: parsedGuild, Channel: parsedChannel,