Example #1
0
// usernameExistsForChat checks if a username exists for a given chat.
// This returns false if the userID exists but the username has changed.
func (j *JarvisBot) usernameExistsForChat(chat, sender *telebot.User) bool {
	res := false
	// Guard against possibility that chat isn't a group chat.
	// We're lazy here, returning true implies that we don't want to run a save.
	if !chat.IsGroupChat() {
		return true
	}

	groupID, senderID, username := strconv.Itoa(chat.ID), strconv.Itoa(sender.ID), sender.Username

	j.db.View(func(tx *bolt.Tx) error {
		b := tx.Bucket(group_usernames_bucket_name)
		gb := b.Bucket([]byte(groupID))
		if gb == nil {
			return nil
		}

		v := gb.Get([]byte(senderID))
		if v != nil && string(v) == username {
			res = true
			return nil
		}

		return nil
	})

	return res
}
Example #2
0
// getAllUsernamesForChat returns all usernames for a chat, sans the sender's.
func (j *JarvisBot) getAllUsernamesForChat(chat, sender *telebot.User) (string, error) {
	uArray, groupID, senderID := []string{}, strconv.Itoa(chat.ID), strconv.Itoa(sender.ID)

	if !chat.IsGroupChat() {
		return "", fmt.Errorf("chat %s is not a group chat!", groupID)
	}

	err := j.db.View(func(tx *bolt.Tx) error {
		b := tx.Bucket(group_usernames_bucket_name)
		gb := b.Bucket([]byte(groupID))
		if gb == nil {
			return fmt.Errorf("error retrieving bucket for group ID %s", groupID)
		}

		gb.ForEach(func(k, v []byte) error {
			key, curr := string(k), string(v)
			if key != senderID && key != timestampKey && key != countKey {
				uArray = append(uArray, curr)
			}
			return nil
		})
		return nil
	})

	if err != nil {
		return "", err
	}

	res := ""
	for _, v := range uArray {
		res = res + "@" + v + " "
	}
	return res, nil
}
Example #3
0
// saveUsernameSafely checks if a user exists in a given group chat, and saves if he/she
// doesn't currently exist.
// We try as much as possible to avoid opening a Read-Write transaction, because
// Bolt can only have one Read-Write transaction at any time.
func (j *JarvisBot) saveUsernameSafely(chat, sender *telebot.User) {
	if sender.Username == "" || !chat.IsGroupChat() {
		return
	}

	if !j.usernameExistsForChat(chat, sender) {
		err := j.saveUserToDB(chat, sender)
		if err != nil {
			j.log.Printf("[%s] error saving user %s to group %s: %s", time.Now().Format(time.RFC3339), sender.Username, chat.Title, err)
		}
	}
}
Example #4
0
// updateLastSentTime updates the last sent time for a given chat.
func (j *JarvisBot) updateLastSentTime(chat *telebot.User) error {
	if !chat.IsGroupChat() {
		return fmt.Errorf("chat is not a group chat!")
	}

	groupID := strconv.Itoa(chat.ID)
	err := j.db.Update(func(tx *bolt.Tx) error {
		b := tx.Bucket(group_usernames_bucket_name)
		gb := b.Bucket([]byte(groupID))
		if gb == nil {
			return fmt.Errorf("invariant error - group bucket does not exist, yet attempt to update timestamp")
		}

		timeString := gb.Get([]byte(timestampKey))
		if timeString == nil {
			return resetTime(gb)
		} else {
			lastTime, err := time.Parse(time.RFC3339, string(timeString))
			if err != nil {
				return err
			}
			if time.Since(lastTime) > time.Hour {
				return resetTime(gb)
			} else {
				countBytes := gb.Get([]byte(countKey))
				if countBytes == nil {
					return fmt.Errorf("invariant error - timestamp was saved but no count exists")
				}
				lastCount, err := strconv.Atoi(string(countBytes))
				if err != nil {
					return err
				}
				newCount := strconv.Itoa(lastCount + 1)
				err = gb.Put([]byte(countKey), []byte(newCount))
				if err != nil {
					return err
				}
			}
		}

		return nil
	})

	return err
}