func (p *topStreamersPlugin) messageFunc(bot *bruxism.Bot, service bruxism.Service, message bruxism.Message) { if !service.IsMe(message) { if bruxism.MatchesCommand(service, "topstreamers", message) { n := time.Now() if !n.After(p.lastUpdate.Add(1 * time.Minute)) { if p.lastMessage != "" { service.SendMessage(message.Channel(), fmt.Sprintf("%s *Last updated %s.*", p.lastMessage, humanize.Time(p.lastUpdate))) } return } service.Typing(message.Channel()) p.lastUpdate = n m, err := p.topStreamers(5) if err != nil { service.SendMessage(message.Channel(), "There was an error while requesting the top streamers, please try again later.") return } service.SendMessage(message.Channel(), m) p.lastMessage = m } } }
func (t *triviaChannel) Message(bot *bruxism.Bot, service bruxism.Service, message bruxism.Message) { if strings.ToLower(message.Message()) == t.Answer { t.Lock() defer t.Unlock() if !t.Active { return } ts := t.Scores[message.UserID()] if ts == nil { ts = &triviaScore{} t.Scores[message.UserID()] = ts } ts.Name = message.UserName() ts.Score++ service.SendMessage(message.Channel(), fmt.Sprintf("%s got it! The answer was %s.", message.UserName(), t.Answer)) service.SendMessage(message.Channel(), fmt.Sprintf("%s answered in %d seconds and their score is now %d.", message.UserName(), int(time.Now().Sub(t.Asked).Seconds()), ts.Score)) t.Unanswered = 0 if t.hintChan != nil { close(t.hintChan) t.hintChan = nil } } }
// SendReminder sends a reminder. func (p *ReminderPlugin) SendReminder(service bruxism.Service, reminder *Reminder) { if reminder.IsPrivate { service.SendMessage(reminder.Target, fmt.Sprintf("%s you set a reminder: %s", humanize.Time(reminder.StartTime), reminder.Message)) } else { service.SendMessage(reminder.Target, fmt.Sprintf("%s %s set a reminder: %s", humanize.Time(reminder.StartTime), reminder.Requester, reminder.Message)) } }
func makeScriptFromMessages(service bruxism.Service, message bruxism.Message, messages []bruxism.Message) *comicgen.Script { speakers := make(map[string]int) avatars := make(map[int]string) script := []*comicgen.Message{} for _, message := range messages { speaker, ok := speakers[message.UserName()] if !ok { speaker = len(speakers) speakers[message.UserName()] = speaker avatars[speaker] = message.UserAvatar() } script = append(script, &comicgen.Message{ Speaker: speaker, Text: message.Message(), Author: message.UserName(), }) } return &comicgen.Script{ Messages: script, Author: fmt.Sprintf(service.UserName()), Avatars: avatars, Type: comicgen.ComicTypeChat, } }
func (p *carbonitexPlugin) carbonitexPluginLoadFunc(bot *bruxism.Bot, service bruxism.Service, data []byte) error { if service.Name() != bruxism.DiscordServiceName { panic("Carbonitex Plugin only supports Discord.") } go p.Run(bot, service) return nil }
func (p *ReminderPlugin) randomReminder(service bruxism.Service) string { ticks := "" if service.Name() == bruxism.DiscordServiceName { ticks = "`" } return fmt.Sprintf("%s%sreminder %s %s%s", ticks, service.CommandPrefix(), p.random(randomTimes), p.random(randomMessages), ticks) }
func (p *chartPlugin) randomChart(service bruxism.Service) string { ticks := "" if service.Name() == bruxism.DiscordServiceName { ticks = "`" } return fmt.Sprintf("%s%schart %s %s, %s%s", ticks, service.CommandPrefix(), p.random(randomDirection), p.random(randomY), p.random(randomX), ticks) }
// Help returns a list of help strings that are printed when the user requests them. func (p *playingPlugin) helpFunc(bot *bruxism.Bot, service bruxism.Service, message bruxism.Message, detailed bool) []string { if detailed { return nil } if !service.IsBotOwner(message) { return nil } return bruxism.CommandHelp(service, "playing", "<game>, <url>", fmt.Sprintf("Set which game %s is playing.", service.UserName())) }
// Message handler. func (p *YouTubeJoinPlugin) Message(bot *bruxism.Bot, service bruxism.Service, message bruxism.Message) { if (service.IsBotOwner(message) || service.IsChannelOwner(message)) && bruxism.MatchesCommand(service, "leave", message) { video, ok := p.youtube.VideoIDForChatID(message.Channel()) if ok { channel, ok := p.youtube.ChannelIDForVideoID(video) if ok { p.Unmonitor(channel) } } } }
// Run will poll YouTube for channels going live and send messages. func (p *livePlugin) Run(bot *bruxism.Bot, service bruxism.Service) { p.RLock() lvc := p.liveVideoChan p.RUnlock() for { v := <-lvc p.RLock() for channel := range p.youTubeChannelToChannels[v.Snippet.ChannelId] { service.SendMessage(channel, fmt.Sprintf("%s has just gone live! http://gaming.youtube.com/watch?v=%s", v.Snippet.ChannelTitle, v.Id)) } p.RUnlock() } }
// MTGCommand is a command for getting information about MTG cards.. func MTGCommand(bot *bruxism.Bot, service bruxism.Service, message bruxism.Message, command string, parts []string) { cardNames := fuzzy.RankFindFold(command, MTGCardNames) if len(cardNames) == 0 { service.SendMessage(message.Channel(), "Could not find a card with that name, sorry.") return } sort.Sort(cardNames) card := MTGCardMap[cardNames[0].Target] rest := "" if card.Text != "" { rest += "\n" } if card.Power != nil { rest += MTGRestReplacer.Replace(fmt.Sprintf("%s/%s", *card.Power, *card.Toughness)) } if card.Loyalty != nil { rest += MTGRestReplacer.Replace(fmt.Sprintf("%d", *card.Loyalty)) } if card.ID != nil { if rest != "" && rest != "\n" { rest += "\n" } rest += fmt.Sprintf("(http://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=%d&type=card)", *card.ID) } if service.Name() == bruxism.DiscordServiceName { service.SendMessage(message.Channel(), fmt.Sprintf("**%s** %s\n*%s*\n%s%s", card.Name, card.ManaCost, card.Type, MTGTextReplacer.Replace(card.Text), rest)) } else { service.SendMessage(message.Channel(), strings.Replace(fmt.Sprintf("%s. %s. %s. %s%s", card.Name, card.Type, card.ManaCost, card.Text, rest), "\n", " ", -1)) } }
// InviteHelp will return the help text for the invite command. func InviteHelp(bot *bruxism.Bot, service bruxism.Service, message bruxism.Message) (string, string) { switch service.Name() { case bruxism.DiscordServiceName: discord := service.(*bruxism.Discord) if discord.ApplicationClientID != "" { return "", fmt.Sprintf("Returns a URL to add %s to your server.", service.UserName()) } return "<discordinvite>", "Joins the provided Discord server." case bruxism.YouTubeServiceName: return "<videoid>", "Joins the provided YouTube live stream." } return "<channel>", "Joins the provided channel." }
// Load will load plugin state from a byte array. func (p *playedPlugin) Load(bot *bruxism.Bot, service bruxism.Service, data []byte) error { if service.Name() != bruxism.DiscordServiceName { panic("Played Plugin only supports Discord.") } if data != nil { if err := json.Unmarshal(data, p); err != nil { log.Println("Error loading data", err) } } go p.Run(bot, service) return nil }
// Load will load plugin state from a byte array. func (p *MusicPlugin) Load(bot *bruxism.Bot, service bruxism.Service, data []byte) (err error) { if service.Name() != bruxism.DiscordServiceName { panic("Music Plugin only supports Discord.") } if data != nil { if err = json.Unmarshal(data, p); err != nil { log.Println("musicplugin: loading data err:", err) } } go p.init() return nil }
func (t *triviaChannel) Stop(bot *bruxism.Bot, service bruxism.Service) { t.Lock() defer t.Unlock() if !t.Active { return } t.Active = false if t.hintChan != nil { close(t.hintChan) t.hintChan = nil } service.SendMessage(t.Channel, "Trivia stopped.") return }
func (t *triviaChannel) Start(bot *bruxism.Bot, service bruxism.Service, theme string) { t.Lock() defer t.Unlock() if t.Active { return } service.SendMessage(t.Channel, "Trivia started.") t.Active = true t.Theme = theme t.Unanswered = 0 go t.question(bot, service) return }
// Load will load plugin state from a byte array. func (p *playingPlugin) Load(bot *bruxism.Bot, service bruxism.Service, data []byte) error { if service.Name() != bruxism.DiscordServiceName { panic("Playing Plugin only supports Discord.") } if data != nil { if err := json.Unmarshal(data, p); err != nil { log.Println("Error loading data", err) } } if p.Game != "" { service.(*bruxism.Discord).Session.UpdateStreamingStatus(0, p.Game, p.URL) } else { service.(*bruxism.Discord).Session.UpdateStatus(0, p.Game) } return nil }
// Message handler. func (p *playingPlugin) messageFunc(bot *bruxism.Bot, service bruxism.Service, message bruxism.Message) { if !service.IsMe(message) { if bruxism.MatchesCommand(service, "playing", message) { if !service.IsBotOwner(message) { return } query, _ := bruxism.ParseCommand(service, message) split := strings.Split(query, ",") p.Game = strings.Trim(split[0], " ") if len(split) > 1 { p.URL = strings.Trim(split[1], " ") service.(*bruxism.Discord).Session.UpdateStreamingStatus(0, p.Game, p.URL) } else { service.(*bruxism.Discord).Session.UpdateStatus(0, p.Game) } } } }
// Load will load plugin state from a byte array. func (p *YouTubeJoinPlugin) Load(bot *bruxism.Bot, service bruxism.Service, data []byte) error { if service.Name() != bruxism.YouTubeServiceName { panic("YouTubeJoin plugin only supports YouTube.") } if data != nil { if err := json.Unmarshal(data, p); err != nil { log.Println("Error loading data", err) } } p.youtube = service.(*bruxism.YouTube) for channel, _ := range p.Channels { p.monitor(channel, false) } go p.Run(bot, service) return nil }
func avatarMessageFunc(bot *bruxism.Bot, service bruxism.Service, message bruxism.Message) { if !service.IsMe(message) { if bruxism.MatchesCommand(service, "avatar", message) { query := strings.Join(strings.Split(message.RawMessage(), " ")[1:], " ") id := message.UserID() match := userIDRegex.FindStringSubmatch(query) if match != nil { id = match[1] } discord := service.(*bruxism.Discord) u, err := discord.Session.User(id) if err != nil { return } service.SendMessage(message.Channel(), discordgo.EndpointUserAvatar(u.ID, u.Avatar)) } } }
// Help returns a list of help strings that are printed when the user requests them. func (p *comicPlugin) Help(bot *bruxism.Bot, service bruxism.Service, message bruxism.Message, detailed bool) []string { help := bruxism.CommandHelp(service, "comic", "[1-10]", "Creates a comic from recent messages, or a number of messages if provided.") ticks := "" if service.Name() == bruxism.DiscordServiceName { ticks = "`" } if detailed { help = append(help, []string{ bruxism.CommandHelp(service, "customcomic", "[id|name:] <text> | [id|name:] <text>", fmt.Sprintf("Creates a custom comic. Available names: %s%s%s", ticks, strings.Join(comicgen.CharacterNames, ", "), ticks))[0], bruxism.CommandHelp(service, "customcomicsimple", "[id:] <text> | [id:] <text>", "Creates a simple custom comic.")[0], "Examples:", bruxism.CommandHelp(service, "comic", "5", "Creates a comic from the last 5 messages")[0], bruxism.CommandHelp(service, "customcomic", "A | B | C", "Creates a comic with 3 lines.")[0], bruxism.CommandHelp(service, "customcomic", "0: Hi! | 1: Hello! | 0: Goodbye.", "Creates a comic with 3 lines, the second line spoken by a different character")[0], bruxism.CommandHelp(service, "customcomic", "tiki: Hi! | jordy: Hello! | tiki: Goodbye.", "Creates a comic with 3 lines, containing tiki and jordy.")[0], bruxism.CommandHelp(service, "customcomicsimple", "0: Foo | 1: Bar", "Creates a comic with 2 lines, both spoken by different characters.")[0], }...) } return help }
// Help returns a list of help strings that are printed when the user requests them. func (p *triviaPlugin) Help(bot *bruxism.Bot, service bruxism.Service, message bruxism.Message, detailed bool) []string { if service.IsPrivate(message) || !(service.IsModerator(message) || service.IsBotOwner(message)) { return nil } return []string{ bruxism.CommandHelp(service, "trivia", "<start|stop> [theme]", "Starts or stops trivia with an optional theme.")[0], bruxism.CommandHelp(service, "trivia", "<score>", "Returns your current trivia score.")[0], } }
func emojiMessageFunc(bot *bruxism.Bot, service bruxism.Service, message bruxism.Message) { if service.Name() == bruxism.DiscordServiceName && !service.IsMe(message) { if bruxism.MatchesCommand(service, "emoji", message) || bruxism.MatchesCommand(service, "hugemoji", message) { base := "emoji/twitter" if bruxism.MatchesCommand(service, "hugemoji", message) { base = "emoji/twitterhuge" } _, parts := bruxism.ParseCommand(service, message) if len(parts) == 1 { submatches := discordRegex.FindStringSubmatch(parts[0]) if len(submatches) != 0 { h, err := http.Get("https://cdn.discordapp.com/emojis/" + submatches[1] + ".png") if err != nil { return } service.SendFile(message.Channel(), "emoji.png", h.Body) h.Body.Close() return } s := strings.TrimSpace(parts[0]) for i := range s { filename := emojiFile(base, s[i:]) if filename != "" { if f, err := os.Open(fmt.Sprintf("%s/%s.png", base, filename)); err == nil { defer f.Close() service.SendFile(message.Channel(), "emoji.png", f) return } } } } } } }
// NumberTriviaCommand is a command for getting number trivial. func NumberTriviaCommand(bot *bruxism.Bot, service bruxism.Service, message bruxism.Message, command string, parts []string) { notfound := true num := rand.Intn(1000) if len(parts) == 1 { if i, err := strconv.Atoi(parts[0]); err == nil { num = i notfound = false } } service.Typing(message.Channel()) str, err := numberTrivia(bot, num, notfound) if err != nil { service.SendMessage(message.Channel(), "There was an error requesting trivia, sorry!") return } service.SendMessage(message.Channel(), str) }
// InviteCommand is a command for accepting an invite to a channel. func InviteCommand(bot *bruxism.Bot, service bruxism.Service, message bruxism.Message, command string, parts []string) { if service.Name() == bruxism.DiscordServiceName { discord := service.(*bruxism.Discord) if discord.ApplicationClientID != "" { service.SendMessage(message.Channel(), fmt.Sprintf("Please visit https://discordapp.com/oauth2/authorize?client_id=%s&scope=bot to add %s to your server.", discord.ApplicationClientID, service.UserName())) return } } if len(parts) == 1 { join := parts[0] if service.Name() == bruxism.DiscordServiceName { join = discordInviteID(join) } if err := service.Join(join); err != nil { if service.Name() == bruxism.DiscordServiceName && err == bruxism.ErrAlreadyJoined { service.PrivateMessage(message.UserID(), "I have already joined that server.") return } log.Println("Error joining %s %v", service.Name(), err) } else if service.Name() == bruxism.DiscordServiceName { service.PrivateMessage(message.UserID(), "I have joined that server.") } } }
func (p *ReminderPlugin) Message(bot *bruxism.Bot, service bruxism.Service, message bruxism.Message) { if !service.IsMe(message) { if bruxism.MatchesCommand(service, "remind", message) || bruxism.MatchesCommand(service, "reminder", message) { _, parts := bruxism.ParseCommand(service, message) if len(parts) < 2 { service.SendMessage(message.Channel(), fmt.Sprintf("Invalid reminder, no time or message. eg: %s", p.randomReminder(service))) return } t, r, err := p.parseReminder(parts) now := time.Now() if err != nil || t.Before(now) || t.After(now.Add(time.Hour*24*365+time.Hour)) { service.SendMessage(message.Channel(), fmt.Sprintf("Invalid time. eg: %s", strings.Join(randomTimes, ", "))) return } if r == "" { service.SendMessage(message.Channel(), fmt.Sprintf("Invalid reminder, no message. eg: %s", p.randomReminder(service))) return } requester := message.UserName() if service.Name() == bruxism.DiscordServiceName { requester = fmt.Sprintf("<@%s>", message.UserID()) } err = p.AddReminder(&Reminder{ StartTime: now, Time: t, Requester: requester, Target: message.Channel(), Message: r, IsPrivate: service.IsPrivate(message), }) if err != nil { service.SendMessage(message.Channel(), err.Error()) return } service.SendMessage(message.Channel(), fmt.Sprintf("Reminder set for %s.", humanize.Time(t))) } } }
func (p *streamerPlugin) messageFunc(bot *bruxism.Bot, service bruxism.Service, message bruxism.Message) { if !service.IsMe(message) { if bruxism.MatchesCommand(service, "streamer", message) { query, parts := bruxism.ParseCommand(service, message) if len(parts) == 0 { return } r, _ := p.requests[query] if r == nil { r = &streamerPluginRequest{} p.requests[query] = r } n := time.Now() if !n.After(r.lastUpdate.Add(60 * time.Minute)) { if r.lastMessage != "" { service.SendMessage(message.Channel(), fmt.Sprintf("%s *Last updated %s.*", r.lastMessage, humanize.Time(r.lastUpdate))) } return } service.Typing(message.Channel()) r.lastUpdate = n m, err := p.streamer(query, service.Name() == bruxism.DiscordServiceName) if err != nil { service.SendMessage(message.Channel(), "There was an error while requesting the streamer, please try again later.") return } service.SendMessage(message.Channel(), m) r.lastMessage = m } } }
// Message handler. func (p *livePlugin) Message(bot *bruxism.Bot, service bruxism.Service, message bruxism.Message) { defer bruxism.MessageRecover() if !service.IsMe(message) { messageChannel := message.Channel() if bruxism.MatchesCommand(service, "live", message) { ticks := "" if service.Name() == bruxism.DiscordServiceName { ticks = "`" } _, parts := bruxism.ParseCommand(service, message) if len(parts) == 0 { service.SendMessage(messageChannel, fmt.Sprintf("Incorrect command. eg: %s%slive [add|remove|list] <%s>%s", ticks, service.CommandPrefix(), "UCGmC0A8mEAPdlELQdP9xJbw", ticks)) } switch parts[0] { case "list": if !service.IsModerator(message) { service.SendMessage(messageChannel, "I'm sorry, you must be the channel owner to list live announcements.") return } list := []string{} p.Lock() for ytChannel := range p.ChannelToYouTubeChannels[messageChannel] { list = append(list, fmt.Sprintf("%s (%s)", p.ytLiveChannel.ChannelName(ytChannel), ytChannel)) } p.Unlock() if len(list) == 0 { service.SendMessage(messageChannel, "No Channels are being announced.") } else { service.SendMessage(messageChannel, fmt.Sprintf("Currently announcing: %s", strings.Join(list, ","))) } case "add": if !service.IsModerator(message) { service.SendMessage(messageChannel, "I'm sorry, you must be the channel owner to add live announcements.") return } if len(parts) != 2 || len(parts[1]) != 24 { service.SendMessage(messageChannel, fmt.Sprintf("Incorrect Channel ID. eg: %s%slive %s %s%s", ticks, service.CommandPrefix(), parts[0], "UCGmC0A8mEAPdlELQdP9xJbw", ticks)) return } err := p.monitor(messageChannel, parts[1]) if err != nil { service.SendMessage(messageChannel, fmt.Sprintf("Could not add Channel ID. %s", err)) return } service.SendMessage(messageChannel, fmt.Sprintf("Messages will be sent here when %s goes live.", p.ytLiveChannel.ChannelName(parts[1]))) case "remove": if !service.IsModerator(message) { service.SendMessage(messageChannel, "I'm sorry, you must be the channel owner to remove live announcements.") return } if len(parts) != 2 || len(parts[1]) != 24 { service.SendMessage(messageChannel, fmt.Sprintf("Incorrect Channel ID. eg: %s%slive %s %s%s", ticks, service.CommandPrefix(), parts[0], "UCGmC0A8mEAPdlELQdP9xJbw", ticks)) return } p.Lock() delete(p.ChannelToYouTubeChannels[messageChannel], parts[1]) delete(p.youTubeChannelToChannels[parts[1]], messageChannel) p.Unlock() service.SendMessage(messageChannel, fmt.Sprintf("Messages will no longer be sent here when %s goes live.", p.ytLiveChannel.ChannelName(parts[1]))) } } } }
func messageFunc(bot *bruxism.Bot, service bruxism.Service, message bruxism.Message) { if service.IsMe(message) || !bruxism.MatchesCommand(service, "myson", message) || service.Name() != bruxism.DiscordServiceName { return } discord := service.(*bruxism.Discord) discord.Session.ChannelMessageSendEmbed(message.Channel(), &discordgo.MessageEmbed{ Color: discord.UserColor(service.UserID(), message.Channel()), Description: "Don't ever talk to me or my son ever again.", Author: &discordgo.MessageEmbedAuthor{ Name: discord.NicknameForID(service.UserID(), service.UserName(), message.Channel()), IconURL: discordgo.EndpointUserAvatar(service.UserID(), discord.Session.State.User.Avatar), }, }) }
func (p *comicPlugin) makeComic(bot *bruxism.Bot, service bruxism.Service, message bruxism.Message, script *comicgen.Script) { p.Comics++ comic := comicgen.NewComicGen("arial", service.Name() != bruxism.DiscordServiceName) image, err := comic.MakeComic(script) if err != nil { service.SendMessage(message.Channel(), fmt.Sprintf("Sorry %s, there was an error creating the comic. %s", message.UserName(), err)) } else { go func() { if service.Name() == bruxism.DiscordServiceName { discord := service.(*bruxism.Discord) p, err := discord.UserChannelPermissions(message.UserID(), message.Channel()) if err == nil && p&discordgo.PermissionAttachFiles != 0 { b := &bytes.Buffer{} err = png.Encode(b, image) if err != nil { service.SendMessage(message.Channel(), fmt.Sprintf("Sorry %s, there was a problem creating your comic.", message.UserName())) return } if err := service.SendFile(message.Channel(), "comic.png", b); err == nil { return } } } b := &bytes.Buffer{} err = png.Encode(b, image) if err != nil { service.SendMessage(message.Channel(), fmt.Sprintf("Sorry %s, there was a problem creating your comic.", message.UserName())) return } url, err := bot.UploadToImgur(b, "comic.png") if err != nil { service.SendMessage(message.Channel(), fmt.Sprintf("Sorry %s, there was a problem uploading the comic to imgur.", message.UserName())) log.Println("Error uploading comic: ", err) return } if service.Name() == bruxism.DiscordServiceName { service.SendMessage(message.Channel(), fmt.Sprintf("Here's your comic <@%s>: %s", message.UserID(), url)) } else { service.SendMessage(message.Channel(), fmt.Sprintf("Here's your comic %s: %s", message.UserName(), url)) } runtime.GC() }() } }