Twitch single-message deletion basic support

This commit is contained in:
Luxferre
2024-09-20 16:17:20 +03:00
parent 3d65d68d8a
commit 707b9e611a
7 changed files with 103 additions and 45 deletions
+2
View File
@@ -108,6 +108,8 @@ func kk_process_message(rawmsg map[string]interface{}) {
/* prepare output message */
out_message := ChatMessage {
Type: "kk",
NativeId: rawmsg["id"].(string),
AuthorId: string(int64(author["id"].(float64))),
Username: author["username"].(string),
Timestamp: sent_dt.UTC().Format("2006-01-02T15:04:05Z"),
Text: rawmsg["content"].(string),
+22 -1
View File
@@ -65,7 +65,26 @@ func oc_api_get(endpoint string) []interface{} {
func oc_process_message(rawmsg map[string]interface{}) {
/* if the message came from a real user, this is the one we should process */
if rawmsg["type"] == "CHAT" {
if !slices.Contains(oc_msg_id_cache, rawmsg["id"].(string)) { /* we have a fresh message here */
/* first, check if we need to include this message at all */
msg_hidden := false
user_banned := false
if _, ok := rawmsg["hiddenAt"]; ok && rawmsg["hiddenAt"].(string) != "" {
msg_hidden = true
}
if _, ok := rawmsg["user"]; ok {
if _, ok := rawmsg["user"].(map[string]interface{})["disabledAt"]; ok {
if rawmsg["user"].(map[string]interface{})["disabledAt"].(string) != "" {
user_banned = true
}
}
}
msg_included := slices.Contains(oc_msg_id_cache, rawmsg["id"].(string))
if msg_hidden || user_banned { /* don't include the message, check if it already is included */
if msg_included { /* delete this message from the cache */
msg_idx := slices.Index(oc_msg_id_cache, rawmsg["id"].(string))
oc_msg_id_cache = slices.Delete(oc_msg_id_cache, msg_idx, msg_idx+1)
}
} else if !msg_included { /* we have a fresh message here */
var author map[string]interface{}
/* check if the "user" field is present */
if _, ok := rawmsg["user"]; ok {
@@ -80,6 +99,8 @@ func oc_process_message(rawmsg map[string]interface{}) {
/* prepare output message */
out_message := ChatMessage {
Type: "oc",
NativeId: rawmsg["id"].(string),
AuthorId: author["id"].(string),
Username: author["displayName"].(string),
Timestamp: sent_dt.UTC().Format("2006-01-02T15:04:05Z"),
Text: rawmsg["body"].(string),
+3 -1
View File
@@ -21,9 +21,11 @@ import (
/* main chat message structure */
type ChatMessage struct {
Id uint64 `json:"id"` /* message id (auto-filled) */
NativeId string `json:"native_id"` /* message id native to the platform */
AuthorId string `json:"author_id"` /* author id native to the platform */
Type string `json:"type"` /* message type string */
Timestamp string `json:"timestamp"` /* timestamp string (formatted) */
Username string `json:"username"` /* username */
Username string `json:"username"` /* author username (as displayed) */
Text string `json:"text"` /* message text */
Icon string `json:"icon"` /* optional message icon URI */
}
+26 -12
View File
@@ -150,22 +150,34 @@ func tw_handle_emotes(text string, emote_data string) string {
/* main message procesing function */
func tw_process_message(rawmsg string) {
/* if the message came from a real user, this is the one we should process */
if strings.HasPrefix(rawmsg, "@badge-info=") {
parts := strings.Split(rawmsg, " :") /* get raw message parts */
/* first part is metadata, second is a full IRC username,
the rest is the message ending with \r\n */
metadata_str := strings.TrimSpace(parts[0])
msg_text := strings.Join(parts[2:], " :")
parts := strings.Split(rawmsg, " :") /* get raw message parts */
/* first part is metadata, second is a full IRC username,
the rest is the message ending with \r\n */
metadata_str := strings.TrimSpace(parts[0])
msg_text := ""
if(len(parts) > 2) {
msg_text = strings.Join(parts[2:], " :")
msg_text = strings.ReplaceAll(msg_text, "\u0000", "") /* remove excess null bytes */
metadata := make(map[string]string) /* store parsed metadata here */
parts = strings.Split(metadata_str, ";")
for _, field := range parts { /* iterate over metadata fields */
}
metadata := make(map[string]string) /* store parsed metadata here */
parts = strings.Split(metadata_str, ";")
for _, field := range parts { /* iterate over metadata fields */
if strings.Contains(field, "=") {
fieldkey, fieldval, _ := strings.Cut(field, "=")
metadata[fieldkey] = fieldval
}
}
/* if the message came from a real user, this is the one we should process */
/* but first, check if this is a single-message deletion event */
if strings.HasPrefix(rawmsg, "@login=") && strings.Contains(rawmsg, " CLEARMSG ") {
/* prepare output message */
out_message := ChatMessage {
Type: "delmsg",
NativeId: metadata["target-msg-id"],
}
/* send it to the message broker via the message_transport channel */
message_transport <- out_message
} else if strings.HasPrefix(rawmsg, "@badge-info=") { /* normal message or usernotice */
/* convert the timestamp */
ts, err := strconv.ParseInt(metadata["tmi-sent-ts"], 10, 0)
if err != nil { /* fallback to current time if anything */
@@ -185,6 +197,8 @@ func tw_process_message(rawmsg string) {
/* prepare output message */
out_message := ChatMessage {
Type: "tw",
NativeId: metadata["id"],
AuthorId: metadata["user-id"],
Username: metadata["display-name"],
Timestamp: sent_dt.UTC().Format("2006-01-02T15:04:05Z"),
Text: strings.TrimSpace(msg_text),
+2
View File
@@ -124,6 +124,8 @@ func yt_inner_action_to_chatitem(action map[string]interface{}) ChatMessage {
/* prepare output message */
out_message := ChatMessage {
Type: "yt",
NativeId: renderer["id"].(string),
AuthorId: renderer["authorExternalChannelId"].(string),
Username: author_name,
Timestamp: sent_dt.UTC().Format("2006-01-02T15:04:05Z"),
Text: yt_inner_runs_to_text(mruns),