Compare commits
2 Commits
466cfb197c
...
b82d5dd0d4
Author | SHA1 | Date | |
---|---|---|---|
|
b82d5dd0d4 | ||
|
5b286926a3 |
2
go.mod
2
go.mod
@@ -7,4 +7,4 @@ require (
|
|||||||
github.com/nicklaw5/helix v1.25.0
|
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
3
go.sum
@@ -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 h1:OCeff+1aH4CZIOxgKOJ8dQjh+1ppC6sLWrXOcpGZyq4=
|
||||||
github.com/gempir/go-twitch-irc/v4 v4.2.0/go.mod h1:QsOMMAk470uxQ7EYD9GJBGAVqM/jDrXBNbuePfTauzg=
|
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.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 h1:Mrz537izZVsGdM3I46uGAAlslj61frgkhS/9xQqyT/M=
|
||||||
github.com/nicklaw5/helix v1.25.0/go.mod h1:yvXZFapT6afIoxnAvlWiJiUMsYnoHl7tNs+t0bloAMw=
|
github.com/nicklaw5/helix v1.25.0/go.mod h1:yvXZFapT6afIoxnAvlWiJiUMsYnoHl7tNs+t0bloAMw=
|
||||||
|
@@ -44,7 +44,7 @@ func StartOAuthServer(addr string) error {
|
|||||||
return http.ListenAndServe(addr, nil)
|
return http.ListenAndServe(addr, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func HandleIndex(w http.ResponseWriter, r *http.Request) {
|
func handleIndex(w http.ResponseWriter, r *http.Request) {
|
||||||
authURL := fmt.Sprintf(
|
authURL := fmt.Sprintf(
|
||||||
"https://id.twitch.tv/oauth2/authorize?response_type=code&client_id=%s&redirect_uri=%s&scope=%s",
|
"https://id.twitch.tv/oauth2/authorize?response_type=code&client_id=%s&redirect_uri=%s&scope=%s",
|
||||||
url.QueryEscape(clientID),
|
url.QueryEscape(clientID),
|
||||||
@@ -63,10 +63,10 @@ func HandleIndex(w http.ResponseWriter, r *http.Request) {
|
|||||||
w.Write([]byte(html))
|
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")
|
code := r.URL.Query().Get("code")
|
||||||
if code == "" {
|
if code == "" {
|
||||||
http.Error(w, "Missing code in query", https.StatusBadRequest)
|
http.Error(w, "Missing code in query", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,13 +78,13 @@ func handleCallback(w http.ResponseWriter, r &http.Request) {
|
|||||||
|
|
||||||
jsonData, _ := json.MarshalIndent(token, "", " ")
|
jsonData, _ := json.MarshalIndent(token, "", " ")
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
w.Write([jsonData])
|
w.Write(jsonData)
|
||||||
}
|
}
|
||||||
|
|
||||||
func exchangeCodeForToken(code string) (*TokenResponse, error) {
|
func exchangeCodeForToken(code string) (*TokenResponse, error) {
|
||||||
data := url.Values{}
|
data := url.Values{}
|
||||||
data.Set("client_id", clientID)
|
data.Set("client_id", clientID)
|
||||||
data.Set("client_Secret", clientSecret)
|
data.Set("client_secret", clientSecret)
|
||||||
data.Set("code", code)
|
data.Set("code", code)
|
||||||
data.Set("grant_type", "authorization_code")
|
data.Set("grant_type", "authorization_code")
|
||||||
data.Set("redirect_uri", redirectURI)
|
data.Set("redirect_uri", redirectURI)
|
||||||
|
@@ -37,7 +37,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type CustomCommand struct {
|
type CustomCommand struct {
|
||||||
Triggers string `json:"triggers"`
|
Triggers []string `json:"triggers"`
|
||||||
Reply string `json:"reply"`
|
Reply string `json:"reply"`
|
||||||
Permission PermissionLevel `json:"permission"`
|
Permission PermissionLevel `json:"permission"`
|
||||||
Match MatchType `json:"match"`
|
Match MatchType `json:"match"`
|
||||||
@@ -55,7 +55,7 @@ func LoadDefaultCommands() error {
|
|||||||
|
|
||||||
// Load Custom User Commands
|
// Load Custom User Commands
|
||||||
func LoadCustomCommands() error {
|
func LoadCustomCommands() error {
|
||||||
path := filepath.Join(commandDir, CustomCommandFile)
|
path := filepath.Join(commandDir, customCommandFile)
|
||||||
if _, err := os.Stat(path); os.IsNotExist(err) {
|
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||||
customCommands = []CustomCommand{}
|
customCommands = []CustomCommand{}
|
||||||
return nil
|
return nil
|
||||||
@@ -92,12 +92,12 @@ func GetAllCommands() []CustomCommand {
|
|||||||
func AddCustomCommand(trigger, reply string, permission PermissionLevel) bool {
|
func AddCustomCommand(trigger, reply string, permission PermissionLevel) bool {
|
||||||
trigger = strings.ToLower(trigger)
|
trigger = strings.ToLower(trigger)
|
||||||
for _, c := range defaultCommands {
|
for _, c := range defaultCommands {
|
||||||
if c.Trigger == trigger {
|
if c.Triggers == trigger {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, c := range customCommands {
|
for _, c := range customCommands {
|
||||||
if c.Trigger == tigger {
|
if c.Triggers == trigger {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -114,7 +114,7 @@ func AddCustomCommand(trigger, reply string, permission PermissionLevel) bool {
|
|||||||
func DeleteCustomCommand(trigger string) bool {
|
func DeleteCustomCommand(trigger string) bool {
|
||||||
tigger = strings.ToLower(trigger)
|
tigger = strings.ToLower(trigger)
|
||||||
for i, c := range customCommands {
|
for i, c := range customCommands {
|
||||||
if c.Trigger == trigger {
|
if c.Triggers == trigger {
|
||||||
customCommands = append(customCommands[:1], customCommands[+1:]...)
|
customCommands = append(customCommands[:1], customCommands[+1:]...)
|
||||||
SaveCustomCommands()
|
SaveCustomCommands()
|
||||||
return true
|
return true
|
||||||
@@ -127,12 +127,12 @@ func DeleteCustomCommand(trigger string) bool {
|
|||||||
func FindCommand(trigger string) *CustomCommand {
|
func FindCommand(trigger string) *CustomCommand {
|
||||||
trigger = strings.ToLower(trigger)
|
trigger = strings.ToLower(trigger)
|
||||||
for _, c := range defaultCommands {
|
for _, c := range defaultCommands {
|
||||||
if c.Trigger == trigger {
|
if c.Triggers == trigger {
|
||||||
return &c
|
return &c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, c:= range customCommands {
|
for _, c:= range customCommands {
|
||||||
if c.Trigger == trigger {
|
if c.Triggers == trigger {
|
||||||
return &c
|
return &c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -7,16 +7,28 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
twitch "github.com/gempir/go-twitch-irc/v4"
|
twitch "github.com/gempir/go-twitch-irc/v4"
|
||||||
|
helix "github.com/nicklaw5/helix"
|
||||||
twitchapi "streambot_twitch/internal/twitchapi"
|
twitchapi "streambot_twitch/internal/twitchapi"
|
||||||
)
|
)
|
||||||
|
|
||||||
// check Twitch API connectivity
|
// check Twitch API connectivity
|
||||||
func TestTwitchAPI(client *twitchapi.Client, streamerChannel string) error {
|
func TestTwitchAPI(client *twitchapi.Client, streamerChannel string) error {
|
||||||
_, err := client.GetUserID(streamerChannel)
|
userID, err := client.GetUserID(streamerChannel)
|
||||||
|
|
||||||
if err != nil {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -11,28 +11,28 @@ type Client struct {
|
|||||||
api *helix.Client
|
api *helix.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClient(clientID, ClientSecret string) (*Client, error) {
|
func NewClient(clientID, clientSecret string) (*Client, error) {
|
||||||
apiClient, err := helix.NewClient(&helix.Options{
|
apiClient, err := helix.NewClient(&helix.Options{
|
||||||
ClientID: clientID,
|
ClientID: clientID,
|
||||||
ClientSecret: clientSecret,
|
ClientSecret: clientSecret,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nill, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := apiClient.RequestAppAccessToken([]string{})
|
resp, err := apiClient.RequestAppAccessToken([]string{})
|
||||||
if err != nil || resp.StatusCode != 200 {
|
if err != nil || resp.StatusCode != 200 {
|
||||||
return nil, fmt.Errorf("Failed to get app access token: %v", err)
|
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
|
return &Client{api: apiClient}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Twitch API helpers
|
// Twitch API helpers
|
||||||
|
|
||||||
func getUserID(client *helix.Client, login String) (string, error) {
|
func (c *Client) GetUserID(login string) (string, error) {
|
||||||
resp, err := client.GetUsers(&helix.UsersParams{
|
resp, err := c.api.GetUsers(&helix.UsersParams{
|
||||||
Logins: []string{login},
|
Logins: []string{login},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -44,8 +44,8 @@ func getUserID(client *helix.Client, login String) (string, error) {
|
|||||||
return resp.Data.Users[0].ID, nil
|
return resp.Data.Users[0].ID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getStreamInfo(client *helix.Client, userID string) (*helix.Stream, error) {
|
func (c *Client) GetStreamInfo(userID string) (*helix.Stream, error) {
|
||||||
resp, err := clinet.GetStreams(&helix.StreamsParams{
|
rep, err := c.api.GetStreams(&helix.StreamsParams{
|
||||||
UserIDs: []string{userID},
|
UserIDs: []string{userID},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -57,29 +57,27 @@ func getStreamInfo(client *helix.Client, userID string) (*helix.Stream, error) {
|
|||||||
return &resp.Data.Streams[0], nil
|
return &resp.Data.Streams[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getStreamUptime(client *helix.Client, channel string) (string, error) {
|
func (c *Client) GetStreamUptime(channel string) (string, error) {
|
||||||
userID, err := getUserID(client, channel)
|
userID, err := c.GetUserId(channel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
stream, err := getStreamInfo(client, userID)
|
stream, err := c.GetStreamInfo(userID)
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
startedAt, err := time.Parse(time.RFC3339, stream.StartedAt)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
startedAt := stream.StartedAt
|
||||||
|
|
||||||
uptime := time.Since(startedAt).Round(time.Second)
|
uptime := time.Since(startedAt).Round(time.Second)
|
||||||
return uptime.String(), nil
|
return uptime.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getStreamTitle(client *helix.Client, channel string) (string, error) {
|
func (c *Client) GetStreamTitle(channel string) (string, error) {
|
||||||
userID, err := getUserID(client, channel)
|
userID, err := C. GetUserID(channel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
resp, err := client.GetChannels(&helix.GetChannelsParams{
|
resp, err := c.api.GetChannelInformation(&helix.GetChannelInformationParams{
|
||||||
BroadcasterID: userID,
|
BroadcasterID: userID,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -91,24 +89,24 @@ func getStreamTitle(client *helix.Client, channel string) (string, error) {
|
|||||||
return resp.Data.Channels[0].Title, nil
|
return resp.Data.Channels[0].Title, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setStreamTitle(client *helix.Client, channel, newTitle string) error {
|
func (c *Client) SetStreamTitle(channel, newTitle string) error {
|
||||||
userID, err := getUserID(client, channel)
|
userID, err := c.GetUserID(channel)
|
||||||
if err!= nil {
|
if err!= nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = client.UpdateChannelInformation(&helix.UpdateChannelInformationParams {
|
_, err = c.api.EditChannelInformation(&helix.EditChannelInformationParams {
|
||||||
BroadcasterID: userID,
|
BroadcasterID: userID,
|
||||||
Title: newTitle,
|
Title: newTitle,
|
||||||
})
|
})
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func getStreamCategory(client *helix.Client, channel string) (srting, error) {
|
func (c *Client) GetStreamCategory(channel string) (string, error) {
|
||||||
userID, er := getUserID(client, channel)
|
userID, err := c.GetUserID(channel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
resp, err := client.GetChannels(&helix.GetChannelsParams{
|
resp, err := c.api.GetChannelInformation(&helix.GetChannelInformationParams{
|
||||||
BroadcasterID: userID,
|
BroadcasterID: userID,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -120,17 +118,17 @@ func getStreamCategory(client *helix.Client, channel string) (srting, error) {
|
|||||||
return resp.Data.Channels[0].GameName, nil
|
return resp.Data.Channels[0].GameName, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setStreamCategory(client *helix.Client, channel,, newCategory string) error {
|
func setStreamCategory(client *helix.Client, channel, newCategory string) error {
|
||||||
userID, err := getUserID(client, channel)
|
userID, err := GetUserID(client, channel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// get Twitch GameID by Name from API
|
// get Twitch GameID by Name from API
|
||||||
gameID, err := getUserIDByName(client, newCategory)
|
gameID, err := getGameIDByName(client, newCategory)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = client.UpdateChannelInformation(&helix.UpdateChannelInformationParams{
|
_, err = client.EditChannelInformation(&helix.EditChannelInformationParams{
|
||||||
BroadcasterID: userID,
|
BroadcasterID: userID,
|
||||||
GameID: gameID,
|
GameID: gameID,
|
||||||
})
|
})
|
||||||
@@ -138,7 +136,7 @@ func setStreamCategory(client *helix.Client, channel,, newCategory string) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getGameIDByName(client *helix.Client, name string) (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},
|
Names: []string{name},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Reference in New Issue
Block a user