Mercurial > public > pacobot
annotate socket/conn.go @ 13:e7ab74d2ad88 default tip
Move to mercurial
author | Dennis C. M. <dennis@denniscm.com> |
---|---|
date | Wed, 04 Jun 2025 09:38:35 +0100 |
parents | aaf85ae1f942 |
children |
rev | line source |
---|---|
8 | 1 package socket |
2 | |
3 import ( | |
4 "encoding/json" | |
5 "log" | |
6 "net/url" | |
7 "os" | |
8 "os/signal" | |
9 "strings" | |
10 "time" | |
11 | |
12 "github.com/denniscmcom/pacobot/bot" | |
13 "github.com/denniscmcom/pacobot/event" | |
14 "github.com/gorilla/websocket" | |
15 ) | |
16 | |
17 func Connect(authToken string) { | |
18 interrupt := make(chan os.Signal, 1) | |
19 signal.Notify(interrupt, os.Interrupt) | |
20 | |
21 baseUrl := url.URL{Scheme: "wss", Host: "eventsub.wss.twitch.tv", Path: "/ws"} | |
22 | |
23 log.Println("socket: connecting...") | |
24 conn, _, err := websocket.DefaultDialer.Dial(baseUrl.String(), nil) | |
25 | |
26 if err != nil { | |
27 log.Fatal(err) | |
28 } | |
29 | |
30 defer conn.Close() | |
31 | |
32 log.Println("socket: connected") | |
33 | |
34 var timeout time.Ticker | |
10 | 35 done := make(chan struct{}) |
8 | 36 |
37 go readMsg(done, conn, &timeout, authToken) | |
38 | |
39 for { | |
40 select { | |
41 case <-interrupt: | |
42 closeConn(conn) | |
43 | |
44 select { | |
45 case <-done: | |
46 case <-time.After(time.Second): | |
47 } | |
48 return | |
49 case <-done: | |
50 log.Println("socket: connection closed by server") | |
51 Connect(authToken) | |
52 case <-timeout.C: | |
53 log.Println("socket: connection lost") | |
54 timeout.Stop() | |
55 Connect(authToken) | |
56 } | |
57 } | |
58 } | |
59 | |
10 | 60 func readMsg(done chan struct{}, conn *websocket.Conn, timeout *time.Ticker, authToken string) { |
61 defer close(done) | |
8 | 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 | |
12
aaf85ae1f942
add very simple html template
Dennis C. M. <dennis@denniscm.com>
parents:
11
diff
changeset
|
72 var metadataMsg MetadataMsg |
8 | 73 |
12
aaf85ae1f942
add very simple html template
Dennis C. M. <dennis@denniscm.com>
parents:
11
diff
changeset
|
74 if err := json.Unmarshal(msg, &metadataMsg); err != nil { |
8 | 75 log.Fatal(err) |
76 } | |
77 | |
12
aaf85ae1f942
add very simple html template
Dennis C. M. <dennis@denniscm.com>
parents:
11
diff
changeset
|
78 msgType := metadataMsg.Metadata.MsgType |
8 | 79 log.Printf("socket: %s msg received", msgType) |
80 | |
81 switch msgType { | |
82 case "session_welcome": | |
12
aaf85ae1f942
add very simple html template
Dennis C. M. <dennis@denniscm.com>
parents:
11
diff
changeset
|
83 var welcomeMsg WelcomeMsg |
8 | 84 |
12
aaf85ae1f942
add very simple html template
Dennis C. M. <dennis@denniscm.com>
parents:
11
diff
changeset
|
85 if err := json.Unmarshal(msg, &welcomeMsg); err != nil { |
8 | 86 log.Fatal(err) |
87 } | |
88 | |
12
aaf85ae1f942
add very simple html template
Dennis C. M. <dennis@denniscm.com>
parents:
11
diff
changeset
|
89 timeout_secs = time.Duration(welcomeMsg.Payload.Session.KeepaliveTimeoutSecs+3) * time.Second |
8 | 90 timeout = time.NewTicker(timeout_secs) |
91 defer timeout.Stop() | |
92 | |
12
aaf85ae1f942
add very simple html template
Dennis C. M. <dennis@denniscm.com>
parents:
11
diff
changeset
|
93 event.SubChannelChatMsg(authToken, welcomeMsg.Payload.Session.Id) |
8 | 94 |
95 case "session_keepalive": | |
96 timeout.Reset(timeout_secs) | |
97 log.Println("socket: timeout resetted") | |
98 | |
99 case "notification": | |
12
aaf85ae1f942
add very simple html template
Dennis C. M. <dennis@denniscm.com>
parents:
11
diff
changeset
|
100 var metadataEvent MetadataEvent |
8 | 101 |
12
aaf85ae1f942
add very simple html template
Dennis C. M. <dennis@denniscm.com>
parents:
11
diff
changeset
|
102 if err := json.Unmarshal(msg, &metadataEvent); err != nil { |
8 | 103 log.Fatal(err) |
104 } | |
105 | |
12
aaf85ae1f942
add very simple html template
Dennis C. M. <dennis@denniscm.com>
parents:
11
diff
changeset
|
106 subType := metadataEvent.Metadata.SubType |
8 | 107 log.Printf("socket: %s event received", subType) |
108 | |
109 switch subType { | |
110 case "channel.chat.message": | |
12
aaf85ae1f942
add very simple html template
Dennis C. M. <dennis@denniscm.com>
parents:
11
diff
changeset
|
111 var channelChatMsgEvent ChannelChatMsgEvent |
8 | 112 |
12
aaf85ae1f942
add very simple html template
Dennis C. M. <dennis@denniscm.com>
parents:
11
diff
changeset
|
113 if err := json.Unmarshal(msg, &channelChatMsgEvent); err != nil { |
8 | 114 log.Fatal(err) |
115 } | |
116 | |
12
aaf85ae1f942
add very simple html template
Dennis C. M. <dennis@denniscm.com>
parents:
11
diff
changeset
|
117 chatMsg := channelChatMsgEvent.Payload.Event.Msg.Text |
8 | 118 |
119 if strings.HasPrefix(chatMsg, "!") { | |
12
aaf85ae1f942
add very simple html template
Dennis C. M. <dennis@denniscm.com>
parents:
11
diff
changeset
|
120 if channelChatMsgEvent.Payload.Event.ChatterUserName == "denniscmartin" { |
11 | 121 go bot.HandleCmd(strings.Split(chatMsg[1:], " ")) |
122 } | |
8 | 123 } |
124 } | |
12
aaf85ae1f942
add very simple html template
Dennis C. M. <dennis@denniscm.com>
parents:
11
diff
changeset
|
125 |
8 | 126 default: |
10 | 127 log.Fatalf("socket: %s message type not implemented", msgType) |
8 | 128 } |
129 } | |
130 } | |
131 | |
132 func closeConn(conn *websocket.Conn) { | |
133 err := conn.WriteMessage( | |
134 websocket.CloseMessage, | |
135 websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")) | |
136 | |
137 if err != nil { | |
138 log.Fatal(err) | |
139 } | |
140 | |
141 log.Println("socket: connection closed") | |
142 } |