mirror of
https://codeberg.org/SafeTwitch/safetwitch-backend.git
synced 2025-01-03 11:20:08 -05:00
Complete websocket
This commit is contained in:
parent
bce1f73823
commit
7b0bec1026
3 changed files with 104 additions and 4 deletions
23
extractor/chat/README.md
Normal file
23
extractor/chat/README.md
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# Notes about twitch messages
|
||||||
|
|
||||||
|
Examples message
|
||||||
|
`@badge-info=subscriber/2;badges=subscriber/0,premium/1;client-nonce=a245bea7f04bac06be7bd637144c3721;color=;display-name=EmbeddedMess;emotes=;first-msg=0;flags=16-19:A.3;id=3ad413d1-1ab1-4cd1-902e-020c29a7b45c;mod=0;returning-chatter=0;room-id=227217502;subscriber=1;tmi-sent-ts=1685535959939;turbo=0;user-id=693838516;user-type= :embeddedmess!embeddedmess@embeddedmess.tmi.twitch.tv PRIVMSG #dino_xx :Why doesn't the noob have loot keys on then?`
|
||||||
|
|
||||||
|
## Parts
|
||||||
|
### Metadata
|
||||||
|
`@badge-info=subscriber/2;badges=subscriber/0,premium/1;client-nonce=a245bea7f04bac06be7bd637144c3721;color=;display-name=EmbeddedMess;emotes=;first-msg=0;flags=16-19:A.3;id=3ad413d1-1ab1-4cd1-902e-020c29a7b45c;mod=0;returning-chatter=0;room-id=227217502;subscriber=1;tmi-sent-ts=1685535959939;turbo=0;user-id=693838516;user-type= `
|
||||||
|
|
||||||
|
### Username
|
||||||
|
`embeddedmess!embeddedmess@embeddedmess.tmi.twitch.tv`
|
||||||
|
|
||||||
|
### Message Type
|
||||||
|
`PRIVMSG`
|
||||||
|
|
||||||
|
### Channel of origin
|
||||||
|
`#dino_xx`
|
||||||
|
|
||||||
|
## Message
|
||||||
|
`Why doesn't the noob have loot keys on then?`
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
- Format looks like `Metadata : Username, message type, channel of origin : message`
|
9
extractor/chat/structs/twitchMessage.go
Normal file
9
extractor/chat/structs/twitchMessage.go
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
package structs
|
||||||
|
|
||||||
|
type TwitchMessageMetadata struct {
|
||||||
|
Username string `json:"username"`
|
||||||
|
MessageType string `json:"type"`
|
||||||
|
Channel string `json:"channel"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
Tags map[string]string `json:"tags"`
|
||||||
|
}
|
|
@ -1,12 +1,14 @@
|
||||||
package chat
|
package chat
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"log"
|
"log"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"safetwitch-backend/extractor/chat/structs"
|
||||||
|
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -43,14 +45,13 @@ func BeginTwitchChatConnection() {
|
||||||
_, msg, err := conn.ReadMessage()
|
_, msg, err := conn.ReadMessage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to read message: %v", err)
|
log.Printf("Failed to read message: %v", err)
|
||||||
|
connectionReady = false
|
||||||
|
BeginTwitchChatConnection()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
parseMessage(string(msg))
|
parseMessage(string(msg))
|
||||||
RemoveUnusedStreamers()
|
RemoveUnusedStreamers()
|
||||||
|
|
||||||
fmt.Println(ClientHandler.FindClientsByStreamer("dino_xx"))
|
|
||||||
|
|
||||||
//fmt.Println("Received message from server:", string(msg))
|
//fmt.Println("Received message from server:", string(msg))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,11 +64,77 @@ func parseMessage(msg string) error {
|
||||||
if !connectionReady && strings.Contains(msg, "001") {
|
if !connectionReady && strings.Contains(msg, "001") {
|
||||||
connectionReady = true
|
connectionReady = true
|
||||||
log.Println("Authenticated with Twitch IRC!")
|
log.Println("Authenticated with Twitch IRC!")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
example message
|
||||||
|
@badge-info=subscriber/2;badges=subscriber/0,premium/1;client-nonce=a245bea7f04bac06be7bd637144c3721;color=;display-name=EmbeddedMess;emotes=;first-msg=0;flags=16-19:A.3;id=3ad413d1-1ab1-4cd1-902e-020c29a7b45c;mod=0;returning-chatter=0;room-id=227217502;subscriber=1;tmi-sent-ts=1685535959939;turbo=0;user-id=693838516;user-type= :embeddedmess!embeddedmess@embeddedmess.tmi.twitch.tv PRIVMSG #dino_xx :Why doesn't the noob have loot keys on then?
|
||||||
|
*/
|
||||||
|
if !connectionReady {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Three parts, metadata, middle, message SEE README.md
|
||||||
|
splitMsg := strings.Split(msg, " :")
|
||||||
|
if len(splitMsg) < 3 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
p1 := splitMsg[0]
|
||||||
|
p2 := splitMsg[1]
|
||||||
|
p3 := splitMsg[2]
|
||||||
|
|
||||||
|
parsedTags := parseTags(p1)
|
||||||
|
|
||||||
|
p2Split := strings.SplitAfter(p2, " ")
|
||||||
|
username := parseUsername(p2Split[0])
|
||||||
|
messageType := strings.Replace(p2Split[1], " ", "", 1)
|
||||||
|
channel := strings.Replace(p2Split[2], "#", "", 1)
|
||||||
|
|
||||||
|
parsedMessage := structs.TwitchMessageMetadata{
|
||||||
|
Username: username,
|
||||||
|
MessageType: messageType,
|
||||||
|
Channel: channel,
|
||||||
|
Message: p3,
|
||||||
|
Tags: parsedTags,
|
||||||
|
}
|
||||||
|
|
||||||
|
parsed, err := json.Marshal(parsedMessage)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
clientsToSendTo := ClientHandler.FindClientsByStreamer(strings.Replace(channel, " ", "", 1))
|
||||||
|
for _, Client := range clientsToSendTo {
|
||||||
|
Client.send <- string(parsed)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseUsername(username string) string {
|
||||||
|
return strings.Split(username, "!")[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseTags(tags string) map[string]string {
|
||||||
|
// Split the data by semicolon separator
|
||||||
|
keyValues := strings.Split(tags, ";")
|
||||||
|
|
||||||
|
// Create an empty map to store the key-value pairs
|
||||||
|
var m = map[string]string{}
|
||||||
|
|
||||||
|
// Parse each key-value pair and add it to the map
|
||||||
|
for _, keyValue := range keyValues {
|
||||||
|
pair := strings.SplitN(keyValue, "=", 2)
|
||||||
|
if len(pair) == 2 {
|
||||||
|
m[pair[0]] = pair[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
func FollowStreamer(streamerName string) error {
|
func FollowStreamer(streamerName string) error {
|
||||||
err := sendMessage("JOIN #" + strings.ToLower(streamerName))
|
err := sendMessage("JOIN #" + strings.ToLower(streamerName))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -100,6 +167,7 @@ func RemoveUnusedStreamers() {
|
||||||
if !found {
|
if !found {
|
||||||
// remove streamer from server map
|
// remove streamer from server map
|
||||||
delete(streamersFollowing, streamer)
|
delete(streamersFollowing, streamer)
|
||||||
|
sendMessage("PART #" + streamer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue