Compare commits

..

2 Commits

Author SHA1 Message Date
bryce
b82d5dd0d4 random commit 2025-07-14 20:46:35 +12:00
bryce
5b286926a3 random commit 2025-07-14 20:46:12 +12:00
6 changed files with 58 additions and 47 deletions

2
go.mod
View File

@@ -7,4 +7,4 @@ require (
github.com/nicklaw5/helix v1.25.0
)
require github.com/golang-jwt/jwt v3.2.1+incompatible // indirect
require github.com/golang-jwt/jwt v3.2.2+incompatible // indirect

3
go.sum
View File

@@ -1,6 +1,7 @@
github.com/gempir/go-twitch-irc/v4 v4.2.0 h1:OCeff+1aH4CZIOxgKOJ8dQjh+1ppC6sLWrXOcpGZyq4=
github.com/gempir/go-twitch-irc/v4 v4.2.0/go.mod h1:QsOMMAk470uxQ7EYD9GJBGAVqM/jDrXBNbuePfTauzg=
github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c=
github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/nicklaw5/helix v1.25.0 h1:Mrz537izZVsGdM3I46uGAAlslj61frgkhS/9xQqyT/M=
github.com/nicklaw5/helix v1.25.0/go.mod h1:yvXZFapT6afIoxnAvlWiJiUMsYnoHl7tNs+t0bloAMw=

View File

@@ -44,7 +44,7 @@ func StartOAuthServer(addr string) error {
return http.ListenAndServe(addr, nil)
}
func HandleIndex(w http.ResponseWriter, r *http.Request) {
func handleIndex(w http.ResponseWriter, r *http.Request) {
authURL := fmt.Sprintf(
"https://id.twitch.tv/oauth2/authorize?response_type=code&client_id=%s&redirect_uri=%s&scope=%s",
url.QueryEscape(clientID),
@@ -63,10 +63,10 @@ func HandleIndex(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(html))
}
func handleCallback(w http.ResponseWriter, r &http.Request) {
func handleCallback(w http.ResponseWriter, r *http.Request) {
code := r.URL.Query().Get("code")
if code == "" {
http.Error(w, "Missing code in query", https.StatusBadRequest)
http.Error(w, "Missing code in query", http.StatusBadRequest)
return
}
@@ -76,15 +76,15 @@ func handleCallback(w http.ResponseWriter, r &http.Request) {
return
}
jsonData, _ := json.MarshalIndent(token, "", " ")
jsonData, _ := json.MarshalIndent(token, "", " ")
w.Header().Set("Content-Type", "application/json")
w.Write([jsonData])
w.Write(jsonData)
}
func exchangeCodeForToken(code string) (*TokenResponse, error) {
data := url.Values{}
data.Set("client_id", clientID)
data.Set("client_Secret", clientSecret)
data.Set("client_secret", clientSecret)
data.Set("code", code)
data.Set("grant_type", "authorization_code")
data.Set("redirect_uri", redirectURI)

View File

@@ -37,7 +37,7 @@ const (
)
type CustomCommand struct {
Triggers string `json:"triggers"`
Triggers []string `json:"triggers"`
Reply string `json:"reply"`
Permission PermissionLevel `json:"permission"`
Match MatchType `json:"match"`
@@ -55,7 +55,7 @@ func LoadDefaultCommands() error {
// Load Custom User Commands
func LoadCustomCommands() error {
path := filepath.Join(commandDir, CustomCommandFile)
path := filepath.Join(commandDir, customCommandFile)
if _, err := os.Stat(path); os.IsNotExist(err) {
customCommands = []CustomCommand{}
return nil
@@ -92,12 +92,12 @@ func GetAllCommands() []CustomCommand {
func AddCustomCommand(trigger, reply string, permission PermissionLevel) bool {
trigger = strings.ToLower(trigger)
for _, c := range defaultCommands {
if c.Trigger == trigger {
if c.Triggers == trigger {
return false
}
}
for _, c := range customCommands {
if c.Trigger == tigger {
if c.Triggers == trigger {
return false
}
}
@@ -114,7 +114,7 @@ func AddCustomCommand(trigger, reply string, permission PermissionLevel) bool {
func DeleteCustomCommand(trigger string) bool {
tigger = strings.ToLower(trigger)
for i, c := range customCommands {
if c.Trigger == trigger {
if c.Triggers == trigger {
customCommands = append(customCommands[:1], customCommands[+1:]...)
SaveCustomCommands()
return true
@@ -127,12 +127,12 @@ func DeleteCustomCommand(trigger string) bool {
func FindCommand(trigger string) *CustomCommand {
trigger = strings.ToLower(trigger)
for _, c := range defaultCommands {
if c.Trigger == trigger {
if c.Triggers == trigger {
return &c
}
}
for _, c:= range customCommands {
if c.Trigger == trigger {
if c.Triggers == trigger {
return &c
}
}

View File

@@ -7,16 +7,28 @@ import (
"time"
twitch "github.com/gempir/go-twitch-irc/v4"
helix "github.com/nicklaw5/helix"
twitchapi "streambot_twitch/internal/twitchapi"
)
// check Twitch API connectivity
func TestTwitchAPI(client *twitchapi.Client, streamerChannel string) error {
_, err := client.GetUserID(streamerChannel)
userID, err := client.GetUserID(streamerChannel)
if err != nil {
return fmt.Errorf("Twitch API test failed: %w", err)
return fmt.Errorf("failed to get Usre ID: %w", err)
}
log.Println("Twitch API connection successful")
resp, err := client.api.GetChannelInformation(&helix.GetChannelInformationParams{
BroadcasterID: userID,
})
if err != nil {
return fmt.Errorf("failed to get channel information: %w", err)
}
if len(resp.Data.Channels) == 0 {
return fmt.Errorf("no channel information found")
}
log.Printf("Twitch API connection Test Successful for channel: %s", streamerChannel)
return nil
}

View File

@@ -11,28 +11,28 @@ type Client struct {
api *helix.Client
}
func NewClient(clientID, ClientSecret string) (*Client, error) {
func NewClient(clientID, clientSecret string) (*Client, error) {
apiClient, err := helix.NewClient(&helix.Options{
ClientID: clientID,
ClientSecret: clientSecret,
})
if err != nil {
return nill, err
return nil, err
}
resp, err := apiClient.RequestAppAccessToken([]string{})
if err != nil || resp.StatusCode != 200 {
return nil, fmt.Errorf("Failed to get app access token: %v", err)
}
apiClient.SetUserAccessToken(resp.Data.AcessToken)
apiClient.SetUserAccessToken(resp.Data.AccessToken)
return &Client{api: apiClient}, nil
}
// Twitch API helpers
func getUserID(client *helix.Client, login String) (string, error) {
resp, err := client.GetUsers(&helix.UsersParams{
func (c *Client) GetUserID(login string) (string, error) {
resp, err := c.api.GetUsers(&helix.UsersParams{
Logins: []string{login},
})
if err != nil {
@@ -44,8 +44,8 @@ func getUserID(client *helix.Client, login String) (string, error) {
return resp.Data.Users[0].ID, nil
}
func getStreamInfo(client *helix.Client, userID string) (*helix.Stream, error) {
resp, err := clinet.GetStreams(&helix.StreamsParams{
func (c *Client) GetStreamInfo(userID string) (*helix.Stream, error) {
rep, err := c.api.GetStreams(&helix.StreamsParams{
UserIDs: []string{userID},
})
if err != nil {
@@ -57,29 +57,27 @@ func getStreamInfo(client *helix.Client, userID string) (*helix.Stream, error) {
return &resp.Data.Streams[0], nil
}
func getStreamUptime(client *helix.Client, channel string) (string, error) {
userID, err := getUserID(client, channel)
func (c *Client) GetStreamUptime(channel string) (string, error) {
userID, err := c.GetUserId(channel)
if err != nil {
return "", err
}
stream, err := getStreamInfo(client, userID)
if err != nil {
return "", err
}
startedAt, err := time.Parse(time.RFC3339, stream.StartedAt)
stream, err := c.GetStreamInfo(userID)
if err != nil {
return "", err
}
startedAt := stream.StartedAt
uptime := time.Since(startedAt).Round(time.Second)
return uptime.String(), nil
}
func getStreamTitle(client *helix.Client, channel string) (string, error) {
userID, err := getUserID(client, channel)
func (c *Client) GetStreamTitle(channel string) (string, error) {
userID, err := C. GetUserID(channel)
if err != nil {
return "", err
}
resp, err := client.GetChannels(&helix.GetChannelsParams{
resp, err := c.api.GetChannelInformation(&helix.GetChannelInformationParams{
BroadcasterID: userID,
})
if err != nil {
@@ -91,24 +89,24 @@ func getStreamTitle(client *helix.Client, channel string) (string, error) {
return resp.Data.Channels[0].Title, nil
}
func setStreamTitle(client *helix.Client, channel, newTitle string) error {
userID, err := getUserID(client, channel)
func (c *Client) SetStreamTitle(channel, newTitle string) error {
userID, err := c.GetUserID(channel)
if err!= nil {
return err
}
_, err = client.UpdateChannelInformation(&helix.UpdateChannelInformationParams {
_, err = c.api.EditChannelInformation(&helix.EditChannelInformationParams {
BroadcasterID: userID,
Title: newTitle,
})
return err
}
func getStreamCategory(client *helix.Client, channel string) (srting, error) {
userID, er := getUserID(client, channel)
func (c *Client) GetStreamCategory(channel string) (string, error) {
userID, err := c.GetUserID(channel)
if err != nil {
return "", err
}
resp, err := client.GetChannels(&helix.GetChannelsParams{
resp, err := c.api.GetChannelInformation(&helix.GetChannelInformationParams{
BroadcasterID: userID,
})
if err != nil {
@@ -120,17 +118,17 @@ func getStreamCategory(client *helix.Client, channel string) (srting, error) {
return resp.Data.Channels[0].GameName, nil
}
func setStreamCategory(client *helix.Client, channel,, newCategory string) error {
userID, err := getUserID(client, channel)
func setStreamCategory(client *helix.Client, channel, newCategory string) error {
userID, err := GetUserID(client, channel)
if err != nil {
return err
}
// get Twitch GameID by Name from API
gameID, err := getUserIDByName(client, newCategory)
gameID, err := getGameIDByName(client, newCategory)
if err != nil {
return err
}
_, err = client.UpdateChannelInformation(&helix.UpdateChannelInformationParams{
_, err = client.EditChannelInformation(&helix.EditChannelInformationParams{
BroadcasterID: userID,
GameID: gameID,
})
@@ -138,7 +136,7 @@ func setStreamCategory(client *helix.Client, channel,, newCategory string) error
}
func getGameIDByName(client *helix.Client, name string) (string, error) {
resp, err := client.GetGames(&helix.GamesParams{
resp, err := GetGames(&helix.GamesParams{
Names: []string{name},
})
if err != nil {