# HG changeset patch # User Dennis C. M. # Date 1741887702 0 # Node ID e9df3bb010f41c5e30e227fe9d168495ffab5d8d # Parent a8aab75f68c92f2ebc22d65021b63d0eea060d6d fix issues diff -r a8aab75f68c9 -r e9df3bb010f4 auth/auth.go --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/auth/auth.go Thu Mar 13 17:41:42 2025 +0000 @@ -0,0 +1,195 @@ +package auth + +import ( + "encoding/json" + "log" + "net/http" + "net/url" +) + +// TODO: Change unmarshall to JSON DECODE + +func GetAuthUrl() string { + config := ReadConfig() + + baseUrl := &url.URL{ + Scheme: "https", + Host: "id.twitch.tv", + Path: "/oauth2/authorize", + } + + params := url.Values{} + params.Add("client_id", config.ClientId) + params.Add("force_verify", "true") + params.Add("redirect_uri", "http://localhost:8080/twitch-auth-code-callback") + params.Add("response_type", "code") + params.Add("scope", "channel:bot user:read:chat") + params.Add("state", "c3ab8aa609ea11e793ae92361f002671") + + baseUrl.RawQuery = params.Encode() + + return baseUrl.String() +} + +func GetAuthToken(authCode string) AuthRes { + config := ReadConfig() + + baseUrl := &url.URL{ + Scheme: "https", + Host: "id.twitch.tv", + Path: "/oauth2/token", + } + + formData := url.Values{} + formData.Add("client_id", config.ClientId) + formData.Add("client_secret", config.ClientSecret) + formData.Add("code", authCode) + formData.Add("grant_type", "authorization_code") + formData.Add("redirect_uri", "http://localhost:8080/twitch-auth-code-callback") + + res, err := http.PostForm(baseUrl.String(), formData) + + if err != nil { + log.Fatal(err) + } + + defer res.Body.Close() + + if res.StatusCode != 200 { + log.Fatal("GetAuthToken") + } + + var authRes AuthRes + + err = json.NewDecoder(res.Body).Decode(&authRes) + + if err != nil { + log.Fatal(err) + } + + return authRes +} + +func IsAuthTokenValid(authToken string) bool { + baseUrl := &url.URL{ + Scheme: "https", + Host: "id.twitch.tv", + Path: "oauth2/validate", + } + + req, err := http.NewRequest("GET", baseUrl.String(), nil) + + if err != nil { + log.Fatal(err) + } + + req.Header.Set("Authorization", "OAuth "+authToken) + + client := &http.Client{} + resp, err := client.Do(req) + + if err != nil { + log.Fatal(err) + } + + defer resp.Body.Close() + + return resp.StatusCode == 200 +} + +func RevokeAuthToken(authToken string) { + config := ReadConfig() + + baseUrl := &url.URL{ + Scheme: "https", + Host: "id.twitch.tv", + Path: "oauth2/revoke", + } + + data := url.Values{} + data.Add("client_id", config.ClientId) + data.Add("token", authToken) + + res, err := http.PostForm(baseUrl.String(), data) + + if err != nil { + log.Fatal(err) + } + + defer res.Body.Close() +} + +func RefreshAuthToken(authToken, refreshToken string) AuthRes { + config := ReadConfig() + + baseUrl := &url.URL{ + Scheme: "https", + Host: "id.twitch.tv", + Path: "oauth2/token", + } + + data := url.Values{} + data.Add("grant_type", "refresh_token") + data.Add("refresh_token", refreshToken) + data.Add("client_id", config.ClientId) + data.Add("client_secret", config.ClientSecret) + + res, err := http.PostForm(baseUrl.String(), data) + + if err != nil { + log.Fatal(err) + } + + defer res.Body.Close() + + var authRes AuthRes + + err = json.NewDecoder(res.Body).Decode(&authRes) + + if err != nil { + log.Fatal(err) + } + + return authRes +} + +func GetUser(userName, authToken string) UserRes { + config := ReadConfig() + + baseUrl := &url.URL{ + Scheme: "https", + Host: "api.twitch.tv", + Path: "helix/users", + } + + params := url.Values{} + params.Add("login", userName) + + req, err := http.NewRequest("GET", baseUrl.String(), nil) + + if err != nil { + log.Fatal(err) + } + + req.Header.Set("Client-ID", config.ClientId) + req.Header.Set("Authorization", "Bearer "+authToken) + + client := &http.Client{} + res, err := client.Do(req) + + if err != nil { + log.Fatal(err) + } + + defer res.Body.Close() + + var userRes UserRes + + err = json.NewDecoder(res.Body).Decode(&userRes) + + if err != nil { + log.Fatal(err) + } + + return userRes +} diff -r a8aab75f68c9 -r e9df3bb010f4 auth/config.go --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/auth/config.go Thu Mar 13 17:41:42 2025 +0000 @@ -0,0 +1,33 @@ +package auth + +import ( + "encoding/json" + "io" + "log" + "os" +) + +func ReadConfig() Config { + file, err := os.Open(".config.json") + + if err != nil { + log.Fatalf("Error opening file: %v", err) + } + + defer file.Close() + + bytes, err := io.ReadAll(file) + + if err != nil { + log.Fatalf("Error reading file: %v", err) + } + + var config Config + + err = json.Unmarshal(bytes, &config) + if err != nil { + log.Fatalf("Error decoding JSON: %v", err) + } + + return config +} diff -r a8aab75f68c9 -r e9df3bb010f4 auth/types.go --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/auth/types.go Thu Mar 13 17:41:42 2025 +0000 @@ -0,0 +1,19 @@ +package auth + +type Config struct { + ClientId string `json:"client_id"` + ClientSecret string `json:"client_secret"` + BroadcasterUserId string `json:"broadcaster_user_id"` +} + +type UserRes struct { + Data []struct { + Id string `json:"id"` + } `json:"data"` +} + +type AuthRes struct { + AccessToken string `json:"access_token"` + RefreshToken string `json:"refresh_token"` + Scope []string `json:"scope"` +} diff -r a8aab75f68c9 -r e9df3bb010f4 bot/bot.go --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bot/bot.go Thu Mar 13 17:41:42 2025 +0000 @@ -0,0 +1,88 @@ +package bot + +import ( + "fmt" + "log" + "os" + "strconv" + "time" +) + +var quitTimer chan bool + +func HandleCmd(cmd []string) { + cmdReceived := cmd[0] + log.Printf("bot: %s command received", cmdReceived) + + switch cmdReceived { + case "timer": + seconds, err := strconv.Atoi(cmd[1]) + + if err != nil { + log.Fatal("err: invalid command arguments") + } + + if quitTimer != nil { + quitTimer <- true + + } + + quitTimer = make(chan bool) + + go func() { + filename := "F:/Media/Twitch/Bot/timer.txt" + + file, err := os.Create(filename) + + if err != nil { + log.Fatal(err) + } + + defer file.Close() + + countdown := time.Duration(seconds) * time.Second + ticker := time.NewTicker(time.Second) + defer ticker.Stop() + + log.Printf("bot: timer started with duration %d seconds", seconds) + + for countdown > 0 { + select { + case <-ticker.C: + totalSeconds := int(countdown.Seconds()) + minutes := totalSeconds / 60 + seconds := totalSeconds % 60 + countdownMsg := fmt.Sprintf("%02d:%02d", minutes, seconds) + + file.Seek(0, 0) + _, err = file.WriteString("") + + if err != nil { + log.Fatal(err) + } + + _, err = file.WriteString(countdownMsg) + + if err != nil { + log.Fatal(err) + } + + log.Printf("bot: timer updated to %s", countdownMsg) + + countdown -= time.Second + case <-quitTimer: + file.Seek(0, 0) + _, err = file.WriteString("") + + if err != nil { + log.Fatal(err) + } + + log.Println("bot: timer stopped") + + return + } + } + }() + } +} diff -r a8aab75f68c9 -r e9df3bb010f4 cmd/auth.go --- a/cmd/auth.go Wed Mar 12 14:45:00 2025 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,207 +0,0 @@ -package cmd - -import ( - "encoding/json" - "log" - "net/http" - "net/url" -) - -// TODO: Change unmarshall to JSON DECODE - -func GetAuthUrl() string { - config := readConfig() - - baseUrl := &url.URL{ - Scheme: "https", - Host: "id.twitch.tv", - Path: "/oauth2/authorize", - } - - params := url.Values{} - params.Add("client_id", config.ClientId) - params.Add("force_verify", "true") - params.Add("redirect_uri", "http://localhost:8080/twitch-auth-code-callback") - params.Add("response_type", "code") - params.Add("scope", "channel:bot user:read:chat") - params.Add("state", "c3ab8aa609ea11e793ae92361f002671") - - baseUrl.RawQuery = params.Encode() - - return baseUrl.String() -} - -type AuthRes struct { - AccessToken string `json:"access_token"` - RefreshToken string `json:"refresh_token"` - Scope []string `json:"scope"` -} - -func GetAuthToken(authCode string) AuthRes { - config := readConfig() - - baseUrl := &url.URL{ - Scheme: "https", - Host: "id.twitch.tv", - Path: "/oauth2/token", - } - - formData := url.Values{} - formData.Add("client_id", config.ClientId) - formData.Add("client_secret", config.ClientSecret) - formData.Add("code", authCode) - formData.Add("grant_type", "authorization_code") - formData.Add("redirect_uri", "http://localhost:8080/twitch-auth-code-callback") - - res, err := http.PostForm(baseUrl.String(), formData) - - if err != nil { - log.Fatal(err) - } - - defer res.Body.Close() - - if res.StatusCode != 200 { - log.Fatal("GetAuthToken") - } - - var authRes AuthRes - - err = json.NewDecoder(res.Body).Decode(&authRes) - - if err != nil { - log.Fatal(err) - } - - return authRes -} - -func IsAuthTokenValid(authToken string) bool { - baseUrl := &url.URL{ - Scheme: "https", - Host: "id.twitch.tv", - Path: "oauth2/validate", - } - - req, err := http.NewRequest("GET", baseUrl.String(), nil) - - if err != nil { - log.Fatal(err) - } - - req.Header.Set("Authorization", "OAuth "+authToken) - - client := &http.Client{} - resp, err := client.Do(req) - - if err != nil { - log.Fatal(err) - } - - defer resp.Body.Close() - - return resp.StatusCode == 200 -} - -func RevokeAuthToken(authToken string) { - config := readConfig() - - baseUrl := &url.URL{ - Scheme: "https", - Host: "id.twitch.tv", - Path: "oauth2/revoke", - } - - data := url.Values{} - data.Add("client_id", config.ClientId) - data.Add("token", authToken) - - res, err := http.PostForm(baseUrl.String(), data) - - if err != nil { - log.Fatal(err) - } - - defer res.Body.Close() -} - -func RefreshAuthToken(authToken, refreshToken string) AuthRes { - config := readConfig() - - baseUrl := &url.URL{ - Scheme: "https", - Host: "id.twitch.tv", - Path: "oauth2/token", - } - - data := url.Values{} - data.Add("grant_type", "refresh_token") - data.Add("refresh_token", refreshToken) - data.Add("client_id", config.ClientId) - data.Add("client_secret", config.ClientSecret) - - res, err := http.PostForm(baseUrl.String(), data) - - if err != nil { - log.Fatal(err) - } - - defer res.Body.Close() - - var authRes AuthRes - - err = json.NewDecoder(res.Body).Decode(&authRes) - - if err != nil { - log.Fatal(err) - } - - return authRes -} - -type UserRes struct { - Data []struct { - Id string `json:"id"` - } `json:"data"` -} - -func GetUser(userName, authToken string) UserRes { - config := readConfig() - - baseUrl := &url.URL{ - Scheme: "https", - Host: "api.twitch.tv", - Path: "helix/users", - } - - params := url.Values{} - params.Add("login", userName) - - req, err := http.NewRequest("GET", baseUrl.String(), nil) - - if err != nil { - log.Fatal(err) - } - - req.Header.Set("Client-ID", config.ClientId) - req.Header.Set("Authorization", "Bearer "+authToken) - - client := &http.Client{} - res, err := client.Do(req) - - if err != nil { - log.Fatal(err) - } - - defer res.Body.Close() - - var userRes UserRes - - err = json.NewDecoder(res.Body).Decode(&userRes) - - if err != nil { - log.Fatal(err) - } - - return userRes -} diff -r a8aab75f68c9 -r e9df3bb010f4 cmd/config.go --- a/cmd/config.go Wed Mar 12 14:45:00 2025 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -package cmd - -import ( - "encoding/json" - "io" - "log" - "os" -) - -type Config struct { - ClientId string `json:"client_id"` - ClientSecret string `json:"client_secret"` - BroadcasterUserId string `json:"broadcaster_user_id"` -} - -func readConfig() Config { - file, err := os.Open(".config.json") - - if err != nil { - log.Fatalf("Error opening file: %v", err) - } - - defer file.Close() - - bytes, err := io.ReadAll(file) - - if err != nil { - log.Fatalf("Error reading file: %v", err) - } - - var config Config - - err = json.Unmarshal(bytes, &config) - if err != nil { - log.Fatalf("Error decoding JSON: %v", err) - } - - return config -} diff -r a8aab75f68c9 -r e9df3bb010f4 cmd/events.go --- a/cmd/events.go Wed Mar 12 14:45:00 2025 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -package cmd - -import ( - "bytes" - "encoding/json" - "io" - "log" - "net/http" - "net/url" -) - -type ChannelChatMsgSubPayload struct { - Payload struct { - Event struct { - Msg struct { - Text string `json:"text"` - } `json:"message"` - } `json:"event"` - } `json:"payload"` -} - -func ChannelChatMsgSub(authToken, session_id string) { - config := readConfig() - - data := map[string]interface{}{ - "type": "channel.chat.message", - "version": "1", - "condition": map[string]string{ - "broadcaster_user_id": config.BroadcasterUserId, - "user_id": config.BroadcasterUserId, - }, - "transport": map[string]string{ - "method": "websocket", - "session_id": session_id, - }, - } - - jsonData, err := json.Marshal(data) - - if err != nil { - log.Fatal(err) - } - - eventSub(authToken, jsonData) -} - -func eventSub(authToken string, subData []byte) { - baseUrl := &url.URL{ - Scheme: "https", - Host: "api.twitch.tv", - Path: "helix/eventsub/subscriptions", - } - - req, err := http.NewRequest("POST", baseUrl.String(), bytes.NewBuffer(subData)) - - if err != nil { - log.Fatal(err) - } - - config := readConfig() - - req.Header.Set("Authorization", "Bearer "+authToken) - req.Header.Set("Client-Id", config.ClientId) - req.Header.Set("Content-Type", "application/json") - - client := &http.Client{} - res, err := client.Do(req) - - if err != nil { - log.Fatal(err) - } - - defer res.Body.Close() - - body, err := io.ReadAll(res.Body) - - if err != nil { - log.Fatal(err) - } - - log.Println(string(body)) -} diff -r a8aab75f68c9 -r e9df3bb010f4 cmd/socket.go --- a/cmd/socket.go Wed Mar 12 14:45:00 2025 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,118 +0,0 @@ -package cmd - -import ( - "encoding/json" - "log" - "net/url" - "os" - "os/signal" - "time" - - "github.com/gorilla/websocket" -) - -type MetadataRes struct { - Metadata struct { - MsgType string `json:"message_type"` - SubType string `json:"subscription_type"` - } `json:"metadata"` -} - -type WelcomeMsgPayload struct { - Payload struct { - Session struct { - Id string `json:"id"` - } `json:"session"` - } `json:"payload"` -} - -func ConnSocket(authToken string) { - interrupt := make(chan os.Signal, 1) - signal.Notify(interrupt, os.Interrupt) - - baseUrl := url.URL{Scheme: "wss", Host: "eventsub.wss.twitch.tv", Path: "/ws"} - - conn, _, err := websocket.DefaultDialer.Dial(baseUrl.String(), nil) - - if err != nil { - log.Fatal(err) - } - - defer conn.Close() - - done := make(chan struct{}) - - ticker := time.NewTicker(time.Second * 15) - defer ticker.Stop() - - go func() { - defer close(done) - - for { - _, msg, err := conn.ReadMessage() - - if err != nil { - log.Fatal(err) - } - - var metadataRes MetadataRes - - if err := json.Unmarshal(msg, &metadataRes); err != nil { - log.Fatal(err) - } - - switch msgType := metadataRes.Metadata.MsgType; msgType { - case "session_welcome": - var welcomeMsgRes WelcomeMsgPayload - - if err := json.Unmarshal(msg, &welcomeMsgRes); err != nil { - log.Fatal(err) - } - - ChannelChatMsgSub(authToken, welcomeMsgRes.Payload.Session.Id) - case "session_keepalive": - ticker.Reset(time.Second * 15) - case "notification": - switch subType := metadataRes.Metadata.SubType; subType { - case "channel.chat.message": - var channelChatMsgSubPayload ChannelChatMsgSubPayload - - if err := json.Unmarshal(msg, &channelChatMsgSubPayload); err != nil { - log.Fatal(err) - } - - log.Println(string(msg)) - log.Println(channelChatMsgSubPayload.Payload.Event.Msg.Text) - - } - default: - log.Fatalf("%s: message type not implemented", msgType) - } - - } - }() - - for { - select { - case <-done: - return - case <-interrupt: - err := conn.WriteMessage( - websocket.CloseMessage, - websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")) - - if err != nil { - log.Fatal(err) - } - - select { - case <-done: - case <-time.After(time.Second): - } - return - case <-ticker.C: - // TODO: Replace this with logic to reconnect - log.Fatal("connection closed: timeout") - } - } -} diff -r a8aab75f68c9 -r e9df3bb010f4 event/events.go --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/event/events.go Thu Mar 13 17:41:42 2025 +0000 @@ -0,0 +1,74 @@ +package event + +import ( + "bytes" + "encoding/json" + "log" + "net/http" + "net/url" + + "github.com/denniscmcom/pacobot/auth" +) + +func ChannelChatMsgSub(authToken, session_id string) { + config := auth.ReadConfig() + + data := map[string]any{ + "type": "channel.chat.message", + "version": "1", + "condition": map[string]string{ + "broadcaster_user_id": config.BroadcasterUserId, + "user_id": config.BroadcasterUserId, + }, + "transport": map[string]string{ + "method": "websocket", + "session_id": session_id, + }, + } + + jsonData, err := json.Marshal(data) + + if err != nil { + log.Fatal(err) + } + + log.Printf("event: subscribing to %s", data["type"]) + eventSub(authToken, jsonData) +} + +func eventSub(authToken string, subData []byte) { + baseUrl := &url.URL{ + Scheme: "https", + Host: "api.twitch.tv", + Path: "helix/eventsub/subscriptions", + } + + req, err := http.NewRequest("POST", baseUrl.String(), bytes.NewBuffer(subData)) + + if err != nil { + log.Fatal(err) + } + + config := auth.ReadConfig() + + req.Header.Set("Authorization", "Bearer "+authToken) + req.Header.Set("Client-Id", config.ClientId) + req.Header.Set("Content-Type", "application/json") + + client := &http.Client{} + res, err := client.Do(req) + + if err != nil { + log.Fatal(err) + } + + log.Printf("status code: %d", res.StatusCode) + + if res.StatusCode != 202 { + log.Fatal("event: failed to subscribe to event") + } + + log.Println("event: subscribed") + + defer res.Body.Close() +} diff -r a8aab75f68c9 -r e9df3bb010f4 event/types.go --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/event/types.go Thu Mar 13 17:41:42 2025 +0000 @@ -0,0 +1,15 @@ +package event + +type ChannelChatMsgSubPayload struct { + Payload struct { + Event struct { + ChatterUserId string `json:"chatter_user_id"` + ChatterUserLogin string `json:"chatter_user_login"` + ChatterUserName string `json:"chatter_user_name"` + Msg struct { + Type string `json:"type"` + Text string `json:"text"` + } `json:"message"` + } `json:"event"` + } `json:"payload"` +} diff -r a8aab75f68c9 -r e9df3bb010f4 socket/conn.go --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/socket/conn.go Thu Mar 13 17:41:42 2025 +0000 @@ -0,0 +1,173 @@ +package socket + +import ( + "encoding/json" + "fmt" + "log" + "net/url" + "os" + "os/signal" + "strings" + "time" + + "github.com/denniscmcom/pacobot/bot" + "github.com/denniscmcom/pacobot/event" + "github.com/gorilla/websocket" +) + +func Connect(authToken string) { + interrupt := make(chan os.Signal, 1) + signal.Notify(interrupt, os.Interrupt) + + baseUrl := url.URL{Scheme: "wss", Host: "eventsub.wss.twitch.tv", Path: "/ws"} + + log.Println("socket: connecting...") + conn, _, err := websocket.DefaultDialer.Dial(baseUrl.String(), nil) + + if err != nil { + log.Fatal(err) + } + + defer conn.Close() + + log.Println("socket: connected") + + var timeout time.Ticker + done := make(chan bool) + + go readMsg(done, conn, &timeout, authToken) + + for { + select { + case <-interrupt: + closeConn(conn) + + select { + case <-done: + case <-time.After(time.Second): + } + return + case <-done: + log.Println("socket: connection closed by server") + Connect(authToken) + case <-timeout.C: + log.Println("socket: connection lost") + timeout.Stop() + Connect(authToken) + } + } +} + +func readMsg(done chan bool, conn *websocket.Conn, timeout *time.Ticker, authToken string) { + var timeout_secs time.Duration + + for { + log.Println("socket: waiting for msg...") + _, msg, err := conn.ReadMessage() + + if err != nil { + break + } + + var resMetadata Res_Metadata + + if err := json.Unmarshal(msg, &resMetadata); err != nil { + log.Fatal(err) + } + + msgType := resMetadata.Metadata.MsgType + log.Printf("socket: %s msg received", msgType) + + switch msgType { + case "session_welcome": + var resWelcome Res_Welcome + + if err := json.Unmarshal(msg, &resWelcome); err != nil { + log.Fatal(err) + } + + timeout_secs = time.Duration(resWelcome.Payload.Session.KeepaliveTimeout+3) * time.Second + timeout = time.NewTicker(timeout_secs) + defer timeout.Stop() + + event.ChannelChatMsgSub(authToken, resWelcome.Payload.Session.Id) + + case "session_keepalive": + timeout.Reset(timeout_secs) + log.Println("socket: timeout resetted") + + case "notification": + var resMetadataNotif Res_Metadata_Notif + + if err := json.Unmarshal(msg, &resMetadataNotif); err != nil { + log.Fatal(err) + } + + subType := resMetadataNotif.Metadata.SubType + log.Printf("socket: %s event received", subType) + + switch subType { + case "channel.chat.message": + var resNotifChannelChatMsg Res_Notif_ChannelChatMsg + + if err := json.Unmarshal(msg, &resNotifChannelChatMsg); err != nil { + log.Fatal(err) + } + + // TODO: Add to a function + jsonFormatted, err := json.MarshalIndent(resNotifChannelChatMsg, "", " ") + + if err != nil { + log.Fatalf("socket: error al formatear") + } + + // log.Println(resNotifChannelChatMsg.Payload.Event) + fmt.Print(string(jsonFormatted)) + + chatMsg := resNotifChannelChatMsg.Payload.Event.Msg.Text + log.Println(chatMsg) + + if strings.HasPrefix(chatMsg, "!") { + bot.HandleCmd(strings.Split(chatMsg[1:], " ")) + } + } + default: + log.Fatalf("%s: message type not implemented", msgType) + } + } + + done <- true +} + +func closeConn(conn *websocket.Conn) { + err := conn.WriteMessage( + websocket.CloseMessage, + websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")) + + if err != nil { + log.Fatal(err) + } + + log.Println("socket: connection closed") +} + +// func test() { +// var res Response + +// // Deserializas +// err := json.Unmarshal([]byte(jsonData), &res) + +// if err != nil { +// fmt.Println("Error al deserializar:", err) +// return +// } + +// // Conviertes la estructura nuevamente a JSON formateado + +// formattedJSON, err := json.MarshalIndent(res, "", " ") + +// if err != nil { +// fmt.Println("Error al formatear JSON:", err) +// return +// } +// } diff -r a8aab75f68c9 -r e9df3bb010f4 socket/types.go --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/socket/types.go Thu Mar 13 17:41:42 2025 +0000 @@ -0,0 +1,117 @@ +package socket + +type Res_Metadata struct { + Metadata Metadata `json:"metadata"` +} + +type Res_Metadata_Notif struct { + Metadata Metadata_Notif `json:"metadata"` +} + +type Res_Welcome struct { + Metadata Metadata `json:"metadata"` + Payload Payload_Welcome `json:"payload"` +} + +type Res_Keepalive struct { + Metadata Metadata `json:"metadata"` + Payload Payload_Keepalive `json:"payload"` +} + +type Res_Notif_ChannelChatMsg struct { + Metadata Metadata_Notif `json:"metadata,omitempty"` + Payload Payload_Notif_ChannelChatMsg `json:"payload,omitempty"` +} + +type Metadata struct { + MsgId string `json:"message_id"` + MsgType string `json:"message_type"` + MsgTimestamp string `json:"message_timestamp"` +} + +type Metadata_Notif struct { + Metadata + SubType string `json:"subscription_type"` + SubVersion string `json:"subscription_version"` +} + +type Payload_Welcome struct { + Session struct { + Id string `json:"id"` + Status string `json:"status"` + ConnectedAt string `json:"connected_at"` + KeepaliveTimeout int `json:"keepalive_timeout_seconds"` + } `json:"session"` +} + +type Payload_Keepalive struct { +} + +type Payload_Notif_ChannelChatMsg struct { + Subscription Payload_Sub_Notif_ChannelChatMsg `json:"subscription"` + Event Payload_Event_Notif_ChannelChatMsg `json:"event"` +} + +type Payload_Sub_Notif struct { + Id string `json:"id"` + Status string `json:"status"` + Type string `json:"type"` + Version string `json:"version"` + Cost int `json:"cost"` + + Transport struct { + Method string `json:"method"` + SessionId string `json:"session_id"` + } `json:"transport"` + + CreatedAt string `json:"created_at"` +} + +type Payload_Sub_Notif_ChannelChatMsg struct { + Payload_Sub_Notif + + Condition struct { + BroadcasterUserId string `json:"broadcaster_user_id"` + UserId string `json:"user_id"` + } `json:"condition"` +} + +type Payload_Event_Notif_ChannelChatMsg struct { + BroadcasterUserId string `json:"broadcaster_user_id"` + BroadcasterUserLogin string `json:"broadcaster_user_login"` + BroadcasterUserName string `json:"broadcaster_user_name"` + ChatterUserId string `json:"chatter_user_id"` + ChatterUserLogin string `json:"chatter_user_login"` + ChatterUserName string `json:"chatter_user_name"` + MsgId string `json:"message_id"` + + Msg struct { + Text string `json:"text"` + + Fragments []struct { + Type string `json:"type"` + Text string `json:"text"` + Cheermote string `json:"cheermote"` + Emote string `json:"emote"` + Mention string `json:"mention"` + } `json:"fragments"` + } `json:"message"` + + Color string `json:"color"` + + Badges []struct { + SetId string `json:"set_id"` + Id string `json:"id"` + Info string `json:"info"` + } `json:"badges"` + + MsgType string `json:"message_type"` + Cheer string `json:"cheer"` + Reply string `json:"reply"` + ChannelPointsCustomRewardId string `json:"channel_points_custom_reward_id"` + SourceBroadcasterUserId string `json:"source_broadcaster_user_id"` + SourceBroadcasterUserLogin string `json:"source_broadcaster_user_login"` + SourceBroadcasterUserName string `json:"source_broadcaster_user_name"` + SourceMessageId string `json:"source_message_id"` + SourceBadges string `json:"source_badges"` +}