Compare commits
10 commits
35489361fe
...
f35ec00a16
Author | SHA1 | Date | |
---|---|---|---|
tyler | f35ec00a16 | ||
6bcc437bc0 | |||
a4125e8de8 | |||
3818644bb0 | |||
ea9955c164 | |||
563d9f9413 | |||
9c32f33d9f | |||
ba26735378 | |||
a779afcaba | |||
5b3593ec1e |
87
chat.go
87
chat.go
|
@ -13,9 +13,23 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/r3labs/sse/v2"
|
"github.com/r3labs/sse/v2"
|
||||||
"github.com/tylertravisty/go-utils/random"
|
|
||||||
"golang.org/x/net/html"
|
"golang.org/x/net/html"
|
||||||
"gopkg.in/cenkalti/backoff.v1"
|
"gopkg.in/cenkalti/backoff.v1"
|
||||||
|
"travisty.io/tyler/go-utils/random"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ChatBadgeRecurringSubscription = "recurring_subscription"
|
||||||
|
ChatBadgeLocalsSupporter = "locals_supporter"
|
||||||
|
|
||||||
|
ChatTypeInit = "init"
|
||||||
|
ChatTypeMessages = "messages"
|
||||||
|
ChatTypeMuteUsers = "mute_users"
|
||||||
|
ChatTypeDeleteMessages = "delete_messages"
|
||||||
|
ChatTypeSubscriber = "locals_supporter"
|
||||||
|
ChatTypeRaiding = "raid_confirmed"
|
||||||
|
ChatTypePinMessage = "pin_message"
|
||||||
|
ChatTypeUnpinMessage = "unpin_message"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ChatInfo struct {
|
type ChatInfo struct {
|
||||||
|
@ -65,24 +79,6 @@ func (c *Client) getChatInfo() (*ChatInfo, error) {
|
||||||
lineS, err := r.ReadString('\n')
|
lineS, err := r.ReadString('\n')
|
||||||
for err == nil {
|
for err == nil {
|
||||||
if strings.Contains(lineS, "RumbleChat(") {
|
if strings.Contains(lineS, "RumbleChat(") {
|
||||||
//start := strings.Index(lineS, "RumbleChat(") + len("RumbleChat(")
|
|
||||||
//if start == -1 {
|
|
||||||
// return nil, fmt.Errorf("error finding chat function in webpage")
|
|
||||||
//}
|
|
||||||
//end := strings.Index(lineS[start:], ");")
|
|
||||||
//if end == -1 {
|
|
||||||
// return nil, fmt.Errorf("error finding end of chat function in webpage")
|
|
||||||
//}
|
|
||||||
//argsS := strings.ReplaceAll(lineS[start:start+end], ", ", ",")
|
|
||||||
//argsS = strings.Replace(argsS, "[", "\"[", 1)
|
|
||||||
//n := strings.LastIndex(argsS, "]")
|
|
||||||
//argsS = argsS[:n] + "]\"" + argsS[n+1:]
|
|
||||||
//c := csv.NewReader(strings.NewReader(argsS))
|
|
||||||
//args, err := c.ReadAll()
|
|
||||||
//if err != nil {
|
|
||||||
// return nil, fmt.Errorf("error parsing csv: %v", err)
|
|
||||||
//}
|
|
||||||
//info := args[0]
|
|
||||||
start := strings.Index(lineS, "RumbleChat(") + len("RumbleChat(")
|
start := strings.Index(lineS, "RumbleChat(") + len("RumbleChat(")
|
||||||
if start == -1 {
|
if start == -1 {
|
||||||
return nil, fmt.Errorf("error finding chat function in webpage")
|
return nil, fmt.Errorf("error finding chat function in webpage")
|
||||||
|
@ -92,11 +88,11 @@ func (c *Client) getChatInfo() (*ChatInfo, error) {
|
||||||
return nil, fmt.Errorf("error finding end of chat function in webpage")
|
return nil, fmt.Errorf("error finding end of chat function in webpage")
|
||||||
}
|
}
|
||||||
args := parseRumbleChatArgs(lineS[start : start+end])
|
args := parseRumbleChatArgs(lineS[start : start+end])
|
||||||
channelID, err := strconv.Atoi(args[5])
|
channelID, err := strconv.Atoi(args[6])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error converting channel ID argument string to int: %v", err)
|
return nil, fmt.Errorf("error converting channel ID argument string to int: %v", err)
|
||||||
}
|
}
|
||||||
chatInfo = &ChatInfo{ChannelID: channelID, ChatID: args[1], UrlPrefix: args[0]}
|
chatInfo = &ChatInfo{ChannelID: channelID, ChatID: args[2], UrlPrefix: args[0]}
|
||||||
} else if strings.Contains(lineS, "media-by--a") && strings.Contains(lineS, "author") {
|
} else if strings.Contains(lineS, "media-by--a") && strings.Contains(lineS, "author") {
|
||||||
r := strings.NewReader(lineS)
|
r := strings.NewReader(lineS)
|
||||||
node, err := html.Parse(r)
|
node, err := html.Parse(r)
|
||||||
|
@ -132,7 +128,7 @@ func parseRumbleChatArgs(argsS string) []string {
|
||||||
arg := []rune{}
|
arg := []rune{}
|
||||||
for _, c := range argsS {
|
for _, c := range argsS {
|
||||||
if c == ',' && open == 0 {
|
if c == ',' && open == 0 {
|
||||||
args = append(args, string(arg))
|
args = append(args, trimRumbleChatArg(string(arg)))
|
||||||
arg = []rune{}
|
arg = []rune{}
|
||||||
} else {
|
} else {
|
||||||
if c == '[' {
|
if c == '[' {
|
||||||
|
@ -146,12 +142,16 @@ func parseRumbleChatArgs(argsS string) []string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(arg) > 0 {
|
if len(arg) > 0 {
|
||||||
args = append(args, string(arg))
|
args = append(args, trimRumbleChatArg(string(arg)))
|
||||||
}
|
}
|
||||||
|
|
||||||
return args
|
return args
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func trimRumbleChatArg(arg string) string {
|
||||||
|
return strings.Trim(strings.TrimSpace(arg), "\"")
|
||||||
|
}
|
||||||
|
|
||||||
type ChatMessage struct {
|
type ChatMessage struct {
|
||||||
Text string `json:"text"`
|
Text string `json:"text"`
|
||||||
}
|
}
|
||||||
|
@ -258,6 +258,15 @@ type ChatEventBlock struct {
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ChatEventNotification struct {
|
||||||
|
Badge string `json:"badge"`
|
||||||
|
Text string `json:"text"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ChatEventRaidNotification struct {
|
||||||
|
StartTs int64 `json:"start_ts"`
|
||||||
|
}
|
||||||
|
|
||||||
type ChatEventRant struct {
|
type ChatEventRant struct {
|
||||||
Duration int `json:"duration"`
|
Duration int `json:"duration"`
|
||||||
ExpiresOn string `json:"expires_on"`
|
ExpiresOn string `json:"expires_on"`
|
||||||
|
@ -265,13 +274,15 @@ type ChatEventRant struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ChatEventMessage struct {
|
type ChatEventMessage struct {
|
||||||
Blocks []ChatEventBlock `json:"blocks"`
|
Blocks []ChatEventBlock `json:"blocks"`
|
||||||
ChannelID *int64 `json:"channel_id"`
|
ChannelID *int64 `json:"channel_id"`
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Rant *ChatEventRant `json:"rant"`
|
Notification *ChatEventNotification `json:"notification"`
|
||||||
Text string `json:"text"`
|
RaidNotification *ChatEventRaidNotification `json:"raid_notification"`
|
||||||
Time string `json:"time"`
|
Rant *ChatEventRant `json:"rant"`
|
||||||
UserID string `json:"user_id"`
|
Text string `json:"text"`
|
||||||
|
Time string `json:"time"`
|
||||||
|
UserID string `json:"user_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ChatEventUser struct {
|
type ChatEventUser struct {
|
||||||
|
@ -392,8 +403,11 @@ type ChatView struct {
|
||||||
ImageUrl string
|
ImageUrl string
|
||||||
Init bool
|
Init bool
|
||||||
IsFollower bool
|
IsFollower bool
|
||||||
|
Raid bool
|
||||||
Rant int
|
Rant int
|
||||||
|
Sub bool
|
||||||
Text string
|
Text string
|
||||||
|
Time time.Time
|
||||||
Type string
|
Type string
|
||||||
Username string
|
Username string
|
||||||
}
|
}
|
||||||
|
@ -455,10 +469,23 @@ func parseMessages(eventType string, messages []ChatEventMessage, users map[stri
|
||||||
view.Color = user.Color
|
view.Color = user.Color
|
||||||
view.ImageUrl = user.Image1
|
view.ImageUrl = user.Image1
|
||||||
view.IsFollower = user.IsFollower
|
view.IsFollower = user.IsFollower
|
||||||
|
if message.RaidNotification != nil {
|
||||||
|
view.Raid = true
|
||||||
|
}
|
||||||
if message.Rant != nil {
|
if message.Rant != nil {
|
||||||
view.Rant = message.Rant.PriceCents
|
view.Rant = message.Rant.PriceCents
|
||||||
}
|
}
|
||||||
|
if message.Notification != nil {
|
||||||
|
if message.Notification.Badge == ChatBadgeRecurringSubscription {
|
||||||
|
view.Sub = true
|
||||||
|
}
|
||||||
|
}
|
||||||
view.Text = message.Text
|
view.Text = message.Text
|
||||||
|
t, err := time.Parse(time.RFC3339, message.Time)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error parsing message time: %v", err)
|
||||||
|
}
|
||||||
|
view.Time = t
|
||||||
view.Type = eventType
|
view.Type = eventType
|
||||||
view.Username = user.Username
|
view.Username = user.Username
|
||||||
|
|
||||||
|
|
18
client.go
18
client.go
|
@ -273,31 +273,37 @@ func (c *Client) userLogout() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type LoggedInResponseData struct {
|
||||||
|
Username string `json:"username"`
|
||||||
|
}
|
||||||
|
|
||||||
type LoggedInResponseUser struct {
|
type LoggedInResponseUser struct {
|
||||||
LoggedIn bool `json:"logged_in"`
|
ID string `json:"id"`
|
||||||
|
LoggedIn bool `json:"logged_in"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type LoggedInResponse struct {
|
type LoggedInResponse struct {
|
||||||
|
Data LoggedInResponseData `json:"data"`
|
||||||
User LoggedInResponseUser `json:"user"`
|
User LoggedInResponseUser `json:"user"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) LoggedIn() (bool, error) {
|
func (c *Client) LoggedIn() (*LoggedInResponse, error) {
|
||||||
resp, err := c.httpClient.Get(urlUserLogin)
|
resp, err := c.httpClient.Get(urlUserLogin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, pkgErr("error getting login service", err)
|
return nil, pkgErr("error getting login service", err)
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
bodyB, err := io.ReadAll(resp.Body)
|
bodyB, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, pkgErr("error reading body bytes", err)
|
return nil, pkgErr("error reading body bytes", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var lir LoggedInResponse
|
var lir LoggedInResponse
|
||||||
err = json.NewDecoder(strings.NewReader(string(bodyB))).Decode(&lir)
|
err = json.NewDecoder(strings.NewReader(string(bodyB))).Decode(&lir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, pkgErr("error un-marshaling response body", err)
|
return nil, pkgErr("error un-marshaling response body", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return lir.User.LoggedIn, nil
|
return &lir, nil
|
||||||
}
|
}
|
||||||
|
|
4
go.mod
4
go.mod
|
@ -1,13 +1,13 @@
|
||||||
module github.com/tylertravisty/rumble-livestream-lib-go
|
module travisty.io/tyler/rumble-livestream-lib-go
|
||||||
|
|
||||||
go 1.19
|
go 1.19
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/r3labs/sse/v2 v2.10.0
|
github.com/r3labs/sse/v2 v2.10.0
|
||||||
github.com/robertkrimen/otto v0.2.1
|
github.com/robertkrimen/otto v0.2.1
|
||||||
github.com/tylertravisty/go-utils v0.0.0-20230524204414-6893ae548909
|
|
||||||
golang.org/x/net v0.24.0
|
golang.org/x/net v0.24.0
|
||||||
gopkg.in/cenkalti/backoff.v1 v1.1.0
|
gopkg.in/cenkalti/backoff.v1 v1.1.0
|
||||||
|
travisty.io/tyler/go-utils v0.0.0-20240614172648-00b0b1a557b4
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -9,8 +9,6 @@ github.com/robertkrimen/otto v0.2.1/go.mod h1:UPwtJ1Xu7JrLcZjNWN8orJaM5n5YEtqL//
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||||
github.com/tylertravisty/go-utils v0.0.0-20230524204414-6893ae548909 h1:xrjIFqzGQXlCrCdMPpW6+SodGFSlrQ3ZNUCr3f5tF1g=
|
|
||||||
github.com/tylertravisty/go-utils v0.0.0-20230524204414-6893ae548909/go.mod h1:2W31Jhs9YSy7y500wsCOW0bcamGi9foQV1CKrfvfTxk=
|
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/net v0.0.0-20191116160921-f9c825593386/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20191116160921-f9c825593386/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
|
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
|
||||||
|
@ -26,3 +24,5 @@ gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI=
|
||||||
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
|
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
travisty.io/tyler/go-utils v0.0.0-20240614172648-00b0b1a557b4 h1:/InkkmR3O6lh63ckLJe14k1DRB6RuOZJv5TpfxGVRKQ=
|
||||||
|
travisty.io/tyler/go-utils v0.0.0-20240614172648-00b0b1a557b4/go.mod h1:2inG89XtlVnppctG2WnKir4mWWN0zbF/PB9m1HXdTYI=
|
||||||
|
|
6
vendor/modules.txt
vendored
6
vendor/modules.txt
vendored
|
@ -10,9 +10,6 @@ github.com/robertkrimen/otto/file
|
||||||
github.com/robertkrimen/otto/parser
|
github.com/robertkrimen/otto/parser
|
||||||
github.com/robertkrimen/otto/registry
|
github.com/robertkrimen/otto/registry
|
||||||
github.com/robertkrimen/otto/token
|
github.com/robertkrimen/otto/token
|
||||||
# github.com/tylertravisty/go-utils v0.0.0-20230524204414-6893ae548909
|
|
||||||
## explicit; go 1.16
|
|
||||||
github.com/tylertravisty/go-utils/random
|
|
||||||
# golang.org/x/net v0.24.0
|
# golang.org/x/net v0.24.0
|
||||||
## explicit; go 1.18
|
## explicit; go 1.18
|
||||||
golang.org/x/net/context
|
golang.org/x/net/context
|
||||||
|
@ -40,3 +37,6 @@ gopkg.in/cenkalti/backoff.v1
|
||||||
## explicit
|
## explicit
|
||||||
gopkg.in/sourcemap.v1
|
gopkg.in/sourcemap.v1
|
||||||
gopkg.in/sourcemap.v1/base64vlq
|
gopkg.in/sourcemap.v1/base64vlq
|
||||||
|
# travisty.io/tyler/go-utils v0.0.0-20240614172648-00b0b1a557b4
|
||||||
|
## explicit; go 1.16
|
||||||
|
travisty.io/tyler/go-utils/random
|
||||||
|
|
Loading…
Reference in a new issue