Пример #1
1
// 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
}
Пример #2
0
func sendMessage(sess *discordgo.Session, message string) {
	channelid := fetchPrimaryTextChannelID(sess)
	logInfo("SENDING MESSAGE:", message)
	retryOnBadGateway(func() error {
		_, err := sess.ChannelMessageSend(channelid, message)
		return err
	})
}
Пример #3
0
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]))

}
Пример #4
0
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
		}
	}
}
Пример #5
0
// 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
		}
	}
}
Пример #6
0
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

}
Пример #7
0
// 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.")
		}
	}
}
Пример #8
0
// 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!")
	}
}
Пример #9
0
// 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)
	}
}
Пример #10
0
func handleExternalCommand(status int, command []string, pluginDir string, plugin *types.Plugin, s *discordgo.Session, m *discordgo.Message) (handled bool) {
	//s := conn.Get()
	// always send the event to messageDelete
	if status == globals.MATCH || status == globals.HELP {
		messageDelete(s, m.ChannelID, m.ID)
		handled = true
	}

	if status == globals.MATCH && plugin.Type == "simple" {
		output, err := plugins.Exec(pluginDir, plugin.Filename, command[1:])
		if err == nil {
			s.ChannelMessageSend(m.ChannelID, string(output))
		}

	} else if (status == globals.MATCH || status == globals.HELP) && plugin.Type == "json" {
		var message types.PluginMessage

		if status == globals.MATCH {
			message.Arguments = command[1:]
		} else if status == globals.HELP {
			message.Arguments = []string{}
		}

		message.User = m.Author.Username

		message.Channel = m.ChannelID
		output, err := plugins.ExecJSON(pluginDir, plugin.Filename, &message)
		if err == nil {
			handleJSONPlugin(plugin.Name, output, s)
		} else {
			log.Warning("Could not exec json plugin %s", plugin.Name)
		}

	} else if status == globals.HELP {
		output, err := plugins.Exec(pluginDir, plugin.Filename, []string{})
		if err == nil {
			s.ChannelMessageSend(m.ChannelID, string(output))
		}

	}
	return
}
Пример #11
0
// the below method is invoked when the Discord Websocket API transmits
// a 'guildMemberAdd' event to the bot
func onGuildMemberAdd(s *discordgo.Session, event *discordgo.GuildMemberAdd) {
	logrus.WithFields(logrus.Fields{
		"guildId":  event.GuildID,
		"joinedAt": event.JoinedAt,
		"userId":   event.User.ID,
		"username": event.User.Username,
	}).Debug("Received guild member add event from Discord Websocket API.")

	guild, err := s.Guild(event.GuildID)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"guildId":       event.GuildID,
			"capturedError": err,
		}).Error("Could not retrieve guild object from identifier.")
		return
	}

	primaryChan, err := findPrimaryChannelInGuild(s, &event.GuildID)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"userId":        event.User.ID,
			"guildId":       event.GuildID,
			"capturedError": err,
		}).Error("Could not determine primary channel for guild.")
		return
	}

	// create a private messaging channel between the bot and the new guild member
	privChan, err := s.UserChannelCreate(event.User.ID)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"userId":        event.User.ID,
			"capturedError": err,
		}).Error("Could not create channel between bot and user.")
		return
	}

	// send greet message to new guild member
	s.ChannelMessageSend(privChan.ID, "Welcome to "+guild.Name+"! We recommend setting your Pokemon GO team to grant access to team-only channels. To do so, type `!setTeam [name]` into the #"+primaryChan.Name+" text channel to set your Pokemon GO team. Available team names are: 'valor' (red), 'mystic' (blue) and 'instinct' (yellow).")
}
Пример #12
0
// the below method is invoked when the Discord Websocket API transmits
// a 'messageCreate' event to the bot
func onMessageCreate(s *discordgo.Session, event *discordgo.MessageCreate) {
	logrus.WithFields(logrus.Fields{
		"authorId":       event.Author.ID,
		"authorUsername": event.Author.Username,
		"channelId":      event.ChannelID,
		"timestamp":      event.Timestamp,
		"content":        event.Content,
	}).Debug("Received message create event from Discord Websocket API.")

	// do not take action if the author of the message is ourself
	if s.State.Ready.User.ID == event.Author.ID {
		return
	}

	// ensure the message was not received via direct message
	currChannel, err := s.Channel(event.ChannelID)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"channelId":     event.ChannelID,
			"capturedError": err,
		}).Error("Could not retrieve channel object from identifier.")
		return
	}

	if currChannel.IsPrivate {
		s.ChannelMessageSend(event.ChannelID, "Hi! I don't respond to commands sent through direct message, as I cannot tell what Discord server you are trying to set on! Please send me a message in the appropriate text channel on a Discord server to try again.")
		return
	}

	// convert the text to lowercase to avoid case-sensitivity issues
	lowerContent := strings.ToLower(event.ContentWithMentionsReplaced())

	if strings.HasPrefix(lowerContent, "!setteam ") {
		givenTeamName := lowerContent[9:]
		go handleTeamSet(s, &givenTeamName, &event.Author.ID, &event.ChannelID)
	}
}
Пример #13
0
func handleInternalCommand(status int, command []string, s *discordgo.Session, m *discordgo.Message) (handled bool) {
	if status == globals.MATCH || status == globals.HELP {
		messageDelete(s, m.ChannelID, m.ID)
		handled = true
	}
	if status == globals.MATCH {
		switch {
		case command[1] == "plugins":
			s.ChannelMessageSend(m.ChannelID, printHelp())
		case command[1] == "reload":
			plugins.Register()
			s.ChannelMessageSend(m.ChannelID, "Digo Reloaded")
		default:
			s.ChannelMessageSend(m.ChannelID, printHelp())
		}
	} else if status == globals.HELP {
		s.ChannelMessageSend(m.ChannelID, printHelp())
	}
	return
}
Пример #14
0
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"))
	}
}
Пример #15
0
func pullFromReddit(ses *discordgo.Session) bool {
	pgDb := dbConn()

	defer func() bool {
		if err := recover(); err != nil {
			//			fmt.Println("recovered from wrong pull")
			pgDb.Close()
			return false
		}
		return true
	}()

	session, _ := geddit.NewLoginSession(
		"",
		"",
		"gedditAgent v1",
	)

	rows, err := pgDb.Query(
		`SELECT last_url FROM reddit 
        ORDER BY time_stamp DESC LIMIT 100`)
	checkErr(err)

	var url string
	urlArr := make(map[string]int)
	for rows.Next() {
		rows.Scan(&url)
		urlArr[url] = 1
	}
	rows.Close()

	subOpts := geddit.ListingOptions{
		Limit: 100,
	}

	submissions, _ := session.Frontpage(geddit.HotSubmissions, subOpts)

	for _, s := range submissions {
		_, ok := urlArr[s.URL]
		if ok {
			break
		}
		tx, err := pgDb.Begin()
		checkErr(err)

		_, err = tx.Exec("INSERT INTO reddit (last_url) VALUES ($1)", s.URL)
		checkErr(err)

		tx.Commit()

		if strings.Contains(s.URL, "imgur") &&
			!strings.Contains(s.URL, "/a/") &&
			!strings.Contains(s.URL, "/gallery/") {
			//			fmt.Println(s.URL)
			rx := regexp.MustCompile(`^(https?://.*?)/(.*?)(\..*)?$`)
			m := rx.FindStringSubmatch(s.URL)
			//			fmt.Println(m)

			base := m[1]
			pref := m[2]
			ext := m[3]
			//			fmt.Println("after m split")
			if len(ext) == 0 {
				ext = ".jpg"
			}
			animated := imgurFilext(pref)

			url := base + "/" + pref + ext
			if animated {
				url = base + "/" + pref + ".gif"
			}

			response, err := http.Get(url)
			checkErr(err)

			//			fmt.Println(response.ContentLength)

			if response.ContentLength <= 8388608 {
				ses.ChannelMessageSend(CHANID,
					fmt.Sprintf("\n```%s```\n%s\n", s.Title, url))
			} else {
				ses.ChannelMessageSend(CHANID,
					fmt.Sprintf(
						"\n```**CANNOT EMBED FILE IS TOO LARGE**\n%s```\n%s",
						s.Title, s.URL))
			}

		} else {
			ses.ChannelMessageSend(CHANID,
				fmt.Sprintf("\n```%s```\n%s\n", s.Title, s.URL))
		}
		time.Sleep(time.Second * 2)
	}
	pgDb.Close()
	return true
}
Пример #16
0
// This function will be called (due to above assignment) every time a new
// message is created on any channel that the autenticated user has access to.
func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
	if !m.Author.Bot {
		s.ChannelMessageSend(m.ChannelID, m.Content)
	}
}
Пример #17
0
func handleTeamSet(s *discordgo.Session, givenTeamName *string, authorID *string, channelID *string) {
	// validate a team option was provided to the command
	if *givenTeamName == "" {
		s.ChannelMessageSend(*channelID, "A team must be provided to this command.")
		return
	}

	// validate the team provided matches a valid option
	hasTeam := false
	for _, team := range teams {
		if *givenTeamName == team {
			hasTeam = true
		}
	}

	if !hasTeam {
		s.ChannelMessageSend(*channelID, "The team selected ("+*givenTeamName+") does not exist. Valid options are: "+strings.Join(teams, ", ")+".")
		return
	}

	currChannel, err := s.Channel(*channelID)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"channelId":     *channelID,
			"capturedError": err,
		}).Error("Could not parse channel identifier into channel object.")
		s.ChannelMessageSend(*channelID, "An error occurred while setting your team. Please wait a moment and try again.")
		return
	}

	currGuild, err := s.Guild(currChannel.GuildID)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"guildId":       currChannel.GuildID,
			"capturedError": err,
		}).Error("Could not parse guild identifier into guild object.")
		s.ChannelMessageSend(*channelID, "An error occurred while setting your team. Please wait a moment and try again.")
		return
	}

	currMember, err := s.GuildMember(currGuild.ID, *authorID)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"guildId":       currGuild.ID,
			"userId":        *authorID,
			"capturedError": err,
		}).Error("Could not parse guild identifier and user identifier into guild member object.")
		s.ChannelMessageSend(*channelID, "An error occurred while setting your team. Please wait a moment and try again.")
		return
	}

	// ensure they are not an existing member of a team
	for _, roleID := range currMember.Roles {
		var role *discordgo.Role
		for _, guildRole := range currGuild.Roles {
			if guildRole.ID == roleID {
				role = guildRole
			}
		}
		if role == nil {
			logrus.WithFields(logrus.Fields{
				"roleId": roleID,
			}).Error("Could not retrieve role object from identifier.")
			s.ChannelMessageSend(*channelID, "An error occurred while setting your team. Please wait a moment and try again.")
			return
		}

		for _, teamName := range teams {
			if role.Name == "Team "+strings.Title(teamName) {
				logrus.WithFields(logrus.Fields{
					"roleName": role.Name,
					"roleId":   role.ID,
					"userId":   currMember.User.ID,
					"userName": currMember.User.Username,
					"guildId":  currGuild.ID,
				}).Warn("Attempted team switch detected.")
				s.ChannelMessageSend(*channelID, "You are already a member of a team and cannot switch now. Ask an administrator if you have made a mistake selecting teams.")
				return
			}
		}
	}

	// add the role to the user
	teamTitle := strings.Title(*givenTeamName)
	for _, role := range currGuild.Roles {
		if role.Name == "Team "+teamTitle {
			err := s.GuildMemberEdit(currGuild.ID, *authorID, append(currMember.Roles, role.ID))
			if err != nil {
				logrus.WithFields(logrus.Fields{
					"guildId":       currGuild.ID,
					"userId":        *authorID,
					"roleId":        role.ID,
					"capturedError": err,
				}).Error("Could not add team role to user.")
				s.ChannelMessageSend(*channelID, "An error occurred while setting your team. Please wait a moment and try again.")
				return
			}
			s.ChannelMessageSend(*channelID, "You have been set to Team "+teamTitle+".")
		}
	}
}
Пример #18
0
func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
	if m.Author.ID == s.State.User.ID {
		// Ignore self
		return
	}

	channel, _ := s.State.Channel(m.ChannelID)

	if channel.IsPrivate {
		channel.Name = "direct message"
	}

	isMentioned := isUserMentioned(s.State.User, m.Mentions) || m.MentionEveryone

	if shouldIgnore(m.Author) {
		return
	}

	text := m.ContentWithMentionsReplaced()
	text = strings.Replace(text, "@everyone", "", -1)

	// Log cleaned up message
	fmt.Printf("%20s %20s %20s > %s\n", channel.Name, time.Now().Format(time.Stamp), m.Author.Username, text)

	commandFound, reply := commands.ParseMessage(s, m, text)

	if commandFound {
		_, err := s.ChannelMessageSend(m.ChannelID, reply)
		if err != nil {
			fmt.Println("s.ChannelMessageSend >> ", err)
		}
		return
	} else if strings.HasPrefix(text, "!") || strings.HasPrefix(text, ".") || strings.HasPrefix(text, "bot.") {
		// Ignore shit meant for other bots
		return
	}

	if config.ChannelIsLewd(channel.GuildID, m.ChannelID) {
		linksFound, reply := lewd.ParseLinks(text)

		if linksFound {
			s.ChannelMessageSend(m.ChannelID, reply)
			return
		}
	}

	// Accept the legacy mention as well and trim it off from text
	if strings.HasPrefix(strings.ToLower(text), "lewdbot, ") {
		text = text[9:]
		isMentioned = true
	}

	if channel.IsPrivate || isMentioned {
		reply := brain.Reply(text)
		reply = regex.Lewdbot.ReplaceAllString(reply, m.Author.Username)

		// Log our reply
		fmt.Printf("%20s %20s %20s > %s\n", channel.Name, time.Now().Format(time.Stamp), s.State.User.Username, reply)

		s.ChannelMessageSend(m.ChannelID, reply)
	} else if !config.GuildIsDumb(channel.GuildID) {
		// Just learn
		brain.Learn(text, true)
	}
}
Пример #19
0
func banUser(s *discordgo.Session, guild *discordgo.Guild,
	author *discordgo.Member, channelID string, arr []string) {
	if len(arr) == 4 && len(arr[2]) == 21 &&
		checkForPermissions(s, channelID, author.Roles) {
		arr[2] = arr[2][2 : len(arr[2])-1]
		userRole := ""
		username := ""
		for _, member := range guild.Members {
			if arr[2] == member.User.ID {
				username = member.User.Username
				userRole = member.Roles[0]
				break
			}
		}
		duration, _ := (strconv.Atoi(arr[3]))

		pgDb := dbConn()
		tx, err := pgDb.Begin()
		checkErr(err)

		rows, err := tx.Query(
			`SELECT duration FROM bans 
			WHERE user_id = $1`, arr[2])
		checkErr(err)

		var (
			dur int
			i   int
		)

		for rows.Next() {
			i++
			rows.Scan(&dur)
		}
		rows.Close()
		if i == 0 {

			_, err = tx.Exec(
				`INSERT INTO bans(name, time_stamp, duration,
				guild_id, role_id, user_id)
				VALUES($1, $2, $3, $4, $5, $6)`,
				username, int64(time.Now().Unix()),
				duration*60, guild.ID, userRole, arr[2])
			checkErr(err)

			s.GuildMemberEdit(guild.ID, arr[2], []string{roleBannedId})
			for _, c := range guild.Channels {
				if c.Name == "AFK" {
					s.GuildMemberMove(guild.ID, arr[2], c.ID)
					break
				}
			}
			s.ChannelMessageSend(channelID,
				fmt.Sprintf(
					"User %s has been temporary banned for %d minute(s)",
					username, duration))
		} else {
			_, err = tx.Exec(
				`UPDATE bans SET duration = $1
				WHERE user_id = $2`, dur+duration*60, arr[2])
			checkErr(err)

			s.ChannelMessageSend(channelID,
				fmt.Sprintf(
					"Users %s temporary ban has been extended by %d minute(s)",
					username, duration))
		}
		tx.Commit()
		pgDb.Close()
	} else {
		s.ChannelMessageSend(channelID,
			fmt.Sprintf("Please check the parameters"))
	}
}
Пример #20
0
func voiceStateUpdateCallback(s *discordgo.Session, v *discordgo.VoiceStateUpdate) {
	log.Debugf("Voice bonus On voice state update: %v", v.VoiceState)

	// Check if it was a part
	if v.ChannelID == "" {
		return
	}

	guild, _ := s.State.Guild(v.GuildID)
	if guild == nil {
		log.WithFields(log.Fields{
			"guild": v.GuildID,
		}).Warning("Failed to grab guild")
		return
	}

	member, _ := s.State.Member(v.GuildID, v.UserID)
	if member == nil {
		log.WithFields(log.Fields{
			"member": member,
		}).Warning("Failed to grab member")
		return
	}

	if member.User.Bot {
		return
	}

	c := voicebonusCollection{ramendb.GetCollection(v.GuildID, ConfigName)}
	if !c.Enabled() {
		return
	}

	span := c.Timespan()
	if span == nil {
		log.Error("Timespan was nil for %v", guild.ID)
		return
	}

	log.Debugf("Timespan is: %v", span)

	currentTime := time.Now().UTC()

	year, month, day := currentTime.Date()
	weekday := currentTime.Weekday()
	nextDay := day + utils.GetDaysTillWeekday(int(weekday), span.Weekday)
	startDate := time.Date(year, month, nextDay, span.Hour, span.Minute, 0, 0, time.UTC)
	previousDate := time.Date(year, month, nextDay-7, span.Hour, span.Minute, 0, 0, time.UTC)

	log.Debugf("Start Date is: %v", startDate)
	log.Debugf("Previous Date is: %v", previousDate)

	lastJoinTime := time.Unix(getUserLastJoin(v.GuildID, v.UserID), 0)

	log.Debugf("Last join date: %v, now: %v", lastJoinTime, currentTime)

	if currentTime.Before(startDate) {
		// Check for previous week parts. Needed if timespan crosses UTC midnight
		if time.Since(previousDate).Hours() > float64(span.Duration) ||
			lastJoinTime.After(previousDate) {

			log.Debugf("Previous time status: %v %v",
				time.Since(previousDate).Hours() > float64(span.Duration),
				lastJoinTime.After(previousDate))
			return
		}
	} else if time.Since(startDate).Hours() > float64(span.Duration) ||
		lastJoinTime.After(startDate) {

		log.Debugf("Current time status: %v %v",
			time.Since(startDate).Hours() > float64(span.Duration),
			lastJoinTime.After(startDate))
		return
	}

	log.Debug("Giving bits for join")
	bits.AddBits(s, v.GuildID, v.UserID, c.Amount(), "Voice join bonus", true)

	username := utils.GetPreferredName(guild, v.UserID)
	message := fmt.Sprintf(joinMessage, username, c.Amount(),
		bits.GetBits(v.GuildID, v.UserID))

	channel, _ := s.UserChannelCreate(v.UserID)
	s.ChannelMessageSend(channel.ID, message)

	updateUserLastJoin(v.GuildID, v.UserID, currentTime.Unix())
}
Пример #21
0
func SBProcessCommand(s *discordgo.Session, m *discordgo.Message, info *GuildInfo, t int64, isdbguild bool, isdebug bool, err error) {
	// Check if this is a command. If it is, process it as a command, otherwise process it with our modules.
	if len(m.Content) > 1 && m.Content[0] == '!' && (len(m.Content) < 2 || m.Content[1] != '!') { // We check for > 1 here because a single character can't possibly be a valid command
		private := info == nil
		isfree := private
		if info != nil {
			_, isfree = info.config.FreeChannels[m.ChannelID]
		}
		_, isOwner := sb.Owners[SBatoi(m.Author.ID)]
		isSelf := m.Author.ID == sb.SelfID
		if !isSelf && info != nil {
			ignore := false
			ApplyFuncRange(len(info.hooks.OnCommand), func(i int) {
				if info.ProcessModule(m.ChannelID, info.hooks.OnCommand[i]) {
					ignore = ignore || info.hooks.OnCommand[i].OnCommand(info, m)
				}
			})
			if ignore && !isOwner && m.Author.ID != info.Guild.OwnerID { // if true, a module wants us to ignore this command
				return
			}
		}

		args := ParseArguments(m.Content[1:])
		arg := strings.ToLower(args[0])
		if info == nil {
			info = getDefaultServer(SBatoi(m.Author.ID))
		}
		if info == nil {
			gIDs := sb.db.GetUserGuilds(SBatoi(m.Author.ID))
			_, independent := sb.NonServerCommands[arg]
			if !independent && len(gIDs) != 1 {
				s.ChannelMessageSend(m.ChannelID, "```Cannot determine what server you belong to! Use !defaultserver to set which server I should use when you PM me.```")
				return
			}
			info = sb.guilds[gIDs[0]]
			if info == nil {
				s.ChannelMessageSend(m.ChannelID, "```I haven't been loaded on that server yet!```")
				return
			}
		}
		alias, ok := info.config.Aliases[arg]
		if ok {
			nargs := ParseArguments(alias)
			args = append(nargs, args[1:]...)
			arg = strings.ToLower(args[0])
		}
		c, ok := info.commands[arg]
		if ok {
			if isdbguild {
				sb.db.Audit(AUDIT_TYPE_COMMAND, m.Author, strings.Join(args, " "), SBatoi(info.Guild.ID))
			}
			isOwner = isOwner || m.Author.ID == info.Guild.OwnerID
			cmdname := strings.ToLower(c.Name())
			cch := info.config.Command_channels[cmdname]
			_, disabled := info.config.Command_disabled[cmdname]
			_, restricted := sb.RestrictedCommands[cmdname]
			if disabled && !isOwner && !isSelf {
				return
			}
			if restricted && !isdbguild {
				return
			}
			if !private && len(cch) > 0 && !isSelf {
				_, reverse := cch["!"]
				_, ok = cch[m.ChannelID]
				if ok == reverse {
					return
				}
			}
			if err != nil || (!isdebug && !isfree && !isSelf) { // debug channels aren't limited
				if info.commandlimit.check(info.config.Commandperduration, info.config.Commandmaxduration, t) { // if we've hit the saturation limit, post an error (which itself will only post if the error saturation limit hasn't been hit)
					info.log.Error(m.ChannelID, "You can't input more than "+strconv.Itoa(info.config.Commandperduration)+" commands every "+TimeDiff(time.Duration(info.config.Commandmaxduration)*time.Second)+"!")
					return
				}
				info.commandlimit.append(t)
			}
			if !isOwner && !isSelf && !info.UserHasAnyRole(m.Author.ID, info.config.Command_roles[cmdname]) {
				info.log.Error(m.ChannelID, "You don't have permission to run this command! Allowed Roles: "+info.GetRoles(c))
				return
			}

			cmdlimit := info.config.Command_limits[cmdname]
			if !isfree && cmdlimit > 0 && !isSelf {
				lastcmd := info.command_last[m.ChannelID][cmdname]
				if !RateLimit(&lastcmd, cmdlimit) {
					info.log.Error(m.ChannelID, "You can only run that command once every "+TimeDiff(time.Duration(cmdlimit)*time.Second)+"!")
					return
				}
				if len(info.command_last[m.ChannelID]) == 0 {
					info.command_last[m.ChannelID] = make(map[string]int64)
				}
				info.command_last[m.ChannelID][cmdname] = t
			}

			result, usepm := c.Process(args[1:], m, info)
			if len(result) > 0 {
				targetchannel := m.ChannelID
				if usepm && !private {
					channel, err := s.UserChannelCreate(m.Author.ID)
					info.log.LogError("Error opening private channel: ", err)
					if err == nil {
						targetchannel = channel.ID
						if rand.Float32() < 0.01 {
							info.SendMessage(m.ChannelID, "Check your ~~privilege~~ Private Messages for my reply!")
						} else {
							info.SendMessage(m.ChannelID, "```Check your Private Messages for my reply!```")
						}
					}
				}

				for len(result) > 1999 { // discord has a 2000 character limit
					if result[0:3] == "```" {
						index := strings.LastIndex(result[:1996], "\n")
						if index < 10 { // Ensure we process at least 10 characters to prevent an infinite loop
							index = 1996
						}
						info.SendMessage(targetchannel, result[:index]+"```")
						result = "```" + result[index:]
					} else {
						index := strings.LastIndex(result[:1999], "\n")
						if index < 10 {
							index = 1999
						}
						info.SendMessage(targetchannel, result[:index])
						result = result[index:]
					}
				}
				info.SendMessage(targetchannel, result)
			}
		} else {
			if !info.config.IgnoreInvalidCommands {
				info.log.Error(m.ChannelID, "Sorry, "+args[0]+" is not a valid command.\nFor a list of valid commands, type !help.")
			}
		}
	} else if info != nil { // If info is nil this was sent through a private message so just ignore it completely
		ApplyFuncRange(len(info.hooks.OnMessageCreate), func(i int) {
			if info.ProcessModule(m.ChannelID, info.hooks.OnMessageCreate[i]) {
				info.hooks.OnMessageCreate[i].OnMessageCreate(info, m)
			}
		})
	}
}
Пример #22
0
Файл: main.go Проект: Xwth/h-bot
func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
	var deleteMessageAuthor bool
	deleteMessageAuthor = true

	text := m.ContentWithMentionsReplaced()

	if m.Author.ID == s.State.User.ID {
		// Ignore self
		return
	}

	channel, _ := s.State.Channel(m.ChannelID)

	if channel.IsPrivate {
		channel.Name = "direct message"
	}

	if strings.HasPrefix(text, "!") || strings.HasPrefix(text, ".") || strings.HasPrefix(text, "bot.") {
		// Ignore shit meant for other bots
		return
	}

	isMentioned := isUserMentioned(s.State.User, m.Mentions) || m.MentionEveryone

	text = strings.Replace(text, "@everyone", "", -1)

	// Log cleaned up message
	fmt.Printf("%20s %20s %20s > %s\n", channel.Name, time.Now().Format(time.Stamp), m.Author.Username, text)

	if shouldIgnore(m.Author) {
		return
	}

	c := config.Get()

	for _, ChannelID := range c.Channels {
		if m.ChannelID == ChannelID {
			linksFound, reply := lewd.ParseLinks(text)

			if linksFound {
				content := strings.Join(lewd.ContentLinks(m.Content)[:], " ")
				if deleteMessageAuthor {
					s.ChannelMessageDelete(m.ChannelID, m.ID)
				}
				s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("%s: %s\n%s", m.Author.Username, content, reply))
				return
			}
		}
	}

	// Accept the legacy mention as well and trim it off from text
	if strings.HasPrefix(strings.ToLower(text), "lewdbot, ") {
		text = text[9:]
		isMentioned = true
	}

	if channel.IsPrivate || isMentioned {
		var reply string
		reply = regex.Lewdbot.ReplaceAllString(reply, m.Author.Username)

		// Log our reply
		fmt.Printf("%20s %20s %20s > %s\n", channel.Name, time.Now().Format(time.Stamp), s.State.User.Username, reply)

		s.ChannelMessageSend(m.ChannelID, reply)
	}
}
Пример #23
0
//discordMsgHandler is a handler function for incomming discord messages
func discordMsgHandler(s *discordgo.Session, m *discordgo.MessageCreate) {
	botMessages++
	//Split messages into arguments
	args := strings.Fields(m.Content)
	//Check if author is admin
	boss := m.Author.ID == discordCfg.Boss
	//Check if second argument is this bots name
	botcheck := (len(args) > 1 && strings.ToUpper(args[1]) == discordCfg.Name)
	//Check if message is relevant to the bot
	//i.e message starts with '!' followed by a word
	relevant := relevantRegex.MatchString(m.Content)

	//If message is relevant process it otherwise leave this function
	if relevant {
		botResponses++
		switch strings.ToUpper(args[0]) {

		//!HELP [string]
		//Can optionally include bots name as second argument
		case "!HELP":
			if len(args) > 1 {
				if strings.ToUpper(args[1]) == discordCfg.Name {
					s.ChannelMessageSend(m.ChannelID, discordHelp)
				}
			} else {
				s.ChannelMessageSend(m.ChannelID, discordHelp)
			}

		//!SUB anime.id
		//anime.id is the id of the anime (string with length of 3 chars)
		case "!SUB":
			if len(args) >= 2 {
				newAnime := anime{ID: strings.ToLower(args[1])}
				if newAnime.Exists() {
					newAnime.AddSub(m.Author.ID)
					s.ChannelMessageSend(m.ChannelID,
						"Successfully subscribed to "+newAnime.Name)
				} else {
					s.ChannelMessageSend(m.ChannelID, "Invalid ID")
				}
			}

		//!UNSUB anime.id
		//anime.id is the id of the anime (string with length of 3 chars)
		case "!UNSUB":
			if len(args) >= 2 {
				newAnime := anime{ID: strings.ToLower(args[1])}
				if newAnime.Exists() {
					newAnime.RemoveSub(m.Author.ID)
					s.ChannelMessageSend(m.ChannelID,
						"Successfully unsubscribed from "+newAnime.Name)
				} else {
					s.ChannelMessageSend(m.ChannelID, "Invalid ID")
				}
			}

		//!UPTIME [string]
		//Can optionally include bots name as second argument
		case "!UPTIME":
			if len(args) > 1 {
				if strings.ToUpper(args[1]) == discordCfg.Name {
					s.ChannelMessageSend(m.ChannelID, "Current uptime is "+getUptime())
				}
			} else {
				s.ChannelMessageSend(m.ChannelID, "Current uptime is "+getUptime())
			}

		//!W string
		//Looks up weather at the the location string
		case "!W":
			if len(args) > 1 {
				var location string
				for i := 1; i < len(args); i++ {
					location += args[i] + " "
				}
				location = location[:len(location)-1]
				s.ChannelMessageSend(m.ChannelID, getWeather(location))
			}

		//!P string
		//Sets the 'currently playing' state of the bot
		//will only work for admin of the bot
		case "!P":
			if boss {
				if len(args) > 1 {
					var game string
					for i := 1; i < len(args); i++ {
						game += args[i] + " "
					}
					game = game[:len(game)-1]
					discord.UpdateStatus(0, game)
				} else {
					discord.UpdateStatus(0, "")
				}
			}

		//!INFO [string]
		//Can optionally include bots name as second argument
		//Lists bot usage and general information
		case "!INFO":
			if len(args) > 1 {
				if strings.ToUpper(args[1]) == discordCfg.Name {
					s.ChannelMessageSend(m.ChannelID, getInfo())
				}
			} else {
				s.ChannelMessageSend(m.ChannelID, getInfo())
			}

		//!GUILDS [string]
		//Can optionally include bots name as second argument
		//Lists all the guilds this bot is a part of
		//will only work for admin of the bot
		//FIXME
		case "!GUILDS":
			if boss && (botcheck || len(args) == 1) {
				s.ChannelMessageSend(m.ChannelID,
					fmt.Sprintf("Currently in %d guilds: %s",
						len(discordCfg.Guilds), strings.Join(discordCfg.Guilds, ", ")))
			}
		}
	}
}
Пример #24
0
func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
	if m.Author.Bot {
		return
	}

	chanl, err := s.Channel(m.ChannelID)
	if err != nil {
		return
	}

	guild, _ := s.Guild(chanl.GuildID)
	var author *discordgo.Member

	if guild != nil {
		author, _ = s.GuildMember(guild.ID, m.Author.ID)
	}

	checkLink(s, m.Content, chanl.ID, chanl.LastMessageID)

	messageContents <- m

	if len(m.Content) > 21 && len(m.Mentions) > 0 &&
		m.Mentions[len(m.Mentions)-1].Username == "MrDestructoid" {
		arr := strings.Fields(m.Content)
		switch arr[1] {
		case "BD":
			bdLinks(s, m.ChannelID)
		// case "state":
		// for _, i := range guild.VoiceStates {
		// fmt.Println(i.UserID)
		// }

		// case "bot":
		// var mem runtime.MemStats
		// runtime.ReadMemStats(&mem)
		// fmt.Println(mem.HeapAlloc)

		case "myid":
			s.ChannelMessageSend(m.ChannelID,
				fmt.Sprintf("```\n%v\n```", m.Author.ID))
		// //---------------- NO WAY TO UTILIZE -----------
		// case "joinchannel":
		// ch := make(chan string)
		// fmt.Println(strings.Join(arr[2:], " "))
		// if findNjoinChannel(s, guild.ID, guild.Channels,
		// strings.Join(arr[2:], " "), ch) {
		// echo(dgv, ch)
		// fmt.Println("opened")
		// }
		// //---------------- NO WAY TO UTILIZE ----------

		case "channels":
			var str string = fmt.Sprintf("\n%-20s\t%-5s\tID", "Name", "Type")
			for _, c := range guild.Channels {
				str += fmt.Sprintf("\n%-20s\t%-5s\t%s", c.Name, c.Type, c.ID)
			}
			s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("```%s```", str))

		case "updateroles":
			updateRolesToDB(s, guild.ID)

		case "guild":
			var owner string
			for _, i := range guild.Members {
				if i.User.ID == guild.OwnerID {
					owner = i.User.Username
				}
			}
			s.ChannelMessageSend(m.ChannelID, fmt.Sprintf(
				"```**Guild information** \nName: %s\nOwner: %s\nID: %s\nRegion: %s\nHas members: %d```",
				guild.Name, owner, guild.ID, guild.Region, len(guild.Members)))

		case "quit":
			if checkForPermissions(s, chanl.ID, author.Roles) {
				quit = true
			}

		case "ban":
			banUser(s, guild, author, m.ChannelID, arr)

		case "unban":
			manualUnban(s, chanl.ID, author.Roles, arr)

		case "bannedusers":
			bannedUsers(s, m)

		default:
			s.ChannelMessageSend(chanl.ID, fmt.Sprintf("No such command"))
		}

	}
}
Пример #25
-13
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()
}