// Message receives a Message struct and sends it to appropriate channels func Message(s *discordgo.Session, m *types.Message) error { message := strings.Join(m.Payload, "\n") var channels []string var dchannels []*discordgo.Channel var err error c := config.Get() if m.Prefix != "" { message = fmt.Sprintf("%s: %s", m.Prefix, message) } if m.Channels[0] == "*" { dchannels, err = s.GuildChannels(c.Guild) if err != nil { return err } //errhandler.Handle(err) for _, chann := range dchannels { channels = append(channels, chann.ID) } } else { channels = m.Channels } log.Debugf("%s\n", len(channels)) for _, channel := range channels { s.ChannelMessageSend(channel, message) } return nil }
// Play a sound func PlaySound(s *discordgo.Session, play *Play, vc *discordgo.VoiceConnection) (err error) { log.WithFields(log.Fields{ "play": play, }).Info("Playing sound") if vc == nil { vc, err = s.ChannelVoiceJoin(play.GuildID, play.ChannelID, false, false) // vc.Receive = false if err != nil { log.WithFields(log.Fields{ "error": err, }).Error("Failed to play sound") delete(queues, play.GuildID) return err } } // If we need to change channels, do that now if vc.ChannelID != play.ChannelID { vc.ChangeChannel(play.ChannelID, false, false) time.Sleep(time.Millisecond * 125) } // // Track stats for this play in redis // go rdTrackSoundStats(play) // Sleep for a specified amount of time before playing the sound time.Sleep(time.Millisecond * 32) // Play the sound play.Sound.Play(vc) // If this is chained, play the chained sound if play.Next != nil { PlaySound(s, play.Next, vc) } // If there is another song in the queue, recurse and play that if len(queues[play.GuildID]) > 0 { play := <-queues[play.GuildID] PlaySound(s, play, vc) return nil } // If the queue is empty, delete it time.Sleep(time.Millisecond * time.Duration(play.Sound.PartDelay)) delete(queues, play.GuildID) vc.Disconnect() return nil }
//Welcome sends an acknowledge to the terminal that it is listening, and prints the current Username func Welcome(dg *discordgo.Session) { d := color.New(color.FgYellow, color.Bold) d.Printf("Listening!\n\n") user, _ := dg.User("@me") d.Printf("Welcome, %s!\n\n", user.Username) }
// Helper function to change the avatar func changeAvatar(s *discordgo.Session) { resp, err := http.Get(URL) if err != nil { fmt.Println("Error retrieving the file, ", err) return } defer func() { _ = resp.Body.Close() }() img, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Println("Error reading the response, ", err) return } base64 := base64.StdEncoding.EncodeToString(img) avatar := fmt.Sprintf("data:%s;base64,%s", http.DetectContentType(img), base64) _, err = s.UserUpdate("", "", BotUsername, avatar, "") if err != nil { fmt.Println("Error setting the avatar, ", err) } }
// playSound plays the current buffer to the provided channel. func playSound(s *discordgo.Session, guildID, channelID string) (err error) { // Join the provided voice channel. vc, err := s.ChannelVoiceJoin(guildID, channelID, false, true) if err != nil { return err } // Sleep for a specified amount of time before playing the sound time.Sleep(250 * time.Millisecond) // Start speaking. _ = vc.Speaking(true) // Send the buffer data. for _, buff := range buffer { vc.OpusSend <- buff } // Stop speaking _ = vc.Speaking(false) // Sleep for a specificed amount of time before ending. time.Sleep(250 * time.Millisecond) // Disconnect from the provided voice channel. _ = vc.Disconnect() return nil }
func dgoListen(s *discordgo.Session) error { log.Notice("Digo listening for WS Events") // Listen blocks until it returns //go acceptInvite(s) err := s.Listen() return err }
func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) { if m.ChannelID != config.Discord.ChannelID { return } ign := "" member, err := s.State.Member(config.Discord.ServerID, m.Author.ID) if err != nil { log.Printf("[Discord] Failed to get member: %s (Make sure you have set the bot permissions to see members)", err.Error()) return } roles, err := s.GuildRoles(config.Discord.ServerID) if err != nil { log.Printf("[Discord] Failed to get roles: %s (Make sure you have set the bot permissions to see roles)", err.Error()) return } for _, role := range member.Roles { if ign != "" { break } for _, gRole := range roles { if ign != "" { break } if strings.TrimSpace(gRole.ID) == strings.TrimSpace(role) { if strings.Contains(gRole.Name, "IGN:") { splitStr := strings.Split(gRole.Name, "IGN:") if len(splitStr) > 1 { ign = strings.TrimSpace(splitStr[1]) } } } } } if ign == "" { return } msg := m.ContentWithMentionsReplaced() //Maximum limit of 4k if len(msg) > 4000 { msg = msg[0:4000] } if len(msg) < 1 { return } ign = sanitize(ign) msg = sanitize(msg) //Send message. if err = Sendln(fmt.Sprintf("emote world 260 %s says from discord, '%s'", ign, msg)); err != nil { log.Printf("[Discord] Error sending message to telnet (%s:%s): %s\n", ign, msg, err.Error()) return } log.Printf("[Discord] %s: %s\n", ign, msg) }
func sendMessage(sess *discordgo.Session, message string) { channelid := fetchPrimaryTextChannelID(sess) logInfo("SENDING MESSAGE:", message) retryOnBadGateway(func() error { _, err := sess.ChannelMessageSend(channelid, message) return err }) }
//Ban function calls the BanCreate api for discord and sets the warnning //and banned information appropriatly func (u *User) Ban(dg *discordgo.Session) (success bool, err error) { u.Banned = true u.BannedDate = time.Now() u.Warnings = 0 err = dg.GuildBanCreate(u.Member.GuildID, u.Member.User.ID, 0) if err == nil { return true, nil } return false, nil }
func ChangeBotName(s *discordgo.Session, name string, avatarfile string) { binary, _ := ioutil.ReadFile(avatarfile) avatar := base64.StdEncoding.EncodeToString(binary) _, err := s.UserUpdate("", "", name, "data:image/jpeg;base64,"+avatar, "") if err != nil { fmt.Println(err.Error()) } else { fmt.Println("Changed username successfully") } }
func bdLinks(s *discordgo.Session, id string) { resp, err := http.Get("https://betterdiscord.net/home/") checkErr(err) bytes, err := ioutil.ReadAll(resp.Body) checkErr(err) rx := regexp.MustCompile(`<a href="(.*.zip)`) mm := rx.FindAllStringSubmatch(string(bytes), 2) s.ChannelMessageSend(id, fmt.Sprintf("\n`OSX:` %s\n`Windows:` %s", mm[1][1], mm[0][1])) }
func onGuildCreate(s *discordgo.Session, event *discordgo.GuildCreate) { if event.Guild.Unavailable != nil { return } for _, channel := range event.Guild.Channels { if channel.ID == event.Guild.ID { s.ChannelMessageSend(channel.ID, "**AIRHORN BOT READY FOR HORNING. TYPE `!AIRHORN` WHILE IN A VOICE CHANNEL TO ACTIVATE**") return } } }
// This function will be called (due to AddHandler above) every time a new // guild is joined. func guildCreate(s *discordgo.Session, event *discordgo.GuildCreate) { if event.Guild.Unavailable != nil { return } for _, channel := range event.Guild.Channels { if channel.ID == event.Guild.ID { _, _ = s.ChannelMessageSend(channel.ID, "Airhorn is ready! Type !airhorn while in a voice channel to play a sound.") return } } }
func fetchUser(sess *discordgo.Session, userid string) *discordgo.User { var result *discordgo.User retryOnBadGateway(func() error { var err error result, err = sess.User(userid) if err != nil { return err } return nil }) return result }
func acceptInvite(s *discordgo.Session) error { var err error c := config.Get() //time.Sleep(1 * time.Second) if c.InviteID != "" { log.Debugf("Attempting to accept invite: %s", c.InviteID) _, err = s.InviteAccept(c.InviteID) } else { log.Debug("No DIGO_INVITE_ID specified, no invite to accept.") } return err }
func checkForPermissions(s *discordgo.Session, channelID string, roleID []string) bool { var ok bool if len(roleID) > 0 { _, ok = adminIds[roleID[0]] if ok == true { return ok } } s.ChannelMessageSend(channelID, fmt.Sprintf("Insuficient permissions")) return ok }
// the below method is invoked when the Discord Websocket API transmits // a 'guildCreate' event to the bot func onGuildCreate(s *discordgo.Session, event *discordgo.GuildCreate) { logrus.WithFields(logrus.Fields{ "guildId": event.ID, "guildName": event.Name, "joinedAt": event.JoinedAt, }).Debug("Received guild create event from Discord Websocket API.") // send greet message to the appropriate general/lobby channel for _, channel := range event.Guild.Channels { if channel.ID == event.Guild.ID { s.ChannelMessageSend(channel.ID, "Pokemon Discord is ready for use! Type `!setTeam [name]` to set your Pokemon GO team.") } } }
func fetchPrimaryTextChannelID(sess *discordgo.Session) string { var channelid string retryOnBadGateway(func() error { guilds, err := sess.UserGuilds() if err != nil { return err } guild, err := sess.Guild(guilds[0].ID) if err != nil { return err } channels, err := sess.GuildChannels(guild.ID) if err != nil { return err } for _, channel := range channels { channel, err = sess.Channel(channel.ID) if err != nil { return err } if channel.Type == "text" { channelid = channel.ID return nil } } return errors.New("No primary channel found") }) return channelid }
func updateRolesToDB(s *discordgo.Session, guild string) { roles, _ := s.GuildRoles(guild) pgDb := dbConn() tx, err := pgDb.Begin() checkErr(err) for i := 0; i < len(roles); i++ { _, err = tx.Exec("INSERT INTO roles(role, role_id) VALUES($1, $2)", roles[i].Name, roles[i].ID) checkErr(err) } tx.Commit() pgDb.Close() }
func ListenToDiscord(config *eqemuconfig.Config, disco *discord.Discord) (err error) { var session *discordgo.Session var guild *discordgo.Guild //log.Println("Listen to discord..") if session, err = disco.GetSession(); err != nil { log.Printf("[Discord] Failed to get instance %s: %s (Make sure bot is part of server)", config.Discord.ServerID, err.Error()) return } if guild, err = session.Guild(config.Discord.ServerID); err != nil { log.Printf("[Discord] Failed to get server %s: %s (Make sure bot is part of server)", config.Discord.ServerID, err.Error()) return } isNotAvail := true if guild.Unavailable == &isNotAvail { log.Printf("[Discord] Failed to get server %s: Server unavailable (Make sure bot is part of server, and has permission)", config.Discord.ServerID, err.Error()) return } session.StateEnabled = true session.AddHandler(messageCreate) log.Printf("[Discord] Connected\n") if err = session.Open(); err != nil { log.Printf("[Discord] Session closed: %s", err.Error()) return } select {} return }
// Helper function to change the avatar func changeAvatar(s *discordgo.Session) { img, err := ioutil.ReadFile(Avatar) if err != nil { fmt.Println(err) } base64 := base64.StdEncoding.EncodeToString(img) avatar := fmt.Sprintf("data:%s;base64,%s", http.DetectContentType(img), base64) _, err = s.UserUpdate("", "", BotUsername, avatar, "") if err != nil { fmt.Println(err) } }
func findPrimaryChannelInGuild(s *discordgo.Session, guildID *string) (*discordgo.Channel, error) { guild, err := s.Guild(*guildID) if err != nil { return nil, err } for _, guildChannel := range guild.Channels { if guildChannel.ID == guild.ID { return guildChannel, nil } } // this should never happen as every Discord server should have a // 'primary' channel return nil, nil }
func doWsHandshake(dg *discordgo.Session) error { var err error // open websocket... err = dg.Open() if err != nil { log.Errorf("Problem opening WS: %s", err) return err } err = dg.Handshake() if err != nil { log.Errorf("Problem handshaking WS: %s", err) } return err }
// This function will be called (due to AddHandler above) every time a new // message is created on any channel that the autenticated bot has access to. func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) { // Ignore all messages created by the bot itself if m.Author.ID == BotID { return } // If the message is "ping" reply with "Pong!" if m.Content == "ping" { _, _ = s.ChannelMessageSend(m.ChannelID, "Pong!") } // If the message is "pong" reply with "Ping!" if m.Content == "pong" { _, _ = s.ChannelMessageSend(m.ChannelID, "Ping!") } }
func manualUnban(s *discordgo.Session, channelID string, roleID []string, arr []string) { if checkForPermissions(s, channelID, roleID) && len(arr) == 3 && len(arr[2]) == 21 { arr[2] = arr[2][2 : len(arr[2])-1] pgDb := dbConn() tx, err := pgDb.Begin() checkErr(err) user, _ := s.User(arr[2]) name := user.Username rows, err := tx.Query( "SELECT id, guild_id, role_id FROM bans WHERE name = $1", name) checkErr(err) flag := false for rows.Next() { flag = true var id, guild_id, role_id string rows.Scan(&id, &guild_id, &role_id) if len(guild_id) != 0 { rows.Close() _, err = tx.Exec("DELETE FROM bans WHERE id = $1", id) checkErr(err) s.GuildMemberEdit(guild_id, arr[2], []string{role_id}) s.ChannelMessageSend(channelID, fmt.Sprintf("User %s has been unbanned", name)) break } } tx.Commit() pgDb.Close() if flag == false { s.ChannelMessageSend(channelID, fmt.Sprintf("User %s is not banned", name)) } } else { s.ChannelMessageSend(channelID, fmt.Sprintf("Please check the parameters")) } }
func doLogin(s *discordgo.Session) error { var err error var token string c := config.Get() log.Debug("Logging in") token, err = s.Login(c.Email, c.Password) if err == nil { if token != "" { s.Token = token } } else { log.Errorf("Can't log in: %s", err) log.Error("Maybe your credentials are invalid?") } // since we're dealing with a ref, only return the error return err }
// Handles bot operator messages, should be refactored (lmao) func handleBotControlMessages(s *discordgo.Session, m *discordgo.MessageCreate, parts []string, g *discordgo.Guild) { if scontains(parts[1], "status") { displayBotStats(m.ChannelID) } else if scontains(parts[1], "stats") { if len(m.Mentions) >= 2 { displayUserStats(m.ChannelID, utilGetMentioned(s, m).ID) } else if len(parts) >= 3 { displayUserStats(m.ChannelID, parts[2]) } else { displayServerStats(m.ChannelID, g.ID) } } else if scontains(parts[1], "bomb") && len(parts) >= 4 { airhornBomb(m.ChannelID, g, utilGetMentioned(s, m), parts[3]) } else if scontains(parts[1], "aps") { s.ChannelMessageSend(m.ChannelID, ":ok_hand: give me a sec m8") go calculateAirhornsPerSecond(m.ChannelID) } }
//SetGuildState sets the Guild inside the State func SetGuildState(dg *discordgo.Session) { State.InsertMode = false Guilds, _ := dg.UserGuilds() d := color.New(color.FgYellow, color.Bold) d.Printf("Select a Guild:\n") for key, guild := range Guilds { fmt.Printf("%d:%s\n", key, guild.Name) } var response int fmt.Scanf("%d\n", &response) State.Guild, _ = dg.Guild(Guilds[response].ID) Clear() State.InsertMode = true }
func main() { logInfo("Logging in...") var err error var session *discordgo.Session if accountToken == "" { logInfo("Logging in with username and password...") session, err = discordgo.New(username, password) } else { logInfo("Logging in with bot account token...") session, err = discordgo.New(accountToken) } setupHandlers(session) panicOnErr(err) logInfo("Opening session...") err = session.Open() panicOnErr(err) logInfo("Sleeping...") <-make(chan struct{}) }
func bannedUsers(s *discordgo.Session, m *discordgo.MessageCreate) { pgDb := dbConn() rows, err := pgDb.Query("SELECT name, time_stamp, duration from bans") checkErr(err) for rows.Next() { var time_stamp, duration int64 var name string rows.Scan(&name, &time_stamp, &duration) s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("```\n%s %s\n```", name, time.Unix(time_stamp+duration, 0).Format("2006-01-02 15:04"))) } rows.Close() pgDb.Close() }