From 025f236144b6c7e0f520c80d1c2abdb90de15f5b Mon Sep 17 00:00:00 2001 From: lyx0 <66651385+lyx0@users.noreply.github.com> Date: Tue, 10 Oct 2023 19:07:49 +0200 Subject: [PATCH] implement adding/deleting channel and joining/parting them --- cmd/nourybot/channel.go | 73 ++++++++++++++++++++++++++++++++++++++++ cmd/nourybot/commands.go | 10 ++++++ internal/data/channel.go | 4 +-- internal/data/models.go | 2 +- internal/ivr/user.go | 27 +++++++++++++++ 5 files changed, 113 insertions(+), 3 deletions(-) create mode 100644 cmd/nourybot/channel.go create mode 100644 internal/ivr/user.go diff --git a/cmd/nourybot/channel.go b/cmd/nourybot/channel.go new file mode 100644 index 0000000..96e517e --- /dev/null +++ b/cmd/nourybot/channel.go @@ -0,0 +1,73 @@ +package main + +import ( + "fmt" + + "github.com/gempir/go-twitch-irc/v4" + "github.com/lyx0/nourybot/internal/ivr" +) + +// AddChannel takes in a channel name, then calls GetIdByLogin for the +// channels ID and inserts both the name and id value into the database. +// If there is no error thrown the TwitchClient joins the channel afterwards. +func (app *application) AddChannel(login string, message twitch.PrivateMessage) { + userID := ivr.IDByUsername(login) + + err := app.Models.Channels.Insert(login, userID) + if err != nil { + reply := fmt.Sprintf("Something went wrong FeelsBadMan %s", err) + app.Send(message.Channel, reply, message) + return + } else { + app.TwitchClient.Join(login) + reply := fmt.Sprintf("Added channel %s", login) + app.Send(message.Channel, reply, message) + return + } +} + +// GetAllChannels() queries the database and lists all channels. +// Only used for debug/information purposes. +func (app *application) GetAllChannels() { + channel, err := app.Models.Channels.GetAll() + if err != nil { + app.Log.Error(err) + return + } + app.Log.Infow("All channels:", + "channel", channel) +} + +// DeleteChannel queries the database for a channel name and if it exists +// deletes the channel and makes the bot depart said channel. +func (app *application) DeleteChannel(login string, message twitch.PrivateMessage) { + err := app.Models.Channels.Delete(login) + if err != nil { + app.Send(message.Channel, "Something went wrong FeelsBadMan", message) + app.Log.Error(err) + return + } + + app.TwitchClient.Depart(login) + + reply := fmt.Sprintf("Deleted channel %s", login) + app.Send(message.Channel, reply, message) +} + +// InitialJoin is called on startup and queries the database for a list of +// channels which the TwitchClient then joins. +func (app *application) InitialJoin() { + // GetJoinable returns a slice of channel names. + channel, err := app.Models.Channels.GetJoinable() + if err != nil { + app.Log.Error(err) + return + } + + // Iterate over the slice of channels and join each. + for _, v := range channel { + app.TwitchClient.Join(v) + app.Log.Infow("Joining channel", + "channel", v) + } +} diff --git a/cmd/nourybot/commands.go b/cmd/nourybot/commands.go index c957551..026eb12 100644 --- a/cmd/nourybot/commands.go +++ b/cmd/nourybot/commands.go @@ -6,6 +6,7 @@ import ( "github.com/gempir/go-twitch-irc/v4" "github.com/lyx0/nourybot/internal/commands" "github.com/lyx0/nourybot/internal/common" + "github.com/lyx0/nourybot/internal/ivr" ) // handleCommand takes in a twitch.PrivateMessage and then routes the message to @@ -237,6 +238,15 @@ func (app *application) handleCommand(message twitch.PrivateMessage) { } } + case "join": + go app.AddChannel(cmdParams[1], message) + + case "part": + go app.DeleteChannel(cmdParams[1], message) + + case "uid": + reply = ivr.IDByUsername(cmdParams[1]) + default: r, err := app.GetCommand(target, commandName, userLevel) if err != nil { diff --git a/internal/data/channel.go b/internal/data/channel.go index 0282552..de5314e 100644 --- a/internal/data/channel.go +++ b/internal/data/channel.go @@ -49,7 +49,7 @@ func (c ChannelModel) Get(login string) (*Channel, error) { } // Insert takes in a channel struct and inserts it into the database. -func (c ChannelModel) Insert(channel *Channel) error { +func (c ChannelModel) Insert(login, id string) error { query := ` INSERT INTO channels(login, twitchid) VALUES ($1, $2) @@ -58,7 +58,7 @@ func (c ChannelModel) Insert(channel *Channel) error { RETURNING id, added_at; ` - args := []interface{}{channel.Login, channel.TwitchID} + args := []interface{}{login, id} // Execute the query returning the number of affected rows. result, err := c.DB.Exec(query, args...) diff --git a/internal/data/models.go b/internal/data/models.go index 8293a4a..73e882c 100644 --- a/internal/data/models.go +++ b/internal/data/models.go @@ -18,7 +18,7 @@ var ( // as app.models.Channels.Get(login) type Models struct { Channels interface { - Insert(channel *Channel) error + Insert(login, id string) error Get(login string) (*Channel, error) GetAll() ([]*Channel, error) GetJoinable() ([]string, error) diff --git a/internal/ivr/user.go b/internal/ivr/user.go new file mode 100644 index 0000000..ea832ae --- /dev/null +++ b/internal/ivr/user.go @@ -0,0 +1,27 @@ +package ivr + +import ( + "encoding/json" + "fmt" + "net/http" +) + +type ivrIDByUsernameResponse struct { + ID string `json:"id"` +} + +func IDByUsername(username string) string { + baseUrl := "https://api.ivr.fi/v2/twitch/user?login=" + + resp, err := http.Get(fmt.Sprintf("%s%s", baseUrl, username)) + if err != nil { + return "xd" + } + + defer resp.Body.Close() + + responseList := make([]ivrIDByUsernameResponse, 0) + _ = json.NewDecoder(resp.Body).Decode(&responseList) + + return responseList[0].ID +}