package twitchbot import "log" type EventHandler struct { messageHandlers []func(*Bot, *Message) } type Bot struct { client *Client host string onLogin func(*Bot) events EventHandler channels []string } type User struct { ID string Name string } type Message struct { ID string Channel string User *User Message string Bot *Bot } func ParseMessage(command *Command, bot *Bot) *Message { return &Message{ ID: command.Tags["id"], Channel: command.Args[0][1:], User: &User{ID: command.Tags["user-id"], Name: command.Tags["display-name"]}, Message: command.Suffix, Bot: bot, } } func NewBot(token string, nick string, channels []string) *Bot { client := Client{Token: token, Nick: nick} return &Bot{client: &client, host: "irc.chat.twitch.tv:6667", events: EventHandler{}, channels: channels} } func (message *Message) Reply(msg string) error { err := message.Bot.SendMessage(&Message{Message: msg, Channel: message.Channel}) if err != nil { return err } return nil } func (message *Message) Delete() error { err := message.Bot.DeleteMessage(&Message{ID: message.ID, Channel: message.Channel}) if err != nil { return err } return nil } func (message *Message) Ban() error { err := message.Bot.BanUser(message.Channel, message.User.Name) if err != nil { return err } return nil } func (event *EventHandler) configure(bot *Bot) { bot.client.AddHandler("PRIVMSG", func(command *Command) bool { message := ParseMessage(command, bot) for _, handler := range event.messageHandlers { go handler(bot, message) } return true }) } func (bot *Bot) OnLogin(f func(*Bot)) { bot.onLogin = f } func (bot *Bot) SendMessage(message *Message) error { err := bot.client.Send(&Command{Command: "PRIVMSG", Args: []string{"#" + message.Channel}, Suffix: message.Message}) if err != nil { return err } return nil } func (bot *Bot) DeleteMessage(message *Message) error { err := bot.SendMessage(&Message{Channel: message.Channel, Message: "/delete " + message.ID}) if err != nil { return err } return nil } func (bot *Bot) Join(channel string) error { err := bot.client.Join("#" + channel) if err != nil { return err } return nil } func (bot *Bot) BanUser(channel string, user string) error { err := bot.SendMessage(&Message{Channel: channel, Message: "/ban " + user}) if err != nil { return err } return nil } func (bot *Bot) OnMessage(f func(*Bot, *Message)) { bot.events.messageHandlers = append(bot.events.messageHandlers, f) } func (bot *Bot) GetClient() *Client { return bot.client } func (bot *Bot) Run() { for { err := bot.Start() if err != nil { log.Printf("Bot error: %s\n", err) } } } func (bot *Bot) Start() error { defer bot.client.Close() err := bot.client.Connect(bot.host) if err != nil { return err } err = bot.client.Auth() if err != nil { return err } bot.events.configure(bot) bot.client.AddHandler("PING", func(command *Command) bool { err := bot.client.Send(&Command{Command: "PONG", Suffix: "tmi.twitch.tv"}) if err != nil { return false } return true }) bot.client.AddHandler("376", func(command *Command) bool { err = bot.GetClient().CapReq("twitch.tv/tags twitch.tv/commands") if err != nil { return false } for _, channel := range bot.channels { err = bot.Join(channel) if err != nil { return false } } if bot.onLogin != nil { bot.onLogin(bot) } return true }) err = bot.client.Handle() if err != nil { return err } return nil }