8
|
1 package socket
|
|
2
|
|
3 import (
|
|
4 "encoding/json"
|
|
5 "fmt"
|
|
6 "log"
|
|
7 "net/url"
|
|
8 "os"
|
|
9 "os/signal"
|
|
10 "strings"
|
|
11 "time"
|
|
12
|
|
13 "github.com/denniscmcom/pacobot/bot"
|
|
14 "github.com/denniscmcom/pacobot/event"
|
|
15 "github.com/gorilla/websocket"
|
|
16 )
|
|
17
|
|
18 func Connect(authToken string) {
|
|
19 interrupt := make(chan os.Signal, 1)
|
|
20 signal.Notify(interrupt, os.Interrupt)
|
|
21
|
|
22 baseUrl := url.URL{Scheme: "wss", Host: "eventsub.wss.twitch.tv", Path: "/ws"}
|
|
23
|
|
24 log.Println("socket: connecting...")
|
|
25 conn, _, err := websocket.DefaultDialer.Dial(baseUrl.String(), nil)
|
|
26
|
|
27 if err != nil {
|
|
28 log.Fatal(err)
|
|
29 }
|
|
30
|
|
31 defer conn.Close()
|
|
32
|
|
33 log.Println("socket: connected")
|
|
34
|
|
35 var timeout time.Ticker
|
|
36 done := make(chan bool)
|
|
37
|
|
38 go readMsg(done, conn, &timeout, authToken)
|
|
39
|
|
40 for {
|
|
41 select {
|
|
42 case <-interrupt:
|
|
43 closeConn(conn)
|
|
44
|
|
45 select {
|
|
46 case <-done:
|
|
47 case <-time.After(time.Second):
|
|
48 }
|
|
49 return
|
|
50 case <-done:
|
|
51 log.Println("socket: connection closed by server")
|
|
52 Connect(authToken)
|
|
53 case <-timeout.C:
|
|
54 log.Println("socket: connection lost")
|
|
55 timeout.Stop()
|
|
56 Connect(authToken)
|
|
57 }
|
|
58 }
|
|
59 }
|
|
60
|
|
61 func readMsg(done chan bool, conn *websocket.Conn, timeout *time.Ticker, authToken string) {
|
|
62 var timeout_secs time.Duration
|
|
63
|
|
64 for {
|
|
65 log.Println("socket: waiting for msg...")
|
|
66 _, msg, err := conn.ReadMessage()
|
|
67
|
|
68 if err != nil {
|
|
69 break
|
|
70 }
|
|
71
|
|
72 var resMetadata Res_Metadata
|
|
73
|
|
74 if err := json.Unmarshal(msg, &resMetadata); err != nil {
|
|
75 log.Fatal(err)
|
|
76 }
|
|
77
|
|
78 msgType := resMetadata.Metadata.MsgType
|
|
79 log.Printf("socket: %s msg received", msgType)
|
|
80
|
|
81 switch msgType {
|
|
82 case "session_welcome":
|
|
83 var resWelcome Res_Welcome
|
|
84
|
|
85 if err := json.Unmarshal(msg, &resWelcome); err != nil {
|
|
86 log.Fatal(err)
|
|
87 }
|
|
88
|
|
89 timeout_secs = time.Duration(resWelcome.Payload.Session.KeepaliveTimeout+3) * time.Second
|
|
90 timeout = time.NewTicker(timeout_secs)
|
|
91 defer timeout.Stop()
|
|
92
|
|
93 event.ChannelChatMsgSub(authToken, resWelcome.Payload.Session.Id)
|
|
94
|
|
95 case "session_keepalive":
|
|
96 timeout.Reset(timeout_secs)
|
|
97 log.Println("socket: timeout resetted")
|
|
98
|
|
99 case "notification":
|
|
100 var resMetadataNotif Res_Metadata_Notif
|
|
101
|
|
102 if err := json.Unmarshal(msg, &resMetadataNotif); err != nil {
|
|
103 log.Fatal(err)
|
|
104 }
|
|
105
|
|
106 subType := resMetadataNotif.Metadata.SubType
|
|
107 log.Printf("socket: %s event received", subType)
|
|
108
|
|
109 switch subType {
|
|
110 case "channel.chat.message":
|
|
111 var resNotifChannelChatMsg Res_Notif_ChannelChatMsg
|
|
112
|
|
113 if err := json.Unmarshal(msg, &resNotifChannelChatMsg); err != nil {
|
|
114 log.Fatal(err)
|
|
115 }
|
|
116
|
|
117 // TODO: Add to a function
|
|
118 jsonFormatted, err := json.MarshalIndent(resNotifChannelChatMsg, "", " ")
|
|
119
|
|
120 if err != nil {
|
|
121 log.Fatalf("socket: error al formatear")
|
|
122 }
|
|
123
|
|
124 // log.Println(resNotifChannelChatMsg.Payload.Event)
|
|
125 fmt.Print(string(jsonFormatted))
|
|
126
|
|
127 chatMsg := resNotifChannelChatMsg.Payload.Event.Msg.Text
|
|
128 log.Println(chatMsg)
|
|
129
|
|
130 if strings.HasPrefix(chatMsg, "!") {
|
|
131 bot.HandleCmd(strings.Split(chatMsg[1:], " "))
|
|
132 }
|
|
133 }
|
|
134 default:
|
|
135 log.Fatalf("%s: message type not implemented", msgType)
|
|
136 }
|
|
137 }
|
|
138
|
|
139 done <- true
|
|
140 }
|
|
141
|
|
142 func closeConn(conn *websocket.Conn) {
|
|
143 err := conn.WriteMessage(
|
|
144 websocket.CloseMessage,
|
|
145 websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
|
|
146
|
|
147 if err != nil {
|
|
148 log.Fatal(err)
|
|
149 }
|
|
150
|
|
151 log.Println("socket: connection closed")
|
|
152 }
|
|
153
|
|
154 // func test() {
|
|
155 // var res Response
|
|
156
|
|
157 // // Deserializas
|
|
158 // err := json.Unmarshal([]byte(jsonData), &res)
|
|
159
|
|
160 // if err != nil {
|
|
161 // fmt.Println("Error al deserializar:", err)
|
|
162 // return
|
|
163 // }
|
|
164
|
|
165 // // Conviertes la estructura nuevamente a JSON formateado
|
|
166
|
|
167 // formattedJSON, err := json.MarshalIndent(res, "", " ")
|
|
168
|
|
169 // if err != nil {
|
|
170 // fmt.Println("Error al formatear JSON:", err)
|
|
171 // return
|
|
172 // }
|
|
173 // }
|