From 078f9451a76257bf0456805b1ac576d8f3f09a50 Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Sun, 2 Jan 2022 01:30:16 +0100 Subject: [PATCH 01/35] start rewrite --- cmd/bot/banphrase.go | 78 ---- cmd/bot/banphrase_test.go | 30 -- cmd/bot/bot.go | 57 --- cmd/{ => bot}/main.go | 29 +- cmd/main_test.go | 18 - pkg/api/aiden/aiden.go | 32 -- pkg/api/aiden/aiden_test.go | 21 - pkg/api/api_test.go | 19 - pkg/api/currency.go | 48 --- pkg/api/ivr/emotelookup_test.go | 41 -- pkg/api/ivr/emoteloookup.go | 47 -- pkg/api/ivr/firstline.go | 47 -- pkg/api/ivr/firstline_test.go | 16 - pkg/api/ivr/followage.go | 50 --- pkg/api/ivr/followage_test.go | 18 - pkg/api/ivr/profilepicture.go | 43 -- pkg/api/ivr/profilepicture_test.go | 18 - pkg/api/ivr/randomquote.go | 47 -- pkg/api/ivr/subage.go | 69 --- pkg/api/ivr/userid.go | 43 -- pkg/api/ivr/userid_test.go | 18 - pkg/api/ivr/whois.go | 77 ---- pkg/api/ivr/whois_test.go | 16 - pkg/api/numbersapi.go | 42 -- pkg/api/randomcat.go | 32 -- pkg/api/randomdog.go | 32 -- pkg/api/randomduck.go | 32 -- pkg/api/randomfox.go | 33 -- pkg/api/randomxkcd.go | 36 -- pkg/api/xkcd.go | 29 -- pkg/commands/botstatus.go | 22 - pkg/commands/bttv.go | 14 - pkg/commands/bttvemotes.go | 20 - pkg/commands/channellist.go | 11 - pkg/commands/coinflip.go | 17 - pkg/commands/color.go | 53 --- pkg/commands/commands_test.go | 18 - pkg/commands/commandslist.go | 10 - pkg/commands/currency.go | 18 - pkg/commands/echo.go | 9 - pkg/commands/eightball.go | 19 - pkg/commands/emotelookup.go | 21 - pkg/commands/ffz.go | 14 - pkg/commands/ffzemotes.go | 20 - pkg/commands/fill.go | 27 -- pkg/commands/firstline.go | 20 - pkg/commands/followage.go | 20 - pkg/commands/game.go | 23 - pkg/commands/godocs.go | 14 - pkg/commands/help.go | 10 - pkg/commands/number.go | 20 - pkg/commands/osrs.go | 15 - pkg/commands/personal/arch.go | 17 - pkg/commands/personal/farm.go | 9 - pkg/commands/personal/justinfan.go | 10 - pkg/commands/personal/personal_test.go | 18 - pkg/commands/personal/rave.go | 13 - pkg/commands/personal/streamlink.go | 10 - pkg/commands/personal/xset.go | 10 - pkg/commands/personal/zneix.go | 10 - pkg/commands/ping.go | 19 - pkg/commands/pingme.go | 14 - pkg/commands/profilepicture.go | 20 - pkg/commands/pyramid.go | 52 --- pkg/commands/randomcat.go | 14 - pkg/commands/randomdog.go | 14 - pkg/commands/randomduck.go | 14 - pkg/commands/randomfox.go | 14 - pkg/commands/randomquote.go | 21 - pkg/commands/randomxkcd.go | 14 - pkg/commands/robohash.go | 16 - pkg/commands/seventv.go | 14 - pkg/commands/subage.go | 21 - pkg/commands/thumbnail.go | 18 - pkg/commands/title.go | 23 - pkg/commands/uptime.go | 22 - pkg/commands/userid.go | 13 - pkg/commands/weather.go | 23 - pkg/commands/whois.go | 13 - pkg/commands/xd.go | 8 - pkg/commands/xkcd.go | 14 - pkg/config/config.go | 40 -- pkg/config/config_test.go | 20 - pkg/handlers/command.go | 568 ------------------------- pkg/handlers/handlers_test.go | 19 - pkg/handlers/privatemessage.go | 49 --- pkg/humanize/time.go | 13 - pkg/humanize/time_test.go | 30 -- pkg/utils/utils.go | 79 ---- pkg/utils/utils_test.go | 39 -- 90 files changed, 3 insertions(+), 2865 deletions(-) delete mode 100644 cmd/bot/banphrase.go delete mode 100644 cmd/bot/banphrase_test.go delete mode 100644 cmd/bot/bot.go rename cmd/{ => bot}/main.go (56%) delete mode 100644 cmd/main_test.go delete mode 100644 pkg/api/aiden/aiden.go delete mode 100644 pkg/api/aiden/aiden_test.go delete mode 100644 pkg/api/api_test.go delete mode 100644 pkg/api/currency.go delete mode 100644 pkg/api/ivr/emotelookup_test.go delete mode 100644 pkg/api/ivr/emoteloookup.go delete mode 100644 pkg/api/ivr/firstline.go delete mode 100644 pkg/api/ivr/firstline_test.go delete mode 100644 pkg/api/ivr/followage.go delete mode 100644 pkg/api/ivr/followage_test.go delete mode 100644 pkg/api/ivr/profilepicture.go delete mode 100644 pkg/api/ivr/profilepicture_test.go delete mode 100644 pkg/api/ivr/randomquote.go delete mode 100644 pkg/api/ivr/subage.go delete mode 100644 pkg/api/ivr/userid.go delete mode 100644 pkg/api/ivr/userid_test.go delete mode 100644 pkg/api/ivr/whois.go delete mode 100644 pkg/api/ivr/whois_test.go delete mode 100644 pkg/api/numbersapi.go delete mode 100644 pkg/api/randomcat.go delete mode 100644 pkg/api/randomdog.go delete mode 100644 pkg/api/randomduck.go delete mode 100644 pkg/api/randomfox.go delete mode 100644 pkg/api/randomxkcd.go delete mode 100644 pkg/api/xkcd.go delete mode 100644 pkg/commands/botstatus.go delete mode 100644 pkg/commands/bttv.go delete mode 100644 pkg/commands/bttvemotes.go delete mode 100644 pkg/commands/channellist.go delete mode 100644 pkg/commands/coinflip.go delete mode 100644 pkg/commands/color.go delete mode 100644 pkg/commands/commands_test.go delete mode 100644 pkg/commands/commandslist.go delete mode 100644 pkg/commands/currency.go delete mode 100644 pkg/commands/echo.go delete mode 100644 pkg/commands/eightball.go delete mode 100644 pkg/commands/emotelookup.go delete mode 100644 pkg/commands/ffz.go delete mode 100644 pkg/commands/ffzemotes.go delete mode 100644 pkg/commands/fill.go delete mode 100644 pkg/commands/firstline.go delete mode 100644 pkg/commands/followage.go delete mode 100644 pkg/commands/game.go delete mode 100644 pkg/commands/godocs.go delete mode 100644 pkg/commands/help.go delete mode 100644 pkg/commands/number.go delete mode 100644 pkg/commands/osrs.go delete mode 100644 pkg/commands/personal/arch.go delete mode 100644 pkg/commands/personal/farm.go delete mode 100644 pkg/commands/personal/justinfan.go delete mode 100644 pkg/commands/personal/personal_test.go delete mode 100644 pkg/commands/personal/rave.go delete mode 100644 pkg/commands/personal/streamlink.go delete mode 100644 pkg/commands/personal/xset.go delete mode 100644 pkg/commands/personal/zneix.go delete mode 100644 pkg/commands/ping.go delete mode 100644 pkg/commands/pingme.go delete mode 100644 pkg/commands/profilepicture.go delete mode 100644 pkg/commands/pyramid.go delete mode 100644 pkg/commands/randomcat.go delete mode 100644 pkg/commands/randomdog.go delete mode 100644 pkg/commands/randomduck.go delete mode 100644 pkg/commands/randomfox.go delete mode 100644 pkg/commands/randomquote.go delete mode 100644 pkg/commands/randomxkcd.go delete mode 100644 pkg/commands/robohash.go delete mode 100644 pkg/commands/seventv.go delete mode 100644 pkg/commands/subage.go delete mode 100644 pkg/commands/thumbnail.go delete mode 100644 pkg/commands/title.go delete mode 100644 pkg/commands/uptime.go delete mode 100644 pkg/commands/userid.go delete mode 100644 pkg/commands/weather.go delete mode 100644 pkg/commands/whois.go delete mode 100644 pkg/commands/xd.go delete mode 100644 pkg/commands/xkcd.go delete mode 100644 pkg/config/config.go delete mode 100644 pkg/config/config_test.go delete mode 100644 pkg/handlers/command.go delete mode 100644 pkg/handlers/handlers_test.go delete mode 100644 pkg/handlers/privatemessage.go delete mode 100644 pkg/humanize/time.go delete mode 100644 pkg/humanize/time_test.go delete mode 100644 pkg/utils/utils.go delete mode 100644 pkg/utils/utils_test.go diff --git a/cmd/bot/banphrase.go b/cmd/bot/banphrase.go deleted file mode 100644 index 13a1f38..0000000 --- a/cmd/bot/banphrase.go +++ /dev/null @@ -1,78 +0,0 @@ -package bot - -import ( - "bytes" - "encoding/json" - "io/ioutil" - "net/http" - - log "github.com/sirupsen/logrus" -) - -// banphraseResponse is the data we receive back from -// the banphrase API -type banphraseResponse struct { - Banned bool `json:"banned"` - InputMessage string `json:"input_message"` - BanphraseData banphraseData `json:"banphrase_data"` -} - -// banphraseData contains details about why a message -// was banphrased. -type banphraseData struct { - Id int `json:"id"` - Name string `json:"name"` - Phrase string `json:"phrase"` - Length int `json:"length"` - Permanent bool `json:"permanent"` -} - -var ( - banPhraseUrl = "https://pajlada.pajbot.com/api/v1/banphrases/test" -) - -// CheckMessage checks a message against a banphrase api.. -// returns false, "okay" if a message was allowed -// returns true, "[banphrased] monkaS" and the reason if not. -// More information: -// https://gist.github.com/pajlada/57464e519ba8d195a97ddcd0755f9715 -func CheckMessage(text string) (bool, string) { - // log.Info("fn CheckMessage") - - // {"message": "AHAHAHAHA LUL"} - reqBody, err := json.Marshal(map[string]string{ - "message": text, - }) - if err != nil { - log.Error(err) - } - - resp, err := http.Post(banPhraseUrl, "application/json", bytes.NewBuffer(reqBody)) - if err != nil { - log.Error(err) - } - - defer resp.Body.Close() - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - log.Error(err) - } - - var responseObject banphraseResponse - json.Unmarshal(body, &responseObject) - - // Bad Message - // - // {"phrase": "No gyazo allowed"} - // reason := responseObject.BanphraseData.Name - if responseObject.Banned { - return true, "[Banphrased]" - } else if !responseObject.Banned { - // Good message - return false, "okay" - } - - // Couldn't contact api so assume it was a bad message - return true, "Banphrase API couldn't be reached monkaS" -} diff --git a/cmd/bot/banphrase_test.go b/cmd/bot/banphrase_test.go deleted file mode 100644 index 302ebb4..0000000 --- a/cmd/bot/banphrase_test.go +++ /dev/null @@ -1,30 +0,0 @@ -package bot - -import "testing" - -func TestBanphrase(t *testing.T) { - t.Run("tests the banphrase api", func(t *testing.T) { - // Banned message - request, _ := CheckMessage("https://gyazo.com/asda") - response := true - - got := request - want := response - - if got != want { - t.Errorf("got %v, want %v", got, want) - } - - // Okay message - request, _ = CheckMessage("LUL") - response = false - - got = request - want = response - - if got != want { - t.Errorf("got %v, want %v", got, want) - } - - }) -} diff --git a/cmd/bot/bot.go b/cmd/bot/bot.go deleted file mode 100644 index ca8e8c9..0000000 --- a/cmd/bot/bot.go +++ /dev/null @@ -1,57 +0,0 @@ -package bot - -import ( - "time" - - twitch "github.com/gempir/go-twitch-irc/v2" - "go.mongodb.org/mongo-driver/mongo" -) - -type Bot struct { - TwitchClient *twitch.Client - MongoClient *mongo.Client - Uptime time.Time -} - -// Send checks the message against a banphrase api -// and also splits the message into two if the message -// is too long for a single twitch chat message. -func (b *Bot) Send(target, text string) { - if len(text) == 0 { - return - } - - if text[0] == '.' || text[0] == '/' || text[0] == '!' { - text = ":tf: " + text - } - - // If a message is too long for a single twitch - // message, split it into two messages. - if len(text) > 500 { - firstMessage := text[0:499] - secondMessage := text[499:] - - b.TwitchClient.Say(target, firstMessage) - b.TwitchClient.Say(target, secondMessage) - - return - } - - // check the message for bad words before we say it - messageBanned, banReason := CheckMessage(text) - if messageBanned { - // Bad message, replace message with a small - // notice on why it's banned. - b.TwitchClient.Say(target, banReason) - return - } else { - // Message was okay. - b.TwitchClient.Say(target, text) - return - } -} - -// SkipChecking sends the message without banphrase check -func (b *Bot) SkipChecking(target, text string) { - b.TwitchClient.Say(target, text) -} diff --git a/cmd/main.go b/cmd/bot/main.go similarity index 56% rename from cmd/main.go rename to cmd/bot/main.go index bd3935a..41dd854 100644 --- a/cmd/main.go +++ b/cmd/bot/main.go @@ -2,21 +2,16 @@ package main import ( "flag" - "fmt" "time" "github.com/gempir/go-twitch-irc/v2" - "github.com/lyx0/nourybot/cmd/bot" - "github.com/lyx0/nourybot/pkg/config" - "github.com/lyx0/nourybot/pkg/db" - "github.com/lyx0/nourybot/pkg/handlers" + "github.com/go-delve/delve/pkg/config" log "github.com/sirupsen/logrus" ) var nb *bot.Bot func main() { - // runMode is either dev or production so that we don't join every channel // everytime we do a small test. runMode := flag.String("mode", "production", "Mode in which to run. (dev/production") @@ -26,27 +21,10 @@ func main() { nb = &bot.Bot{ TwitchClient: twitch.NewClient(conf.Username, conf.Oauth), - MongoClient: db.Connect(conf), - Uptime: time.Now(), + // MongoClient: db.Connect(conf), + Uptime: time.Now(), } - nb.TwitchClient.OnPrivateMessage(func(message twitch.PrivateMessage) { - // If channelID is missing something must have gone wrong. - channelID := message.Tags["room-id"] - if channelID == "" { - fmt.Printf("Missing room-id tag in message") - return - } - - // Don't act on bots own messages. - if message.Tags["user-id"] == conf.BotUserId { - return - } - - // Forward the message for further processing. - handlers.PrivateMessage(message, nb) - }) - // Depending on the mode we run in, join different channel. if *runMode == "production" { log.Info("[PRODUCTION]: Joining every channel.") @@ -62,5 +40,4 @@ func main() { nb.Send("nourybot", "[DEV] Badabing Badaboom Pepepains") } - nb.TwitchClient.Connect() } diff --git a/cmd/main_test.go b/cmd/main_test.go deleted file mode 100644 index 7100647..0000000 --- a/cmd/main_test.go +++ /dev/null @@ -1,18 +0,0 @@ -package main - -import "testing" - -func TestMain(t *testing.T) { - t.Run("main package test placeholder", func(t *testing.T) { - request := 1 - response := 1 - - got := request - want := response - - if got != want { - t.Errorf("got %q, want %q", got, want) - } - - }) -} diff --git a/pkg/api/aiden/aiden.go b/pkg/api/aiden/aiden.go deleted file mode 100644 index 4fc8fa9..0000000 --- a/pkg/api/aiden/aiden.go +++ /dev/null @@ -1,32 +0,0 @@ -package aiden - -import ( - "fmt" - "io/ioutil" - "net/http" - - log "github.com/sirupsen/logrus" -) - -var ( - basePath = "https://customapi.aidenwallis.co.uk/" -) - -// ApiCall calls https://customapi.aidenwallis.co.uk/ with -// a given uri and returns the result and an error. -func ApiCall(uri string) (string, error) { - resp, err := http.Get(fmt.Sprint(basePath + uri)) - if err != nil { - log.Error(err) - return "Something went wrong FeelsBadMan", err - } - - defer resp.Body.Close() - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - log.Error(err) - return "Something went wrong FeelsBadMan", err - } - return string(body), nil -} diff --git a/pkg/api/aiden/aiden_test.go b/pkg/api/aiden/aiden_test.go deleted file mode 100644 index 64293eb..0000000 --- a/pkg/api/aiden/aiden_test.go +++ /dev/null @@ -1,21 +0,0 @@ -package aiden - -import ( - "testing" -) - -// TestAidenBotRatelimits calls aidens bot ratelimits api and checks -// the results against each other with my bot and another verified bot. -func TestAidenBotRatelimits(t *testing.T) { - t.Run("returns a twitch accounts ratelimits", func(t *testing.T) { - requestPajbot, _ := ApiCall("api/v1/twitch/botStatus/pajbot?includeLimits=1") - requestNourybot, _ := ApiCall("api/v1/twitch/botStatus/nourybot?includeLimits=1") - - got := requestPajbot - want := requestNourybot - - if got != want { - t.Errorf("got %q, want %q", got, want) - } - }) -} diff --git a/pkg/api/api_test.go b/pkg/api/api_test.go deleted file mode 100644 index abaa9b4..0000000 --- a/pkg/api/api_test.go +++ /dev/null @@ -1,19 +0,0 @@ -package api - -import "testing" - -// Idk how to test this really since almost everything in here is random -func TestApi(t *testing.T) { - t.Run("api package test placeholder", func(t *testing.T) { - request := 1 - response := 1 - - got := request - want := response - - if got != want { - t.Errorf("got %q, want %q", got, want) - } - - }) -} diff --git a/pkg/api/currency.go b/pkg/api/currency.go deleted file mode 100644 index a39c7af..0000000 --- a/pkg/api/currency.go +++ /dev/null @@ -1,48 +0,0 @@ -package api - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - "strings" - - log "github.com/sirupsen/logrus" -) - -type currencyResponse struct { - Amount int `json:"amount"` - Base string `json:"base"` - Rates map[string]float32 `json:"rates"` -} - -// Currency returns the exchange rate for a given given amount to another. -func Currency(currAmount, currFrom, currTo string) (string, error) { - baseUrl := "https://api.frankfurter.app" - currFromUpper := strings.ToUpper(currFrom) - currToUpper := strings.ToUpper(currTo) - - // https://api.frankfurter.app/latest?amount=10&from=gbp&to=usd - response, err := http.Get(fmt.Sprintf("%s/latest?amount=%s&from=%s&to=%s", baseUrl, currAmount, currFromUpper, currToUpper)) - if err != nil { - log.Error(err) - } - - responseData, err := ioutil.ReadAll(response.Body) - if err != nil { - log.Error(err) - } - - var responseObject currencyResponse - json.Unmarshal(responseData, &responseObject) - - // log.Info(responseObject.Amount) - // log.Info(responseObject.Base) - // log.Info(responseObject.Rates[strings.ToUpper(currTo)]) - - if responseObject.Rates[currToUpper] != 0 { - return fmt.Sprintf("%s %s = %.2f %s", currAmount, currFromUpper, responseObject.Rates[currToUpper], currToUpper), nil - } - - return "Something went wrong FeelsBadMan", nil -} diff --git a/pkg/api/ivr/emotelookup_test.go b/pkg/api/ivr/emotelookup_test.go deleted file mode 100644 index c875843..0000000 --- a/pkg/api/ivr/emotelookup_test.go +++ /dev/null @@ -1,41 +0,0 @@ -package ivr - -import "testing" - -func TestEmoteLookup(t *testing.T) { - t.Run("returns the channel a twitch emote is from and its tier", func(t *testing.T) { - // Tier 1 - request, _ := EmoteLookup("forsenE") - response := "forsenE is a Tier 1 emote to channel forsen." - - got := request - want := response - - if got != want { - t.Errorf("got %q, want %q", got, want) - } - - // Tier 2 - request, _ = EmoteLookup("nanZ") - response = "nanZ is a Tier 2 emote to channel nani." - - got = request - want = response - - if got != want { - t.Errorf("got %q, want %q", got, want) - } - - // Tier 3 - request, _ = EmoteLookup("pajaCORAL") - response = "pajaCORAL is a Tier 3 emote to channel pajlada." - - got = request - want = response - - if got != want { - t.Errorf("got %q, want %q", got, want) - } - - }) -} diff --git a/pkg/api/ivr/emoteloookup.go b/pkg/api/ivr/emoteloookup.go deleted file mode 100644 index 3f8ece7..0000000 --- a/pkg/api/ivr/emoteloookup.go +++ /dev/null @@ -1,47 +0,0 @@ -package ivr - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - - log "github.com/sirupsen/logrus" -) - -type emoteLookupResponse struct { - Channel string `json:"channel"` - EmoteCode string `json:"emotecode"` - Tier string `json:"tier"` - Emote string `json:"emote"` - Error string `json:"error"` -} - -// ProfilePicture returns a link to a given users profilepicture. -func EmoteLookup(emote string) (string, error) { - baseUrl := "https://api.ivr.fi/twitch/emotes" - - resp, err := http.Get(fmt.Sprintf("%s/%s", baseUrl, emote)) - if err != nil { - log.Error(err) - } - - defer resp.Body.Close() - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - log.Error(err) - } - - var responseObject emoteLookupResponse - json.Unmarshal(body, &responseObject) - - // log.Info(responseObject.Tier) - - // Emote not found - if responseObject.Error != "" { - return fmt.Sprintf(responseObject.Error + " FeelsBadMan"), nil - } else { - return fmt.Sprintf("%s is a Tier %v emote to channel %s.", responseObject.EmoteCode, responseObject.Tier, responseObject.Channel), nil - } -} diff --git a/pkg/api/ivr/firstline.go b/pkg/api/ivr/firstline.go deleted file mode 100644 index 66ada50..0000000 --- a/pkg/api/ivr/firstline.go +++ /dev/null @@ -1,47 +0,0 @@ -package ivr - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - - log "github.com/sirupsen/logrus" -) - -type firstLineApiResponse struct { - User string `json:"user"` - Message string `json:"message"` - Time string `json:"time"` - Error string `json:"error"` -} - -// FirstLine returns the first line a given user has sent in a -// given channel. -func FirstLine(channel, username string) (string, error) { - baseUrl := "https://api.ivr.fi/logs/firstmessage" - - resp, err := http.Get(fmt.Sprintf("%s/%s/%s", baseUrl, channel, username)) - if err != nil { - log.Error(err) - return "Something went wrong FeelsBadMan", err - } - - defer resp.Body.Close() - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - log.Error(err) - } - - var responseObject firstLineApiResponse - json.Unmarshal(body, &responseObject) - - // User or channel was not found - if responseObject.Error != "" { - return fmt.Sprintf(responseObject.Error + " FeelsBadMan"), nil - } else { - return fmt.Sprintf(username + ": " + responseObject.Message + " (" + responseObject.Time + " ago)."), nil - } - -} diff --git a/pkg/api/ivr/firstline_test.go b/pkg/api/ivr/firstline_test.go deleted file mode 100644 index 07bf9e5..0000000 --- a/pkg/api/ivr/firstline_test.go +++ /dev/null @@ -1,16 +0,0 @@ -package ivr - -// func TestFirstLine(t *testing.T) { -// t.Run("returns a users first message in a channel", func(t *testing.T) { -// request, _ := FirstLine("forsen", "forsen") -// response := "forsen: EZ or Ezy (3y, 9mo, 16d ago)." - -// got := request -// want := response - -// if got != want { -// t.Errorf("got %q, want %q", got, want) -// } - -// }) -// } diff --git a/pkg/api/ivr/followage.go b/pkg/api/ivr/followage.go deleted file mode 100644 index de6687a..0000000 --- a/pkg/api/ivr/followage.go +++ /dev/null @@ -1,50 +0,0 @@ -package ivr - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - - log "github.com/sirupsen/logrus" -) - -// https://api.ivr.fi -type followageApiResponse struct { - User string `json:"user"` - UserID string `json:"userid"` - Channel string `json:"channel"` - ChannelId string `json:"channelid"` - FollowedAt string `json:"followedAt"` - Error string `json:"error"` -} - -// Followage returns the time since a given user followed a given streamer -func Followage(streamer, username string) (string, error) { - baseUrl := "https://api.ivr.fi/twitch/subage" - - resp, err := http.Get(fmt.Sprintf("%s/%s/%s", baseUrl, username, streamer)) - if err != nil { - log.Error(err) - } - - defer resp.Body.Close() - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - log.Error(err) - } - - var responseObject followageApiResponse - json.Unmarshal(body, &responseObject) - - // User or channel was not found - if responseObject.Error != "" { - return fmt.Sprintf(responseObject.Error + " FeelsBadMan"), nil - } else if responseObject.FollowedAt == "" { - return fmt.Sprintf(username + " is not following " + streamer), nil - } else { - d := responseObject.FollowedAt[:10] - return fmt.Sprintf(username + " has been following " + streamer + " since " + d + "."), nil - } -} diff --git a/pkg/api/ivr/followage_test.go b/pkg/api/ivr/followage_test.go deleted file mode 100644 index 7b4f838..0000000 --- a/pkg/api/ivr/followage_test.go +++ /dev/null @@ -1,18 +0,0 @@ -package ivr - -import "testing" - -func TestFollowage(t *testing.T) { - t.Run("returns a users date they followed a channel", func(t *testing.T) { - request, _ := Followage("forsen", "pajlada") - response := "pajlada has been following forsen since 2015-03-09." - - got := request - want := response - - if got != want { - t.Errorf("got %q, want %q", got, want) - } - - }) -} diff --git a/pkg/api/ivr/profilepicture.go b/pkg/api/ivr/profilepicture.go deleted file mode 100644 index 70180f2..0000000 --- a/pkg/api/ivr/profilepicture.go +++ /dev/null @@ -1,43 +0,0 @@ -package ivr - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - - log "github.com/sirupsen/logrus" -) - -// https://api.ivr.fi -type pfpApiResponse struct { - Logo string `json:"logo"` - Error string `json:"error"` -} - -// ProfilePicture returns a link to a given users profilepicture. -func ProfilePicture(username string) (string, error) { - baseUrl := "https://api.ivr.fi/twitch/resolve" - - resp, err := http.Get(fmt.Sprintf("%s/%s", baseUrl, username)) - if err != nil { - log.Error(err) - } - - defer resp.Body.Close() - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - log.Error(err) - } - - var responseObject pfpApiResponse - json.Unmarshal(body, &responseObject) - - // User not found - if responseObject.Error != "" { - return fmt.Sprintf(responseObject.Error + " FeelsBadMan"), nil - } else { - return fmt.Sprintf(responseObject.Logo), nil - } -} diff --git a/pkg/api/ivr/profilepicture_test.go b/pkg/api/ivr/profilepicture_test.go deleted file mode 100644 index 4c83c50..0000000 --- a/pkg/api/ivr/profilepicture_test.go +++ /dev/null @@ -1,18 +0,0 @@ -package ivr - -import "testing" - -func TestProfilePicture(t *testing.T) { - t.Run("returns a link to a users profile picture", func(t *testing.T) { - request, _ := ProfilePicture("forsen") - response := "https://static-cdn.jtvnw.net/jtv_user_pictures/forsen-profile_image-48b43e1e4f54b5c8-600x600.png" - - got := request - want := response - - if got != want { - t.Errorf("got %q, want %q", got, want) - } - - }) -} diff --git a/pkg/api/ivr/randomquote.go b/pkg/api/ivr/randomquote.go deleted file mode 100644 index b48a526..0000000 --- a/pkg/api/ivr/randomquote.go +++ /dev/null @@ -1,47 +0,0 @@ -package ivr - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - - log "github.com/sirupsen/logrus" -) - -type randomQuoteApiResponse struct { - User string `json:"user"` - Message string `json:"message"` - Time string `json:"time"` - Error string `json:"error"` -} - -// FirstLine returns the first line a given user has sent in a -// given channel. -func RandomQuote(channel, username string) (string, error) { - baseUrl := "https://api.ivr.fi/logs/rq" - - resp, err := http.Get(fmt.Sprintf("%s/%s/%s", baseUrl, channel, username)) - if err != nil { - log.Error(err) - return "Something went wrong FeelsBadMan", err - } - - defer resp.Body.Close() - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - log.Error(err) - } - - var responseObject randomQuoteApiResponse - json.Unmarshal(body, &responseObject) - - // User or channel was not found - if responseObject.Error != "" { - return fmt.Sprintf(responseObject.Error + " FeelsBadMan"), nil - } else { - return fmt.Sprintf(username + ": " + responseObject.Message + " (" + responseObject.Time + " ago)."), nil - } - -} diff --git a/pkg/api/ivr/subage.go b/pkg/api/ivr/subage.go deleted file mode 100644 index f87f27f..0000000 --- a/pkg/api/ivr/subage.go +++ /dev/null @@ -1,69 +0,0 @@ -package ivr - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - - log "github.com/sirupsen/logrus" -) - -type subageApiResponse struct { - User string `json:"user"` - UserID string `json:"userId"` - Channel string `json:"channel"` - ChannelId string `json:"channelid"` - SubageHidden bool `json:"hidden"` - Subscribed bool `json:"subscribed"` - FollowedAt string `json:"followedAt"` - Cumulative cumulative `json:"cumulative"` - Streak subStreak `json:"streak"` - Error string `json:"error"` -} - -type cumulative struct { - Months int `json:"months"` -} - -type subStreak struct { - Months int `json:"months"` -} - -// Subage returns the length a given user has been subscribed to a given channel. -func Subage(username, channel string) (string, error) { - baseUrl := "https://api.ivr.fi/twitch/subage" - - resp, err := http.Get(fmt.Sprintf("%s/%s/%s", baseUrl, username, channel)) - if err != nil { - log.Error(err) - return "Something went wrong FeelsBadMan", err - } - - defer resp.Body.Close() - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - log.Error(err) - } - - var responseObject subageApiResponse - json.Unmarshal(body, &responseObject) - - // User or channel was not found - if responseObject.Error != "" { - reply := fmt.Sprintf(responseObject.Error + " FeelsBadMan") - // client.Say(channel, fmt.Sprintf(responseObject.Error+" FeelsBadMan")) - return reply, nil - } - - if responseObject.SubageHidden { - - reply := fmt.Sprintf(username + " has their subscription status hidden. FeelsBadMan") - return reply, nil - } else { - months := fmt.Sprint(responseObject.Cumulative.Months) - reply := fmt.Sprintf(username + " has been subscribed to " + channel + " for " + months + " months.") - return reply, nil - } -} diff --git a/pkg/api/ivr/userid.go b/pkg/api/ivr/userid.go deleted file mode 100644 index 72f8095..0000000 --- a/pkg/api/ivr/userid.go +++ /dev/null @@ -1,43 +0,0 @@ -package ivr - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - - log "github.com/sirupsen/logrus" -) - -// https://api.ivr.fi -type uidApiResponse struct { - Id string `json:"id"` - Error string `json:"error"` -} - -// Userid returns the userID of a given user -func Userid(username string) string { - baseUrl := "https://api.ivr.fi/twitch/resolve" - - resp, err := http.Get(fmt.Sprintf("%s/%s", baseUrl, username)) - if err != nil { - log.Error(err) - } - - defer resp.Body.Close() - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - log.Error(err) - } - - var responseObject uidApiResponse - json.Unmarshal(body, &responseObject) - - // User not found - if responseObject.Error != "" { - return fmt.Sprintf(responseObject.Error + " FeelsBadMan") - } else { - return fmt.Sprintf(responseObject.Id) - } -} diff --git a/pkg/api/ivr/userid_test.go b/pkg/api/ivr/userid_test.go deleted file mode 100644 index 2f2f060..0000000 --- a/pkg/api/ivr/userid_test.go +++ /dev/null @@ -1,18 +0,0 @@ -package ivr - -import "testing" - -func TestUserid(t *testing.T) { - t.Run("returns a link to a users profile picture", func(t *testing.T) { - request := Userid("nouryxd") - response := "31437432" - - got := request - want := response - - if got != want { - t.Errorf("got %q, want %q", got, want) - } - - }) -} diff --git a/pkg/api/ivr/whois.go b/pkg/api/ivr/whois.go deleted file mode 100644 index d43287a..0000000 --- a/pkg/api/ivr/whois.go +++ /dev/null @@ -1,77 +0,0 @@ -package ivr - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - "strings" - - log "github.com/sirupsen/logrus" -) - -// https://api.ivr.fi -type whoisApiResponse struct { - Id string `json:"id"` - DisplayName string `json:"displayName"` - Login string `json:"login"` - Bio string `json:"bio"` - ChatColor string `json:"chatColor"` - Partner bool `json:"partner"` - // Affiliate bool `json:"affiliate"` - Bot bool `json:"bot"` - CreatedAt string `json:"createdAt"` - Roles roles - Error string `json:"error"` -} - -type roles struct { - IsAffiliate bool `json:"isAffiliate"` - IsPartner bool `json:"isPartner"` - IsSiteAdmin bool `json:"isSiteAdmin"` - IsStaff bool `json:"isStaff"` -} - -// Userid returns the userID of a given user -func Whois(username string) string { - baseUrl := "https://api.ivr.fi/twitch/resolve" - - resp, err := http.Get(fmt.Sprintf("%s/%s", baseUrl, username)) - if err != nil { - log.Error(err) - } - - defer resp.Body.Close() - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - log.Error(err) - } - - var responseObject whoisApiResponse - json.Unmarshal(body, &responseObject) - - // time string format 2011-05-19T00:28:28.310449Z - // discard everything after T - created := strings.Split(responseObject.CreatedAt, "T") - - reply := fmt.Sprintf("User: %s, ID: %s, Created on: %s, Color: %s, Affiliate: %v, Partner: %v, Staff: %v, Admin: %v, Bot: %v, Bio: %v", - responseObject.DisplayName, - responseObject.Id, - created[0], - responseObject.ChatColor, - responseObject.Roles.IsAffiliate, - responseObject.Roles.IsPartner, - responseObject.Roles.IsStaff, - responseObject.Roles.IsSiteAdmin, - responseObject.Bot, - responseObject.Bio, - ) - - // User not found - if responseObject.Error != "" { - return fmt.Sprintf(responseObject.Error + " FeelsBadMan") - } else { - return reply - } -} diff --git a/pkg/api/ivr/whois_test.go b/pkg/api/ivr/whois_test.go deleted file mode 100644 index 9ac797d..0000000 --- a/pkg/api/ivr/whois_test.go +++ /dev/null @@ -1,16 +0,0 @@ -package ivr - -import "testing" - -func TestWhois(t *testing.T) { - t.Run("returns a link to a users profile picture", func(t *testing.T) { - request := Whois("forsen") - got := request - want := Whois("forsen") - - if got != want { - t.Errorf("got %q, want %q", got, want) - } - - }) -} diff --git a/pkg/api/numbersapi.go b/pkg/api/numbersapi.go deleted file mode 100644 index dcfb469..0000000 --- a/pkg/api/numbersapi.go +++ /dev/null @@ -1,42 +0,0 @@ -package api - -import ( - "fmt" - "io/ioutil" - "net/http" - - log "github.com/sirupsen/logrus" -) - -// RandomNumber returns a string containg fun facts about a random number. -// API used: http://numbersapi.com -func RandomNumber() string { - response, err := http.Get("http://numbersapi.com/random/trivia") - if err != nil { - log.Error(err) - } - - responseData, err := ioutil.ReadAll(response.Body) - if err != nil { - log.Error(err) - } - - return string(responseData) -} - -// Number returns a string containing fun facts about a given number. -// API used: http://numbersapi.com -func Number(number string) string { - response, err := http.Get(fmt.Sprint("http://numbersapi.com/" + string(number))) - - if err != nil { - log.Error(err) - } - - responseData, err := ioutil.ReadAll(response.Body) - if err != nil { - log.Error(err) - } - - return string(responseData) -} diff --git a/pkg/api/randomcat.go b/pkg/api/randomcat.go deleted file mode 100644 index c2a4cff..0000000 --- a/pkg/api/randomcat.go +++ /dev/null @@ -1,32 +0,0 @@ -package api - -import ( - "encoding/json" - "io/ioutil" - "net/http" - - log "github.com/sirupsen/logrus" -) - -type randomCatResponse struct { - File string `json:"file"` -} - -// RandomCat returns a link to a random cat picture. -// API used: https://aws.random.cat/meow -func RandomCat() string { - response, err := http.Get("https://aws.random.cat/meow") - if err != nil { - log.Error(err) - } - - responseData, err := ioutil.ReadAll(response.Body) - if err != nil { - log.Error(err) - } - - var responseObject randomCatResponse - json.Unmarshal(responseData, &responseObject) - - return string(responseObject.File) -} diff --git a/pkg/api/randomdog.go b/pkg/api/randomdog.go deleted file mode 100644 index f96c3e3..0000000 --- a/pkg/api/randomdog.go +++ /dev/null @@ -1,32 +0,0 @@ -package api - -import ( - "encoding/json" - "io/ioutil" - "net/http" - - log "github.com/sirupsen/logrus" -) - -type randomDogResponse struct { - Url string `json:"url"` -} - -// RandomDog returns a link to a random dog picture. -// API used: https://random.dog/woof.json -func RandomDog() string { - response, err := http.Get("https://random.dog/woof.json") - if err != nil { - log.Error(err) - } - - responseData, err := ioutil.ReadAll(response.Body) - if err != nil { - log.Error(err) - } - - var responseObject randomDogResponse - json.Unmarshal(responseData, &responseObject) - - return string(responseObject.Url) -} diff --git a/pkg/api/randomduck.go b/pkg/api/randomduck.go deleted file mode 100644 index 615851b..0000000 --- a/pkg/api/randomduck.go +++ /dev/null @@ -1,32 +0,0 @@ -package api - -import ( - "encoding/json" - "io/ioutil" - "net/http" - - log "github.com/sirupsen/logrus" -) - -type randomDuckResponse struct { - Url string `json:"url"` -} - -// RandomDuck returns a link to a random duck picture. -// API used: https://random-d.uk/api/random -func RandomDuck() string { - response, err := http.Get("https://random-d.uk/api/random") - if err != nil { - log.Error(err) - } - - responseData, err := ioutil.ReadAll(response.Body) - if err != nil { - log.Error(err) - } - - var responseObject randomDuckResponse - json.Unmarshal(responseData, &responseObject) - - return string(responseObject.Url) -} diff --git a/pkg/api/randomfox.go b/pkg/api/randomfox.go deleted file mode 100644 index 63f55ef..0000000 --- a/pkg/api/randomfox.go +++ /dev/null @@ -1,33 +0,0 @@ -package api - -import ( - "encoding/json" - "io/ioutil" - "net/http" - - log "github.com/sirupsen/logrus" -) - -type randomFoxResponse struct { - Image string `json:"image"` - Link string `json:"link"` -} - -// RandomFox returns a link to a random fox picture. -// API used: https://randomfox.ca/floof/ -func RandomFox() string { - response, err := http.Get("https://randomfox.ca/floof/") - if err != nil { - log.Error(err) - } - - responseData, err := ioutil.ReadAll(response.Body) - if err != nil { - log.Error(err) - } - - var responseObject randomFoxResponse - json.Unmarshal(responseData, &responseObject) - - return string(responseObject.Image) -} diff --git a/pkg/api/randomxkcd.go b/pkg/api/randomxkcd.go deleted file mode 100644 index de73468..0000000 --- a/pkg/api/randomxkcd.go +++ /dev/null @@ -1,36 +0,0 @@ -package api - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - - "github.com/lyx0/nourybot/pkg/utils" - log "github.com/sirupsen/logrus" -) - -type XkcdResponse struct { - Num int `json:"num"` - SafeTitle string `json:"safe_title"` - Img string `json:"img"` -} - -// RandomXkcd returns a link to a random Xkcd comic. -func RandomXkcd() string { - comicNum := fmt.Sprint(utils.GenerateRandomNumber(2468)) - - response, err := http.Get(fmt.Sprint("http://xkcd.com/" + comicNum + "/info.0.json")) - if err != nil { - log.Error(err) - } - responseData, err := ioutil.ReadAll(response.Body) - if err != nil { - log.Error(err) - } - var responseObject XkcdResponse - json.Unmarshal(responseData, &responseObject) - - reply := fmt.Sprint("Random Xkcd #", responseObject.Num, " Title: ", responseObject.SafeTitle, " ", responseObject.Img) - return reply -} diff --git a/pkg/api/xkcd.go b/pkg/api/xkcd.go deleted file mode 100644 index febc34c..0000000 --- a/pkg/api/xkcd.go +++ /dev/null @@ -1,29 +0,0 @@ -package api - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - - log "github.com/sirupsen/logrus" -) - -// Xkcd returns a link to the latest Xkcd comic. -// API used: https://xkcd.com/info.0.json -func Xkcd() string { - response, err := http.Get("https://xkcd.com/info.0.json") - if err != nil { - log.Error(err) - } - responseData, err := ioutil.ReadAll(response.Body) - if err != nil { - log.Error(err) - } - var responseObject XkcdResponse - json.Unmarshal(responseData, &responseObject) - - reply := fmt.Sprint("Current Xkcd #", responseObject.Num, " Title: ", responseObject.SafeTitle, " ", responseObject.Img) - - return reply -} diff --git a/pkg/commands/botstatus.go b/pkg/commands/botstatus.go deleted file mode 100644 index f178c71..0000000 --- a/pkg/commands/botstatus.go +++ /dev/null @@ -1,22 +0,0 @@ -package commands - -import ( - "fmt" - - "github.com/lyx0/nourybot/cmd/bot" - "github.com/lyx0/nourybot/pkg/api/aiden" - log "github.com/sirupsen/logrus" -) - -// Botstatus responds with if a given bot is verified/known and its ratelimits. -func BotStatus(channel, name string, nb *bot.Bot) { - resp, err := aiden.ApiCall(fmt.Sprintf("api/v1/twitch/botStatus/%s?includeLimits=1", name)) - - if err != nil { - nb.Send(channel, "Something went wrong FeelsBadMan") - log.Error(err) - return - } - - nb.Send(channel, resp) -} diff --git a/pkg/commands/bttv.go b/pkg/commands/bttv.go deleted file mode 100644 index 21a9bc6..0000000 --- a/pkg/commands/bttv.go +++ /dev/null @@ -1,14 +0,0 @@ -package commands - -import ( - "fmt" - - "github.com/lyx0/nourybot/cmd/bot" -) - -// Bttv responds with a search for a given bttv emote. -func Bttv(target, emote string, nb *bot.Bot) { - reply := fmt.Sprintf("https://betterttv.com/emotes/shared/search?query=%s", emote) - - nb.Send(target, reply) -} diff --git a/pkg/commands/bttvemotes.go b/pkg/commands/bttvemotes.go deleted file mode 100644 index 010bb83..0000000 --- a/pkg/commands/bttvemotes.go +++ /dev/null @@ -1,20 +0,0 @@ -package commands - -// import ( -// "fmt" - -// "github.com/lyx0/nourybot/cmd/bot" -// "github.com/lyx0/nourybot/pkg/api/aiden" -// log "github.com/sirupsen/logrus" -// ) - -// func BttvEmotes(channel string, nb *bot.Bot) { -// resp, err := aiden.ApiCall(fmt.Sprintf("api/v1/emotes/%s/bttv", channel)) - -// if err != nil { -// log.Error(err) -// nb.Send(channel, "Something went wrong FeelsBadMan") -// } - -// nb.Send(channel, string(resp)) -// } diff --git a/pkg/commands/channellist.go b/pkg/commands/channellist.go deleted file mode 100644 index 3275c99..0000000 --- a/pkg/commands/channellist.go +++ /dev/null @@ -1,11 +0,0 @@ -package commands - -import ( - "github.com/lyx0/nourybot/cmd/bot" - "github.com/lyx0/nourybot/pkg/db" -) - -func ChannelList(target string, nb *bot.Bot) { - db.ListChannel(nb) - nb.Send(target, "Whispered you the list of channel.") -} diff --git a/pkg/commands/coinflip.go b/pkg/commands/coinflip.go deleted file mode 100644 index f9b7d11..0000000 --- a/pkg/commands/coinflip.go +++ /dev/null @@ -1,17 +0,0 @@ -package commands - -import ( - "github.com/lyx0/nourybot/cmd/bot" - "github.com/lyx0/nourybot/pkg/utils" -) - -// Coinflip responds with Heads or Tails. -func Coinflip(channel string, nb *bot.Bot) { - result := utils.GenerateRandomNumber(2) - - if result == 1 { - nb.Send(channel, "Heads") - } else { - nb.Send(channel, "Tails") - } -} diff --git a/pkg/commands/color.go b/pkg/commands/color.go deleted file mode 100644 index 9b68458..0000000 --- a/pkg/commands/color.go +++ /dev/null @@ -1,53 +0,0 @@ -package commands - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - - "github.com/lyx0/nourybot/cmd/bot" - log "github.com/sirupsen/logrus" -) - -// https://api.ivr.fi -type colorApiResponse struct { - Id string `json:"id"` - DisplayName string `json:"displayName"` - ChatColor string `json:"chatColor"` - Error string `json:"error"` -} - -// Userid returns the userID of a given user -func Color(username, target string, nb *bot.Bot) { - baseUrl := "https://api.ivr.fi/twitch/resolve" - - resp, err := http.Get(fmt.Sprintf("%s/%s", baseUrl, username)) - if err != nil { - log.Error(err) - } - - defer resp.Body.Close() - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - log.Error(err) - } - - var responseObject colorApiResponse - json.Unmarshal(body, &responseObject) - - // time string format 2011-05-19T00:28:28.310449Z - // discard everything after T - - reply := fmt.Sprintf("%s color is %s", - responseObject.DisplayName, - responseObject.ChatColor, - ) - - // User not found - if responseObject.Error != "" { - nb.Send(target, "Something went wrong... FeelsBadMan") - } - nb.Send(target, reply) -} diff --git a/pkg/commands/commands_test.go b/pkg/commands/commands_test.go deleted file mode 100644 index 9abc549..0000000 --- a/pkg/commands/commands_test.go +++ /dev/null @@ -1,18 +0,0 @@ -package commands - -import "testing" - -func TestCommands(t *testing.T) { - t.Run("commands package test placeholder", func(t *testing.T) { - request := 1 - response := 1 - - got := request - want := response - - if got != want { - t.Errorf("got %q, want %q", got, want) - } - - }) -} diff --git a/pkg/commands/commandslist.go b/pkg/commands/commandslist.go deleted file mode 100644 index 13f2d27..0000000 --- a/pkg/commands/commandslist.go +++ /dev/null @@ -1,10 +0,0 @@ -package commands - -import "github.com/lyx0/nourybot/cmd/bot" - -// Commandslist responds with a link to the list of commands. -func CommandsList(target string, nb *bot.Bot) { - reply := "https://gist.github.com/lyx0/6e326451ed9602157fcf6b5e40fb1dfd" - - nb.Send(target, reply) -} diff --git a/pkg/commands/currency.go b/pkg/commands/currency.go deleted file mode 100644 index 08c46b5..0000000 --- a/pkg/commands/currency.go +++ /dev/null @@ -1,18 +0,0 @@ -package commands - -import ( - "github.com/lyx0/nourybot/cmd/bot" - "github.com/lyx0/nourybot/pkg/api" - "github.com/sirupsen/logrus" -) - -// Currency responds with the conversion rate for two given currencies. -// Example: ()currency 10 usd to eur -func Currency(target, currAmount, currFrom, currTo string, nb *bot.Bot) { - reply, err := api.Currency(currAmount, currFrom, currTo) - if err != nil { - logrus.Info(err) - } - - nb.Send(target, reply) -} diff --git a/pkg/commands/echo.go b/pkg/commands/echo.go deleted file mode 100644 index 4a0dd99..0000000 --- a/pkg/commands/echo.go +++ /dev/null @@ -1,9 +0,0 @@ -package commands - -import "github.com/lyx0/nourybot/cmd/bot" - -// Echo responds with the given message. -func Echo(channel, message string, nb *bot.Bot) { - - nb.Send(channel, message) -} diff --git a/pkg/commands/eightball.go b/pkg/commands/eightball.go deleted file mode 100644 index ec37bdb..0000000 --- a/pkg/commands/eightball.go +++ /dev/null @@ -1,19 +0,0 @@ -package commands - -import ( - "github.com/lyx0/nourybot/cmd/bot" - "github.com/lyx0/nourybot/pkg/api/aiden" - log "github.com/sirupsen/logrus" -) - -// Eightball asks the magic 8ball for guidance. -func EightBall(channel string, nb *bot.Bot) { - resp, err := aiden.ApiCall("api/v1/misc/8ball") - - if err != nil { - log.Error(err) - nb.Send(channel, "Something went wrong FeelsBadMan") - } - - nb.Send(channel, string(resp)) -} diff --git a/pkg/commands/emotelookup.go b/pkg/commands/emotelookup.go deleted file mode 100644 index c6fb6db..0000000 --- a/pkg/commands/emotelookup.go +++ /dev/null @@ -1,21 +0,0 @@ -package commands - -import ( - "fmt" - - "github.com/lyx0/nourybot/cmd/bot" - "github.com/lyx0/nourybot/pkg/api/ivr" -) - -// EmoteLookup looks up a given emote and responds with the channel it is -// associated with and its tier. -func EmoteLookup(channel, emote string, nb *bot.Bot) { - reply, err := ivr.EmoteLookup(emote) - - if err != nil { - nb.Send(channel, fmt.Sprint(err)) - return - } - - nb.Send(channel, reply) -} diff --git a/pkg/commands/ffz.go b/pkg/commands/ffz.go deleted file mode 100644 index e861c29..0000000 --- a/pkg/commands/ffz.go +++ /dev/null @@ -1,14 +0,0 @@ -package commands - -import ( - "fmt" - - "github.com/lyx0/nourybot/cmd/bot" -) - -// Ffz responds with a search link for a given ffz emote. -func Ffz(target, emote string, nb *bot.Bot) { - reply := fmt.Sprintf("https://www.frankerfacez.com/emoticons/?q=%s", emote) - - nb.Send(target, reply) -} diff --git a/pkg/commands/ffzemotes.go b/pkg/commands/ffzemotes.go deleted file mode 100644 index ca66765..0000000 --- a/pkg/commands/ffzemotes.go +++ /dev/null @@ -1,20 +0,0 @@ -package commands - -// import ( -// "fmt" - -// "github.com/lyx0/nourybot/cmd/bot" -// "github.com/lyx0/nourybot/pkg/api/aiden" -// log "github.com/sirupsen/logrus" -// ) - -// func FfzEmotes(channel string, nb *bot.Bot) { -// resp, err := aiden.ApiCall(fmt.Sprintf("api/v1/emotes/%s/ffz", channel)) - -// if err != nil { -// log.Error(err) -// nb.Send(channel, "Something went wrong FeelsBadMan") -// } - -// nb.Send(channel, string(resp)) -// } diff --git a/pkg/commands/fill.go b/pkg/commands/fill.go deleted file mode 100644 index b8aa49b..0000000 --- a/pkg/commands/fill.go +++ /dev/null @@ -1,27 +0,0 @@ -package commands - -import ( - "fmt" - "strings" - - "github.com/lyx0/nourybot/cmd/bot" -) - -// Fill repeats a given emote until the whole twitch message -// is filled up with the emote and then sends it. -func Fill(channel, emote string, nb *bot.Bot) { - if emote[0] == '.' || emote[0] == '/' { - nb.Send(channel, ":tf:") - return - } - - // Get the length of the emote - emoteLength := (len(emote) + 1) - - // Check how often the emote fits into a single message - repeatCount := (499 / emoteLength) - - reply := strings.Repeat(fmt.Sprintf(emote+" "), repeatCount) - nb.Send(channel, reply) - -} diff --git a/pkg/commands/firstline.go b/pkg/commands/firstline.go deleted file mode 100644 index ced2fe1..0000000 --- a/pkg/commands/firstline.go +++ /dev/null @@ -1,20 +0,0 @@ -package commands - -import ( - "fmt" - - "github.com/lyx0/nourybot/cmd/bot" - "github.com/lyx0/nourybot/pkg/api/ivr" -) - -// Firstline responds a given users first message in a given channel. -func Firstline(channel, streamer, username string, nb *bot.Bot) { - ivrResponse, err := ivr.FirstLine(streamer, username) - - if err != nil { - nb.Send(channel, fmt.Sprint(err)) - return - } - - nb.Send(channel, ivrResponse) -} diff --git a/pkg/commands/followage.go b/pkg/commands/followage.go deleted file mode 100644 index 6583f36..0000000 --- a/pkg/commands/followage.go +++ /dev/null @@ -1,20 +0,0 @@ -package commands - -import ( - "fmt" - - "github.com/lyx0/nourybot/cmd/bot" - "github.com/lyx0/nourybot/pkg/api/ivr" -) - -// Followage responds with a given users time since he followed a streamer. -func Followage(channel, streamer, username string, nb *bot.Bot) { - ivrResponse, err := ivr.Followage(streamer, username) - - if err != nil { - nb.Send(channel, fmt.Sprint(err)) - return - } - - nb.Send(channel, ivrResponse) -} diff --git a/pkg/commands/game.go b/pkg/commands/game.go deleted file mode 100644 index 4487726..0000000 --- a/pkg/commands/game.go +++ /dev/null @@ -1,23 +0,0 @@ -package commands - -import ( - "fmt" - - "github.com/lyx0/nourybot/cmd/bot" - "github.com/lyx0/nourybot/pkg/api/aiden" - log "github.com/sirupsen/logrus" -) - -// Game responds with the current game category a given stream is set to. -func Game(channel, name string, nb *bot.Bot) { - game, err := aiden.ApiCall(fmt.Sprintf("api/v1/twitch/channel/%s/game", name)) - - if err != nil { - nb.Send(channel, "Something went wrong FeelsBadMan") - log.Error(err) - return - } - - reply := fmt.Sprintf("@%s was last seen playing: %s", name, game) - nb.Send(channel, reply) -} diff --git a/pkg/commands/godocs.go b/pkg/commands/godocs.go deleted file mode 100644 index 4c31dc8..0000000 --- a/pkg/commands/godocs.go +++ /dev/null @@ -1,14 +0,0 @@ -package commands - -import ( - "fmt" - - "github.com/lyx0/nourybot/cmd/bot" -) - -// Godocs responds with a search for a given term on godocs.io -func Godocs(channel, searchTerm string, nb *bot.Bot) { - resp := fmt.Sprintf("https://godocs.io/?q=%s", searchTerm) - - nb.Send(channel, resp) -} diff --git a/pkg/commands/help.go b/pkg/commands/help.go deleted file mode 100644 index 5654206..0000000 --- a/pkg/commands/help.go +++ /dev/null @@ -1,10 +0,0 @@ -package commands - -import "github.com/lyx0/nourybot/cmd/bot" - -// Help responds with basic information about the bot. -func Help(target string, nb *bot.Bot) { - reply := "Bot made in Go by @Nouryqt, Prefix: (), Commands: https://gist.github.com/lyx0/6e326451ed9602157fcf6b5e40fb1dfd" - - nb.Send(target, reply) -} diff --git a/pkg/commands/number.go b/pkg/commands/number.go deleted file mode 100644 index 6284667..0000000 --- a/pkg/commands/number.go +++ /dev/null @@ -1,20 +0,0 @@ -package commands - -import ( - "github.com/lyx0/nourybot/cmd/bot" - "github.com/lyx0/nourybot/pkg/api" -) - -// RandomNumber calls the numbers api with a random number. -func RandomNumber(channel string, nb *bot.Bot) { - reply := api.RandomNumber() - - nb.Send(channel, string(reply)) -} - -// Number calls the numbers api with a given number. -func Number(channel, number string, nb *bot.Bot) { - reply := api.Number(number) - - nb.Send(channel, string(reply)) -} diff --git a/pkg/commands/osrs.go b/pkg/commands/osrs.go deleted file mode 100644 index 3e67630..0000000 --- a/pkg/commands/osrs.go +++ /dev/null @@ -1,15 +0,0 @@ -package commands - -import ( - "fmt" - "net/url" - - "github.com/lyx0/nourybot/cmd/bot" -) - -// Osrs responds with a link to a given osrs wiki search. -func Osrs(target, term string, nb *bot.Bot) { - reply := fmt.Sprint("https://oldschool.runescape.wiki/?search=" + url.QueryEscape(term)) - - nb.Send(target, reply) -} diff --git a/pkg/commands/personal/arch.go b/pkg/commands/personal/arch.go deleted file mode 100644 index 8a989f8..0000000 --- a/pkg/commands/personal/arch.go +++ /dev/null @@ -1,17 +0,0 @@ -package personal - -import "github.com/lyx0/nourybot/cmd/bot" - -// Arch responds with a meme about Arch linux -func Arch(target string, nb *bot.Bot) { - reply := "Your friend isn't wrong. Being on the actual latest up to date software, having a single unified community repository for out of repo software (AUR) instead of a bunch of scattered broken PPAs for extra software, not having so many hard dependencies that removing GNOME removes basic system utilities, broader customization support and other things is indeed, pretty nice." - - nb.Send(target, reply) -} - -// ArchTwo responds with a meme about Arch linux -func ArchTwo(target string, nb *bot.Bot) { - reply := "One time I was ordering coffee and suddenly realised the barista didn't know I use Arch. Needless to say, I stopped mid-order to inform her that I do indeed use Arch. I must have spoken louder than I intended because the whole café instantly erupted into a prolonged applause. I walked outside with my head held high. I never did finish my order that day, but just knowing that everyone around me was aware that I use Arch was more energising than a simple cup of coffee could ever be." - - nb.Send(target, reply) -} diff --git a/pkg/commands/personal/farm.go b/pkg/commands/personal/farm.go deleted file mode 100644 index 0721354..0000000 --- a/pkg/commands/personal/farm.go +++ /dev/null @@ -1,9 +0,0 @@ -package personal - -import "github.com/lyx0/nourybot/cmd/bot" - -// Farm responds with osrs wiki farming guide -func Farm(target string, nb *bot.Bot) { - nb.Send(target, "Trees: https://oldschool.runescape.wiki/w/Crop_running#Example_tree_run_sequence") - nb.Send(target, "Herbs: https://oldschool.runescape.wiki/w/Crop_running#Example_allotment,_flower_and_herb_run_sequence") -} diff --git a/pkg/commands/personal/justinfan.go b/pkg/commands/personal/justinfan.go deleted file mode 100644 index 3199655..0000000 --- a/pkg/commands/personal/justinfan.go +++ /dev/null @@ -1,10 +0,0 @@ -package personal - -import "github.com/lyx0/nourybot/cmd/bot" - -// Justinfan responds with the Jusinfan user chatterino has used before. -func Justinfan(target string, nb *bot.Bot) { - reply := "64537" - - nb.Send(target, reply) -} diff --git a/pkg/commands/personal/personal_test.go b/pkg/commands/personal/personal_test.go deleted file mode 100644 index f4c78fa..0000000 --- a/pkg/commands/personal/personal_test.go +++ /dev/null @@ -1,18 +0,0 @@ -package personal - -import "testing" - -func TestCommands(t *testing.T) { - t.Run("personal package test placeholder", func(t *testing.T) { - request := 1 - response := 1 - - got := request - want := response - - if got != want { - t.Errorf("got %q, want %q", got, want) - } - - }) -} diff --git a/pkg/commands/personal/rave.go b/pkg/commands/personal/rave.go deleted file mode 100644 index 4cdca3b..0000000 --- a/pkg/commands/personal/rave.go +++ /dev/null @@ -1,13 +0,0 @@ -package personal - -import "github.com/lyx0/nourybot/cmd/bot" - -// Rave returns youtube music playlists. -func Rave(target string, nb *bot.Bot) { - reply := `https://www.youtube.com/playlist?list=PLY9LTYa8xnQKrug3VvgkPWqmpmXSKAYPe` - reply2 := `https://www.youtube.com/playlist?list=PLWwCeXamjNuZ2ZNJiNwvdmVT9TtULsHc6` - - nb.Send(target, reply) - nb.Send(target, reply2) - -} diff --git a/pkg/commands/personal/streamlink.go b/pkg/commands/personal/streamlink.go deleted file mode 100644 index 04d51b2..0000000 --- a/pkg/commands/personal/streamlink.go +++ /dev/null @@ -1,10 +0,0 @@ -package personal - -import "github.com/lyx0/nourybot/cmd/bot" - -// Streamlink returns the streamlink config. -func Streamlink(target string, nb *bot.Bot) { - reply := `https://haste.zneix.eu/udajirixep put this in ~/.config/streamlink/config on Linux (or %appdata%\streamlink\streamlinkrc on Windows)` - - nb.Send(target, reply) -} diff --git a/pkg/commands/personal/xset.go b/pkg/commands/personal/xset.go deleted file mode 100644 index 0b62bb1..0000000 --- a/pkg/commands/personal/xset.go +++ /dev/null @@ -1,10 +0,0 @@ -package personal - -import "github.com/lyx0/nourybot/cmd/bot" - -// Xset returns the keyboard repeat rate command. -func Xset(target string, nb *bot.Bot) { - reply := "xset r rate 175 50" - - nb.Send(target, reply) -} diff --git a/pkg/commands/personal/zneix.go b/pkg/commands/personal/zneix.go deleted file mode 100644 index 6377087..0000000 --- a/pkg/commands/personal/zneix.go +++ /dev/null @@ -1,10 +0,0 @@ -package personal - -import "github.com/lyx0/nourybot/cmd/bot" - -// Zneix returns a meme about Zneix leaking stuff. -func Zneix(target string, nb *bot.Bot) { - reply := "ᵃᵈ⁴³ oh frick ⁵²⁴ᵈ ⁸⁹ᵈˢ ⁷⁵⁴⁹ ᶠᵈ³⁴ ᶦᵒ⁶⁸ frick sorry guys ᶠ⁷⁸ᶠ ᵈ⁹⁸⁹ ᵍ⁸²³ ᵍ⁹⁰ˣ ⁹ᵍᶠᵖ sorry im dropping ⁸⁹⁸⁴ ⁰⁹⁰ᶠ my api keys all over the ⁵³²ᵈ place ⁸⁷ᶠᵈ ⁹⁸⁴ᶠ ⁰⁹¹ᵃ sorry zneixApu zneixLeak" - - nb.Send(target, reply) -} diff --git a/pkg/commands/ping.go b/pkg/commands/ping.go deleted file mode 100644 index fffdbcc..0000000 --- a/pkg/commands/ping.go +++ /dev/null @@ -1,19 +0,0 @@ -package commands - -import ( - "fmt" - - "github.com/lyx0/nourybot/cmd/bot" - "github.com/lyx0/nourybot/pkg/humanize" - "github.com/lyx0/nourybot/pkg/utils" -) - -// Ping responds with Pong and basic information about the bot. -func Ping(target string, nb *bot.Bot) { - commandCount := fmt.Sprint(utils.GetCommandsUsed()) - botUptime := humanize.Time(nb.Uptime) - - reply := fmt.Sprintf("Pong! :) Commands used: %v, Last restart: %v", commandCount, botUptime) - - nb.Send(target, reply) -} diff --git a/pkg/commands/pingme.go b/pkg/commands/pingme.go deleted file mode 100644 index f98b082..0000000 --- a/pkg/commands/pingme.go +++ /dev/null @@ -1,14 +0,0 @@ -package commands - -import ( - "fmt" - - "github.com/lyx0/nourybot/cmd/bot" -) - -// Pingme pings a user. -func Pingme(channel, user string, nb *bot.Bot) { - response := fmt.Sprintf("🔔 @%s 🔔", user) - - nb.Send(channel, response) -} diff --git a/pkg/commands/profilepicture.go b/pkg/commands/profilepicture.go deleted file mode 100644 index 102fef5..0000000 --- a/pkg/commands/profilepicture.go +++ /dev/null @@ -1,20 +0,0 @@ -package commands - -import ( - "fmt" - - "github.com/lyx0/nourybot/cmd/bot" - "github.com/lyx0/nourybot/pkg/api/ivr" -) - -// ProfilePicture responds with a link to a given users Twitch Profilepicture. -func ProfilePicture(channel, target string, nb *bot.Bot) { - reply, err := ivr.ProfilePicture(target) - - if err != nil { - nb.Send(channel, fmt.Sprint(err)) - return - } - - nb.Send(channel, reply) -} diff --git a/pkg/commands/pyramid.go b/pkg/commands/pyramid.go deleted file mode 100644 index 1de7e70..0000000 --- a/pkg/commands/pyramid.go +++ /dev/null @@ -1,52 +0,0 @@ -package commands - -// import ( -// "fmt" -// "strconv" -// "strings" - -// "github.com/lyx0/nourybot/cmd/bot" -// ) - -// func Pyramid(channel, size, emote string, nb *bot.Bot) { -// if size[0] == '.' || size[0] == '/' { -// nb.Send(channel, ":tf:") -// return -// } - -// if emote[0] == '.' || emote[0] == '/' { -// nb.Send(channel, ":tf:") -// return -// } - -// pyramidSize, err := strconv.Atoi(size) -// pyramidEmote := fmt.Sprint(emote + " ") - -// if err != nil { -// nb.Send(channel, "Something went wrong") -// } - -// if pyramidSize == 1 { -// nb.Send(channel, fmt.Sprint(pyramidEmote+"...")) -// return -// } - -// if pyramidSize > 3 { -// nb.Send(channel, "Max pyramid size is 3") -// return -// } - -// for i := 0; i <= pyramidSize; i++ { -// pyramidMessageAsc := strings.Repeat(pyramidEmote, i) -// // fmt.Println(pyramidMessageAsc) - -// nb.Send(channel, pyramidMessageAsc) -// } - -// for j := pyramidSize - 1; j >= 0; j-- { -// pyramidMessageDesc := strings.Repeat(pyramidEmote, j) -// // fmt.Println(pyramidMessageDesc) - -// nb.Send(channel, pyramidMessageDesc) -// } -// } diff --git a/pkg/commands/randomcat.go b/pkg/commands/randomcat.go deleted file mode 100644 index f206738..0000000 --- a/pkg/commands/randomcat.go +++ /dev/null @@ -1,14 +0,0 @@ -package commands - -import ( - "github.com/lyx0/nourybot/cmd/bot" - "github.com/lyx0/nourybot/pkg/api" -) - -// RandomCat calls the RandomCat api and responds with a link for a -// random cat image. -func RandomCat(channel string, nb *bot.Bot) { - reply := api.RandomCat() - - nb.Send(channel, reply) -} diff --git a/pkg/commands/randomdog.go b/pkg/commands/randomdog.go deleted file mode 100644 index c176b85..0000000 --- a/pkg/commands/randomdog.go +++ /dev/null @@ -1,14 +0,0 @@ -package commands - -import ( - "github.com/lyx0/nourybot/cmd/bot" - "github.com/lyx0/nourybot/pkg/api" -) - -// RandomDog calls the RandomDog api and responds with a link for a -// random dog image. -func RandomDog(channel string, nb *bot.Bot) { - reply := api.RandomDog() - - nb.Send(channel, reply) -} diff --git a/pkg/commands/randomduck.go b/pkg/commands/randomduck.go deleted file mode 100644 index 82ccb67..0000000 --- a/pkg/commands/randomduck.go +++ /dev/null @@ -1,14 +0,0 @@ -package commands - -import ( - "github.com/lyx0/nourybot/cmd/bot" - "github.com/lyx0/nourybot/pkg/api" -) - -// RandomDuck calls the RandomDuck api and responds with a link for a -// random duck image. -func RandomDuck(channel string, nb *bot.Bot) { - reply := api.RandomDuck() - - nb.Send(channel, reply) -} diff --git a/pkg/commands/randomfox.go b/pkg/commands/randomfox.go deleted file mode 100644 index 061d4a4..0000000 --- a/pkg/commands/randomfox.go +++ /dev/null @@ -1,14 +0,0 @@ -package commands - -import ( - "github.com/lyx0/nourybot/cmd/bot" - "github.com/lyx0/nourybot/pkg/api" -) - -// RandomFox calls the RandomFox api and responds with a link for a -// random fox image. -func RandomFox(channel string, nb *bot.Bot) { - reply := api.RandomFox() - - nb.Send(channel, reply) -} diff --git a/pkg/commands/randomquote.go b/pkg/commands/randomquote.go deleted file mode 100644 index 4453d90..0000000 --- a/pkg/commands/randomquote.go +++ /dev/null @@ -1,21 +0,0 @@ -package commands - -import ( - "fmt" - - "github.com/lyx0/nourybot/cmd/bot" - "github.com/lyx0/nourybot/pkg/api/ivr" -) - -// RandomQuote calls the RandomQuote api and responds with a link for a -// random quote image. -func RandomQuote(channel, target, username string, nb *bot.Bot) { - ivrResponse, err := ivr.RandomQuote(target, username) - - if err != nil { - nb.Send(channel, fmt.Sprint(err)) - return - } - - nb.Send(channel, ivrResponse) -} diff --git a/pkg/commands/randomxkcd.go b/pkg/commands/randomxkcd.go deleted file mode 100644 index c6ed164..0000000 --- a/pkg/commands/randomxkcd.go +++ /dev/null @@ -1,14 +0,0 @@ -package commands - -import ( - "github.com/lyx0/nourybot/cmd/bot" - "github.com/lyx0/nourybot/pkg/api" -) - -// RandomXkcd calls the RandomXkcd api and responds with a link to a -// random xkcd comic. -func RandomXkcd(channel string, nb *bot.Bot) { - reply := api.RandomXkcd() - - nb.Send(channel, reply) -} diff --git a/pkg/commands/robohash.go b/pkg/commands/robohash.go deleted file mode 100644 index 03a7375..0000000 --- a/pkg/commands/robohash.go +++ /dev/null @@ -1,16 +0,0 @@ -package commands - -import ( - "fmt" - - "github.com/gempir/go-twitch-irc/v2" - "github.com/lyx0/nourybot/cmd/bot" -) - -// Robohash takes the message ID from the message and responds -// with the robohash image link for the message id. -func RoboHash(target string, message twitch.PrivateMessage, nb *bot.Bot) { - reply := fmt.Sprintf("https://robohash.org/%s", message.ID) - - nb.Send(target, reply) -} diff --git a/pkg/commands/seventv.go b/pkg/commands/seventv.go deleted file mode 100644 index 39bba56..0000000 --- a/pkg/commands/seventv.go +++ /dev/null @@ -1,14 +0,0 @@ -package commands - -import ( - "fmt" - - "github.com/lyx0/nourybot/cmd/bot" -) - -// SevenTV responds with a link to the 7tv search for a given emote. -func SevenTV(target, emote string, nb *bot.Bot) { - reply := fmt.Sprintf("https://7tv.app/emotes?query=%s", emote) - - nb.Send(target, reply) -} diff --git a/pkg/commands/subage.go b/pkg/commands/subage.go deleted file mode 100644 index 11614cb..0000000 --- a/pkg/commands/subage.go +++ /dev/null @@ -1,21 +0,0 @@ -package commands - -import ( - "fmt" - - "github.com/lyx0/nourybot/cmd/bot" - "github.com/lyx0/nourybot/pkg/api/ivr" -) - -// Subage responds with the time a given user has been subscribed -// to a given channel. -func Subage(channel, username, streamer string, nb *bot.Bot) { - ivrResponse, err := ivr.Subage(username, streamer) - - if err != nil { - nb.Send(channel, fmt.Sprint(err)) - return - } - - nb.Send(channel, ivrResponse) -} diff --git a/pkg/commands/thumbnail.go b/pkg/commands/thumbnail.go deleted file mode 100644 index 640a2ff..0000000 --- a/pkg/commands/thumbnail.go +++ /dev/null @@ -1,18 +0,0 @@ -package commands - -import ( - "fmt" - - "github.com/lyx0/nourybot/cmd/bot" - "github.com/lyx0/nourybot/pkg/utils" -) - -// Thumbnail responds with the current preview image for a given channel. -func Thumbnail(channel, target string, nb *bot.Bot) { - imageHeight := utils.GenerateRandomNumberRange(1040, 1080) - imageWidth := utils.GenerateRandomNumberRange(1890, 1920) - - response := fmt.Sprintf("https://static-cdn.jtvnw.net/previews-ttv/live_user_%v-%vx%v.jpg", target, imageWidth, imageHeight) - - nb.Send(channel, response) -} diff --git a/pkg/commands/title.go b/pkg/commands/title.go deleted file mode 100644 index 4350312..0000000 --- a/pkg/commands/title.go +++ /dev/null @@ -1,23 +0,0 @@ -package commands - -import ( - "fmt" - - "github.com/lyx0/nourybot/cmd/bot" - "github.com/lyx0/nourybot/pkg/api/aiden" - log "github.com/sirupsen/logrus" -) - -// Title responds with the stream title for a given channel. -func Title(channel, target string, nb *bot.Bot) { - title, err := aiden.ApiCall(fmt.Sprintf("api/v1/twitch/channel/%s/title", target)) - - if err != nil { - nb.Send(channel, "Something went wrong FeelsBadMan") - log.Error(err) - return - } - - reply := fmt.Sprintf("%s title is: %s", target, title) - nb.Send(channel, reply) -} diff --git a/pkg/commands/uptime.go b/pkg/commands/uptime.go deleted file mode 100644 index f9d3aad..0000000 --- a/pkg/commands/uptime.go +++ /dev/null @@ -1,22 +0,0 @@ -package commands - -import ( - "fmt" - - "github.com/lyx0/nourybot/cmd/bot" - "github.com/lyx0/nourybot/pkg/api/aiden" - log "github.com/sirupsen/logrus" -) - -// Uptime responds with the time a given channel has been live. -func Uptime(channel, name string, nb *bot.Bot) { - resp, err := aiden.ApiCall(fmt.Sprintf("api/v1/twitch/channel/%s/uptime", name)) - - if err != nil { - nb.Send(channel, "Something went wrong FeelsBadMan") - log.Error(err) - return - } - - nb.Send(channel, resp) -} diff --git a/pkg/commands/userid.go b/pkg/commands/userid.go deleted file mode 100644 index bff6adc..0000000 --- a/pkg/commands/userid.go +++ /dev/null @@ -1,13 +0,0 @@ -package commands - -import ( - "github.com/lyx0/nourybot/cmd/bot" - "github.com/lyx0/nourybot/pkg/api/ivr" -) - -// Userid responds with the userid for a given user. -func Userid(channel, target string, nb *bot.Bot) { - reply := ivr.Userid(target) - - nb.Send(channel, reply) -} diff --git a/pkg/commands/weather.go b/pkg/commands/weather.go deleted file mode 100644 index 05ab804..0000000 --- a/pkg/commands/weather.go +++ /dev/null @@ -1,23 +0,0 @@ -package commands - -import ( - "fmt" - - "github.com/lyx0/nourybot/cmd/bot" - "github.com/lyx0/nourybot/pkg/api/aiden" - log "github.com/sirupsen/logrus" -) - -// Weather calls the weather api for a given location and responds -// with the current weather data. -func Weather(channel, location string, nb *bot.Bot) { - reply, err := aiden.ApiCall(fmt.Sprintf("api/v1/misc/weather/%s", location)) - - if err != nil { - nb.Send(channel, "Something went wrong FeelsBadMan") - log.Error(err) - return - } - - nb.Send(channel, reply) -} diff --git a/pkg/commands/whois.go b/pkg/commands/whois.go deleted file mode 100644 index dcac00a..0000000 --- a/pkg/commands/whois.go +++ /dev/null @@ -1,13 +0,0 @@ -package commands - -import ( - "github.com/lyx0/nourybot/cmd/bot" - "github.com/lyx0/nourybot/pkg/api/ivr" -) - -// Whois responds with information about a given users Twitch account. -func Whois(target, user string, nb *bot.Bot) { - reply := ivr.Whois(user) - - nb.Send(target, reply) -} diff --git a/pkg/commands/xd.go b/pkg/commands/xd.go deleted file mode 100644 index e48492b..0000000 --- a/pkg/commands/xd.go +++ /dev/null @@ -1,8 +0,0 @@ -package commands - -import "github.com/lyx0/nourybot/cmd/bot" - -// Xd responds with a xd -func Xd(channel string, nb *bot.Bot) { - nb.Send(channel, "xd") -} diff --git a/pkg/commands/xkcd.go b/pkg/commands/xkcd.go deleted file mode 100644 index b245a1a..0000000 --- a/pkg/commands/xkcd.go +++ /dev/null @@ -1,14 +0,0 @@ -package commands - -import ( - "github.com/lyx0/nourybot/cmd/bot" - "github.com/lyx0/nourybot/pkg/api" -) - -// Xkcd responds with a link to the current xkcd comic and information about i. -func Xkcd(channel string, nb *bot.Bot) { - reply := api.Xkcd() - - nb.Send(channel, reply) - -} diff --git a/pkg/config/config.go b/pkg/config/config.go deleted file mode 100644 index 4538075..0000000 --- a/pkg/config/config.go +++ /dev/null @@ -1,40 +0,0 @@ -package config - -import ( - "os" - - "github.com/joho/godotenv" - log "github.com/sirupsen/logrus" -) - -type Config struct { - Username string - Oauth string - BotUserId string - MongoURI string -} - -func LoadConfig() *Config { - err := godotenv.Load() - - if err != nil { - log.Fatal("Error loading .env") - } - - cfg := &Config{ - Username: os.Getenv("TWITCH_USER"), - Oauth: os.Getenv("TWITCH_PASS"), - BotUserId: os.Getenv("BOT_USER_ID"), - MongoURI: os.Getenv("MONGO_URI"), - } - - log.Info("Config loaded succesfully") - - return cfg -} - -// Only for tests -func LoadConfigTest() { - os.Setenv("TEST_VALUE", "xDLUL420") - // defer os.Unsetenv("TEST_VALUE") -} diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go deleted file mode 100644 index 48fc16e..0000000 --- a/pkg/config/config_test.go +++ /dev/null @@ -1,20 +0,0 @@ -package config - -import ( - "os" - "testing" -) - -func TestLoadConfig(t *testing.T) { - t.Run("loads a testing value from the .env file", func(t *testing.T) { - LoadConfigTest() - - got := os.Getenv("TEST_VALUE") - want := "xDLUL420" - - if got != want { - t.Errorf("got %q, want %q", got, want) - } - - }) -} diff --git a/pkg/handlers/command.go b/pkg/handlers/command.go deleted file mode 100644 index ce4fd63..0000000 --- a/pkg/handlers/command.go +++ /dev/null @@ -1,568 +0,0 @@ -package handlers - -import ( - "strings" - - "github.com/gempir/go-twitch-irc/v2" - "github.com/lyx0/nourybot/cmd/bot" - "github.com/lyx0/nourybot/pkg/commands" - "github.com/lyx0/nourybot/pkg/commands/personal" - "github.com/lyx0/nourybot/pkg/db" - "github.com/lyx0/nourybot/pkg/utils" -) - -// Command contains all the logic for routing mesasges containing commands -// and will forward the messages to the specific command handlers. -func Command(message twitch.PrivateMessage, nb *bot.Bot) { - utils.CommandUsed() - - // commandName is the actual command name without the prefix. - commandName := strings.ToLower(strings.SplitN(message.Message, " ", 3)[0][2:]) - - // cmdParams are additional command inputs. - // example: "weather san antonion - // is: commandName cmdParams[0] cmdParams[1] - cmdParams := strings.SplitN(message.Message, " ", 500) - - // msgLen is the amount of words in the message without the prefix. - // Useful for checking if enough cmdParams are given. - msgLen := len(strings.SplitN(message.Message, " ", -2)) - - // target channel - target := message.Channel - - // Logs the message to the database since it invoked a command. - db.InsertCommand(nb, commandName, message.User.Name, message.Channel, message.User.ID, message.Message) - - switch commandName { - case "": - if msgLen == 1 { - nb.Send(target, "xd") - return - } - - case "7tv": - if msgLen == 1 { - nb.Send(target, "Usage: ()7tv [emote]") - return - } - commands.SevenTV(target, cmdParams[1], nb) - return - - case "8ball": - commands.EightBall(target, nb) - return - - case "bot": - commands.Help(target, nb) - return - - case "botinfo": - commands.Help(target, nb) - return - - case "botstatus": - if msgLen == 1 { - nb.Send(target, "Usage: ()botstatus [username]") - return - } else { - commands.BotStatus(target, cmdParams[1], nb) - return - } - - case "bttv": - if msgLen == 1 { - nb.Send(target, "Usage: ()bttv [emote]") - return - } - commands.Bttv(target, cmdParams[1], nb) - return - - case "channellist": - if message.User.ID != "31437432" { - nb.Send(target, "You are not allowed to do this") - return - } - commands.ChannelList(target, nb) - return - - // case "bttvemotes": - // commands.BttvEmotes(target, nb) - // return - - case "cat": - commands.RandomCat(target, nb) - return - - case "cf": - commands.Coinflip(target, nb) - return - - case "coin": - commands.Coinflip(target, nb) - return - - case "coinflip": - commands.Coinflip(target, nb) - return - - case "color": - commands.Color(cmdParams[1], target, nb) - return - - case "commands": - commands.CommandsList(target, nb) - return - - case "dog": - commands.RandomDog(target, nb) - return - - case "duck": - commands.RandomDuck(target, nb) - return - - case "currency": - if msgLen <= 4 { - nb.Send(target, "Usage: ()currency 10 usd to eur, only 3 letter codes work.") - return - } - commands.Currency(target, cmdParams[1], cmdParams[2], cmdParams[4], nb) - return - - case "echo": - if message.User.ID != "31437432" { - // nb.Send(target, "You're not authorized to do this.") - return - } else { - commands.Echo(target, message.Message[7:len(message.Message)], nb) - return - } - - case "emote": - commands.EmoteLookup(target, cmdParams[1], nb) - return - - case "emotelookup": - commands.EmoteLookup(target, cmdParams[1], nb) - return - - case "ffz": - if msgLen == 1 { - nb.Send(target, "Usage: ()ffz [emote]") - return - } - commands.Ffz(target, cmdParams[1], nb) - return - - // case "ffzemotes": - // commands.FfzEmotes(target, nb) - // return - - case "fill": - if message.User.ID != "31437432" { - nb.Send(target, "You're not authorized to do this.") - return - } else if msgLen == 1 { - nb.Send(target, "Usage: ()fill [emote]") - return - } else { - commands.Fill(target, message.Message[7:len(message.Message)], nb) - return - } - - case "firstline": - if msgLen == 1 { - nb.Send(target, "Usage: ()firstline [channel] [user]") - return - } else if msgLen == 2 { - commands.Firstline(target, target, cmdParams[1], nb) - return - } else { - commands.Firstline(target, cmdParams[1], cmdParams[2], nb) - return - } - - case "fl": - if msgLen == 1 { - nb.Send(target, "Usage: ()firstline [channel] [user]") - return - } else if msgLen == 2 { - commands.Firstline(target, target, cmdParams[1], nb) - return - } else { - commands.Firstline(target, cmdParams[1], cmdParams[2], nb) - return - } - - case "followage": - if msgLen <= 2 { - nb.Send(target, "Usage: ()followage [channel] [user]") - return - } else { - commands.Followage(target, cmdParams[1], cmdParams[2], nb) - return - } - - case "fox": - commands.RandomFox(target, nb) - return - - case "game": - if msgLen == 1 { - nb.Send(target, "Usage: ()game [channel]") - return - } else { - commands.Game(target, cmdParams[1], nb) - } - - case "godoc": - if msgLen == 1 { - nb.Send(target, "Usage: ()godoc [term]") - return - } else { - commands.Godocs(target, message.Message[8:len(message.Message)], nb) - return - } - - case "godocs": - if msgLen == 1 { - nb.Send(target, "Usage: ()godoc [term]") - return - } else { - commands.Godocs(target, message.Message[9:len(message.Message)], nb) - return - } - - case "help": - commands.Help(target, nb) - return - - case "join": - if msgLen == 1 || message.User.ID != "31437432" { - nb.Send(target, "You are not allowed to do this") - return - } - db.AddChannel(target, cmdParams[1], nb) - return - - //. case "mycolor": - //. commands.Color(message, nb) - //. return - - case "nourybot": - commands.Help(target, nb) - return - - case "num": - if msgLen == 1 { - commands.RandomNumber(target, nb) - return - } else { - commands.Number(target, cmdParams[1], nb) - return - } - - case "number": - if msgLen == 1 { - commands.RandomNumber(target, nb) - return - } else { - commands.Number(target, cmdParams[1], nb) - return - - } - case "osrs": - if msgLen == 1 { - nb.Send(target, "Usage: ()osrs [term]") - return - } else { - commands.Osrs(target, message.Message[7:len(message.Message)], nb) - return - } - - case "part": - if msgLen == 1 || message.User.ID != "31437432" { - nb.Send(target, "You are not allowed to do this") - return - } - db.PartChannel(target, cmdParams[1], nb) - return - - case "ping": - commands.Ping(target, nb) - return - - case "pingme": - commands.Pingme(target, message.User.DisplayName, nb) - return - - case "preview": - if msgLen == 1 { - nb.Send(target, "Usage: ()preview [channel]") - return - } else { - commands.Thumbnail(target, cmdParams[1], nb) - return - } - - case "profilepicture": - if msgLen == 1 { - nb.Send(target, "Usage: ()profilepicture [user]") - return - } - - commands.ProfilePicture(target, cmdParams[1], nb) - return - - case "pfp": - if msgLen == 1 { - nb.Send(target, "Usage: ()pfp [user]") - return - } - - commands.ProfilePicture(target, cmdParams[1], nb) - return - - // case "pyramid": - // if msgLen != 3 { - // nb.Send(target, "Usage: ()pyramid [size] [emote]") - // } else if utils.ElevatedPrivsMessage(message) { - // commands.Pyramid(target, cmdParams[1], cmdParams[2], nb) - // } else { - // nb.Send(target, "Pleb's can't pyramid FeelsBadMan") - // } - - case "randomcat": - commands.RandomCat(target, nb) - return - - case "randomdog": - commands.RandomDog(target, nb) - return - - case "randomduck": - commands.RandomDuck(target, nb) - return - - case "randomfox": - commands.RandomFox(target, nb) - return - - case "rq": - if msgLen == 1 { - nb.Send(target, "Usage: ()rq [channel] [user]") - return - } else if msgLen == 2 { - commands.RandomQuote(target, target, cmdParams[1], nb) - return - } else { - commands.RandomQuote(target, cmdParams[1], cmdParams[2], nb) - return - } - - case "randomquote": - if msgLen == 1 { - nb.Send(target, "Usage: ()randomquote [channel] [user]") - return - } else if msgLen == 2 { - commands.RandomQuote(target, target, cmdParams[1], nb) - return - } else { - commands.RandomQuote(target, cmdParams[1], cmdParams[2], nb) - return - } - - case "randomxkcd": - commands.RandomXkcd(target, nb) - return - - case "robo": - commands.RoboHash(target, message, nb) - return - - case "robohash": - commands.RoboHash(target, message, nb) - return - - case "subage": - if msgLen < 3 { - nb.Send(target, "Usage: ()subage [streamer] [user]") - return - } else { - commands.Subage(target, cmdParams[2], cmdParams[1], nb) - return - } - - case "thumb": - if msgLen == 1 { - nb.Send(target, "Usage: ()thumb [channel]") - return - } else { - commands.Thumbnail(target, cmdParams[1], nb) - return - } - - case "thumbnail": - if msgLen == 1 { - nb.Send(target, "Usage: ()thumbnail [channel]") - return - } else { - commands.Thumbnail(target, cmdParams[1], nb) - return - } - - case "title": - if msgLen == 1 { - commands.Title(target, target, nb) - return - } else { - commands.Title(target, cmdParams[1], nb) - return - } - - case "uptime": - if msgLen == 1 { - commands.Uptime(target, target, nb) - return - } else { - commands.Uptime(target, cmdParams[1], nb) - return - } - - case "uid": - if msgLen == 1 { - nb.Send(target, "Usage: ()uid [username]") - return - } else { - commands.Userid(target, cmdParams[1], nb) - return - } - - case "userid": - if msgLen == 1 { - nb.Send(target, "Usage: ()userid [username]") - return - } else { - commands.Userid(target, cmdParams[1], nb) - return - } - - case "weather": - if msgLen == 1 { - nb.Send(target, "Usage: ()weather [location]") - return - } else { - commands.Weather(target, message.Message[9:len(message.Message)], nb) - return - } - - case "whois": - if msgLen == 1 { - nb.Send(target, "Usage: ()whois [user]") - return - } else { - commands.Whois(target, cmdParams[1], nb) - return - } - - case "xd": - commands.Xd(target, nb) - return - - case "xkcd": - commands.Xkcd(target, nb) - return - - // Basically just personal commands for my own channel from here on. - - case "arch": - if target == "nouryxd" || target == "nourybot" { - personal.Arch(target, nb) - return - } else { - return - } - - case "arch2": - if target == "nouryxd" || target == "nourybot" { - personal.ArchTwo(target, nb) - return - } else { - return - } - - case "farm": - if target == "nouryxd" || target == "nourybot" { - personal.Farm(target, nb) - return - } else { - return - } - - case "justinfan": - if target == "nouryxd" || target == "nourybot" { - personal.Justinfan(target, nb) - return - } else { - return - } - - case "farming": - if target == "nouryxd" || target == "nourybot" { - personal.Farm(target, nb) - return - } else { - return - } - - case "rave": - if target == "nouryxd" || target == "nourybot" { - personal.Rave(target, nb) - return - } else { - return - } - - case "repeat": - if target == "nouryxd" || target == "nourybot" { - personal.Xset(target, nb) - return - } else { - return - } - - case "streamlink": - if target == "nouryxd" || target == "nourybot" { - personal.Streamlink(target, nb) - return - } else { - return - } - - case "streamlinkconfig": - if target == "nouryxd" || target == "nourybot" { - personal.Streamlink(target, nb) - return - } else { - return - } - - case "xset": - if target == "nouryxd" || target == "nourybot" { - personal.Xset(target, nb) - return - } else { - return - } - - case "zneix": - if target == "nouryxd" || target == "nourybot" { - personal.Zneix(target, nb) - return - } else { - return - } - - } -} diff --git a/pkg/handlers/handlers_test.go b/pkg/handlers/handlers_test.go deleted file mode 100644 index f36492f..0000000 --- a/pkg/handlers/handlers_test.go +++ /dev/null @@ -1,19 +0,0 @@ -package handlers - -import "testing" - -// Idk how to test this really we don't return anything -func TestHandlers(t *testing.T) { - t.Run("handlers package test placeholder", func(t *testing.T) { - request := 1 - response := 1 - - got := request - want := response - - if got != want { - t.Errorf("got %q, want %q", got, want) - } - - }) -} diff --git a/pkg/handlers/privatemessage.go b/pkg/handlers/privatemessage.go deleted file mode 100644 index e2a3b14..0000000 --- a/pkg/handlers/privatemessage.go +++ /dev/null @@ -1,49 +0,0 @@ -package handlers - -import ( - "github.com/gempir/go-twitch-irc/v2" - "github.com/lyx0/nourybot/cmd/bot" - log "github.com/sirupsen/logrus" -) - -// PrivateMessage checks messages for correctness and forwards -// commands to the command handler. -func PrivateMessage(message twitch.PrivateMessage, nb *bot.Bot) { - // log.Info("fn PrivateMessage") - // log.Info(message.Raw) - - // roomId is the Twitch UserID of the channel the message - // was sent in. - roomId := message.Tags["room-id"] - - // The message has no room-id so something went wrong. - if roomId == "" { - log.Error("Missing room-id in message tag", roomId) - return - } - - // General message logging. Not in use currently. - // db.InsertMessage(nb, message.User.Name, message.Channel, message.User.ID, message.Message) - - // Thing for #pajlada - if message.Channel == "pajlada" && message.Message == "pajaS 🚨 ALERT" && message.User.Name == "pajbot" && message.Action { - // log.Info(message.Message) - nb.SkipChecking("pajlada", "/me PAJAS 🚨 pajaAAAAAAAAAAA") - return - } - - // Since our command prefix is () ignore every message - // that is less than 2 - if len(message.Message) >= 2 { - // Message starts with (), pass it on to - // the command handler. - if message.Message[:2] == "()" { - Command(message, nb) - return - } - } - - // Message was no command - log.Infof("[#%s]:%s: %s", message.Channel, message.User.DisplayName, message.Message) - -} diff --git a/pkg/humanize/time.go b/pkg/humanize/time.go deleted file mode 100644 index 811a4f6..0000000 --- a/pkg/humanize/time.go +++ /dev/null @@ -1,13 +0,0 @@ -package humanize - -import ( - "time" - - "github.com/dustin/go-humanize" -) - -// Time returns a more human readable -// time as a string for a given time.Time -func Time(t time.Time) string { - return humanize.Time(t) -} diff --git a/pkg/humanize/time_test.go b/pkg/humanize/time_test.go deleted file mode 100644 index cb76dc3..0000000 --- a/pkg/humanize/time_test.go +++ /dev/null @@ -1,30 +0,0 @@ -package humanize - -import ( - "fmt" - "testing" - "time" -) - -func TestTime(t *testing.T) { - t.Run("tests the humanized time", func(t *testing.T) { - - now := time.Now() - - fmt.Println("now:", now) - - count := 10 - // then is the current time - 10 minutes. - then := now.Add(time.Duration(-count) * time.Minute) - - request := Time(then) - response := "10 minutes ago" - - got := request - want := response - - if got != want { - t.Errorf("got %v, want %v", got, want) - } - }) -} diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go deleted file mode 100644 index bf1642d..0000000 --- a/pkg/utils/utils.go +++ /dev/null @@ -1,79 +0,0 @@ -package utils - -import ( - "fmt" - "math/rand" - "strconv" - "time" - - "github.com/gempir/go-twitch-irc/v2" -) - -var ( - tempCommands = 0 -) - -// CommandUsed is called on every command and -// Incremenents tempCommands by 1 -func CommandUsed() { - tempCommands++ -} - -// GetCommandsUsed gets tempCommands and -// returns it. Only used in ping command -func GetCommandsUsed() int { - return tempCommands -} - -// StrGenerateRandomNumber generates a random number from -// a given max value as a string -func StrGenerateRandomNumber(max string) int { - num, err := strconv.Atoi(max) - if num < 1 { - return 0 - } - - if err != nil { - fmt.Printf("Supplied value %v is not a number", num) - return 0 - } else { - rand.Seed(time.Now().UnixNano()) - return rand.Intn(num) - } -} - -// GenerateRandomNumber returns a random number from -// a given max value as a int -func GenerateRandomNumber(max int) int { - rand.Seed(time.Now().UnixNano()) - return rand.Intn(max) -} - -// GenerateRandomNumberRange returns a random number -// over a given minimum and maximum range. -func GenerateRandomNumberRange(min int, max int) int { - return (rand.Intn(max-min) + min) -} - -// ElevatedPrivsMessage is checking a given message twitch.PrivateMessage -// if it came from a moderator/vip/or broadcaster and returns a bool -func ElevatedPrivsMessage(message twitch.PrivateMessage) bool { - if message.User.Badges["moderator"] == 1 || - message.User.Badges["vip"] == 1 || - message.User.Badges["broadcaster"] == 1 { - return true - } else { - return false - } -} - -// ModPrivsMessage is checking a given message twitch.PrivateMessage -// if it came from a moderator or broadcaster and returns a bool -func ModPrivsMessage(message twitch.PrivateMessage) bool { - if message.User.Badges["moderator"] == 1 || - message.User.Badges["broadcaster"] == 1 { - return true - } else { - return false - } -} diff --git a/pkg/utils/utils_test.go b/pkg/utils/utils_test.go deleted file mode 100644 index c927b4d..0000000 --- a/pkg/utils/utils_test.go +++ /dev/null @@ -1,39 +0,0 @@ -package utils - -import ( - "testing" -) - -// I don't know how to test the other ones since they are random -func TestCommandsUsed(t *testing.T) { - t.Run("tests the commands used counter", func(t *testing.T) { - - request := mockCommandsUsed(127) - response := 127 - - got := request - want := response - - if got != want { - t.Errorf("got %v, want %v", got, want) - } - - // 127 + 53 - // request = mockCommandsUsed(53) - // response = 180 - - // got = request - // want = response - - // if got != want { - // t.Errorf("got %v, want %v", got, want) - // } - }) -} - -func mockCommandsUsed(n int) int { - for i := 0; i < n; i++ { - CommandUsed() - } - return tempCommands -} From 0098d5fb487e1fdcda4694873cd0656eda06f44b Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Sun, 6 Mar 2022 20:19:55 +0100 Subject: [PATCH 02/35] start rewrite --- .gitignore | 3 +- cmd/bot/main.go | 43 ------------------- cmd/nourybot/nourybot.go | 27 ++++++++++++ go.mod | 7 ++- go.sum | 76 +++------------------------------ internal/bot/bot.go | 14 ++++++ internal/config/config.go | 34 +++++++++++++++ {pkg => internal}/db/connect.go | 2 +- pkg/db/addchannel.go | 32 -------------- pkg/db/db_test.go | 18 -------- pkg/db/initialjoin.go | 45 ------------------- pkg/db/listchannel.go | 37 ---------------- pkg/db/log_command.go | 47 -------------------- pkg/db/log_message.go | 45 ------------------- pkg/db/partchannel.go | 38 ----------------- pkg/db/typings.go | 12 ------ 16 files changed, 87 insertions(+), 393 deletions(-) delete mode 100644 cmd/bot/main.go create mode 100644 cmd/nourybot/nourybot.go create mode 100644 internal/bot/bot.go create mode 100644 internal/config/config.go rename {pkg => internal}/db/connect.go (95%) delete mode 100644 pkg/db/addchannel.go delete mode 100644 pkg/db/db_test.go delete mode 100644 pkg/db/initialjoin.go delete mode 100644 pkg/db/listchannel.go delete mode 100644 pkg/db/log_command.go delete mode 100644 pkg/db/log_message.go delete mode 100644 pkg/db/partchannel.go delete mode 100644 pkg/db/typings.go diff --git a/.gitignore b/.gitignore index 639f9cc..8823d62 100644 --- a/.gitignore +++ b/.gitignore @@ -15,5 +15,4 @@ # vendor/ .env -Nourybot -nourybot \ No newline at end of file +Nourybot \ No newline at end of file diff --git a/cmd/bot/main.go b/cmd/bot/main.go deleted file mode 100644 index 41dd854..0000000 --- a/cmd/bot/main.go +++ /dev/null @@ -1,43 +0,0 @@ -package main - -import ( - "flag" - "time" - - "github.com/gempir/go-twitch-irc/v2" - "github.com/go-delve/delve/pkg/config" - log "github.com/sirupsen/logrus" -) - -var nb *bot.Bot - -func main() { - // runMode is either dev or production so that we don't join every channel - // everytime we do a small test. - runMode := flag.String("mode", "production", "Mode in which to run. (dev/production") - flag.Parse() - - conf := config.LoadConfig() - - nb = &bot.Bot{ - TwitchClient: twitch.NewClient(conf.Username, conf.Oauth), - // MongoClient: db.Connect(conf), - Uptime: time.Now(), - } - - // Depending on the mode we run in, join different channel. - if *runMode == "production" { - log.Info("[PRODUCTION]: Joining every channel.") - - // Production, joining all regular channels - db.InitialJoin(nb) - - } else if *runMode == "dev" { - log.Info("[DEV]: Joining nouryxd and nourybot.") - - // Development, only join my two channels - nb.TwitchClient.Join("nouryxd", "nourybot") - nb.Send("nourybot", "[DEV] Badabing Badaboom Pepepains") - } - -} diff --git a/cmd/nourybot/nourybot.go b/cmd/nourybot/nourybot.go new file mode 100644 index 0000000..56f03dd --- /dev/null +++ b/cmd/nourybot/nourybot.go @@ -0,0 +1,27 @@ +package main + +import ( + "time" + + "github.com/gempir/go-twitch-irc/v3" + "github.com/lyx0/nourybot/internal/bot" + "github.com/lyx0/nourybot/internal/config" + "github.com/lyx0/nourybot/internal/db" +) + +func main() { + cfg := config.LoadConfig() + + twitchClient := twitch.NewClient(cfg.Username, cfg.Oauth) + now := time.Now() + mongoClient := db.Connect(cfg) + + nb := &bot.Bot{ + TwitchClient: twitchClient, + MongoClient: mongoClient, + Uptime: now, + } + + nb.TwitchClient.Join("nourybot") + nb.TwitchClient.Connect() +} diff --git a/go.mod b/go.mod index c08b916..4e2937e 100644 --- a/go.mod +++ b/go.mod @@ -3,11 +3,10 @@ module github.com/lyx0/nourybot go 1.17 require ( - github.com/dustin/go-humanize v1.0.0 - github.com/gempir/go-twitch-irc/v2 v2.5.0 + github.com/gempir/go-twitch-irc/v3 v3.0.0 github.com/joho/godotenv v1.4.0 github.com/sirupsen/logrus v1.8.1 - go.mongodb.org/mongo-driver v1.7.3 + go.mongodb.org/mongo-driver v1.8.4 ) require ( @@ -19,7 +18,7 @@ require ( github.com/xdg-go/scram v1.0.2 // indirect github.com/xdg-go/stringprep v1.0.2 // indirect github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect - golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 // indirect + golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f // indirect golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e // indirect golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 // indirect golang.org/x/text v0.3.5 // indirect diff --git a/go.sum b/go.sum index 0b36145..418a086 100644 --- a/go.sum +++ b/go.sum @@ -1,78 +1,30 @@ -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/gempir/go-twitch-irc/v2 v2.5.0 h1:aybXNoyDNQaa4vHhXb0UpIDmspqutQUmXIYUFsjgecU= -github.com/gempir/go-twitch-irc/v2 v2.5.0/go.mod h1:120d2SdlRYg8tRnZwsyNPeS+mWPn+YmNEzB7Bv/CDGE= +github.com/gempir/go-twitch-irc/v3 v3.0.0 h1:e34R+9BdKy+qrO/wN+FCt+BUtyn38gCnJuKWscIKbl4= +github.com/gempir/go-twitch-irc/v3 v3.0.0/go.mod h1:/W9KZIiyizVecp4PEb7kc4AlIyXKiCmvlXrzlpPUytU= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= -github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= -github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= -github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= -github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= -github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= -github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= -github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= -github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= -github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= -github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= -github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= -github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= -github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= -github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= -github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= -github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= -github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= -github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= -github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= -github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= -github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= -github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= -github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= -github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= -github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= @@ -85,42 +37,28 @@ github.com/xdg-go/stringprep v1.0.2 h1:6iq84/ryjjeRmMJwxutI51F2GIPlP5BfTvXHeYjyh github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= -go.mongodb.org/mongo-driver v1.7.3 h1:G4l/eYY9VrQAK/AUgkV0koQKzQnyddnWxrd/Etf0jIs= -go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +go.mongodb.org/mongo-driver v1.8.4 h1:NruvZPPL0PBcRJKmbswoWSrmHeUvzdxA3GCPfD/NEOA= +go.mongodb.org/mongo-driver v1.8.4/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCuAROlKEPY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= -golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 h1:xMPOj6Pz6UipU1wXLkrtqpHbR0AVFnyPEQq/wRWz9lM= -golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f h1:aZp0e2vLN4MToVqnjNEYEtrEA8RH8U8FN1CU7JgqsPU= +golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/bot/bot.go b/internal/bot/bot.go new file mode 100644 index 0000000..475a416 --- /dev/null +++ b/internal/bot/bot.go @@ -0,0 +1,14 @@ +package bot + +import ( + "time" + + twitch "github.com/gempir/go-twitch-irc/v3" + "go.mongodb.org/mongo-driver/mongo" +) + +type Bot struct { + TwitchClient *twitch.Client + MongoClient *mongo.Client + Uptime time.Time +} diff --git a/internal/config/config.go b/internal/config/config.go new file mode 100644 index 0000000..8587620 --- /dev/null +++ b/internal/config/config.go @@ -0,0 +1,34 @@ +package config + +import ( + "os" + + "github.com/joho/godotenv" + log "github.com/sirupsen/logrus" +) + +type Config struct { + Username string + Oauth string + BotUserId string + MongoURI string +} + +func LoadConfig() *Config { + err := godotenv.Load() + + if err != nil { + log.Fatal("Error loading .env") + } + + cfg := &Config{ + Username: os.Getenv("TWITCH_USER"), + Oauth: os.Getenv("TWITCH_PASS"), + BotUserId: os.Getenv("BOT_USER_ID"), + MongoURI: os.Getenv("MONGO_URI"), + } + + log.Info("Config loaded succesfully") + + return cfg +} diff --git a/pkg/db/connect.go b/internal/db/connect.go similarity index 95% rename from pkg/db/connect.go rename to internal/db/connect.go index 89be5e6..8ec13be 100644 --- a/pkg/db/connect.go +++ b/internal/db/connect.go @@ -4,7 +4,7 @@ import ( "context" "time" - "github.com/lyx0/nourybot/pkg/config" + "github.com/lyx0/nourybot/internal/config" log "github.com/sirupsen/logrus" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" diff --git a/pkg/db/addchannel.go b/pkg/db/addchannel.go deleted file mode 100644 index 066b989..0000000 --- a/pkg/db/addchannel.go +++ /dev/null @@ -1,32 +0,0 @@ -package db - -import ( - "context" - "fmt" - "time" - - "github.com/lyx0/nourybot/cmd/bot" - log "github.com/sirupsen/logrus" -) - -// AddChannel adds a given channel name to the database. -func AddChannel(target, channelName string, nb *bot.Bot) { - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - collection := nb.MongoClient.Database("nourybot").Collection("channels") - - // Channel - // {{"name": string}, {"connect": bool}} - chnl := Channel{channelName, true} - - _, insertErr := collection.InsertOne(ctx, chnl) - if insertErr != nil { - nb.Send(target, fmt.Sprintf("Error trying to join %s", channelName)) - log.Error(insertErr) - return - } - - nb.TwitchClient.Join(channelName) - nb.Send(target, fmt.Sprintf("Joined %s", channelName)) -} diff --git a/pkg/db/db_test.go b/pkg/db/db_test.go deleted file mode 100644 index 0a9e3ed..0000000 --- a/pkg/db/db_test.go +++ /dev/null @@ -1,18 +0,0 @@ -package db - -import "testing" - -func TestDb(t *testing.T) { - t.Run("db package test placeholder", func(t *testing.T) { - request := 1 - response := 1 - - got := request - want := response - - if got != want { - t.Errorf("got %q, want %q", got, want) - } - - }) -} diff --git a/pkg/db/initialjoin.go b/pkg/db/initialjoin.go deleted file mode 100644 index 757c7a4..0000000 --- a/pkg/db/initialjoin.go +++ /dev/null @@ -1,45 +0,0 @@ -package db - -import ( - "context" - "fmt" - "time" - - "github.com/lyx0/nourybot/cmd/bot" - log "github.com/sirupsen/logrus" - "go.mongodb.org/mongo-driver/bson" -) - -// InitialJoin is called everytime the Bot starts and joins the -// initial list of twitch channels it should be in. -func InitialJoin(nb *bot.Bot) { - collection := nb.MongoClient.Database("nourybot").Collection("channels") - - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - // defer nb.MongoClient.Disconnect(ctx) - - cur, currErr := collection.Find(ctx, bson.D{}) - - if currErr != nil { - panic(currErr) - } - defer cur.Close(ctx) - - var channels []Channel - if err := cur.All(ctx, &channels); err != nil { - panic(err) - } - - channelCount := 0 - - for _, ch := range channels { - nb.TwitchClient.Join(ch.Name) - // nb.TwitchClient.Say(ch.Name, "xd") - channelCount++ - log.Infof("Joined: %s\n", ch.Name) - } - // It worked - nb.Send("nourybot", fmt.Sprintf("Badabing Badaboom Pepepains Joined %v channel", channelCount)) -} diff --git a/pkg/db/listchannel.go b/pkg/db/listchannel.go deleted file mode 100644 index 4122bdb..0000000 --- a/pkg/db/listchannel.go +++ /dev/null @@ -1,37 +0,0 @@ -package db - -import ( - "context" - "time" - - "github.com/lyx0/nourybot/cmd/bot" - "go.mongodb.org/mongo-driver/bson" -) - -// Listchannel reads the list of channel from the database and -// whispers them to my own account. -func ListChannel(nb *bot.Bot) { - collection := nb.MongoClient.Database("nourybot").Collection("channels") - - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - cur, currErr := collection.Find(ctx, bson.D{}) - - if currErr != nil { - panic(currErr) - } - defer cur.Close(ctx) - - var channels []Channel - if err := cur.All(ctx, &channels); err != nil { - panic(err) - } - - channelList := "" - for _, ch := range channels { - channelList += ch.Name + " " - } - - nb.TwitchClient.Whisper("nouryxd", channelList) -} diff --git a/pkg/db/log_command.go b/pkg/db/log_command.go deleted file mode 100644 index 4ba097a..0000000 --- a/pkg/db/log_command.go +++ /dev/null @@ -1,47 +0,0 @@ -package db - -import ( - "context" - "time" - - "github.com/lyx0/nourybot/cmd/bot" - "github.com/sirupsen/logrus" -) - -type logCommand struct { - CommandName string `json:"command_name"` - LoginName string `json:"login_name"` - Channel string `json:"channel"` - UserID string `json:"user_id"` - Text string `json:"message"` -} - -func (l *logCommand) insert(nb *bot.Bot, commandName, name, channel, id, text string) error { - logrus.Info("logging command") - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) - defer cancel() - - collection := nb.MongoClient.Database("nourybot").Collection("commandLogs") - - _, err := collection.InsertOne(ctx, &logCommand{ - LoginName: name, - Channel: channel, - UserID: id, - Text: text, - CommandName: commandName, - }) - if err != nil { - logrus.Info("failed to log command") - return err - } - return nil -} - -// InsertCommand is called on every message that invokes a command -// and inserts the message and command details into the database. -func InsertCommand(nb *bot.Bot, commandName, name, channel, id, text string) { - err := (&logCommand{}).insert(nb, commandName, name, channel, id, text) - if err != nil { - logrus.Info("failed to log command") - } -} diff --git a/pkg/db/log_message.go b/pkg/db/log_message.go deleted file mode 100644 index 4e57336..0000000 --- a/pkg/db/log_message.go +++ /dev/null @@ -1,45 +0,0 @@ -package db - -import ( - "context" - "time" - - "github.com/lyx0/nourybot/cmd/bot" - "github.com/sirupsen/logrus" -) - -type logMessage struct { - LoginName string `json:"login_name"` - Channel string `json:"channel"` - UserID string `json:"user_id"` - Text string `json:"message"` -} - -func (l *logMessage) insert(nb *bot.Bot, name, channel, id, text string) error { - logrus.Info("logging message") - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) - defer cancel() - - collection := nb.MongoClient.Database("nourybot").Collection("messageLogs") - - _, err := collection.InsertOne(ctx, &logMessage{ - LoginName: name, - Channel: channel, - UserID: id, - Text: text, - }) - if err != nil { - logrus.Info("failed to log message") - return err - } - return nil -} - -// InsertMessage is called on every message and logs message details -// into the database. -func InsertMessage(nb *bot.Bot, name, channel, id, text string) { - err := (&logMessage{}).insert(nb, name, channel, id, text) - if err != nil { - logrus.Info("failed to log message") - } -} diff --git a/pkg/db/partchannel.go b/pkg/db/partchannel.go deleted file mode 100644 index f9c734c..0000000 --- a/pkg/db/partchannel.go +++ /dev/null @@ -1,38 +0,0 @@ -package db - -import ( - "context" - "fmt" - "time" - - "github.com/lyx0/nourybot/cmd/bot" - log "github.com/sirupsen/logrus" -) - -// PartChannel takes in a target channel and querys the database for -// its name. If the channel is found it deletes the channel and returns a -// success message. If the channel couldn't be found it will return an error. -func PartChannel(target, channelName string, nb *bot.Bot) { - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - collection := nb.MongoClient.Database("nourybot").Collection("channels") - - // Channel - // {{"name": string}, {"connect": bool}} - chnl := Channel{channelName, true} - - res, insertErr := collection.DeleteOne(ctx, chnl) - - // res.DeletedCount is 0 if trying to delete something that wasn't there. - if insertErr != nil || res.DeletedCount != 1 { - nb.Send(target, fmt.Sprintf("Error trying to part %s", channelName)) - log.Error(insertErr) - return - } - - nb.TwitchClient.Depart(channelName) - nb.Send(target, fmt.Sprintf("Parted %s", channelName)) - - // log.Info(res) -} diff --git a/pkg/db/typings.go b/pkg/db/typings.go deleted file mode 100644 index d49888f..0000000 --- a/pkg/db/typings.go +++ /dev/null @@ -1,12 +0,0 @@ -package db - -type Channel struct { - Name string `bson:"name,omitempty"` - Connect bool `bson:"connect,omitempty"` -} - -// type Command struct { -// Name string `bson:"name,omitempty"` -// Text string `bson:"text,omitempty"` -// Channel string `bson:"channel,omitempty"` -// } From fab09d68ae20e3ce7efcb3d5ea864d7711e9750b Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Sun, 6 Mar 2022 20:40:00 +0100 Subject: [PATCH 03/35] fix .env --- cmd/nourybot/nourybot.go | 9 ++++++++- internal/config/config.go | 4 ++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/cmd/nourybot/nourybot.go b/cmd/nourybot/nourybot.go index 56f03dd..491b1be 100644 --- a/cmd/nourybot/nourybot.go +++ b/cmd/nourybot/nourybot.go @@ -7,10 +7,12 @@ import ( "github.com/lyx0/nourybot/internal/bot" "github.com/lyx0/nourybot/internal/config" "github.com/lyx0/nourybot/internal/db" + "github.com/sirupsen/logrus" ) func main() { cfg := config.LoadConfig() + logrus.Info(cfg.Username, cfg.Oauth) twitchClient := twitch.NewClient(cfg.Username, cfg.Oauth) now := time.Now() @@ -23,5 +25,10 @@ func main() { } nb.TwitchClient.Join("nourybot") - nb.TwitchClient.Connect() + + err := nb.TwitchClient.Connect() + if err != nil { + panic(err) + } + } diff --git a/internal/config/config.go b/internal/config/config.go index 8587620..ac49088 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -22,8 +22,8 @@ func LoadConfig() *Config { } cfg := &Config{ - Username: os.Getenv("TWITCH_USER"), - Oauth: os.Getenv("TWITCH_PASS"), + Username: os.Getenv("BOT_USERNAME"), + Oauth: os.Getenv("BOT_PASS"), BotUserId: os.Getenv("BOT_USER_ID"), MongoURI: os.Getenv("MONGO_URI"), } From 61946d64024f3050dca887dae22b2e4cb912f2f1 Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Mon, 7 Mar 2022 16:45:16 +0100 Subject: [PATCH 04/35] add Admin config variables --- cmd/nourybot/nourybot.go | 4 ++++ internal/config/config.go | 20 +++++++++++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/cmd/nourybot/nourybot.go b/cmd/nourybot/nourybot.go index 491b1be..ca32ff3 100644 --- a/cmd/nourybot/nourybot.go +++ b/cmd/nourybot/nourybot.go @@ -26,6 +26,10 @@ func main() { nb.TwitchClient.Join("nourybot") + nb.TwitchClient.OnConnect(func() { + nb.TwitchClient.Say("nourybot", "xd") + }) + err := nb.TwitchClient.Connect() if err != nil { panic(err) diff --git a/internal/config/config.go b/internal/config/config.go index ac49088..a1bafff 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -8,10 +8,17 @@ import ( ) type Config struct { + // Bot Username string - Oauth string BotUserId string - MongoURI string + Oauth string + + // Admin + AdminUsername string + AdminUserId string + + // DB + MongoURI string } func LoadConfig() *Config { @@ -22,10 +29,17 @@ func LoadConfig() *Config { } cfg := &Config{ + // Bot Username: os.Getenv("BOT_USERNAME"), Oauth: os.Getenv("BOT_PASS"), BotUserId: os.Getenv("BOT_USER_ID"), - MongoURI: os.Getenv("MONGO_URI"), + + // Admin + AdminUsername: os.Getenv("ADMIN_USER_NAME"), + AdminUserId: os.Getenv("ADMIN_USER_ID"), + + // DB + MongoURI: os.Getenv("MONGO_URI"), } log.Info("Config loaded succesfully") From b7daac2619820e2f75cdf03d32f3bc32e53e42b2 Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Thu, 10 Mar 2022 23:00:37 +0100 Subject: [PATCH 05/35] restructure --- Makefile | 10 +++++---- cmd/bot/bot.go | 17 +++++++++++++++ cmd/bot/main.go | 35 +++++++++++++++++++++++++++++ cmd/nourybot/nourybot.go | 38 -------------------------------- internal/bot/bot.go | 13 ----------- internal/config/config.go | 3 ++- internal/db/connect.go | 46 --------------------------------------- migrations/nourybot.sql | 39 +++++++++++++++++++++++++++++++++ 8 files changed, 99 insertions(+), 102 deletions(-) create mode 100644 cmd/bot/bot.go create mode 100644 cmd/bot/main.go delete mode 100644 cmd/nourybot/nourybot.go delete mode 100644 internal/db/connect.go create mode 100644 migrations/nourybot.sql diff --git a/Makefile b/Makefile index fda9904..35a50d4 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,14 @@ build: - cd cmd && go build -o Nourybot + cd cmd/bot && go build -o Nourybot run: - cd cmd && ./Nourybot + cd cmd/bot && ./Nourybot dev: - cd cmd && go build -o Nourybot && ./Nourybot -mode dev + cd cmd/bot && go build -o Nourybot && ./Nourybot -mode dev prod: - cd cmd && go build -o Nourybot && ./Nourybot -mode production + cd cmd/bot && go build -o Nourybot && ./Nourybot -mode production +xd: + cd cmd/bot && go build -o Nourybot && ./Nourybot \ No newline at end of file diff --git a/cmd/bot/bot.go b/cmd/bot/bot.go new file mode 100644 index 0000000..3ca1b77 --- /dev/null +++ b/cmd/bot/bot.go @@ -0,0 +1,17 @@ +package main + +func (nb *nourybot) connect() error { + nb.twitchClient.Join("nourybot") + + err := nb.twitchClient.Connect() + if err != nil { + panic(err) + } + + nb.twitchClient.Say("nourybot", "xd") + return nil +} + +func (nb *nourybot) onConnect() { + nb.twitchClient.Say("nourybot", "xd") +} diff --git a/cmd/bot/main.go b/cmd/bot/main.go new file mode 100644 index 0000000..09bf1ee --- /dev/null +++ b/cmd/bot/main.go @@ -0,0 +1,35 @@ +package main + +import ( + "time" + + "github.com/gempir/go-twitch-irc/v3" + "github.com/lyx0/nourybot/internal/config" + "github.com/sirupsen/logrus" +) + +type nourybot struct { + twitchClient *twitch.Client + uptime time.Time +} + +func main() { + cfg := config.LoadConfig() + logrus.Info(cfg.Username, cfg.Oauth) + + twitchClient := twitch.NewClient(cfg.Username, cfg.Oauth) + now := time.Now() + + nb := &nourybot{ + twitchClient: twitchClient, + uptime: now, + } + + nb.twitchClient.OnConnect(nb.onConnect) + + err := nb.connect() + if err != nil { + panic(err) + } + +} diff --git a/cmd/nourybot/nourybot.go b/cmd/nourybot/nourybot.go deleted file mode 100644 index ca32ff3..0000000 --- a/cmd/nourybot/nourybot.go +++ /dev/null @@ -1,38 +0,0 @@ -package main - -import ( - "time" - - "github.com/gempir/go-twitch-irc/v3" - "github.com/lyx0/nourybot/internal/bot" - "github.com/lyx0/nourybot/internal/config" - "github.com/lyx0/nourybot/internal/db" - "github.com/sirupsen/logrus" -) - -func main() { - cfg := config.LoadConfig() - logrus.Info(cfg.Username, cfg.Oauth) - - twitchClient := twitch.NewClient(cfg.Username, cfg.Oauth) - now := time.Now() - mongoClient := db.Connect(cfg) - - nb := &bot.Bot{ - TwitchClient: twitchClient, - MongoClient: mongoClient, - Uptime: now, - } - - nb.TwitchClient.Join("nourybot") - - nb.TwitchClient.OnConnect(func() { - nb.TwitchClient.Say("nourybot", "xd") - }) - - err := nb.TwitchClient.Connect() - if err != nil { - panic(err) - } - -} diff --git a/internal/bot/bot.go b/internal/bot/bot.go index 475a416..7e49431 100644 --- a/internal/bot/bot.go +++ b/internal/bot/bot.go @@ -1,14 +1 @@ package bot - -import ( - "time" - - twitch "github.com/gempir/go-twitch-irc/v3" - "go.mongodb.org/mongo-driver/mongo" -) - -type Bot struct { - TwitchClient *twitch.Client - MongoClient *mongo.Client - Uptime time.Time -} diff --git a/internal/config/config.go b/internal/config/config.go index a1bafff..d122efa 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -12,12 +12,12 @@ type Config struct { Username string BotUserId string Oauth string - // Admin AdminUsername string AdminUserId string // DB + MySQLURI string MongoURI string } @@ -39,6 +39,7 @@ func LoadConfig() *Config { AdminUserId: os.Getenv("ADMIN_USER_ID"), // DB + MySQLURI: os.Getenv("MYSQL_URI"), MongoURI: os.Getenv("MONGO_URI"), } diff --git a/internal/db/connect.go b/internal/db/connect.go deleted file mode 100644 index 8ec13be..0000000 --- a/internal/db/connect.go +++ /dev/null @@ -1,46 +0,0 @@ -package db - -import ( - "context" - "time" - - "github.com/lyx0/nourybot/internal/config" - log "github.com/sirupsen/logrus" - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/mongo" - "go.mongodb.org/mongo-driver/mongo/options" -) - -// Connect connects the the MongoDB database through a supplied cfg -// and returns a *mongo.Client -func Connect(cfg *config.Config) *mongo.Client { - client, err := mongo.NewClient(options.Client().ApplyURI(cfg.MongoURI)) - if err != nil { - log.Fatal(err) - } - - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - err = client.Connect(ctx) - if err != nil { - log.Fatal(err) - } - // defer client.Disconnect(ctx) - - err = client.Ping(context.TODO(), nil) - if err != nil { - log.Fatal(err) - } - - log.Info("Connected to MongoDB!") - - databases, err := client.ListDatabaseNames(ctx, bson.M{}) - if err != nil { - log.Fatal(err) - } - _ = databases - // log.Info(databases) - - return client -} diff --git a/migrations/nourybot.sql b/migrations/nourybot.sql new file mode 100644 index 0000000..ce28e5c --- /dev/null +++ b/migrations/nourybot.sql @@ -0,0 +1,39 @@ +CREATE DATABASE nourybot CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +USE nourybot; + +-- create a 'channel' table. +CREATE TABLE channel ( + id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, + username VARCHAR(50) NOT NULL, + twitchid VARCHAR(50) NOT NULL, + added DATETIME NOT NULL +); + +-- add an index on the created column. +CREATE INDEX idx_channel_created ON channel(added); + +-- add dummy records +INSERT INTO channel (username, twitchid, added) VALUES ( + 'whereismymnd', + '31437432', + UTC_TIMESTAMP() +); + +INSERT INTO channel (username, twitchid, added) VALUES ( + 'nourybot', + '596581605', + UTC_TIMESTAMP() +); + +INSERT INTO channel (username, twitchid, added) VALUES ( + 'xnoury', + '197780373', + UTC_TIMESTAMP() +); + +-- Important: Make sure to swap 'pass' and 'username' with a password/user of your own choosing. +CREATE USER 'username'@'localhost'; +GRANT SELECT, INSERT ON nourybot.* TO 'username'@'localhost'; + +ALTER USER 'username'@'localhost' IDENTIFIED BY 'pass'; \ No newline at end of file From 1ebf4df8e778b66036fb45d2fd3a53d480e891b9 Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Thu, 10 Mar 2022 23:27:06 +0100 Subject: [PATCH 06/35] add onConnect callback --- cmd/bot/bot.go | 11 ++++++++++- cmd/bot/command.go | 1 + cmd/bot/main.go | 4 ++++ go.mod | 13 +------------ go.sum | 44 -------------------------------------------- 5 files changed, 16 insertions(+), 57 deletions(-) create mode 100644 cmd/bot/command.go diff --git a/cmd/bot/bot.go b/cmd/bot/bot.go index 3ca1b77..654c393 100644 --- a/cmd/bot/bot.go +++ b/cmd/bot/bot.go @@ -1,17 +1,26 @@ package main +import ( + "github.com/gempir/go-twitch-irc/v3" + "github.com/sirupsen/logrus" +) + func (nb *nourybot) connect() error { nb.twitchClient.Join("nourybot") + logrus.Info("Connecting to Twitch...") err := nb.twitchClient.Connect() if err != nil { panic(err) } - nb.twitchClient.Say("nourybot", "xd") return nil } func (nb *nourybot) onConnect() { nb.twitchClient.Say("nourybot", "xd") } + +func (nb *nourybot) onPrivateMessage(message twitch.PrivateMessage) { + logrus.Info(message.Message) +} diff --git a/cmd/bot/command.go b/cmd/bot/command.go new file mode 100644 index 0000000..06ab7d0 --- /dev/null +++ b/cmd/bot/command.go @@ -0,0 +1 @@ +package main diff --git a/cmd/bot/main.go b/cmd/bot/main.go index 09bf1ee..f7f1eb9 100644 --- a/cmd/bot/main.go +++ b/cmd/bot/main.go @@ -25,6 +25,10 @@ func main() { uptime: now, } + nb.twitchClient.OnPrivateMessage(func(message twitch.PrivateMessage) { + nb.onPrivateMessage(message) + }) + nb.twitchClient.OnConnect(nb.onConnect) err := nb.connect() diff --git a/go.mod b/go.mod index 4e2937e..f7e2a71 100644 --- a/go.mod +++ b/go.mod @@ -6,20 +6,9 @@ require ( github.com/gempir/go-twitch-irc/v3 v3.0.0 github.com/joho/godotenv v1.4.0 github.com/sirupsen/logrus v1.8.1 - go.mongodb.org/mongo-driver v1.8.4 ) require ( - github.com/go-stack/stack v1.8.0 // indirect - github.com/golang/snappy v0.0.1 // indirect - github.com/klauspost/compress v1.13.6 // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/xdg-go/pbkdf2 v1.0.0 // indirect - github.com/xdg-go/scram v1.0.2 // indirect - github.com/xdg-go/stringprep v1.0.2 // indirect - github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect - golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f // indirect - golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e // indirect + github.com/stretchr/testify v1.6.1 // indirect golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 // indirect - golang.org/x/text v0.3.5 // indirect ) diff --git a/go.sum b/go.sum index 418a086..8990637 100644 --- a/go.sum +++ b/go.sum @@ -3,22 +3,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/gempir/go-twitch-irc/v3 v3.0.0 h1:e34R+9BdKy+qrO/wN+FCt+BUtyn38gCnJuKWscIKbl4= github.com/gempir/go-twitch-irc/v3 v3.0.0/go.mod h1:/W9KZIiyizVecp4PEb7kc4AlIyXKiCmvlXrzlpPUytU= -github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= -github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= -github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= @@ -27,38 +13,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= -github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= -github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.0.2 h1:akYIkZ28e6A96dkWNJQu3nmCzH3YfwMPQExUYDaRv7w= -github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= -github.com/xdg-go/stringprep v1.0.2 h1:6iq84/ryjjeRmMJwxutI51F2GIPlP5BfTvXHeYjyhBc= -github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= -github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= -github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= -go.mongodb.org/mongo-driver v1.8.4 h1:NruvZPPL0PBcRJKmbswoWSrmHeUvzdxA3GCPfD/NEOA= -go.mongodb.org/mongo-driver v1.8.4/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCuAROlKEPY= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f h1:aZp0e2vLN4MToVqnjNEYEtrEA8RH8U8FN1CU7JgqsPU= -golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From ddca49605c8d405359be2fd242884985df3029cf Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Thu, 10 Mar 2022 23:41:13 +0100 Subject: [PATCH 07/35] add database models --- cmd/bot/main.go | 26 +++++++++++++++++++++++++- go.mod | 1 + go.sum | 2 ++ pkg/models/models.go | 15 +++++++++++++++ pkg/models/mysql/channel.go | 23 +++++++++++++++++++++++ 5 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 pkg/models/models.go create mode 100644 pkg/models/mysql/channel.go diff --git a/cmd/bot/main.go b/cmd/bot/main.go index f7f1eb9..0b71705 100644 --- a/cmd/bot/main.go +++ b/cmd/bot/main.go @@ -1,16 +1,22 @@ package main import ( + "database/sql" + "log" "time" "github.com/gempir/go-twitch-irc/v3" "github.com/lyx0/nourybot/internal/config" + "github.com/lyx0/nourybot/pkg/models/mysql" "github.com/sirupsen/logrus" + + _ "github.com/go-sql-driver/mysql" ) type nourybot struct { twitchClient *twitch.Client uptime time.Time + channels *mysql.ChannelModel } func main() { @@ -20,9 +26,16 @@ func main() { twitchClient := twitch.NewClient(cfg.Username, cfg.Oauth) now := time.Now() + db, err := openDB(cfg.MySQLURI) + if err != nil { + log.Fatal(err) + } + + defer db.Close() nb := &nourybot{ twitchClient: twitchClient, uptime: now, + channels: &mysql.ChannelModel{DB: db}, } nb.twitchClient.OnPrivateMessage(func(message twitch.PrivateMessage) { @@ -31,9 +44,20 @@ func main() { nb.twitchClient.OnConnect(nb.onConnect) - err := nb.connect() + err = nb.connect() if err != nil { panic(err) } } + +func openDB(dsn string) (*sql.DB, error) { + db, err := sql.Open("mysql", dsn) + if err != nil { + return nil, err + } + if err = db.Ping(); err != nil { + return nil, err + } + return db, nil +} diff --git a/go.mod b/go.mod index f7e2a71..0dd7232 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.17 require ( github.com/gempir/go-twitch-irc/v3 v3.0.0 + github.com/go-sql-driver/mysql v1.6.0 github.com/joho/godotenv v1.4.0 github.com/sirupsen/logrus v1.8.1 ) diff --git a/go.sum b/go.sum index 8990637..ca9376e 100644 --- a/go.sum +++ b/go.sum @@ -3,6 +3,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/gempir/go-twitch-irc/v3 v3.0.0 h1:e34R+9BdKy+qrO/wN+FCt+BUtyn38gCnJuKWscIKbl4= github.com/gempir/go-twitch-irc/v3 v3.0.0/go.mod h1:/W9KZIiyizVecp4PEb7kc4AlIyXKiCmvlXrzlpPUytU= +github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= diff --git a/pkg/models/models.go b/pkg/models/models.go new file mode 100644 index 0000000..af97f62 --- /dev/null +++ b/pkg/models/models.go @@ -0,0 +1,15 @@ +package models + +import ( + "errors" + "time" +) + +var ErrNoRecord = errors.New("models: no matching record found") + +type Channel struct { + ID int + Username string + TwitchID string + Added time.Time +} diff --git a/pkg/models/mysql/channel.go b/pkg/models/mysql/channel.go new file mode 100644 index 0000000..87c3da6 --- /dev/null +++ b/pkg/models/mysql/channel.go @@ -0,0 +1,23 @@ +package mysql + +import ( + "database/sql" + + "github.com/lyx0/nourybot/pkg/models" +) + +type ChannelModel struct { + DB *sql.DB +} + +func (m *ChannelModel) Insert(username string, twitchid string) (int, error) { + return 0, nil +} + +func (m *ChannelModel) Get(id int) (*models.Channel, error) { + return nil, nil +} + +func (m *ChannelModel) Latest() ([]*models.Channel, error) { + return nil, nil +} From a2a99b81ebee56c096bea6e545b4da22c23338df Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Fri, 15 Apr 2022 23:11:42 +0200 Subject: [PATCH 08/35] start new --- cmd/bot/bot.go | 26 --------------- cmd/bot/command.go | 1 - cmd/bot/main.go | 63 ------------------------------------- internal/bot/bot.go | 1 - internal/config/config.go | 49 ----------------------------- migrations/nourybot.sql | 39 ----------------------- pkg/models/models.go | 15 --------- pkg/models/mysql/channel.go | 23 -------------- 8 files changed, 217 deletions(-) delete mode 100644 cmd/bot/bot.go delete mode 100644 cmd/bot/command.go delete mode 100644 cmd/bot/main.go delete mode 100644 internal/bot/bot.go delete mode 100644 internal/config/config.go delete mode 100644 migrations/nourybot.sql delete mode 100644 pkg/models/models.go delete mode 100644 pkg/models/mysql/channel.go diff --git a/cmd/bot/bot.go b/cmd/bot/bot.go deleted file mode 100644 index 654c393..0000000 --- a/cmd/bot/bot.go +++ /dev/null @@ -1,26 +0,0 @@ -package main - -import ( - "github.com/gempir/go-twitch-irc/v3" - "github.com/sirupsen/logrus" -) - -func (nb *nourybot) connect() error { - nb.twitchClient.Join("nourybot") - - logrus.Info("Connecting to Twitch...") - err := nb.twitchClient.Connect() - if err != nil { - panic(err) - } - - return nil -} - -func (nb *nourybot) onConnect() { - nb.twitchClient.Say("nourybot", "xd") -} - -func (nb *nourybot) onPrivateMessage(message twitch.PrivateMessage) { - logrus.Info(message.Message) -} diff --git a/cmd/bot/command.go b/cmd/bot/command.go deleted file mode 100644 index 06ab7d0..0000000 --- a/cmd/bot/command.go +++ /dev/null @@ -1 +0,0 @@ -package main diff --git a/cmd/bot/main.go b/cmd/bot/main.go deleted file mode 100644 index 0b71705..0000000 --- a/cmd/bot/main.go +++ /dev/null @@ -1,63 +0,0 @@ -package main - -import ( - "database/sql" - "log" - "time" - - "github.com/gempir/go-twitch-irc/v3" - "github.com/lyx0/nourybot/internal/config" - "github.com/lyx0/nourybot/pkg/models/mysql" - "github.com/sirupsen/logrus" - - _ "github.com/go-sql-driver/mysql" -) - -type nourybot struct { - twitchClient *twitch.Client - uptime time.Time - channels *mysql.ChannelModel -} - -func main() { - cfg := config.LoadConfig() - logrus.Info(cfg.Username, cfg.Oauth) - - twitchClient := twitch.NewClient(cfg.Username, cfg.Oauth) - now := time.Now() - - db, err := openDB(cfg.MySQLURI) - if err != nil { - log.Fatal(err) - } - - defer db.Close() - nb := &nourybot{ - twitchClient: twitchClient, - uptime: now, - channels: &mysql.ChannelModel{DB: db}, - } - - nb.twitchClient.OnPrivateMessage(func(message twitch.PrivateMessage) { - nb.onPrivateMessage(message) - }) - - nb.twitchClient.OnConnect(nb.onConnect) - - err = nb.connect() - if err != nil { - panic(err) - } - -} - -func openDB(dsn string) (*sql.DB, error) { - db, err := sql.Open("mysql", dsn) - if err != nil { - return nil, err - } - if err = db.Ping(); err != nil { - return nil, err - } - return db, nil -} diff --git a/internal/bot/bot.go b/internal/bot/bot.go deleted file mode 100644 index 7e49431..0000000 --- a/internal/bot/bot.go +++ /dev/null @@ -1 +0,0 @@ -package bot diff --git a/internal/config/config.go b/internal/config/config.go deleted file mode 100644 index d122efa..0000000 --- a/internal/config/config.go +++ /dev/null @@ -1,49 +0,0 @@ -package config - -import ( - "os" - - "github.com/joho/godotenv" - log "github.com/sirupsen/logrus" -) - -type Config struct { - // Bot - Username string - BotUserId string - Oauth string - // Admin - AdminUsername string - AdminUserId string - - // DB - MySQLURI string - MongoURI string -} - -func LoadConfig() *Config { - err := godotenv.Load() - - if err != nil { - log.Fatal("Error loading .env") - } - - cfg := &Config{ - // Bot - Username: os.Getenv("BOT_USERNAME"), - Oauth: os.Getenv("BOT_PASS"), - BotUserId: os.Getenv("BOT_USER_ID"), - - // Admin - AdminUsername: os.Getenv("ADMIN_USER_NAME"), - AdminUserId: os.Getenv("ADMIN_USER_ID"), - - // DB - MySQLURI: os.Getenv("MYSQL_URI"), - MongoURI: os.Getenv("MONGO_URI"), - } - - log.Info("Config loaded succesfully") - - return cfg -} diff --git a/migrations/nourybot.sql b/migrations/nourybot.sql deleted file mode 100644 index ce28e5c..0000000 --- a/migrations/nourybot.sql +++ /dev/null @@ -1,39 +0,0 @@ -CREATE DATABASE nourybot CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - -USE nourybot; - --- create a 'channel' table. -CREATE TABLE channel ( - id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, - username VARCHAR(50) NOT NULL, - twitchid VARCHAR(50) NOT NULL, - added DATETIME NOT NULL -); - --- add an index on the created column. -CREATE INDEX idx_channel_created ON channel(added); - --- add dummy records -INSERT INTO channel (username, twitchid, added) VALUES ( - 'whereismymnd', - '31437432', - UTC_TIMESTAMP() -); - -INSERT INTO channel (username, twitchid, added) VALUES ( - 'nourybot', - '596581605', - UTC_TIMESTAMP() -); - -INSERT INTO channel (username, twitchid, added) VALUES ( - 'xnoury', - '197780373', - UTC_TIMESTAMP() -); - --- Important: Make sure to swap 'pass' and 'username' with a password/user of your own choosing. -CREATE USER 'username'@'localhost'; -GRANT SELECT, INSERT ON nourybot.* TO 'username'@'localhost'; - -ALTER USER 'username'@'localhost' IDENTIFIED BY 'pass'; \ No newline at end of file diff --git a/pkg/models/models.go b/pkg/models/models.go deleted file mode 100644 index af97f62..0000000 --- a/pkg/models/models.go +++ /dev/null @@ -1,15 +0,0 @@ -package models - -import ( - "errors" - "time" -) - -var ErrNoRecord = errors.New("models: no matching record found") - -type Channel struct { - ID int - Username string - TwitchID string - Added time.Time -} diff --git a/pkg/models/mysql/channel.go b/pkg/models/mysql/channel.go deleted file mode 100644 index 87c3da6..0000000 --- a/pkg/models/mysql/channel.go +++ /dev/null @@ -1,23 +0,0 @@ -package mysql - -import ( - "database/sql" - - "github.com/lyx0/nourybot/pkg/models" -) - -type ChannelModel struct { - DB *sql.DB -} - -func (m *ChannelModel) Insert(username string, twitchid string) (int, error) { - return 0, nil -} - -func (m *ChannelModel) Get(id int) (*models.Channel, error) { - return nil, nil -} - -func (m *ChannelModel) Latest() ([]*models.Channel, error) { - return nil, nil -} From 0b7b365e03626567a8c5ec401b297e67ba187c9d Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Tue, 26 Apr 2022 06:30:53 +0200 Subject: [PATCH 09/35] asd --- .env.example | 4 -- commands.md | 135 -------------------------------------- internal/config/config.go | 1 + 3 files changed, 1 insertion(+), 139 deletions(-) delete mode 100644 .env.example delete mode 100644 commands.md create mode 100644 internal/config/config.go diff --git a/.env.example b/.env.example deleted file mode 100644 index a128ba4..0000000 --- a/.env.example +++ /dev/null @@ -1,4 +0,0 @@ -TWITCH_USER=forsen -TWITCH_PASS=oauth:asdhjadsjksajkhdjhksadjkias -BOT_USER_ID=133769 -MONGO_URI=mongodb+srv://coolurihere \ No newline at end of file diff --git a/commands.md b/commands.md deleted file mode 100644 index d426f26..0000000 --- a/commands.md +++ /dev/null @@ -1,135 +0,0 @@ -nourybot commands - -##### 8ball: - Ask the magic 8ball for guidance - - -#### Bot/Botinfo/Nourybot/Help: - Returns information about the bot - -#### Botstatus: - Returns the status of a verified/known/normal bots and its ratelimits - API used: https://customapi.aidenwallis.co.uk/docs/twitch/bot-status - -#### Bttv: - Returns a bttv search link for a given emote name - -#### Bttvemotes: - Returns all Bttv emotes from the current channel - API used: https://customapi.aidenwallis.co.uk/docs/emotes/bttv - -#### Commands: - Returns this page 4Head - -#### Coinflip: - Head or Tails - -#### Ffz: - Return sa ffz search link for a given emote name - Usage: ()ffz [emotename] - -#### Ffzemotes: - Returns all Ffz emotes from the current channel - API used: https://customapi.aidenwallis.co.uk/docs/emotes/ffz - -#### Fill: - Repeats an emote for the maximum size of a single message and "fills" the message with it. - Only usable for vips/moderators/broadcaster. - -#### Firstline/fl: - Returns the first line a user has written in a channel. - Usage: ()fl [channel] [user] - API used: https://api.ivr.fi/logs/firstmessage/ - -#### Followage: - Returns the date a user has been following a channel. - Usage: ()followage [channel] [user] - API used: https://api.ivr.fi/twitch/subage/ - -#### Game: - Returns the game of the current channel if no parameters are given, otherwise for the given channel - Usage: ()game [channel] - -#### Number/num: - Returns a fact about a given number, or if none is given a random number. - API used: http://numbersapi.com/ - -#### Godoc/Godocs: - Returns the godocs.io search for a given word - -#### Ping: - Returns a Pong - -#### Profilepicture/pfp: - Returns a link to a users profile picture. - API used: https://api.ivr.fi/twitch/resolve/ - -#### Pingme: - Pings you in chat - -#### Pyramid: - Builds a pyramid of a given emote, only usable by vips/moderators/broadcaster in the channel. Max size 20 - -#### RandomCat/cat: - Returns a random cat image - API used: https://aws.random.cat/meow - -#### RandomCat/dog: - Returns a random dog image - API used: https://random.dog/woof.json - -#### Randomduck/duck: - Returns a random duck image - API used: https://random-d.uk/ - -#### RandomFox/fox: - Returns a random fox image - API used: https://randomfox.ca/floof - -#### Randomxkcd/rxkcd: - Returns a random Xkcd comic - -#### Randomquote/rq: - Returns a random quote from a user in a channel. - Usage: ()rq [channel] [user] - API used: https://api.ivr.fi/logs/rq/ - -### Robohash/robo: - Returns a link to the robohash image of your Twitch Message Id. - API Used: https://robohash.org - -#### Subage: - Returns the months someone has been subscribed to a channel. - Usage: ()subage [channel] [user] - API used: https://api.ivr.fi/twitch/subage/ - -### Thumb/Preview: - Returns a screenshot of a given live channel. - Usage: ()thumb [channel] - -#### Title: - Returns the title of the current channel if no parameters are given, otherwise for the given channel - -#### Mycolor/color: - Returns the hexcode of your Twitch color - -#### Uptime: - Returns the uptime of the current channel if no parameters are given, otherwise for the given channel - Usage: ()uptime [channel] - -#### userid/uid: - Returns the Twitch User ID of a given user, otherwise the senders userid. - Usage: ()uid [name] - -#### Uid: - Returns the Twitch userid of a given username - API used: https://api.ivr.fi/twitch/resolve/ - -#### Weather: - Returns the weather for a given location - API used: https://customapi.aidenwallis.co.uk/api/v1/misc/weather/ - Usage: ()weather [location] - -#### Xkcd: - Returns a link to the current Xkcd comic - diff --git a/internal/config/config.go b/internal/config/config.go new file mode 100644 index 0000000..d912156 --- /dev/null +++ b/internal/config/config.go @@ -0,0 +1 @@ +package config From 8375f902659a580d01af81b4fefd03311c51feb9 Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Sat, 4 Jun 2022 02:21:20 +0200 Subject: [PATCH 10/35] start rewrite --- cmd/bot/main.go | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ go.mod | 9 +-------- go.sum | 22 ++-------------------- 3 files changed, 51 insertions(+), 28 deletions(-) create mode 100644 cmd/bot/main.go diff --git a/cmd/bot/main.go b/cmd/bot/main.go new file mode 100644 index 0000000..56e789c --- /dev/null +++ b/cmd/bot/main.go @@ -0,0 +1,48 @@ +package main + +import ( + "flag" + "log" + "os" + + "github.com/gempir/go-twitch-irc/v2" + "github.com/joho/godotenv" +) + +type config struct { + env string + botUsername string + botOauth string +} + +type application struct { + config config + twitchClient *twitch.Client + logger *log.Logger +} + +func main() { + var cfg config + + flag.StringVar(&cfg.env, "env", "development", "Environment (development|string|production)") + flag.Parse() + + err := godotenv.Load() + if err != nil { + log.Fatal("Error loading .env file") + } + + cfg.botUsername = os.Getenv("TWITCH_USER") + cfg.botOauth = os.Getenv("TWITCH_OAUTH") + + logger := log.New(os.Stdout, "", log.Ldate|log.Ltime) + + twitchClient := twitch.NewClient(cfg.botUsername, cfg.botOauth) + app := &application{ + config: cfg, + twitchClient: twitchClient, + logger: logger, + } + + app.twitchClient.Connect() +} diff --git a/go.mod b/go.mod index 0dd7232..16fcf91 100644 --- a/go.mod +++ b/go.mod @@ -3,13 +3,6 @@ module github.com/lyx0/nourybot go 1.17 require ( - github.com/gempir/go-twitch-irc/v3 v3.0.0 - github.com/go-sql-driver/mysql v1.6.0 + github.com/gempir/go-twitch-irc/v2 v2.8.1 github.com/joho/godotenv v1.4.0 - github.com/sirupsen/logrus v1.8.1 -) - -require ( - github.com/stretchr/testify v1.6.1 // indirect - golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 // indirect ) diff --git a/go.sum b/go.sum index ca9376e..dc267dc 100644 --- a/go.sum +++ b/go.sum @@ -1,22 +1,4 @@ -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/gempir/go-twitch-irc/v3 v3.0.0 h1:e34R+9BdKy+qrO/wN+FCt+BUtyn38gCnJuKWscIKbl4= -github.com/gempir/go-twitch-irc/v3 v3.0.0/go.mod h1:/W9KZIiyizVecp4PEb7kc4AlIyXKiCmvlXrzlpPUytU= -github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= -github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/gempir/go-twitch-irc/v2 v2.8.1 h1:M0Rt2ODGPEk33+UEwv2XSrnGMMwVyUoBt+MNI3ZVf8c= +github.com/gempir/go-twitch-irc/v2 v2.8.1/go.mod h1:120d2SdlRYg8tRnZwsyNPeS+mWPn+YmNEzB7Bv/CDGE= github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 82626346cee93fe2f8b398c1e3d4710126559ccb Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Sat, 4 Jun 2022 02:29:05 +0200 Subject: [PATCH 11/35] use go-twitch-irc v3 instead --- cmd/bot/main.go | 17 +++++++++++++---- go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/cmd/bot/main.go b/cmd/bot/main.go index 56e789c..7f0b77b 100644 --- a/cmd/bot/main.go +++ b/cmd/bot/main.go @@ -5,7 +5,7 @@ import ( "log" "os" - "github.com/gempir/go-twitch-irc/v2" + "github.com/gempir/go-twitch-irc/v3" "github.com/joho/godotenv" ) @@ -32,8 +32,8 @@ func main() { log.Fatal("Error loading .env file") } - cfg.botUsername = os.Getenv("TWITCH_USER") - cfg.botOauth = os.Getenv("TWITCH_OAUTH") + cfg.botUsername = os.Getenv("BOT_USER") + cfg.botOauth = os.Getenv("BOT_OAUTH") logger := log.New(os.Stdout, "", log.Ldate|log.Ltime) @@ -44,5 +44,14 @@ func main() { logger: logger, } - app.twitchClient.Connect() + app.twitchClient.Join("nourylul") + app.twitchClient.Join("nourybot") + + app.twitchClient.Say("nourylul", "xd") + app.twitchClient.Say("nourybot", "xd") + + err = app.twitchClient.Connect() + if err != nil { + panic(err) + } } diff --git a/go.mod b/go.mod index 16fcf91..7a4f2ca 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,6 @@ module github.com/lyx0/nourybot go 1.17 require ( - github.com/gempir/go-twitch-irc/v2 v2.8.1 + github.com/gempir/go-twitch-irc/v3 v3.1.0 github.com/joho/godotenv v1.4.0 ) diff --git a/go.sum b/go.sum index dc267dc..67e7216 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,4 @@ -github.com/gempir/go-twitch-irc/v2 v2.8.1 h1:M0Rt2ODGPEk33+UEwv2XSrnGMMwVyUoBt+MNI3ZVf8c= -github.com/gempir/go-twitch-irc/v2 v2.8.1/go.mod h1:120d2SdlRYg8tRnZwsyNPeS+mWPn+YmNEzB7Bv/CDGE= +github.com/gempir/go-twitch-irc/v3 v3.1.0 h1:bUVZ5mADhH7KidJVcl+z79kgLJ7sjdAk4b/ylAvaLy0= +github.com/gempir/go-twitch-irc/v3 v3.1.0/go.mod h1:/W9KZIiyizVecp4PEb7kc4AlIyXKiCmvlXrzlpPUytU= github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= From 956b1a8614772ef19830f6e065bc3e9ec42866a1 Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Sat, 4 Jun 2022 02:40:43 +0200 Subject: [PATCH 12/35] add privatemessage base --- cmd/bot/main.go | 4 ++++ cmd/bot/privatemessage.go | 27 +++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 cmd/bot/privatemessage.go diff --git a/cmd/bot/main.go b/cmd/bot/main.go index 7f0b77b..4d767d3 100644 --- a/cmd/bot/main.go +++ b/cmd/bot/main.go @@ -44,6 +44,10 @@ func main() { logger: logger, } + app.twitchClient.OnPrivateMessage(func(message twitch.PrivateMessage) { + app.handlePrivateMessage(message) + }) + app.twitchClient.Join("nourylul") app.twitchClient.Join("nourybot") diff --git a/cmd/bot/privatemessage.go b/cmd/bot/privatemessage.go new file mode 100644 index 0000000..1594e2f --- /dev/null +++ b/cmd/bot/privatemessage.go @@ -0,0 +1,27 @@ +package main + +import "github.com/gempir/go-twitch-irc/v3" + +func (app *application) handlePrivateMessage(message twitch.PrivateMessage) { + // roomId is the Twitch UserID of the channel the + // message originated from. + roomId := message.Tags["room-id"] + + // If there is no roomId something went wrong. + if roomId == "" { + app.logger.Print("Missing room-id in message tag ", roomId) + return + } + + if len(message.Message) >= 2 { + if message.Message[:2] == "()" { + // TODO: Command Handling + app.logger.Println("[Command detected]: ", message.Message) + return + } + } + + // Message was no command so we just print it. + app.logger.Printf("[#%s]:%s: %s", message.Channel, message.User.DisplayName, message.Message) + +} From 9293b6ff00771e5e72ba11e21e9e3e1534a716ff Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Sat, 4 Jun 2022 02:56:28 +0200 Subject: [PATCH 13/35] add comments, print a message on successful connection --- Makefile | 6 +++--- cmd/bot/main.go | 38 +++++++++++++++++++++++++++++++++----- cmd/bot/whispermessage.go | 9 +++++++++ 3 files changed, 45 insertions(+), 8 deletions(-) create mode 100644 cmd/bot/whispermessage.go diff --git a/Makefile b/Makefile index 35a50d4..c4aed9b 100644 --- a/Makefile +++ b/Makefile @@ -5,10 +5,10 @@ run: cd cmd/bot && ./Nourybot dev: - cd cmd/bot && go build -o Nourybot && ./Nourybot -mode dev + cd cmd/bot && go build -o Nourybot && ./Nourybot -env development prod: - cd cmd/bot && go build -o Nourybot && ./Nourybot -mode production + cd cmd/bot && go build -o Nourybot && ./Nourybot -env production xd: - cd cmd/bot && go build -o Nourybot && ./Nourybot \ No newline at end of file + cd cmd/bot && go build -o Nourybot && ./Nourybot diff --git a/cmd/bot/main.go b/cmd/bot/main.go index 4d767d3..e3b7ef7 100644 --- a/cmd/bot/main.go +++ b/cmd/bot/main.go @@ -24,36 +24,64 @@ type application struct { func main() { var cfg config + // Parse which environment we are running in. This will decide in + // the future how many channels we join or which database we are + // connecting to for example. flag.StringVar(&cfg.env, "env", "development", "Environment (development|string|production)") flag.Parse() + // Initialize a new logger we attach to our application struct. + logger := log.New(os.Stdout, "", log.Ldate|log.Ltime) + + // Load the .env file and check for errors. err := godotenv.Load() if err != nil { - log.Fatal("Error loading .env file") + logger.Fatal("Error loading .env file") } + // Load bot credentials from the .env file. cfg.botUsername = os.Getenv("BOT_USER") cfg.botOauth = os.Getenv("BOT_OAUTH") - logger := log.New(os.Stdout, "", log.Ldate|log.Ltime) - + // Initialize a new twitch client which we attach to our + // application struct. twitchClient := twitch.NewClient(cfg.botUsername, cfg.botOauth) + + // Finally Initialize a new application instance with our + // attached methods. app := &application{ config: cfg, twitchClient: twitchClient, logger: logger, } + // Received a PrivateMessage (normal chat message), pass it to + // the handler who checks for further action. app.twitchClient.OnPrivateMessage(func(message twitch.PrivateMessage) { app.handlePrivateMessage(message) }) + // Received a WhisperMessage (Twitch DM), pass it to + // the handler who checks for further action. + app.twitchClient.OnWhisperMessage(func(message twitch.WhisperMessage) { + app.handleWhisperMessage(message) + }) + + // Successfully connected to Twitch so we log a message with the + // mode we are currently running in.. + app.twitchClient.OnConnect(func() { + app.logger.Printf("Successfully connected to Twitch Servers in %s mode!", app.config.env) + }) + + // Join test channels app.twitchClient.Join("nourylul") app.twitchClient.Join("nourybot") - app.twitchClient.Say("nourylul", "xd") - app.twitchClient.Say("nourybot", "xd") + // Say hello because we are nice :^) + app.twitchClient.Say("nourylul", "RaccAttack") + app.twitchClient.Say("nourybot", "RaccAttack") + // Connect to the twitch IRC servers. err = app.twitchClient.Connect() if err != nil { panic(err) diff --git a/cmd/bot/whispermessage.go b/cmd/bot/whispermessage.go new file mode 100644 index 0000000..75fe3af --- /dev/null +++ b/cmd/bot/whispermessage.go @@ -0,0 +1,9 @@ +package main + +import "github.com/gempir/go-twitch-irc/v3" + +func (app *application) handleWhisperMessage(message twitch.WhisperMessage) { + // Print the whisper message for now. + // TODO: Implement a basic whisper handler. + app.logger.Printf("[#whisper]:%s: %s", message.User.DisplayName, message.Message) +} From 2ee85c47d7e164d5cce5d683d152424b64ee6f26 Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Sat, 4 Jun 2022 03:03:51 +0200 Subject: [PATCH 14/35] use logrus logger instead of standard logger --- cmd/bot/main.go | 12 ++++++------ cmd/bot/privatemessage.go | 6 +++--- cmd/bot/whispermessage.go | 2 +- go.mod | 3 +++ go.sum | 10 ++++++++++ 5 files changed, 23 insertions(+), 10 deletions(-) diff --git a/cmd/bot/main.go b/cmd/bot/main.go index e3b7ef7..3d78e97 100644 --- a/cmd/bot/main.go +++ b/cmd/bot/main.go @@ -2,11 +2,11 @@ package main import ( "flag" - "log" "os" "github.com/gempir/go-twitch-irc/v3" "github.com/joho/godotenv" + "github.com/sirupsen/logrus" ) type config struct { @@ -18,7 +18,7 @@ type config struct { type application struct { config config twitchClient *twitch.Client - logger *log.Logger + logger *logrus.Logger } func main() { @@ -31,12 +31,12 @@ func main() { flag.Parse() // Initialize a new logger we attach to our application struct. - logger := log.New(os.Stdout, "", log.Ldate|log.Ltime) + lgr := logrus.New() // Load the .env file and check for errors. err := godotenv.Load() if err != nil { - logger.Fatal("Error loading .env file") + lgr.Fatal("Error loading .env file") } // Load bot credentials from the .env file. @@ -52,7 +52,7 @@ func main() { app := &application{ config: cfg, twitchClient: twitchClient, - logger: logger, + logger: lgr, } // Received a PrivateMessage (normal chat message), pass it to @@ -70,7 +70,7 @@ func main() { // Successfully connected to Twitch so we log a message with the // mode we are currently running in.. app.twitchClient.OnConnect(func() { - app.logger.Printf("Successfully connected to Twitch Servers in %s mode!", app.config.env) + app.logger.Infof("Successfully connected to Twitch Servers in %s mode!", app.config.env) }) // Join test channels diff --git a/cmd/bot/privatemessage.go b/cmd/bot/privatemessage.go index 1594e2f..d9d8d18 100644 --- a/cmd/bot/privatemessage.go +++ b/cmd/bot/privatemessage.go @@ -9,19 +9,19 @@ func (app *application) handlePrivateMessage(message twitch.PrivateMessage) { // If there is no roomId something went wrong. if roomId == "" { - app.logger.Print("Missing room-id in message tag ", roomId) + app.logger.Error("Missing room-id in message tag ", roomId) return } if len(message.Message) >= 2 { if message.Message[:2] == "()" { // TODO: Command Handling - app.logger.Println("[Command detected]: ", message.Message) + app.logger.Infof("[Command detected]: ", message.Message) return } } // Message was no command so we just print it. - app.logger.Printf("[#%s]:%s: %s", message.Channel, message.User.DisplayName, message.Message) + app.logger.Infof("[#%s]:%s: %s", message.Channel, message.User.DisplayName, message.Message) } diff --git a/cmd/bot/whispermessage.go b/cmd/bot/whispermessage.go index 75fe3af..f491ecd 100644 --- a/cmd/bot/whispermessage.go +++ b/cmd/bot/whispermessage.go @@ -5,5 +5,5 @@ import "github.com/gempir/go-twitch-irc/v3" func (app *application) handleWhisperMessage(message twitch.WhisperMessage) { // Print the whisper message for now. // TODO: Implement a basic whisper handler. - app.logger.Printf("[#whisper]:%s: %s", message.User.DisplayName, message.Message) + app.logger.Infof("[#whisper]:%s: %s", message.User.DisplayName, message.Message) } diff --git a/go.mod b/go.mod index 7a4f2ca..2aceb09 100644 --- a/go.mod +++ b/go.mod @@ -5,4 +5,7 @@ go 1.17 require ( github.com/gempir/go-twitch-irc/v3 v3.1.0 github.com/joho/godotenv v1.4.0 + github.com/sirupsen/logrus v1.8.1 ) + +require golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 // indirect diff --git a/go.sum b/go.sum index 67e7216..aad75a3 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,14 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/gempir/go-twitch-irc/v3 v3.1.0 h1:bUVZ5mADhH7KidJVcl+z79kgLJ7sjdAk4b/ylAvaLy0= github.com/gempir/go-twitch-irc/v3 v3.1.0/go.mod h1:/W9KZIiyizVecp4PEb7kc4AlIyXKiCmvlXrzlpPUytU= github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= From a7ab565b2436af4118e46bf45572c6a9e1dd8959 Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Sat, 4 Jun 2022 20:06:44 +0200 Subject: [PATCH 15/35] start implementing basic command handler --- cmd/bot/command.go | 41 +++++++++++++++++++++++++++++++++++++++ cmd/bot/privatemessage.go | 3 ++- 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 cmd/bot/command.go diff --git a/cmd/bot/command.go b/cmd/bot/command.go new file mode 100644 index 0000000..56ddb5c --- /dev/null +++ b/cmd/bot/command.go @@ -0,0 +1,41 @@ +package main + +import ( + "strings" + + "github.com/gempir/go-twitch-irc/v3" +) + +func (app *application) handleCommand(message twitch.PrivateMessage) { + app.logger.Info("[COMMAND HANDLER]", message) + + // commandName is the actual name of the command without the prefix. + // e.g. `()ping` would be `ping`. + commandName := strings.ToLower(strings.SplitN(message.Message, " ", 3)[0][2:]) + + // cmdParams are additional command parameters. + // e.g. `()weather san antonio` + // cmdParam[0] is `san` and cmdParam[1] = `antonio`. + // + // Since Twitch messages are at most 500 characters I use a + // maximum count of 500+10 just to be safe. + // https://discuss.dev.twitch.tv/t/missing-client-side-message-length-check/21316 + cmdParams := strings.SplitN(message.Message, " ", 510) + _ = cmdParams + + // msgLen is the amount of words in a message without the prefix. + // Useful to check if enough cmdParams are provided. + msgLen := len(strings.SplitN(message.Message, " ", -2)) + + // target is the channelname the message originated from and + // where we are responding. + target := message.Channel + + switch commandName { + case "": + if msgLen == 1 { + app.twitchClient.Say(target, "xd") + return + } + } +} diff --git a/cmd/bot/privatemessage.go b/cmd/bot/privatemessage.go index d9d8d18..9be2caa 100644 --- a/cmd/bot/privatemessage.go +++ b/cmd/bot/privatemessage.go @@ -16,7 +16,8 @@ func (app *application) handlePrivateMessage(message twitch.PrivateMessage) { if len(message.Message) >= 2 { if message.Message[:2] == "()" { // TODO: Command Handling - app.logger.Infof("[Command detected]: ", message.Message) + app.handleCommand(message) + // app.logger.Infof("[Command detected]: ", message.Message) return } } From 40da7b90f83e6a3e1c78601af0771b9752601b49 Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Sat, 4 Jun 2022 20:38:14 +0200 Subject: [PATCH 16/35] add send helper function which checks the banphrase api --- cmd/bot/command.go | 10 +++- cmd/bot/send.go | 119 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 cmd/bot/send.go diff --git a/cmd/bot/command.go b/cmd/bot/command.go index 56ddb5c..57f49b7 100644 --- a/cmd/bot/command.go +++ b/cmd/bot/command.go @@ -34,7 +34,15 @@ func (app *application) handleCommand(message twitch.PrivateMessage) { switch commandName { case "": if msgLen == 1 { - app.twitchClient.Say(target, "xd") + app.Send(target, "xd") + return + } + case "echo": + if msgLen < 2 { + app.Send(target, "Not enough arguments provided.") + return + } else { + app.Send(target, message.Message[7:len(message.Message)]) return } } diff --git a/cmd/bot/send.go b/cmd/bot/send.go new file mode 100644 index 0000000..c02dad5 --- /dev/null +++ b/cmd/bot/send.go @@ -0,0 +1,119 @@ +package main + +import ( + "bytes" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" +) + +// banphraseResponse is the data we receive back from +// the banphrase API +type banphraseResponse struct { + Banned bool `json:"banned"` + InputMessage string `json:"input_message"` + BanphraseData banphraseData `json:"banphrase_data"` +} + +// banphraseData contains details about why a message +// was banphrased. +type banphraseData struct { + Id int `json:"id"` + Name string `json:"name"` + Phrase string `json:"phrase"` + Length int `json:"length"` + Permanent bool `json:"permanent"` +} + +var ( + banPhraseUrl = "https://pajlada.pajbot.com/api/v1/banphrases/test" +) + +// CheckMessage checks a given message against the banphrase api. +// returns false, "okay" if a message is allowed +// returns true and a string with the reason if it was banned. +// More information: +// https://gist.github.com/pajlada/57464e519ba8d195a97ddcd0755f9715 +func (app *application) checkMessage(text string) (bool, string) { + + // {"message": "AHAHAHAHA LUL"} + reqBody, err := json.Marshal(map[string]string{ + "message": text, + }) + if err != nil { + app.logger.Error(err) + } + + resp, err := http.Post(banPhraseUrl, "application/json", bytes.NewBuffer(reqBody)) + if err != nil { + app.logger.Error(err) + } + + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + app.logger.Error(err) + } + + var responseObject banphraseResponse + json.Unmarshal(body, &responseObject) + + // Bad Message + // + // {"phrase": "No gyazo allowed"} + reason := responseObject.BanphraseData.Name + if responseObject.Banned { + return true, fmt.Sprint(reason) + } else if !responseObject.Banned { + // Good message + return false, "okay" + } + + // Couldn't contact api so assume it was a bad message + return true, "Banphrase API couldn't be reached monkaS" +} + +// Send is used to send twitch replies and contains the necessary +// safeguards and logic for that. +func (app *application) Send(target, message string) { + // Message we are trying to send is empty. + if len(message) == 0 { + return + } + + // Since messages starting with `.` or `/` are used for special actions + // (ban, whisper, timeout) and so on, we place a emote infront of it so + // the actions wouldn't execute. `!` and `$` are common bot prefixes so we + // don't allow them either. + if message[0] == '.' || message[0] == '/' || message[0] == '!' || message[0] == '$' { + message = ":tf: " + message + } + + // check the message for bad words before we say it + messageBanned, banReason := app.checkMessage(message) + if messageBanned { + // Bad message, replace message and log it. + app.twitchClient.Say(target, "[BANPHRASED] monkaS") + app.logger.Info("Banned message detected: ", banReason) + + return + } else { + // In case the message we are trying to send is longer than the + // maximum allowed message length on twitch. We split the message + // in two parts. + if len(message) > 500 { + firstMessage := message[0:499] + secondMessage := message[499:] + + app.twitchClient.Say(target, firstMessage) + app.twitchClient.Say(target, secondMessage) + + return + } + // Message was fine. + app.twitchClient.Say(target, message) + return + } +} From d4d15a82e32533b1518ef5d0231468d326d479f6 Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Tue, 21 Jun 2022 00:08:37 +0200 Subject: [PATCH 17/35] asd --- cmd/bot/command.go | 49 ---------------- cmd/bot/main.go | 89 ---------------------------- cmd/bot/privatemessage.go | 28 --------- cmd/bot/send.go | 119 -------------------------------------- cmd/bot/whispermessage.go | 9 --- 5 files changed, 294 deletions(-) delete mode 100644 cmd/bot/command.go delete mode 100644 cmd/bot/main.go delete mode 100644 cmd/bot/privatemessage.go delete mode 100644 cmd/bot/send.go delete mode 100644 cmd/bot/whispermessage.go diff --git a/cmd/bot/command.go b/cmd/bot/command.go deleted file mode 100644 index 57f49b7..0000000 --- a/cmd/bot/command.go +++ /dev/null @@ -1,49 +0,0 @@ -package main - -import ( - "strings" - - "github.com/gempir/go-twitch-irc/v3" -) - -func (app *application) handleCommand(message twitch.PrivateMessage) { - app.logger.Info("[COMMAND HANDLER]", message) - - // commandName is the actual name of the command without the prefix. - // e.g. `()ping` would be `ping`. - commandName := strings.ToLower(strings.SplitN(message.Message, " ", 3)[0][2:]) - - // cmdParams are additional command parameters. - // e.g. `()weather san antonio` - // cmdParam[0] is `san` and cmdParam[1] = `antonio`. - // - // Since Twitch messages are at most 500 characters I use a - // maximum count of 500+10 just to be safe. - // https://discuss.dev.twitch.tv/t/missing-client-side-message-length-check/21316 - cmdParams := strings.SplitN(message.Message, " ", 510) - _ = cmdParams - - // msgLen is the amount of words in a message without the prefix. - // Useful to check if enough cmdParams are provided. - msgLen := len(strings.SplitN(message.Message, " ", -2)) - - // target is the channelname the message originated from and - // where we are responding. - target := message.Channel - - switch commandName { - case "": - if msgLen == 1 { - app.Send(target, "xd") - return - } - case "echo": - if msgLen < 2 { - app.Send(target, "Not enough arguments provided.") - return - } else { - app.Send(target, message.Message[7:len(message.Message)]) - return - } - } -} diff --git a/cmd/bot/main.go b/cmd/bot/main.go deleted file mode 100644 index 3d78e97..0000000 --- a/cmd/bot/main.go +++ /dev/null @@ -1,89 +0,0 @@ -package main - -import ( - "flag" - "os" - - "github.com/gempir/go-twitch-irc/v3" - "github.com/joho/godotenv" - "github.com/sirupsen/logrus" -) - -type config struct { - env string - botUsername string - botOauth string -} - -type application struct { - config config - twitchClient *twitch.Client - logger *logrus.Logger -} - -func main() { - var cfg config - - // Parse which environment we are running in. This will decide in - // the future how many channels we join or which database we are - // connecting to for example. - flag.StringVar(&cfg.env, "env", "development", "Environment (development|string|production)") - flag.Parse() - - // Initialize a new logger we attach to our application struct. - lgr := logrus.New() - - // Load the .env file and check for errors. - err := godotenv.Load() - if err != nil { - lgr.Fatal("Error loading .env file") - } - - // Load bot credentials from the .env file. - cfg.botUsername = os.Getenv("BOT_USER") - cfg.botOauth = os.Getenv("BOT_OAUTH") - - // Initialize a new twitch client which we attach to our - // application struct. - twitchClient := twitch.NewClient(cfg.botUsername, cfg.botOauth) - - // Finally Initialize a new application instance with our - // attached methods. - app := &application{ - config: cfg, - twitchClient: twitchClient, - logger: lgr, - } - - // Received a PrivateMessage (normal chat message), pass it to - // the handler who checks for further action. - app.twitchClient.OnPrivateMessage(func(message twitch.PrivateMessage) { - app.handlePrivateMessage(message) - }) - - // Received a WhisperMessage (Twitch DM), pass it to - // the handler who checks for further action. - app.twitchClient.OnWhisperMessage(func(message twitch.WhisperMessage) { - app.handleWhisperMessage(message) - }) - - // Successfully connected to Twitch so we log a message with the - // mode we are currently running in.. - app.twitchClient.OnConnect(func() { - app.logger.Infof("Successfully connected to Twitch Servers in %s mode!", app.config.env) - }) - - // Join test channels - app.twitchClient.Join("nourylul") - app.twitchClient.Join("nourybot") - - // Say hello because we are nice :^) - app.twitchClient.Say("nourylul", "RaccAttack") - app.twitchClient.Say("nourybot", "RaccAttack") - - // Connect to the twitch IRC servers. - err = app.twitchClient.Connect() - if err != nil { - panic(err) - } -} diff --git a/cmd/bot/privatemessage.go b/cmd/bot/privatemessage.go deleted file mode 100644 index 9be2caa..0000000 --- a/cmd/bot/privatemessage.go +++ /dev/null @@ -1,28 +0,0 @@ -package main - -import "github.com/gempir/go-twitch-irc/v3" - -func (app *application) handlePrivateMessage(message twitch.PrivateMessage) { - // roomId is the Twitch UserID of the channel the - // message originated from. - roomId := message.Tags["room-id"] - - // If there is no roomId something went wrong. - if roomId == "" { - app.logger.Error("Missing room-id in message tag ", roomId) - return - } - - if len(message.Message) >= 2 { - if message.Message[:2] == "()" { - // TODO: Command Handling - app.handleCommand(message) - // app.logger.Infof("[Command detected]: ", message.Message) - return - } - } - - // Message was no command so we just print it. - app.logger.Infof("[#%s]:%s: %s", message.Channel, message.User.DisplayName, message.Message) - -} diff --git a/cmd/bot/send.go b/cmd/bot/send.go deleted file mode 100644 index c02dad5..0000000 --- a/cmd/bot/send.go +++ /dev/null @@ -1,119 +0,0 @@ -package main - -import ( - "bytes" - "encoding/json" - "fmt" - "io/ioutil" - "net/http" -) - -// banphraseResponse is the data we receive back from -// the banphrase API -type banphraseResponse struct { - Banned bool `json:"banned"` - InputMessage string `json:"input_message"` - BanphraseData banphraseData `json:"banphrase_data"` -} - -// banphraseData contains details about why a message -// was banphrased. -type banphraseData struct { - Id int `json:"id"` - Name string `json:"name"` - Phrase string `json:"phrase"` - Length int `json:"length"` - Permanent bool `json:"permanent"` -} - -var ( - banPhraseUrl = "https://pajlada.pajbot.com/api/v1/banphrases/test" -) - -// CheckMessage checks a given message against the banphrase api. -// returns false, "okay" if a message is allowed -// returns true and a string with the reason if it was banned. -// More information: -// https://gist.github.com/pajlada/57464e519ba8d195a97ddcd0755f9715 -func (app *application) checkMessage(text string) (bool, string) { - - // {"message": "AHAHAHAHA LUL"} - reqBody, err := json.Marshal(map[string]string{ - "message": text, - }) - if err != nil { - app.logger.Error(err) - } - - resp, err := http.Post(banPhraseUrl, "application/json", bytes.NewBuffer(reqBody)) - if err != nil { - app.logger.Error(err) - } - - defer resp.Body.Close() - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - app.logger.Error(err) - } - - var responseObject banphraseResponse - json.Unmarshal(body, &responseObject) - - // Bad Message - // - // {"phrase": "No gyazo allowed"} - reason := responseObject.BanphraseData.Name - if responseObject.Banned { - return true, fmt.Sprint(reason) - } else if !responseObject.Banned { - // Good message - return false, "okay" - } - - // Couldn't contact api so assume it was a bad message - return true, "Banphrase API couldn't be reached monkaS" -} - -// Send is used to send twitch replies and contains the necessary -// safeguards and logic for that. -func (app *application) Send(target, message string) { - // Message we are trying to send is empty. - if len(message) == 0 { - return - } - - // Since messages starting with `.` or `/` are used for special actions - // (ban, whisper, timeout) and so on, we place a emote infront of it so - // the actions wouldn't execute. `!` and `$` are common bot prefixes so we - // don't allow them either. - if message[0] == '.' || message[0] == '/' || message[0] == '!' || message[0] == '$' { - message = ":tf: " + message - } - - // check the message for bad words before we say it - messageBanned, banReason := app.checkMessage(message) - if messageBanned { - // Bad message, replace message and log it. - app.twitchClient.Say(target, "[BANPHRASED] monkaS") - app.logger.Info("Banned message detected: ", banReason) - - return - } else { - // In case the message we are trying to send is longer than the - // maximum allowed message length on twitch. We split the message - // in two parts. - if len(message) > 500 { - firstMessage := message[0:499] - secondMessage := message[499:] - - app.twitchClient.Say(target, firstMessage) - app.twitchClient.Say(target, secondMessage) - - return - } - // Message was fine. - app.twitchClient.Say(target, message) - return - } -} diff --git a/cmd/bot/whispermessage.go b/cmd/bot/whispermessage.go deleted file mode 100644 index f491ecd..0000000 --- a/cmd/bot/whispermessage.go +++ /dev/null @@ -1,9 +0,0 @@ -package main - -import "github.com/gempir/go-twitch-irc/v3" - -func (app *application) handleWhisperMessage(message twitch.WhisperMessage) { - // Print the whisper message for now. - // TODO: Implement a basic whisper handler. - app.logger.Infof("[#whisper]:%s: %s", message.User.DisplayName, message.Message) -} From aa565a86e9c50cd75993723f80a169a63b0d0784 Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Tue, 21 Jun 2022 00:31:17 +0200 Subject: [PATCH 18/35] start rewrite --- cmd/bot/main.go | 1 + pkg/bot/bot.go | 68 ++++++++++++++++++++++ pkg/bot/command.go | 49 ++++++++++++++++ pkg/bot/privatemessage.go | 28 +++++++++ pkg/bot/send.go | 119 ++++++++++++++++++++++++++++++++++++++ pkg/bot/whispermessage.go | 9 +++ 6 files changed, 274 insertions(+) create mode 100644 cmd/bot/main.go create mode 100644 pkg/bot/bot.go create mode 100644 pkg/bot/command.go create mode 100644 pkg/bot/privatemessage.go create mode 100644 pkg/bot/send.go create mode 100644 pkg/bot/whispermessage.go diff --git a/cmd/bot/main.go b/cmd/bot/main.go new file mode 100644 index 0000000..85f0393 --- /dev/null +++ b/cmd/bot/main.go @@ -0,0 +1 @@ +package main \ No newline at end of file diff --git a/pkg/bot/bot.go b/pkg/bot/bot.go new file mode 100644 index 0000000..98c3376 --- /dev/null +++ b/pkg/bot/bot.go @@ -0,0 +1,68 @@ +package bot + +import ( + "os" + + "github.com/gempir/go-twitch-irc/v3" + "github.com/joho/godotenv" + "github.com/sirupsen/logrus" +) + +type config struct { + env string + botUsername string + botOauth string +} + +type Bot struct { + config config + twitchClient *twitch.Client + logger *logrus.Logger +} + +func New() *Bot { + var cfg config + + // Initialize a new logger we attach to our application struct. + lgr := logrus.New() + + // Load the .env file and check for errors. + err := godotenv.Load() + if err != nil { + lgr.Fatal("Error loading .env file") + } + + // Load bot credentials from the .env file. + cfg.botUsername = os.Getenv("BOT_USER") + cfg.botOauth = os.Getenv("BOT_OAUTH") + + // Initialize a new twitch client which we attach to our + // application struct. + twitchClient := twitch.NewClient(cfg.botUsername, cfg.botOauth) + + bot := &Bot{ + config: cfg, + twitchClient: twitchClient, + logger: lgr, + } + // Received a PrivateMessage (normal chat message), pass it to + // the handler who checks for further action. + bot.twitchClient.OnPrivateMessage(func(message twitch.PrivateMessage) { + bot.handlePrivateMessage(message) + }) + + // Received a WhisperMessage (Twitch DM), pass it to + // the handler who checks for further action. + bot.twitchClient.OnWhisperMessage(func(message twitch.WhisperMessage) { + bot.handleWhisperMessage(message) + }) + + // Successfully connected to Twitch so we log a message with the + // mode we are currently running in.. + bot.twitchClient.OnConnect(func() { + bot.logger.Infof("Successfully connected to Twitch Servers in %s mode!", bot.config.env) + }) + + return bot + +} diff --git a/pkg/bot/command.go b/pkg/bot/command.go new file mode 100644 index 0000000..77d53e5 --- /dev/null +++ b/pkg/bot/command.go @@ -0,0 +1,49 @@ +package bot + +import ( + "strings" + + "github.com/gempir/go-twitch-irc/v3" +) + +func (bot *Bot) handleCommand(message twitch.PrivateMessage) { + bot.logger.Info("[COMMAND HANDLER]", message) + + // commandName is the actual name of the command without the prefix. + // e.g. `()ping` would be `ping`. + commandName := strings.ToLower(strings.SplitN(message.Message, " ", 3)[0][2:]) + + // cmdParams are additional command parameters. + // e.g. `()weather san antonio` + // cmdParam[0] is `san` and cmdParam[1] = `antonio`. + // + // Since Twitch messages are at most 500 characters I use a + // maximum count of 500+10 just to be safe. + // https://discuss.dev.twitch.tv/t/missing-client-side-message-length-check/21316 + cmdParams := strings.SplitN(message.Message, " ", 510) + _ = cmdParams + + // msgLen is the amount of words in a message without the prefix. + // Useful to check if enough cmdParams are provided. + msgLen := len(strings.SplitN(message.Message, " ", -2)) + + // target is the channelname the message originated from and + // where we are responding. + target := message.Channel + + switch commandName { + case "": + if msgLen == 1 { + bot.Send(target, "xd") + return + } + case "echo": + if msgLen < 2 { + bot.Send(target, "Not enough arguments provided.") + return + } else { + bot.Send(target, message.Message[7:len(message.Message)]) + return + } + } +} diff --git a/pkg/bot/privatemessage.go b/pkg/bot/privatemessage.go new file mode 100644 index 0000000..39be731 --- /dev/null +++ b/pkg/bot/privatemessage.go @@ -0,0 +1,28 @@ +package bot + +import "github.com/gempir/go-twitch-irc/v3" + +func (bot *Bot) handlePrivateMessage(message twitch.PrivateMessage) { + // roomId is the Twitch UserID of the channel the + // message originated from. + roomId := message.Tags["room-id"] + + // If there is no roomId something went wrong. + if roomId == "" { + bot.logger.Error("Missing room-id in message tag ", roomId) + return + } + + if len(message.Message) >= 2 { + if message.Message[:2] == "()" { + // TODO: Command Handling + bot.handleCommand(message) + // app.logger.Infof("[Command detected]: ", message.Message) + return + } + } + + // Message was no command so we just print it. + bot.logger.Infof("[#%s]:%s: %s", message.Channel, message.User.DisplayName, message.Message) + +} diff --git a/pkg/bot/send.go b/pkg/bot/send.go new file mode 100644 index 0000000..c6b32e5 --- /dev/null +++ b/pkg/bot/send.go @@ -0,0 +1,119 @@ +package bot + +import ( + "bytes" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" +) + +// banphraseResponse is the data we receive back from +// the banphrase API +type banphraseResponse struct { + Banned bool `json:"banned"` + InputMessage string `json:"input_message"` + BanphraseData banphraseData `json:"banphrase_data"` +} + +// banphraseData contains details about why a message +// was banphrased. +type banphraseData struct { + Id int `json:"id"` + Name string `json:"name"` + Phrase string `json:"phrase"` + Length int `json:"length"` + Permanent bool `json:"permanent"` +} + +var ( + banPhraseUrl = "https://pajlada.pajbot.com/api/v1/banphrases/test" +) + +// CheckMessage checks a given message against the banphrase api. +// returns false, "okay" if a message is allowed +// returns true and a string with the reason if it was banned. +// More information: +// https://gist.github.com/pajlada/57464e519ba8d195a97ddcd0755f9715 +func (bot *Bot) checkMessage(text string) (bool, string) { + + // {"message": "AHAHAHAHA LUL"} + reqBody, err := json.Marshal(map[string]string{ + "message": text, + }) + if err != nil { + bot.logger.Error(err) + } + + resp, err := http.Post(banPhraseUrl, "application/json", bytes.NewBuffer(reqBody)) + if err != nil { + bot.logger.Error(err) + } + + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + bot.logger.Error(err) + } + + var responseObject banphraseResponse + json.Unmarshal(body, &responseObject) + + // Bad Message + // + // {"phrase": "No gyazo allowed"} + reason := responseObject.BanphraseData.Name + if responseObject.Banned { + return true, fmt.Sprint(reason) + } else if !responseObject.Banned { + // Good message + return false, "okay" + } + + // Couldn't contact api so assume it was a bad message + return true, "Banphrase API couldn't be reached monkaS" +} + +// Send is used to send twitch replies and contains the necessary +// safeguards and logic for that. +func (bot *Bot) Send(target, message string) { + // Message we are trying to send is empty. + if len(message) == 0 { + return + } + + // Since messages starting with `.` or `/` are used for special actions + // (ban, whisper, timeout) and so on, we place a emote infront of it so + // the actions wouldn't execute. `!` and `$` are common bot prefixes so we + // don't allow them either. + if message[0] == '.' || message[0] == '/' || message[0] == '!' || message[0] == '$' { + message = ":tf: " + message + } + + // check the message for bad words before we say it + messageBanned, banReason := bot.checkMessage(message) + if messageBanned { + // Bad message, replace message and log it. + bot.twitchClient.Say(target, "[BANPHRASED] monkaS") + bot.logger.Info("Banned message detected: ", banReason) + + return + } else { + // In case the message we are trying to send is longer than the + // maximum allowed message length on twitch. We split the message + // in two parts. + if len(message) > 500 { + firstMessage := message[0:499] + secondMessage := message[499:] + + bot.twitchClient.Say(target, firstMessage) + bot.twitchClient.Say(target, secondMessage) + + return + } + // Message was fine. + bot.twitchClient.Say(target, message) + return + } +} diff --git a/pkg/bot/whispermessage.go b/pkg/bot/whispermessage.go new file mode 100644 index 0000000..716dda1 --- /dev/null +++ b/pkg/bot/whispermessage.go @@ -0,0 +1,9 @@ +package bot + +import "github.com/gempir/go-twitch-irc/v3" + +func (bot *Bot) handleWhisperMessage(message twitch.WhisperMessage) { + // Print the whisper message for now. + // TODO: Implement a basic whisper handler. + bot.logger.Infof("[#whisper]:%s: %s", message.User.DisplayName, message.Message) +} From 86c7217974805f00b828bfa699ff4d553e07fd57 Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Sat, 6 Aug 2022 23:45:02 +0200 Subject: [PATCH 19/35] start rewrite --- cmd/bot/main.go | 15 +++++++++++++- internal/config/config.go | 25 ++++++++++++++++++++++++ pkg/bot/bot.go | 41 ++++++++++++--------------------------- pkg/bot/send.go | 8 ++++---- 4 files changed, 55 insertions(+), 34 deletions(-) diff --git a/cmd/bot/main.go b/cmd/bot/main.go index 85f0393..3c6f6cc 100644 --- a/cmd/bot/main.go +++ b/cmd/bot/main.go @@ -1 +1,14 @@ -package main \ No newline at end of file +package main + +import "github.com/lyx0/nourybot/pkg/bot" + +func main() { + + bot := bot.New() + + bot.TwitchClient.Join("nourylul") + err := bot.TwitchClient.Connect() + if err != nil { + panic(err) + } +} diff --git a/internal/config/config.go b/internal/config/config.go index d912156..b33210e 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -1 +1,26 @@ package config + +import ( + "log" + "os" + + "github.com/joho/godotenv" +) + +type Config struct { + TwitchUsername string + TwitchOauth string + Environment string +} + +func New() *Config { + err := godotenv.Load() + if err != nil { + log.Fatal("Error loading .env file") + } + twitchUsername := os.Getenv("TWITCH_USERNAME") + twitchOauth := os.Getenv("TWITCH_OAUTH") + environment := "Development" + + return &Config{twitchUsername, twitchOauth, environment} +} diff --git a/pkg/bot/bot.go b/pkg/bot/bot.go index 98c3376..9f71e19 100644 --- a/pkg/bot/bot.go +++ b/pkg/bot/bot.go @@ -1,66 +1,49 @@ package bot import ( - "os" - "github.com/gempir/go-twitch-irc/v3" - "github.com/joho/godotenv" + "github.com/lyx0/nourybot/internal/config" "github.com/sirupsen/logrus" ) -type config struct { - env string - botUsername string - botOauth string -} - type Bot struct { - config config - twitchClient *twitch.Client + TwitchClient *twitch.Client logger *logrus.Logger } func New() *Bot { - var cfg config - // Initialize a new logger we attach to our application struct. lgr := logrus.New() - // Load the .env file and check for errors. - err := godotenv.Load() - if err != nil { - lgr.Fatal("Error loading .env file") - } - - // Load bot credentials from the .env file. - cfg.botUsername = os.Getenv("BOT_USER") - cfg.botOauth = os.Getenv("BOT_OAUTH") + cfg := config.New() // Initialize a new twitch client which we attach to our // application struct. - twitchClient := twitch.NewClient(cfg.botUsername, cfg.botOauth) + logrus.Info(cfg.TwitchUsername, cfg.TwitchOauth) + twitchClient := twitch.NewClient(cfg.TwitchUsername, cfg.TwitchOauth) bot := &Bot{ - config: cfg, - twitchClient: twitchClient, + TwitchClient: twitchClient, logger: lgr, } + // Received a PrivateMessage (normal chat message), pass it to // the handler who checks for further action. - bot.twitchClient.OnPrivateMessage(func(message twitch.PrivateMessage) { + bot.TwitchClient.OnPrivateMessage(func(message twitch.PrivateMessage) { bot.handlePrivateMessage(message) }) // Received a WhisperMessage (Twitch DM), pass it to // the handler who checks for further action. - bot.twitchClient.OnWhisperMessage(func(message twitch.WhisperMessage) { + bot.TwitchClient.OnWhisperMessage(func(message twitch.WhisperMessage) { bot.handleWhisperMessage(message) }) // Successfully connected to Twitch so we log a message with the // mode we are currently running in.. - bot.twitchClient.OnConnect(func() { - bot.logger.Infof("Successfully connected to Twitch Servers in %s mode!", bot.config.env) + bot.TwitchClient.OnConnect(func() { + bot.logger.Infof("Successfully connected to Twitch Servers in %s mode!", cfg.Environment) + bot.Send("nourylul", "xd") }) return bot diff --git a/pkg/bot/send.go b/pkg/bot/send.go index c6b32e5..3333abe 100644 --- a/pkg/bot/send.go +++ b/pkg/bot/send.go @@ -95,7 +95,7 @@ func (bot *Bot) Send(target, message string) { messageBanned, banReason := bot.checkMessage(message) if messageBanned { // Bad message, replace message and log it. - bot.twitchClient.Say(target, "[BANPHRASED] monkaS") + bot.TwitchClient.Say(target, "[BANPHRASED] monkaS") bot.logger.Info("Banned message detected: ", banReason) return @@ -107,13 +107,13 @@ func (bot *Bot) Send(target, message string) { firstMessage := message[0:499] secondMessage := message[499:] - bot.twitchClient.Say(target, firstMessage) - bot.twitchClient.Say(target, secondMessage) + bot.TwitchClient.Say(target, firstMessage) + bot.TwitchClient.Say(target, secondMessage) return } // Message was fine. - bot.twitchClient.Say(target, message) + bot.TwitchClient.Say(target, message) return } } From 79c9fa9da7e3eae534c96378e3cc4f7dfecf5f47 Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Sun, 7 Aug 2022 01:34:27 +0200 Subject: [PATCH 20/35] restructure --- pkg/commands/echo.go | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 pkg/commands/echo.go diff --git a/pkg/commands/echo.go b/pkg/commands/echo.go new file mode 100644 index 0000000..981bbc4 --- /dev/null +++ b/pkg/commands/echo.go @@ -0,0 +1,5 @@ +package commands + +func Echo(target, message string) { + +} From fee71708e750882dc5ee01b37a359ec1f93ec33c Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Sun, 7 Aug 2022 01:34:31 +0200 Subject: [PATCH 21/35] restructure --- {pkg => cmd}/bot/command.go | 14 ++++---- cmd/bot/main.go | 41 +++++++++++++++++++++--- {pkg => cmd}/bot/privatemessage.go | 10 +++--- {pkg => cmd}/bot/send.go | 28 ++++++++-------- cmd/bot/whispermessage.go | 9 ++++++ pkg/bot/bot.go | 51 ------------------------------ pkg/bot/whispermessage.go | 9 ------ 7 files changed, 74 insertions(+), 88 deletions(-) rename {pkg => cmd}/bot/command.go (73%) rename {pkg => cmd}/bot/privatemessage.go (66%) rename {pkg => cmd}/bot/send.go (84%) create mode 100644 cmd/bot/whispermessage.go delete mode 100644 pkg/bot/bot.go delete mode 100644 pkg/bot/whispermessage.go diff --git a/pkg/bot/command.go b/cmd/bot/command.go similarity index 73% rename from pkg/bot/command.go rename to cmd/bot/command.go index 77d53e5..79670e0 100644 --- a/pkg/bot/command.go +++ b/cmd/bot/command.go @@ -1,13 +1,14 @@ -package bot +package main import ( "strings" "github.com/gempir/go-twitch-irc/v3" + "github.com/lyx0/nourybot/pkg/commands" ) -func (bot *Bot) handleCommand(message twitch.PrivateMessage) { - bot.logger.Info("[COMMAND HANDLER]", message) +func (app *Application) handleCommand(message twitch.PrivateMessage) { + app.Logger.Info("[COMMAND HANDLER]", message) // commandName is the actual name of the command without the prefix. // e.g. `()ping` would be `ping`. @@ -34,15 +35,16 @@ func (bot *Bot) handleCommand(message twitch.PrivateMessage) { switch commandName { case "": if msgLen == 1 { - bot.Send(target, "xd") + app.Send(target, "xd") return } case "echo": if msgLen < 2 { - bot.Send(target, "Not enough arguments provided.") + app.Send(target, "Not enough arguments provided.") return } else { - bot.Send(target, message.Message[7:len(message.Message)]) + commands.Echo(target, message.Message[7:len(message.Message)]) + // bot.Send(target, message.Message[7:len(message.Message)]) return } } diff --git a/cmd/bot/main.go b/cmd/bot/main.go index 3c6f6cc..59bda3b 100644 --- a/cmd/bot/main.go +++ b/cmd/bot/main.go @@ -1,13 +1,46 @@ package main -import "github.com/lyx0/nourybot/pkg/bot" +import ( + "github.com/gempir/go-twitch-irc/v3" + "github.com/lyx0/nourybot/internal/config" + "github.com/sirupsen/logrus" +) + +type Application struct { + TwitchClient *twitch.Client + Logger *logrus.Logger +} func main() { + cfg := config.New() - bot := bot.New() + twitchClient := twitch.NewClient(cfg.TwitchUsername, cfg.TwitchOauth) - bot.TwitchClient.Join("nourylul") - err := bot.TwitchClient.Connect() + app := Application{ + TwitchClient: twitchClient, + Logger: logrus.New(), + } + // Received a PrivateMessage (normal chat message), pass it to + // the handler who checks for further action. + app.TwitchClient.OnPrivateMessage(func(message twitch.PrivateMessage) { + app.handlePrivateMessage(message) + }) + + // Received a WhisperMessage (Twitch DM), pass it to + // the handler who checks for further action. + app.TwitchClient.OnWhisperMessage(func(message twitch.WhisperMessage) { + app.handleWhisperMessage(message) + }) + + // Successfully connected to Twitch so we log a message with the + // mode we are currently running in.. + app.TwitchClient.OnConnect(func() { + app.Logger.Infof("Successfully connected to Twitch Servers in %s mode!", cfg.Environment) + app.Send("nourylul", "xd") + }) + + app.TwitchClient.Join("nourylul") + err := app.TwitchClient.Connect() if err != nil { panic(err) } diff --git a/pkg/bot/privatemessage.go b/cmd/bot/privatemessage.go similarity index 66% rename from pkg/bot/privatemessage.go rename to cmd/bot/privatemessage.go index 39be731..907130d 100644 --- a/pkg/bot/privatemessage.go +++ b/cmd/bot/privatemessage.go @@ -1,28 +1,28 @@ -package bot +package main import "github.com/gempir/go-twitch-irc/v3" -func (bot *Bot) handlePrivateMessage(message twitch.PrivateMessage) { +func (app *Application) handlePrivateMessage(message twitch.PrivateMessage) { // roomId is the Twitch UserID of the channel the // message originated from. roomId := message.Tags["room-id"] // If there is no roomId something went wrong. if roomId == "" { - bot.logger.Error("Missing room-id in message tag ", roomId) + app.Logger.Error("Missing room-id in message tag ", roomId) return } if len(message.Message) >= 2 { if message.Message[:2] == "()" { // TODO: Command Handling - bot.handleCommand(message) + app.handleCommand(message) // app.logger.Infof("[Command detected]: ", message.Message) return } } // Message was no command so we just print it. - bot.logger.Infof("[#%s]:%s: %s", message.Channel, message.User.DisplayName, message.Message) + app.Logger.Infof("[#%s]:%s: %s", message.Channel, message.User.DisplayName, message.Message) } diff --git a/pkg/bot/send.go b/cmd/bot/send.go similarity index 84% rename from pkg/bot/send.go rename to cmd/bot/send.go index 3333abe..382a22a 100644 --- a/pkg/bot/send.go +++ b/cmd/bot/send.go @@ -1,4 +1,4 @@ -package bot +package main import ( "bytes" @@ -6,6 +6,8 @@ import ( "fmt" "io/ioutil" "net/http" + + "github.com/sirupsen/logrus" ) // banphraseResponse is the data we receive back from @@ -35,26 +37,26 @@ var ( // returns true and a string with the reason if it was banned. // More information: // https://gist.github.com/pajlada/57464e519ba8d195a97ddcd0755f9715 -func (bot *Bot) checkMessage(text string) (bool, string) { - +func checkMessage(text string) (bool, string) { + var l *logrus.Logger // {"message": "AHAHAHAHA LUL"} reqBody, err := json.Marshal(map[string]string{ "message": text, }) if err != nil { - bot.logger.Error(err) + l.Error(err) } resp, err := http.Post(banPhraseUrl, "application/json", bytes.NewBuffer(reqBody)) if err != nil { - bot.logger.Error(err) + l.Error(err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { - bot.logger.Error(err) + l.Error(err) } var responseObject banphraseResponse @@ -77,7 +79,7 @@ func (bot *Bot) checkMessage(text string) (bool, string) { // Send is used to send twitch replies and contains the necessary // safeguards and logic for that. -func (bot *Bot) Send(target, message string) { +func (app *Application) Send(target, message string) { // Message we are trying to send is empty. if len(message) == 0 { return @@ -92,11 +94,11 @@ func (bot *Bot) Send(target, message string) { } // check the message for bad words before we say it - messageBanned, banReason := bot.checkMessage(message) + messageBanned, banReason := checkMessage(message) if messageBanned { // Bad message, replace message and log it. - bot.TwitchClient.Say(target, "[BANPHRASED] monkaS") - bot.logger.Info("Banned message detected: ", banReason) + app.TwitchClient.Say(target, "[BANPHRASED] monkaS") + app.Logger.Info("Banned message detected: ", banReason) return } else { @@ -107,13 +109,13 @@ func (bot *Bot) Send(target, message string) { firstMessage := message[0:499] secondMessage := message[499:] - bot.TwitchClient.Say(target, firstMessage) - bot.TwitchClient.Say(target, secondMessage) + app.TwitchClient.Say(target, firstMessage) + app.TwitchClient.Say(target, secondMessage) return } // Message was fine. - bot.TwitchClient.Say(target, message) + app.TwitchClient.Say(target, message) return } } diff --git a/cmd/bot/whispermessage.go b/cmd/bot/whispermessage.go new file mode 100644 index 0000000..e6b7076 --- /dev/null +++ b/cmd/bot/whispermessage.go @@ -0,0 +1,9 @@ +package main + +import "github.com/gempir/go-twitch-irc/v3" + +func (app *Application) handleWhisperMessage(message twitch.WhisperMessage) { + // Print the whisper message for now. + // TODO: Implement a basic whisper handler. + app.Logger.Infof("[#whisper]:%s: %s", message.User.DisplayName, message.Message) +} diff --git a/pkg/bot/bot.go b/pkg/bot/bot.go deleted file mode 100644 index 9f71e19..0000000 --- a/pkg/bot/bot.go +++ /dev/null @@ -1,51 +0,0 @@ -package bot - -import ( - "github.com/gempir/go-twitch-irc/v3" - "github.com/lyx0/nourybot/internal/config" - "github.com/sirupsen/logrus" -) - -type Bot struct { - TwitchClient *twitch.Client - logger *logrus.Logger -} - -func New() *Bot { - // Initialize a new logger we attach to our application struct. - lgr := logrus.New() - - cfg := config.New() - - // Initialize a new twitch client which we attach to our - // application struct. - logrus.Info(cfg.TwitchUsername, cfg.TwitchOauth) - twitchClient := twitch.NewClient(cfg.TwitchUsername, cfg.TwitchOauth) - - bot := &Bot{ - TwitchClient: twitchClient, - logger: lgr, - } - - // Received a PrivateMessage (normal chat message), pass it to - // the handler who checks for further action. - bot.TwitchClient.OnPrivateMessage(func(message twitch.PrivateMessage) { - bot.handlePrivateMessage(message) - }) - - // Received a WhisperMessage (Twitch DM), pass it to - // the handler who checks for further action. - bot.TwitchClient.OnWhisperMessage(func(message twitch.WhisperMessage) { - bot.handleWhisperMessage(message) - }) - - // Successfully connected to Twitch so we log a message with the - // mode we are currently running in.. - bot.TwitchClient.OnConnect(func() { - bot.logger.Infof("Successfully connected to Twitch Servers in %s mode!", cfg.Environment) - bot.Send("nourylul", "xd") - }) - - return bot - -} diff --git a/pkg/bot/whispermessage.go b/pkg/bot/whispermessage.go deleted file mode 100644 index 716dda1..0000000 --- a/pkg/bot/whispermessage.go +++ /dev/null @@ -1,9 +0,0 @@ -package bot - -import "github.com/gempir/go-twitch-irc/v3" - -func (bot *Bot) handleWhisperMessage(message twitch.WhisperMessage) { - // Print the whisper message for now. - // TODO: Implement a basic whisper handler. - bot.logger.Infof("[#whisper]:%s: %s", message.User.DisplayName, message.Message) -} From effffff270e0166db27df86935362d5770aed391 Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Sun, 7 Aug 2022 02:27:40 +0200 Subject: [PATCH 22/35] fix dereference error somehow --- cmd/bot/command.go | 17 +++++++++++------ cmd/bot/main.go | 23 +++++++++++++---------- cmd/bot/privatemessage.go | 3 ++- pkg/commands/echo.go | 7 ++++++- cmd/bot/send.go => pkg/common/common.go | 24 +++++++++++++----------- 5 files changed, 45 insertions(+), 29 deletions(-) rename cmd/bot/send.go => pkg/common/common.go (88%) diff --git a/cmd/bot/command.go b/cmd/bot/command.go index 79670e0..a263ed7 100644 --- a/cmd/bot/command.go +++ b/cmd/bot/command.go @@ -5,14 +5,18 @@ import ( "github.com/gempir/go-twitch-irc/v3" "github.com/lyx0/nourybot/pkg/commands" + "github.com/lyx0/nourybot/pkg/common" + "github.com/sirupsen/logrus" ) -func (app *Application) handleCommand(message twitch.PrivateMessage) { - app.Logger.Info("[COMMAND HANDLER]", message) +func handleCommand(message twitch.PrivateMessage, tc *twitch.Client) { + logrus.Info("[COMMAND HANDLER]", message) + logrus.Info(message) // commandName is the actual name of the command without the prefix. // e.g. `()ping` would be `ping`. commandName := strings.ToLower(strings.SplitN(message.Message, " ", 3)[0][2:]) + logrus.Info(commandName) // cmdParams are additional command parameters. // e.g. `()weather san antonio` @@ -21,12 +25,13 @@ func (app *Application) handleCommand(message twitch.PrivateMessage) { // Since Twitch messages are at most 500 characters I use a // maximum count of 500+10 just to be safe. // https://discuss.dev.twitch.tv/t/missing-client-side-message-length-check/21316 - cmdParams := strings.SplitN(message.Message, " ", 510) + cmdParams := strings.SplitN(message.Message, " ", 500) _ = cmdParams // msgLen is the amount of words in a message without the prefix. // Useful to check if enough cmdParams are provided. msgLen := len(strings.SplitN(message.Message, " ", -2)) + logrus.Info(msgLen) // target is the channelname the message originated from and // where we are responding. @@ -35,15 +40,15 @@ func (app *Application) handleCommand(message twitch.PrivateMessage) { switch commandName { case "": if msgLen == 1 { - app.Send(target, "xd") + common.Send(target, "xd", tc) return } case "echo": if msgLen < 2 { - app.Send(target, "Not enough arguments provided.") + common.Send(target, "Not enough arguments provided.", tc) return } else { - commands.Echo(target, message.Message[7:len(message.Message)]) + commands.Echo(target, message.Message[7:len(message.Message)], tc) // bot.Send(target, message.Message[7:len(message.Message)]) return } diff --git a/cmd/bot/main.go b/cmd/bot/main.go index 59bda3b..2ed98bb 100644 --- a/cmd/bot/main.go +++ b/cmd/bot/main.go @@ -3,6 +3,7 @@ package main import ( "github.com/gempir/go-twitch-irc/v3" "github.com/lyx0/nourybot/internal/config" + "github.com/lyx0/nourybot/pkg/common" "github.com/sirupsen/logrus" ) @@ -13,33 +14,35 @@ type Application struct { func main() { cfg := config.New() + lgr := logrus.New() - twitchClient := twitch.NewClient(cfg.TwitchUsername, cfg.TwitchOauth) - - app := Application{ - TwitchClient: twitchClient, - Logger: logrus.New(), + tc := twitch.NewClient(cfg.TwitchUsername, cfg.TwitchOauth) + app := &Application{ + TwitchClient: tc, + Logger: lgr, } // Received a PrivateMessage (normal chat message), pass it to // the handler who checks for further action. app.TwitchClient.OnPrivateMessage(func(message twitch.PrivateMessage) { + app.Logger.Infof("%s", message) + app.handlePrivateMessage(message) }) // Received a WhisperMessage (Twitch DM), pass it to // the handler who checks for further action. - app.TwitchClient.OnWhisperMessage(func(message twitch.WhisperMessage) { - app.handleWhisperMessage(message) - }) + // twitchClient.OnWhisperMessage(func(message twitch.WhisperMessage) { + // app.handleWhisperMessage(message) + // }) // Successfully connected to Twitch so we log a message with the // mode we are currently running in.. app.TwitchClient.OnConnect(func() { app.Logger.Infof("Successfully connected to Twitch Servers in %s mode!", cfg.Environment) - app.Send("nourylul", "xd") + common.Send("nourylul", "xd", app.TwitchClient) }) - app.TwitchClient.Join("nourylul") + err := app.TwitchClient.Connect() if err != nil { panic(err) diff --git a/cmd/bot/privatemessage.go b/cmd/bot/privatemessage.go index 907130d..80d7cde 100644 --- a/cmd/bot/privatemessage.go +++ b/cmd/bot/privatemessage.go @@ -16,7 +16,8 @@ func (app *Application) handlePrivateMessage(message twitch.PrivateMessage) { if len(message.Message) >= 2 { if message.Message[:2] == "()" { // TODO: Command Handling - app.handleCommand(message) + app.Logger.Infof("[Command detected]: ", message.Message) + handleCommand(message, app.TwitchClient) // app.logger.Infof("[Command detected]: ", message.Message) return } diff --git a/pkg/commands/echo.go b/pkg/commands/echo.go index 981bbc4..f99cfe5 100644 --- a/pkg/commands/echo.go +++ b/pkg/commands/echo.go @@ -1,5 +1,10 @@ package commands -func Echo(target, message string) { +import ( + "github.com/gempir/go-twitch-irc/v3" + "github.com/lyx0/nourybot/pkg/common" +) +func Echo(target, message string, tc *twitch.Client) { + common.Send(target, message, tc) } diff --git a/cmd/bot/send.go b/pkg/common/common.go similarity index 88% rename from cmd/bot/send.go rename to pkg/common/common.go index 382a22a..f6cd59f 100644 --- a/cmd/bot/send.go +++ b/pkg/common/common.go @@ -1,12 +1,14 @@ -package main +package common import ( "bytes" "encoding/json" "fmt" "io/ioutil" + "log" "net/http" + "github.com/gempir/go-twitch-irc/v3" "github.com/sirupsen/logrus" ) @@ -38,25 +40,24 @@ var ( // More information: // https://gist.github.com/pajlada/57464e519ba8d195a97ddcd0755f9715 func checkMessage(text string) (bool, string) { - var l *logrus.Logger // {"message": "AHAHAHAHA LUL"} reqBody, err := json.Marshal(map[string]string{ "message": text, }) if err != nil { - l.Error(err) + log.Panic(err) } resp, err := http.Post(banPhraseUrl, "application/json", bytes.NewBuffer(reqBody)) if err != nil { - l.Error(err) + log.Panic(err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { - l.Error(err) + log.Panic(err) } var responseObject banphraseResponse @@ -79,11 +80,12 @@ func checkMessage(text string) (bool, string) { // Send is used to send twitch replies and contains the necessary // safeguards and logic for that. -func (app *Application) Send(target, message string) { +func Send(target, message string, tc *twitch.Client) { // Message we are trying to send is empty. if len(message) == 0 { return } + fmt.Println(message) // Since messages starting with `.` or `/` are used for special actions // (ban, whisper, timeout) and so on, we place a emote infront of it so @@ -97,8 +99,8 @@ func (app *Application) Send(target, message string) { messageBanned, banReason := checkMessage(message) if messageBanned { // Bad message, replace message and log it. - app.TwitchClient.Say(target, "[BANPHRASED] monkaS") - app.Logger.Info("Banned message detected: ", banReason) + tc.Say(target, "[BANPHRASED] monkaS") + logrus.Info("Banned message detected: ", banReason) return } else { @@ -109,13 +111,13 @@ func (app *Application) Send(target, message string) { firstMessage := message[0:499] secondMessage := message[499:] - app.TwitchClient.Say(target, firstMessage) - app.TwitchClient.Say(target, secondMessage) + tc.Say(target, firstMessage) + tc.Say(target, secondMessage) return } // Message was fine. - app.TwitchClient.Say(target, message) + tc.Say(target, message) return } } From edae669bee70fef678a3416b3e5e51183f02f2b0 Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Sun, 7 Aug 2022 03:09:09 +0200 Subject: [PATCH 23/35] replace logrus with zap --- cmd/bot/command.go | 16 ++++++---- cmd/bot/main.go | 25 +++++++++------- cmd/bot/privatemessage.go | 21 ++++++++++---- cmd/bot/whispermessage.go | 4 ++- go.mod | 7 +++-- go.sum | 61 +++++++++++++++++++++++++++++++++++---- pkg/common/common.go | 14 ++++++--- 7 files changed, 113 insertions(+), 35 deletions(-) diff --git a/cmd/bot/command.go b/cmd/bot/command.go index a263ed7..dcb43b4 100644 --- a/cmd/bot/command.go +++ b/cmd/bot/command.go @@ -6,17 +6,21 @@ import ( "github.com/gempir/go-twitch-irc/v3" "github.com/lyx0/nourybot/pkg/commands" "github.com/lyx0/nourybot/pkg/common" - "github.com/sirupsen/logrus" + "go.uber.org/zap" ) func handleCommand(message twitch.PrivateMessage, tc *twitch.Client) { - logrus.Info("[COMMAND HANDLER]", message) - logrus.Info(message) + sugar := zap.NewExample().Sugar() + defer sugar.Sync() + + //sugar.Infow("Command received", + // "message", message) // commandName is the actual name of the command without the prefix. // e.g. `()ping` would be `ping`. commandName := strings.ToLower(strings.SplitN(message.Message, " ", 3)[0][2:]) - logrus.Info(commandName) + sugar.Infow("[handleCommand]", + "commandName", commandName) // cmdParams are additional command parameters. // e.g. `()weather san antonio` @@ -31,7 +35,8 @@ func handleCommand(message twitch.PrivateMessage, tc *twitch.Client) { // msgLen is the amount of words in a message without the prefix. // Useful to check if enough cmdParams are provided. msgLen := len(strings.SplitN(message.Message, " ", -2)) - logrus.Info(msgLen) + // sugar.Infow("handleCommand", + // "msgLen:", msgLen) // target is the channelname the message originated from and // where we are responding. @@ -49,7 +54,6 @@ func handleCommand(message twitch.PrivateMessage, tc *twitch.Client) { return } else { commands.Echo(target, message.Message[7:len(message.Message)], tc) - // bot.Send(target, message.Message[7:len(message.Message)]) return } } diff --git a/cmd/bot/main.go b/cmd/bot/main.go index 2ed98bb..93bbc30 100644 --- a/cmd/bot/main.go +++ b/cmd/bot/main.go @@ -4,41 +4,46 @@ import ( "github.com/gempir/go-twitch-irc/v3" "github.com/lyx0/nourybot/internal/config" "github.com/lyx0/nourybot/pkg/common" - "github.com/sirupsen/logrus" + "go.uber.org/zap" ) type Application struct { TwitchClient *twitch.Client - Logger *logrus.Logger + Logger *zap.SugaredLogger } func main() { cfg := config.New() - lgr := logrus.New() + + sugar := zap.NewExample().Sugar() + defer sugar.Sync() tc := twitch.NewClient(cfg.TwitchUsername, cfg.TwitchOauth) + app := &Application{ TwitchClient: tc, - Logger: lgr, + Logger: sugar, } // Received a PrivateMessage (normal chat message), pass it to // the handler who checks for further action. app.TwitchClient.OnPrivateMessage(func(message twitch.PrivateMessage) { - app.Logger.Infof("%s", message) - + //app.Logger.Infof("%s", message) app.handlePrivateMessage(message) }) // Received a WhisperMessage (Twitch DM), pass it to // the handler who checks for further action. - // twitchClient.OnWhisperMessage(func(message twitch.WhisperMessage) { - // app.handleWhisperMessage(message) - // }) + app.TwitchClient.OnWhisperMessage(func(message twitch.WhisperMessage) { + app.handleWhisperMessage(message) + }) // Successfully connected to Twitch so we log a message with the // mode we are currently running in.. app.TwitchClient.OnConnect(func() { - app.Logger.Infof("Successfully connected to Twitch Servers in %s mode!", cfg.Environment) + sugar.Infow("Successfully connected to Twitch Servers", + "Bot username", cfg.TwitchUsername, + "Environment", cfg.Environment) + common.Send("nourylul", "xd", app.TwitchClient) }) app.TwitchClient.Join("nourylul") diff --git a/cmd/bot/privatemessage.go b/cmd/bot/privatemessage.go index 80d7cde..237ed6c 100644 --- a/cmd/bot/privatemessage.go +++ b/cmd/bot/privatemessage.go @@ -1,29 +1,38 @@ package main -import "github.com/gempir/go-twitch-irc/v3" +import ( + "github.com/gempir/go-twitch-irc/v3" + "go.uber.org/zap" +) func (app *Application) handlePrivateMessage(message twitch.PrivateMessage) { + sugar := zap.NewExample().Sugar() + defer sugar.Sync() // roomId is the Twitch UserID of the channel the // message originated from. roomId := message.Tags["room-id"] // If there is no roomId something went wrong. if roomId == "" { - app.Logger.Error("Missing room-id in message tag ", roomId) + sugar.Errorw("Missing room-id in message tag", + "roomId", roomId) return } if len(message.Message) >= 2 { if message.Message[:2] == "()" { - // TODO: Command Handling - app.Logger.Infof("[Command detected]: ", message.Message) + // app.Logger.Infow("handlePrivateMessage", + // "message.Message", message.Message) + handleCommand(message, app.TwitchClient) - // app.logger.Infof("[Command detected]: ", message.Message) return } } // Message was no command so we just print it. - app.Logger.Infof("[#%s]:%s: %s", message.Channel, message.User.DisplayName, message.Message) + app.Logger.Infow("Private Message received", + "message.Channel", message.Channel, + "message.User", message.User.DisplayName, + "message.Message", message.Message) } diff --git a/cmd/bot/whispermessage.go b/cmd/bot/whispermessage.go index e6b7076..8a255bc 100644 --- a/cmd/bot/whispermessage.go +++ b/cmd/bot/whispermessage.go @@ -5,5 +5,7 @@ import "github.com/gempir/go-twitch-irc/v3" func (app *Application) handleWhisperMessage(message twitch.WhisperMessage) { // Print the whisper message for now. // TODO: Implement a basic whisper handler. - app.Logger.Infof("[#whisper]:%s: %s", message.User.DisplayName, message.Message) + app.Logger.Infow("Whisper Message received", + "message.User.DisplayName", message.User.DisplayName, + "message.Message", message.Message) } diff --git a/go.mod b/go.mod index 2aceb09..61be804 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,10 @@ go 1.17 require ( github.com/gempir/go-twitch-irc/v3 v3.1.0 github.com/joho/godotenv v1.4.0 - github.com/sirupsen/logrus v1.8.1 + go.uber.org/zap v1.21.0 ) -require golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 // indirect +require ( + go.uber.org/atomic v1.9.0 // indirect + go.uber.org/multierr v1.8.0 // indirect +) diff --git a/go.sum b/go.sum index aad75a3..79c5570 100644 --- a/go.sum +++ b/go.sum @@ -1,14 +1,63 @@ +github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/gempir/go-twitch-irc/v3 v3.1.0 h1:bUVZ5mADhH7KidJVcl+z79kgLJ7sjdAk4b/ylAvaLy0= github.com/gempir/go-twitch-irc/v3 v3.1.0/go.mod h1:/W9KZIiyizVecp4PEb7kc4AlIyXKiCmvlXrzlpPUytU= github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= +go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pkg/common/common.go b/pkg/common/common.go index f6cd59f..f988def 100644 --- a/pkg/common/common.go +++ b/pkg/common/common.go @@ -9,7 +9,7 @@ import ( "net/http" "github.com/gempir/go-twitch-irc/v3" - "github.com/sirupsen/logrus" + "go.uber.org/zap" ) // banphraseResponse is the data we receive back from @@ -40,12 +40,15 @@ var ( // More information: // https://gist.github.com/pajlada/57464e519ba8d195a97ddcd0755f9715 func checkMessage(text string) (bool, string) { + sugar := zap.NewExample().Sugar() + defer sugar.Sync() + // {"message": "AHAHAHAHA LUL"} reqBody, err := json.Marshal(map[string]string{ "message": text, }) if err != nil { - log.Panic(err) + log.Fatal(err) } resp, err := http.Post(banPhraseUrl, "application/json", bytes.NewBuffer(reqBody)) @@ -81,11 +84,13 @@ func checkMessage(text string) (bool, string) { // Send is used to send twitch replies and contains the necessary // safeguards and logic for that. func Send(target, message string, tc *twitch.Client) { + sugar := zap.NewExample().Sugar() + defer sugar.Sync() + // Message we are trying to send is empty. if len(message) == 0 { return } - fmt.Println(message) // Since messages starting with `.` or `/` are used for special actions // (ban, whisper, timeout) and so on, we place a emote infront of it so @@ -100,7 +105,8 @@ func Send(target, message string, tc *twitch.Client) { if messageBanned { // Bad message, replace message and log it. tc.Say(target, "[BANPHRASED] monkaS") - logrus.Info("Banned message detected: ", banReason) + sugar.Infow("banned message detected", + "banReason", banReason) return } else { From c5d9804c2141d4932e1568437c2a15f78e2bbb58 Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Sun, 7 Aug 2022 03:17:29 +0200 Subject: [PATCH 24/35] remove unused comments and clean up --- cmd/bot/command.go | 16 +++++++++------- cmd/bot/main.go | 2 +- cmd/bot/privatemessage.go | 12 ++++++------ cmd/bot/whispermessage.go | 1 + 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/cmd/bot/command.go b/cmd/bot/command.go index dcb43b4..d289fd9 100644 --- a/cmd/bot/command.go +++ b/cmd/bot/command.go @@ -13,14 +13,9 @@ func handleCommand(message twitch.PrivateMessage, tc *twitch.Client) { sugar := zap.NewExample().Sugar() defer sugar.Sync() - //sugar.Infow("Command received", - // "message", message) - // commandName is the actual name of the command without the prefix. // e.g. `()ping` would be `ping`. commandName := strings.ToLower(strings.SplitN(message.Message, " ", 3)[0][2:]) - sugar.Infow("[handleCommand]", - "commandName", commandName) // cmdParams are additional command parameters. // e.g. `()weather san antonio` @@ -35,13 +30,20 @@ func handleCommand(message twitch.PrivateMessage, tc *twitch.Client) { // msgLen is the amount of words in a message without the prefix. // Useful to check if enough cmdParams are provided. msgLen := len(strings.SplitN(message.Message, " ", -2)) - // sugar.Infow("handleCommand", - // "msgLen:", msgLen) // target is the channelname the message originated from and // where we are responding. target := message.Channel + sugar.Infow("Command received", + // "message", message, + "message.Message", message.Message, + "target", target, + "commandName", commandName, + "cmdParams", cmdParams, + "msgLen", msgLen, + ) + switch commandName { case "": if msgLen == 1 { diff --git a/cmd/bot/main.go b/cmd/bot/main.go index 93bbc30..d70ded8 100644 --- a/cmd/bot/main.go +++ b/cmd/bot/main.go @@ -24,10 +24,10 @@ func main() { TwitchClient: tc, Logger: sugar, } + // Received a PrivateMessage (normal chat message), pass it to // the handler who checks for further action. app.TwitchClient.OnPrivateMessage(func(message twitch.PrivateMessage) { - //app.Logger.Infof("%s", message) app.handlePrivateMessage(message) }) diff --git a/cmd/bot/privatemessage.go b/cmd/bot/privatemessage.go index 237ed6c..5cf0ad5 100644 --- a/cmd/bot/privatemessage.go +++ b/cmd/bot/privatemessage.go @@ -8,8 +8,8 @@ import ( func (app *Application) handlePrivateMessage(message twitch.PrivateMessage) { sugar := zap.NewExample().Sugar() defer sugar.Sync() - // roomId is the Twitch UserID of the channel the - // message originated from. + + // roomId is the Twitch UserID of the channel the message originated from. roomId := message.Tags["room-id"] // If there is no roomId something went wrong. @@ -19,11 +19,9 @@ func (app *Application) handlePrivateMessage(message twitch.PrivateMessage) { return } + // Message was shorter than our prefix is therefore it's irrelevant for us. if len(message.Message) >= 2 { if message.Message[:2] == "()" { - // app.Logger.Infow("handlePrivateMessage", - // "message.Message", message.Message) - handleCommand(message, app.TwitchClient) return } @@ -31,8 +29,10 @@ func (app *Application) handlePrivateMessage(message twitch.PrivateMessage) { // Message was no command so we just print it. app.Logger.Infow("Private Message received", + "message", message, "message.Channel", message.Channel, "message.User", message.User.DisplayName, - "message.Message", message.Message) + "message.Message", message.Message, + ) } diff --git a/cmd/bot/whispermessage.go b/cmd/bot/whispermessage.go index 8a255bc..ffb0076 100644 --- a/cmd/bot/whispermessage.go +++ b/cmd/bot/whispermessage.go @@ -6,6 +6,7 @@ func (app *Application) handleWhisperMessage(message twitch.WhisperMessage) { // Print the whisper message for now. // TODO: Implement a basic whisper handler. app.Logger.Infow("Whisper Message received", + "message", message, "message.User.DisplayName", message.User.DisplayName, "message.Message", message.Message) } From dc70232d54414cb49c0dfc7d8e698a47d46e27cf Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Sun, 7 Aug 2022 04:35:00 +0200 Subject: [PATCH 25/35] cleanup --- go.mod | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 61be804..b67291e 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,9 @@ module github.com/lyx0/nourybot -go 1.17 +go 1.19 require ( - github.com/gempir/go-twitch-irc/v3 v3.1.0 + github.com/gempir/go-twitch-irc/v3 v3.2.0 github.com/joho/godotenv v1.4.0 go.uber.org/zap v1.21.0 ) From 33f61e2f0fab3f09efd1a6be3a1ac64ba4896500 Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Sun, 7 Aug 2022 04:35:03 +0200 Subject: [PATCH 26/35] cleanup --- cmd/bot/command.go | 2 +- cmd/bot/main.go | 8 ++++---- cmd/bot/privatemessage.go | 12 +++++++----- cmd/bot/whispermessage.go | 3 ++- go.sum | 2 ++ pkg/common/common.go | 13 +++++++++---- 6 files changed, 25 insertions(+), 15 deletions(-) diff --git a/cmd/bot/command.go b/cmd/bot/command.go index d289fd9..b77b2dd 100644 --- a/cmd/bot/command.go +++ b/cmd/bot/command.go @@ -37,8 +37,8 @@ func handleCommand(message twitch.PrivateMessage, tc *twitch.Client) { sugar.Infow("Command received", // "message", message, + "message.Channel", target, "message.Message", message.Message, - "target", target, "commandName", commandName, "cmdParams", cmdParams, "msgLen", msgLen, diff --git a/cmd/bot/main.go b/cmd/bot/main.go index d70ded8..9fc4bd1 100644 --- a/cmd/bot/main.go +++ b/cmd/bot/main.go @@ -15,11 +15,10 @@ type Application struct { func main() { cfg := config.New() + tc := twitch.NewClient(cfg.TwitchUsername, cfg.TwitchOauth) sugar := zap.NewExample().Sugar() defer sugar.Sync() - tc := twitch.NewClient(cfg.TwitchUsername, cfg.TwitchOauth) - app := &Application{ TwitchClient: tc, Logger: sugar, @@ -40,9 +39,10 @@ func main() { // Successfully connected to Twitch so we log a message with the // mode we are currently running in.. app.TwitchClient.OnConnect(func() { - sugar.Infow("Successfully connected to Twitch Servers", + app.Logger.Infow("Successfully connected to Twitch Servers", "Bot username", cfg.TwitchUsername, - "Environment", cfg.Environment) + "Environment", cfg.Environment, + ) common.Send("nourylul", "xd", app.TwitchClient) }) diff --git a/cmd/bot/privatemessage.go b/cmd/bot/privatemessage.go index 5cf0ad5..cf00f29 100644 --- a/cmd/bot/privatemessage.go +++ b/cmd/bot/privatemessage.go @@ -10,17 +10,19 @@ func (app *Application) handlePrivateMessage(message twitch.PrivateMessage) { defer sugar.Sync() // roomId is the Twitch UserID of the channel the message originated from. + // If there is no roomId something went really wrong. roomId := message.Tags["room-id"] - - // If there is no roomId something went wrong. if roomId == "" { - sugar.Errorw("Missing room-id in message tag", - "roomId", roomId) + app.Logger.Errorw("Missing room-id in message tag", + "roomId", roomId, + ) + return } // Message was shorter than our prefix is therefore it's irrelevant for us. if len(message.Message) >= 2 { + // Strip the `()` prefix if message.Message[:2] == "()" { handleCommand(message, app.TwitchClient) return @@ -29,7 +31,7 @@ func (app *Application) handlePrivateMessage(message twitch.PrivateMessage) { // Message was no command so we just print it. app.Logger.Infow("Private Message received", - "message", message, + // "message", message, "message.Channel", message.Channel, "message.User", message.User.DisplayName, "message.Message", message.Message, diff --git a/cmd/bot/whispermessage.go b/cmd/bot/whispermessage.go index ffb0076..f9f7c0e 100644 --- a/cmd/bot/whispermessage.go +++ b/cmd/bot/whispermessage.go @@ -8,5 +8,6 @@ func (app *Application) handleWhisperMessage(message twitch.WhisperMessage) { app.Logger.Infow("Whisper Message received", "message", message, "message.User.DisplayName", message.User.DisplayName, - "message.Message", message.Message) + "message.Message", message.Message, + ) } diff --git a/go.sum b/go.sum index 79c5570..8b284aa 100644 --- a/go.sum +++ b/go.sum @@ -5,6 +5,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/gempir/go-twitch-irc/v3 v3.1.0 h1:bUVZ5mADhH7KidJVcl+z79kgLJ7sjdAk4b/ylAvaLy0= github.com/gempir/go-twitch-irc/v3 v3.1.0/go.mod h1:/W9KZIiyizVecp4PEb7kc4AlIyXKiCmvlXrzlpPUytU= +github.com/gempir/go-twitch-irc/v3 v3.2.0 h1:ENhsa7RgBE1GMmDqe0iMkvcSYfgw6ZsXilt+sAg32/U= +github.com/gempir/go-twitch-irc/v3 v3.2.0/go.mod h1:/W9KZIiyizVecp4PEb7kc4AlIyXKiCmvlXrzlpPUytU= github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= diff --git a/pkg/common/common.go b/pkg/common/common.go index f988def..cb1bd79 100644 --- a/pkg/common/common.go +++ b/pkg/common/common.go @@ -93,7 +93,7 @@ func Send(target, message string, tc *twitch.Client) { } // Since messages starting with `.` or `/` are used for special actions - // (ban, whisper, timeout) and so on, we place a emote infront of it so + // (ban, whisper, timeout) and so on, we place an emote infront of it so // the actions wouldn't execute. `!` and `$` are common bot prefixes so we // don't allow them either. if message[0] == '.' || message[0] == '/' || message[0] == '!' || message[0] == '$' { @@ -106,13 +106,18 @@ func Send(target, message string, tc *twitch.Client) { // Bad message, replace message and log it. tc.Say(target, "[BANPHRASED] monkaS") sugar.Infow("banned message detected", - "banReason", banReason) + "target channel", target, + "message", message, + "ban reason", banReason, + ) return } else { // In case the message we are trying to send is longer than the - // maximum allowed message length on twitch. We split the message - // in two parts. + // maximum allowed message length on twitch we split the message in two parts. + // Twitch has a maximum length for messages of 510 characters so to be safe + // we split and check at 500 characters. + // https://discuss.dev.twitch.tv/t/missing-client-side-message-length-check/21316 if len(message) > 500 { firstMessage := message[0:499] secondMessage := message[499:] From 44e7972efca1cc9ab2e64c418418004d8fe6605d Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Sun, 7 Aug 2022 16:08:20 +0200 Subject: [PATCH 27/35] rename common.go to send.go --- pkg/common/{common.go => send.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename pkg/common/{common.go => send.go} (100%) diff --git a/pkg/common/common.go b/pkg/common/send.go similarity index 100% rename from pkg/common/common.go rename to pkg/common/send.go From 802dbd2cafd856a3e68b57e5d61f25000db6dc39 Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Sun, 7 Aug 2022 16:08:25 +0200 Subject: [PATCH 28/35] add jq option --- Makefile | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index c4aed9b..653dedf 100644 --- a/Makefile +++ b/Makefile @@ -4,11 +4,8 @@ build: run: cd cmd/bot && ./Nourybot -dev: - cd cmd/bot && go build -o Nourybot && ./Nourybot -env development - -prod: - cd cmd/bot && go build -o Nourybot && ./Nourybot -env production - xd: cd cmd/bot && go build -o Nourybot && ./Nourybot + +jq: + cd cmd/bot && go build -o Nourybot && ./Nourybot | jq \ No newline at end of file From be9962f9f24a3e940ad24f1dc27b75a431bb8ffc Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Sun, 7 Aug 2022 16:08:30 +0200 Subject: [PATCH 29/35] add tweet command --- cmd/bot/command.go | 7 +++++++ pkg/commands/tweet.go | 20 ++++++++++++++++++++ pkg/decapi/tweet.go | 43 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 pkg/commands/tweet.go create mode 100644 pkg/decapi/tweet.go diff --git a/cmd/bot/command.go b/cmd/bot/command.go index b77b2dd..29fed9c 100644 --- a/cmd/bot/command.go +++ b/cmd/bot/command.go @@ -58,5 +58,12 @@ func handleCommand(message twitch.PrivateMessage, tc *twitch.Client) { commands.Echo(target, message.Message[7:len(message.Message)], tc) return } + case "tweet": + if msgLen < 2 { + common.Send(target, "Not enough arguments provided. Usage: ()tweet ", tc) + return + } else { + commands.Tweet(target, cmdParams[1], tc) + } } } diff --git a/pkg/commands/tweet.go b/pkg/commands/tweet.go new file mode 100644 index 0000000..9880af1 --- /dev/null +++ b/pkg/commands/tweet.go @@ -0,0 +1,20 @@ +package commands + +import ( + "github.com/gempir/go-twitch-irc/v3" + "github.com/lyx0/nourybot/pkg/common" + "github.com/lyx0/nourybot/pkg/decapi" + "go.uber.org/zap" +) + +func Tweet(target, username string, tc *twitch.Client) { + sugar := zap.NewExample().Sugar() + defer sugar.Sync() + + resp, err := decapi.Tweet(username) + if err != nil { + sugar.Error(err) + } + + common.Send(target, resp, tc) +} diff --git a/pkg/decapi/tweet.go b/pkg/decapi/tweet.go new file mode 100644 index 0000000..8958745 --- /dev/null +++ b/pkg/decapi/tweet.go @@ -0,0 +1,43 @@ +package decapi + +import ( + "fmt" + "io/ioutil" + "net/http" + + "go.uber.org/zap" +) + +var ( + basePath = "https://decapi.me/twitter/latest/" + twitterUserNotFoundError = "[Error] - [34] Sorry, that page does not exist." +) + +func Tweet(username string) (string, error) { + sugar := zap.NewExample().Sugar() + defer sugar.Sync() + + // https://decapi.me/twitter/latest/forsen?url&no_rts + // ?url adds the url at the end and &no_rts ignores retweets. + resp, err := http.Get(fmt.Sprint(basePath + username + "?url" + "&no_rts")) + if err != nil { + sugar.Error(err) + return "Something went wrong FeelsBadMan", err + } + + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + sugar.Error(err) + return "Something went wrong FeelsBadMan", err + } + + // If the response was a known error message return a message with the error. + if string(body) == twitterUserNotFoundError { + return "Something went wrong: Twitter username not found", err + } else { // No known error was found, probably a tweet. + resp := fmt.Sprintf("Latest Tweet from @%s: \"%s \"", username, body) + return resp, nil + } +} From 723d4ed9a599ad7e8134cd45f709ca85f3159882 Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Sun, 7 Aug 2022 16:11:33 +0200 Subject: [PATCH 30/35] use package io since io/ioutil has been deprecated --- pkg/decapi/tweet.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/decapi/tweet.go b/pkg/decapi/tweet.go index 8958745..fd67bd5 100644 --- a/pkg/decapi/tweet.go +++ b/pkg/decapi/tweet.go @@ -2,7 +2,7 @@ package decapi import ( "fmt" - "io/ioutil" + "io" "net/http" "go.uber.org/zap" @@ -27,7 +27,7 @@ func Tweet(username string) (string, error) { defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) if err != nil { sugar.Error(err) return "Something went wrong FeelsBadMan", err From ed8d09eae2a8cfa15b645978a3567280672a117a Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Sun, 7 Aug 2022 16:13:00 +0200 Subject: [PATCH 31/35] use package io since io/ioutil has been deprecated --- pkg/common/send.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/common/send.go b/pkg/common/send.go index cb1bd79..3cec32d 100644 --- a/pkg/common/send.go +++ b/pkg/common/send.go @@ -4,7 +4,7 @@ import ( "bytes" "encoding/json" "fmt" - "io/ioutil" + "io" "log" "net/http" @@ -58,7 +58,7 @@ func checkMessage(text string) (bool, string) { defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) if err != nil { log.Panic(err) } From 47e7091a09e5d7fc60205d9006dfb91b56a6a898 Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Sun, 7 Aug 2022 16:35:49 +0200 Subject: [PATCH 32/35] add humanize time package --- pkg/humanize/time.go | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 pkg/humanize/time.go diff --git a/pkg/humanize/time.go b/pkg/humanize/time.go new file mode 100644 index 0000000..044abd3 --- /dev/null +++ b/pkg/humanize/time.go @@ -0,0 +1,11 @@ +package humanize + +import ( + "time" + + "github.com/dustin/go-humanize" +) + +func Time(t time.Time) string { + return humanize.Time(t) +} From d7e38bb17cb85b19f9030691747f5536aa492088 Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Sun, 7 Aug 2022 16:36:06 +0200 Subject: [PATCH 33/35] add ping command and uptime time helper --- cmd/bot/command.go | 2 ++ cmd/bot/main.go | 2 ++ go.mod | 1 + go.sum | 4 ++-- pkg/commands/ping.go | 16 ++++++++++++++++ pkg/common/uptime.go | 15 +++++++++++++++ 6 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 pkg/commands/ping.go create mode 100644 pkg/common/uptime.go diff --git a/cmd/bot/command.go b/cmd/bot/command.go index 29fed9c..8404393 100644 --- a/cmd/bot/command.go +++ b/cmd/bot/command.go @@ -65,5 +65,7 @@ func handleCommand(message twitch.PrivateMessage, tc *twitch.Client) { } else { commands.Tweet(target, cmdParams[1], tc) } + case "ping": + commands.Ping(target, tc) } } diff --git a/cmd/bot/main.go b/cmd/bot/main.go index 9fc4bd1..79e1665 100644 --- a/cmd/bot/main.go +++ b/cmd/bot/main.go @@ -19,6 +19,8 @@ func main() { sugar := zap.NewExample().Sugar() defer sugar.Sync() + common.StartTime() + app := &Application{ TwitchClient: tc, Logger: sugar, diff --git a/go.mod b/go.mod index b67291e..5c4c9b6 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/lyx0/nourybot go 1.19 require ( + github.com/dustin/go-humanize v1.0.0 github.com/gempir/go-twitch-irc/v3 v3.2.0 github.com/joho/godotenv v1.4.0 go.uber.org/zap v1.21.0 diff --git a/go.sum b/go.sum index 8b284aa..1ce7637 100644 --- a/go.sum +++ b/go.sum @@ -3,8 +3,8 @@ github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZx github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/gempir/go-twitch-irc/v3 v3.1.0 h1:bUVZ5mADhH7KidJVcl+z79kgLJ7sjdAk4b/ylAvaLy0= -github.com/gempir/go-twitch-irc/v3 v3.1.0/go.mod h1:/W9KZIiyizVecp4PEb7kc4AlIyXKiCmvlXrzlpPUytU= +github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/gempir/go-twitch-irc/v3 v3.2.0 h1:ENhsa7RgBE1GMmDqe0iMkvcSYfgw6ZsXilt+sAg32/U= github.com/gempir/go-twitch-irc/v3 v3.2.0/go.mod h1:/W9KZIiyizVecp4PEb7kc4AlIyXKiCmvlXrzlpPUytU= github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= diff --git a/pkg/commands/ping.go b/pkg/commands/ping.go new file mode 100644 index 0000000..5092459 --- /dev/null +++ b/pkg/commands/ping.go @@ -0,0 +1,16 @@ +package commands + +import ( + "fmt" + + "github.com/gempir/go-twitch-irc/v3" + "github.com/lyx0/nourybot/pkg/common" + "github.com/lyx0/nourybot/pkg/humanize" +) + +func Ping(target string, tc *twitch.Client) { + botUptime := humanize.Time(common.GetUptime()) + + reply := fmt.Sprintf("Pong! :) Last restart: %v", botUptime) + common.Send(target, reply, tc) +} diff --git a/pkg/common/uptime.go b/pkg/common/uptime.go new file mode 100644 index 0000000..a1d0086 --- /dev/null +++ b/pkg/common/uptime.go @@ -0,0 +1,15 @@ +package common + +import "time" + +var ( + uptime time.Time +) + +func StartTime() { + uptime = time.Now() +} + +func GetUptime() time.Time { + return uptime +} From f33a7382ad867a7b16d8cbc9c8d2010b34d87599 Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Sun, 7 Aug 2022 17:24:42 +0200 Subject: [PATCH 34/35] add currency command --- pkg/decapi/tweet.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/pkg/decapi/tweet.go b/pkg/decapi/tweet.go index fd67bd5..94904cf 100644 --- a/pkg/decapi/tweet.go +++ b/pkg/decapi/tweet.go @@ -8,12 +8,9 @@ import ( "go.uber.org/zap" ) -var ( - basePath = "https://decapi.me/twitter/latest/" - twitterUserNotFoundError = "[Error] - [34] Sorry, that page does not exist." -) - func Tweet(username string) (string, error) { + var basePath = "https://decapi.me/twitter/latest/" + sugar := zap.NewExample().Sugar() defer sugar.Sync() From b31468ae3c630f92c86c6f6a5ecb9ff0733fb79b Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Sun, 7 Aug 2022 17:24:47 +0200 Subject: [PATCH 35/35] add currency command --- cmd/bot/command.go | 11 ++++++++++- pkg/commands/currency.go | 21 +++++++++++++++++++++ pkg/commands/ping.go | 3 ++- pkg/common/counter.go | 16 ++++++++++++++++ pkg/decapi/currency.go | 38 ++++++++++++++++++++++++++++++++++++++ pkg/decapi/types.go | 5 +++++ 6 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 pkg/commands/currency.go create mode 100644 pkg/common/counter.go create mode 100644 pkg/decapi/currency.go create mode 100644 pkg/decapi/types.go diff --git a/cmd/bot/command.go b/cmd/bot/command.go index 8404393..f9e752b 100644 --- a/cmd/bot/command.go +++ b/cmd/bot/command.go @@ -13,6 +13,9 @@ func handleCommand(message twitch.PrivateMessage, tc *twitch.Client) { sugar := zap.NewExample().Sugar() defer sugar.Sync() + // Increments the counter how many commands were used. + common.CommandUsed() + // commandName is the actual name of the command without the prefix. // e.g. `()ping` would be `ping`. commandName := strings.ToLower(strings.SplitN(message.Message, " ", 3)[0][2:]) @@ -50,6 +53,12 @@ func handleCommand(message twitch.PrivateMessage, tc *twitch.Client) { common.Send(target, "xd", tc) return } + case "currency": + if msgLen < 4 { + common.Send(target, "Not enough arguments provided. Usage: ()currency 10 USD to EUR", tc) + return + } + commands.Currency(target, cmdParams[1], cmdParams[2], cmdParams[4], tc) case "echo": if msgLen < 2 { common.Send(target, "Not enough arguments provided.", tc) @@ -60,7 +69,7 @@ func handleCommand(message twitch.PrivateMessage, tc *twitch.Client) { } case "tweet": if msgLen < 2 { - common.Send(target, "Not enough arguments provided. Usage: ()tweet ", tc) + common.Send(target, "Not enough arguments provided. Usage: ()tweet forsen", tc) return } else { commands.Tweet(target, cmdParams[1], tc) diff --git a/pkg/commands/currency.go b/pkg/commands/currency.go new file mode 100644 index 0000000..9142f22 --- /dev/null +++ b/pkg/commands/currency.go @@ -0,0 +1,21 @@ +package commands + +import ( + "github.com/gempir/go-twitch-irc/v3" + "github.com/lyx0/nourybot/pkg/common" + "github.com/lyx0/nourybot/pkg/decapi" + "go.uber.org/zap" +) + +// ()currency 10 USD to EUR +func Currency(target, currAmount, currFrom, currTo string, tc *twitch.Client) { + sugar := zap.NewExample().Sugar() + defer sugar.Sync() + + resp, err := decapi.Currency(currAmount, currFrom, currTo) + if err != nil { + sugar.Error(err) + } + + common.Send(target, resp, tc) +} diff --git a/pkg/commands/ping.go b/pkg/commands/ping.go index 5092459..6df60d8 100644 --- a/pkg/commands/ping.go +++ b/pkg/commands/ping.go @@ -10,7 +10,8 @@ import ( func Ping(target string, tc *twitch.Client) { botUptime := humanize.Time(common.GetUptime()) + commandsUsed := common.GetCommandsUsed() - reply := fmt.Sprintf("Pong! :) Last restart: %v", botUptime) + reply := fmt.Sprintf("Pong! :) Commands used: %v, Last restart: %v", commandsUsed, botUptime) common.Send(target, reply, tc) } diff --git a/pkg/common/counter.go b/pkg/common/counter.go new file mode 100644 index 0000000..28451bc --- /dev/null +++ b/pkg/common/counter.go @@ -0,0 +1,16 @@ +package common + +var ( + tempCommands = 0 +) + +// CommandUsed is called on every command incremenenting tempCommands. +func CommandUsed() { + tempCommands++ +} + +// GetCommandsUsed returns the amount of commands that have been used +// since the last restart. +func GetCommandsUsed() int { + return tempCommands +} diff --git a/pkg/decapi/currency.go b/pkg/decapi/currency.go new file mode 100644 index 0000000..3308bf6 --- /dev/null +++ b/pkg/decapi/currency.go @@ -0,0 +1,38 @@ +package decapi + +import ( + "fmt" + "io" + "net/http" + + "go.uber.org/zap" +) + +// ()currency 10 USD to EUR +func Currency(currAmount, currFrom, currTo string) (string, error) { + sugar := zap.NewExample().Sugar() + defer sugar.Sync() + + basePath := "https://decapi.me/misc/currency/" + from := fmt.Sprintf("?from=%s", currFrom) + to := fmt.Sprintf("&to=%s", currTo) + value := fmt.Sprintf("&value=%s", currAmount) + + // https://decapi.me/misc/currency/?from=usd&to=usd&value=10 + resp, err := http.Get(fmt.Sprint(basePath + from + to + value)) + if err != nil { + sugar.Error(err) + return "Something went wrong FeelsBadMan", err + } + + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + sugar.Error(err) + return "Something went wrong FeelsBadMan", err + } + + reply := string(body) + return reply, nil +} diff --git a/pkg/decapi/types.go b/pkg/decapi/types.go new file mode 100644 index 0000000..74752c7 --- /dev/null +++ b/pkg/decapi/types.go @@ -0,0 +1,5 @@ +package decapi + +var ( + twitterUserNotFoundError = "[Error] - [34] Sorry, that page does not exist." +)