go-discord-bot / bot / bot.go
bot.go
Raw
package bot

import (
	"encoding/json"
	"fmt"
	"log"
	"os"
	"strings"

	dg "github.com/bwmarrin/discordgo"
	"github.com/mr1hm/go-discord-bot/internal/config"
	"github.com/mr1hm/go-discord-bot/internal/tft"
)

type UserMatchData struct {
	MatchID           string
	PUUID             string
	Username          string
	Placement         int
	PlayersEliminated int
	TotalDmgToPlayers int
}

type UserMatchIDs struct {
	MatchIDs []string
}

var (
	BotId       string
	bot_session *dg.Session

	BotInfoLogger = log.New(os.Stdout, "INFO:\t", log.Ldate|log.Ltime)
	BotErrLogger  = log.New(os.Stdout, "ERROR:\t", log.Ldate|log.Ltime)

	allowedDiscordUsers = map[string]string{
		"300470010936033282": "defter",
		"165294847551340544": "nukleas",
		"374758145685323776": "lavem",
		"588501940820901889": "samuelz",
	}
)

func Start() error {
	// Create new bot session
	bot_session, err := dg.New("Bot " + config.Token)
	if err != nil {
		fmt.Println(err.Error())
		return err
	}

	// Make bot a user using User function
	u, err := bot_session.User("@me")
	if err != nil {
		fmt.Println(err.Error())
		return err
	}

	// Store Bot ID from User to BotId
	BotId = u.ID

	// Add handler function to handle our messages using AddHandler from `discordgo` package
	bot_session.AddHandler(messageHandler)

	err = bot_session.Open()
	if err != nil {
		fmt.Println(err.Error())
		return err
	}
	fmt.Println("Bot is running!")

	return nil
}

func messageHandler(dgs *dg.Session, m *dg.MessageCreate) {
	// Only users registered with this Bot will be allowed to use it
	current_user := ""
	for id, username := range allowedDiscordUsers {
		if m.Author.ID == id {
			current_user = username
		}
	}
	// Bot musn't reply to its own messages. To confirm it we perform this check
	if m.Author.ID == BotId || current_user == "" {
		return
	}

	if current_user == "" {
		if _, err := dgs.ChannelMessageSend(m.ChannelID, "Sorry, only registered users are allowed to use this bot"); err != nil {
			fmt.Println(err.Error())
		}
	}

	// If we message ping to our bot in our discord it will return us pong
	if m.Content == "ping" {
		if _, err := dgs.ChannelMessageSend(m.ChannelID, "pong"); err != nil {
			fmt.Println(err.Error())
		}
	}

	split_msg := strings.Split(m.Content, " ")
	switch split_msg[0] {
	case "debug":
		bot_resp := fmt.Sprintf("Showing currently stored data: %+v", tft.UserData.Data)
		if _, err := dgs.ChannelMessageSend(m.ChannelID, bot_resp); err != nil {
			fmt.Println(err.Error())
		}
	case "help":
		bot_resp := "Here are some commands to help you get started:\n`get {TFT GameName} | optional{matches/matchinfo} | if matchinfo was used{MatchID}`"
		if _, err := dgs.ChannelMessageSend(m.ChannelID, bot_resp); err != nil {
			fmt.Println(err.Error())
		}
	case "register":
		if len(allowedDiscordUsers) >= 8 {
			if _, err := dgs.ChannelMessageSend(m.ChannelID, "Sorry, registration is currently closed since we're full"); err != nil {
				fmt.Println(err.Error())
			}
			return
		}

		if _, err := dgs.ChannelMessageSend(m.ChannelID, "Sorry, registration is currently unavailable"); err != nil {
			fmt.Println(err.Error())
		}
		return
	case "get":
		len_split_msg := len(split_msg)
		if len_split_msg == 1 {
			if _, err := dgs.ChannelMessageSend(m.ChannelID,
				"Sorry you must enter a username for me to look up. "+
					"If you're unsure which usernames are available please type in `get users` to see a list"); err != nil {
				fmt.Println(err.Error())
			}
			return
		}
		if len_split_msg == 2 && split_msg[1] != "users" {
			bot_resp := Fun(split_msg[1])
			if _, err := dgs.ChannelMessageSend(m.ChannelID, bot_resp); err != nil {
				fmt.Println(err.Error())
			}
		}
		if split_msg[1] == "users" {
			bot_resp, err := ListUsers()
			if err != nil {
				fmt.Println(err.Error())
			}
			if _, err := dgs.ChannelMessageSend(m.ChannelID, bot_resp); err != nil {
				fmt.Println(err.Error())
			}
		} else {
			// Handle which user we are targeting
			if len_split_msg == 3 {
				// List matches by MatchID
				matches, _, err := GetUserTFTData(split_msg[1], split_msg[2])
				if err != nil {
					if _, err := dgs.ChannelMessageSend(m.ChannelID, "Sorry I didn't find anyone by that username..."); err != nil {
						fmt.Println(err.Error())
					}
					fmt.Println(err.Error())
					return
				}

				b, err := json.Marshal(matches)
				if err != nil {
					fmt.Println(err.Error())
					return
				}
				if _, err := dgs.ChannelMessageSend(m.ChannelID, "Please select a match from the following by replying with `get {username} matchinfo {MatchID}`:\n"+string(b)); err != nil {
					fmt.Println(err.Error())
				}
			} else if len_split_msg == 4 {
				// Get player specific data by MatchID
				_, matchinfo, err := GetUserTFTData(split_msg[1], split_msg[2], split_msg[3])
				if err != nil {
					fmt.Printf("Error getting match info: %v\n", err.Error())
				}

				if _, err := dgs.ChannelMessageSend(m.ChannelID, "__**MatchInfo**__\n"+matchinfo); err != nil {
					fmt.Println(err.Error())
				}
			}
		}
		break
	default:
		return
	}
}