multichat-ts 0.0.84 → 0.0.86
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/default/index.d.ts +5 -0
- package/dist/default/kick.d.ts +16 -2
- package/dist/default/kick.js +45 -10
- package/dist/worker/index.d.ts +5 -0
- package/dist/worker/kick.d.ts +16 -2
- package/dist/worker/kick.js +45 -15
- package/package.json +1 -1
- package/src/default/index.ts +5 -0
- package/src/default/kick.ts +68 -13
- package/src/worker/index.ts +5 -0
- package/src/worker/kick.ts +68 -19
package/dist/default/index.d.ts
CHANGED
package/dist/default/kick.d.ts
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import Pusher from 'pusher-js';
|
|
2
2
|
import { type BadgeURLsByNameOrCount, type EmoteURLsByName, type Message } from './index.js';
|
|
3
|
+
type ConnectionState = 'initialized' | 'connecting' | 'connected' | 'unavailable' | 'failed';
|
|
4
|
+
type ConnectionStateEvent = {
|
|
5
|
+
previous: ConnectionState;
|
|
6
|
+
current: ConnectionState;
|
|
7
|
+
};
|
|
3
8
|
type EventCallbackFunctions = {
|
|
4
9
|
message: (message: Message) => unknown;
|
|
5
10
|
subscription: (data: ChatSubscriptionEvent) => unknown;
|
|
6
11
|
gifted: (data: ChatGiftedEvent) => unknown;
|
|
7
12
|
raw_message: (message: ChatMessageEvent) => unknown;
|
|
13
|
+
connection_state_changed: (state: ConnectionStateEvent) => unknown;
|
|
8
14
|
};
|
|
9
15
|
type EventNames = keyof EventCallbackFunctions;
|
|
10
16
|
export declare class KickPusher {
|
|
@@ -20,7 +26,7 @@ export declare class KickPusher {
|
|
|
20
26
|
getStoredExternalEmotes(): EmoteURLsByName;
|
|
21
27
|
connect(channel?: {
|
|
22
28
|
channelName?: string;
|
|
23
|
-
}): Promise<void>;
|
|
29
|
+
}, get_channel?: (channelName: string) => Promise<GetChannelResponse | undefined>): Promise<void>;
|
|
24
30
|
disconnect(): void;
|
|
25
31
|
on<EventName extends EventNames>(event_name: EventName, callback_fn: EventCallbackFunctions[EventName]): void;
|
|
26
32
|
private onSubscriptionSuccess;
|
|
@@ -163,8 +169,16 @@ export interface ChatMessageEvent {
|
|
|
163
169
|
id: string;
|
|
164
170
|
chatroom_id: number;
|
|
165
171
|
content: string;
|
|
166
|
-
type:
|
|
172
|
+
type: 'message' | 'celebration';
|
|
167
173
|
created_at: string;
|
|
174
|
+
metadata?: {
|
|
175
|
+
celebration: {
|
|
176
|
+
created_at: string;
|
|
177
|
+
id: string;
|
|
178
|
+
total_months: number;
|
|
179
|
+
type: 'subscription_renewed';
|
|
180
|
+
};
|
|
181
|
+
};
|
|
168
182
|
sender: {
|
|
169
183
|
id: number;
|
|
170
184
|
username: string;
|
package/dist/default/kick.js
CHANGED
|
@@ -37,15 +37,22 @@ export class KickPusher {
|
|
|
37
37
|
getStoredExternalEmotes() {
|
|
38
38
|
return this.assets.external_emotes;
|
|
39
39
|
}
|
|
40
|
-
async connect(channel) {
|
|
40
|
+
async connect(channel, get_channel = async (channelName) => {
|
|
41
|
+
const res = await fetch(`https://kick.com/api/v2/channels/${channelName}`, {
|
|
42
|
+
headers: {
|
|
43
|
+
accept: 'aplication/json',
|
|
44
|
+
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
const json = await res.json();
|
|
48
|
+
return json;
|
|
49
|
+
}) {
|
|
41
50
|
if (channel?.channelName)
|
|
42
51
|
this.channel_name = channel.channelName;
|
|
43
52
|
if (!this.channel_name)
|
|
44
53
|
return console.error('channel_name not specified');
|
|
45
54
|
console.log(`connecting to ${this.channel_name}...`);
|
|
46
|
-
const channel_response = await
|
|
47
|
-
.then((res) => res.json())
|
|
48
|
-
.then((json) => json);
|
|
55
|
+
const channel_response = await get_channel(this.channel_name);
|
|
49
56
|
if (!channel_response)
|
|
50
57
|
return console.error('Failed to connect to Kick.com chat');
|
|
51
58
|
channel_response.subscriber_badges.forEach((subscriber_badge) => {
|
|
@@ -60,10 +67,31 @@ export class KickPusher {
|
|
|
60
67
|
});
|
|
61
68
|
this.socket
|
|
62
69
|
.subscribe(`chatrooms.${channel_response.chatroom.id}.v2`)
|
|
63
|
-
.bind('pusher:subscription_succeeded', () => this.onSubscriptionSuccess())
|
|
70
|
+
.bind('pusher:subscription_succeeded', () => this.onSubscriptionSuccess('pusher:subscription_succeeded'))
|
|
64
71
|
.bind('App\\Events\\ChatMessageEvent', (data) => this.onChatMessage(data))
|
|
65
72
|
.bind('App\\Events\\SubscriptionEvent', (data) => this.onChatSubscription(data))
|
|
66
73
|
.bind('App\\Events\\GiftedSubscriptionsEvent', (data) => this.onChatGifted(data));
|
|
74
|
+
this.socket.connection.bind('state_change', (state) => {
|
|
75
|
+
switch (state.current) {
|
|
76
|
+
case 'connected': {
|
|
77
|
+
console.log(`Connected to Kick Pusher (${this.channel_name})!`);
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
case 'connecting': {
|
|
81
|
+
console.log(`Connecting to Kick Pusher (${this.channel_name})...`);
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
case 'failed': {
|
|
85
|
+
console.log(`Failed to connect to Kick Pusher (${this.channel_name})`);
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
case 'unavailable': {
|
|
89
|
+
console.log(`Disconnected from Kick Pusher (${this.channel_name})`);
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
this.public_listeners.connection_state_changed?.(state);
|
|
94
|
+
});
|
|
67
95
|
}
|
|
68
96
|
disconnect() {
|
|
69
97
|
this.socket?.disconnect();
|
|
@@ -72,8 +100,8 @@ export class KickPusher {
|
|
|
72
100
|
on(event_name, callback_fn) {
|
|
73
101
|
this.public_listeners[event_name] = callback_fn;
|
|
74
102
|
}
|
|
75
|
-
onSubscriptionSuccess() {
|
|
76
|
-
console.log(`
|
|
103
|
+
onSubscriptionSuccess(channel) {
|
|
104
|
+
console.log(`Subscribed to Channel on Kick Pusher (${channel})`);
|
|
77
105
|
}
|
|
78
106
|
onChatSubscription(data) {
|
|
79
107
|
this.public_listeners.subscription?.(data);
|
|
@@ -85,7 +113,6 @@ export class KickPusher {
|
|
|
85
113
|
this.public_listeners.raw_message?.(data);
|
|
86
114
|
const text = data.content;
|
|
87
115
|
const emote_matches = [...data.content.matchAll(/\[emote:\d+:[a-zA-Z0-9]*\]/g)];
|
|
88
|
-
console.log(emote_matches);
|
|
89
116
|
const body = [];
|
|
90
117
|
emote_matches.forEach((match) => {
|
|
91
118
|
const emote_string = match[0];
|
|
@@ -135,7 +162,7 @@ export class KickPusher {
|
|
|
135
162
|
});
|
|
136
163
|
}
|
|
137
164
|
body.sort((a, b) => a.start_inclusive - b.start_inclusive);
|
|
138
|
-
|
|
165
|
+
const message = {
|
|
139
166
|
id: data.id,
|
|
140
167
|
user: {
|
|
141
168
|
id: `${data.sender.id}`,
|
|
@@ -172,6 +199,14 @@ export class KickPusher {
|
|
|
172
199
|
},
|
|
173
200
|
raw_text: data.content,
|
|
174
201
|
timestamp_sent: Date.parse(data.created_at),
|
|
175
|
-
}
|
|
202
|
+
};
|
|
203
|
+
if (data.type === 'celebration' && data.metadata?.celebration) {
|
|
204
|
+
message.resubscription = {
|
|
205
|
+
id: data.metadata.celebration.id,
|
|
206
|
+
months: data.metadata.celebration.total_months,
|
|
207
|
+
subscribed_since_timestamp: data.metadata.celebration.created_at,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
this.public_listeners.message?.(message);
|
|
176
211
|
}
|
|
177
212
|
}
|
package/dist/worker/index.d.ts
CHANGED
package/dist/worker/kick.d.ts
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import Pusher from 'pusher-js/worker';
|
|
2
2
|
import { type BadgeURLsByNameOrCount, type EmoteURLsByName, type Message } from './index.js';
|
|
3
|
+
type ConnectionState = 'initialized' | 'connecting' | 'connected' | 'unavailable' | 'failed';
|
|
4
|
+
type ConnectionStateEvent = {
|
|
5
|
+
previous: ConnectionState;
|
|
6
|
+
current: ConnectionState;
|
|
7
|
+
};
|
|
3
8
|
type EventCallbackFunctions = {
|
|
4
9
|
message: (message: Message) => unknown;
|
|
5
10
|
subscription: (data: ChatSubscriptionEvent) => unknown;
|
|
6
11
|
gifted: (data: ChatGiftedEvent) => unknown;
|
|
7
12
|
raw_message: (message: ChatMessageEvent) => unknown;
|
|
13
|
+
connection_state_changed: (state: ConnectionStateEvent) => unknown;
|
|
8
14
|
};
|
|
9
15
|
type EventNames = keyof EventCallbackFunctions;
|
|
10
16
|
export declare class KickPusher {
|
|
@@ -20,7 +26,7 @@ export declare class KickPusher {
|
|
|
20
26
|
getStoredExternalEmotes(): EmoteURLsByName;
|
|
21
27
|
connect(channel?: {
|
|
22
28
|
channelName?: string;
|
|
23
|
-
}): Promise<void>;
|
|
29
|
+
}, get_channel?: (channelName: string) => Promise<GetChannelResponse | undefined>): Promise<void>;
|
|
24
30
|
disconnect(): void;
|
|
25
31
|
on<EventName extends EventNames>(event_name: EventName, callback_fn: EventCallbackFunctions[EventName]): void;
|
|
26
32
|
private onSubscriptionSuccess;
|
|
@@ -163,8 +169,16 @@ export interface ChatMessageEvent {
|
|
|
163
169
|
id: string;
|
|
164
170
|
chatroom_id: number;
|
|
165
171
|
content: string;
|
|
166
|
-
type:
|
|
172
|
+
type: 'message' | 'celebration';
|
|
167
173
|
created_at: string;
|
|
174
|
+
metadata?: {
|
|
175
|
+
celebration: {
|
|
176
|
+
created_at: string;
|
|
177
|
+
id: string;
|
|
178
|
+
total_months: number;
|
|
179
|
+
type: 'subscription_renewed';
|
|
180
|
+
};
|
|
181
|
+
};
|
|
168
182
|
sender: {
|
|
169
183
|
id: number;
|
|
170
184
|
username: string;
|
package/dist/worker/kick.js
CHANGED
|
@@ -37,20 +37,22 @@ export class KickPusher {
|
|
|
37
37
|
getStoredExternalEmotes() {
|
|
38
38
|
return this.assets.external_emotes;
|
|
39
39
|
}
|
|
40
|
-
async connect(channel) {
|
|
40
|
+
async connect(channel, get_channel = async (channelName) => {
|
|
41
|
+
const res = await fetch(`https://kick.com/api/v2/channels/${channelName}`, {
|
|
42
|
+
headers: {
|
|
43
|
+
accept: 'aplication/json',
|
|
44
|
+
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
const json = await res.json();
|
|
48
|
+
return json;
|
|
49
|
+
}) {
|
|
41
50
|
if (channel?.channelName)
|
|
42
51
|
this.channel_name = channel.channelName;
|
|
43
52
|
if (!this.channel_name)
|
|
44
53
|
return console.error('channel_name not specified');
|
|
45
54
|
console.log(`connecting to ${this.channel_name}...`);
|
|
46
|
-
const channel_response = await
|
|
47
|
-
headers: {
|
|
48
|
-
accept: 'aplication/json',
|
|
49
|
-
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
|
|
50
|
-
},
|
|
51
|
-
})
|
|
52
|
-
.then((res) => res.json())
|
|
53
|
-
.then((json) => json);
|
|
55
|
+
const channel_response = await get_channel(this.channel_name);
|
|
54
56
|
if (!channel_response)
|
|
55
57
|
return console.error('Failed to connect to Kick.com chat');
|
|
56
58
|
channel_response.subscriber_badges.forEach((subscriber_badge) => {
|
|
@@ -65,10 +67,31 @@ export class KickPusher {
|
|
|
65
67
|
});
|
|
66
68
|
this.socket
|
|
67
69
|
.subscribe(`chatrooms.${channel_response.chatroom.id}.v2`)
|
|
68
|
-
.bind('pusher:subscription_succeeded', () => this.onSubscriptionSuccess())
|
|
70
|
+
.bind('pusher:subscription_succeeded', () => this.onSubscriptionSuccess('pusher:subscription_succeeded'))
|
|
69
71
|
.bind('App\\Events\\ChatMessageEvent', (data) => this.onChatMessage(data))
|
|
70
72
|
.bind('App\\Events\\SubscriptionEvent', (data) => this.onChatSubscription(data))
|
|
71
73
|
.bind('App\\Events\\GiftedSubscriptionsEvent', (data) => this.onChatGifted(data));
|
|
74
|
+
this.socket.connection.bind('state_change', (state) => {
|
|
75
|
+
switch (state.current) {
|
|
76
|
+
case 'connected': {
|
|
77
|
+
console.log(`Connected to Kick Pusher (${this.channel_name})!`);
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
case 'connecting': {
|
|
81
|
+
console.log(`Connecting to Kick Pusher (${this.channel_name})...`);
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
case 'failed': {
|
|
85
|
+
console.log(`Failed to connect to Kick Pusher (${this.channel_name})`);
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
case 'unavailable': {
|
|
89
|
+
console.log(`Disconnected from Kick Pusher (${this.channel_name})`);
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
this.public_listeners.connection_state_changed?.(state);
|
|
94
|
+
});
|
|
72
95
|
}
|
|
73
96
|
disconnect() {
|
|
74
97
|
this.socket?.disconnect();
|
|
@@ -77,8 +100,8 @@ export class KickPusher {
|
|
|
77
100
|
on(event_name, callback_fn) {
|
|
78
101
|
this.public_listeners[event_name] = callback_fn;
|
|
79
102
|
}
|
|
80
|
-
onSubscriptionSuccess() {
|
|
81
|
-
console.log(`
|
|
103
|
+
onSubscriptionSuccess(channel) {
|
|
104
|
+
console.log(`Subscribed to Channel on Kick Pusher (${channel})`);
|
|
82
105
|
}
|
|
83
106
|
onChatSubscription(data) {
|
|
84
107
|
this.public_listeners.subscription?.(data);
|
|
@@ -90,7 +113,6 @@ export class KickPusher {
|
|
|
90
113
|
this.public_listeners.raw_message?.(data);
|
|
91
114
|
const text = data.content;
|
|
92
115
|
const emote_matches = [...data.content.matchAll(/\[emote:\d+:[a-zA-Z0-9]*\]/g)];
|
|
93
|
-
console.log(emote_matches);
|
|
94
116
|
const body = [];
|
|
95
117
|
emote_matches.forEach((match) => {
|
|
96
118
|
const emote_string = match[0];
|
|
@@ -140,7 +162,7 @@ export class KickPusher {
|
|
|
140
162
|
});
|
|
141
163
|
}
|
|
142
164
|
body.sort((a, b) => a.start_inclusive - b.start_inclusive);
|
|
143
|
-
|
|
165
|
+
const message = {
|
|
144
166
|
id: data.id,
|
|
145
167
|
user: {
|
|
146
168
|
id: `${data.sender.id}`,
|
|
@@ -177,6 +199,14 @@ export class KickPusher {
|
|
|
177
199
|
},
|
|
178
200
|
raw_text: data.content,
|
|
179
201
|
timestamp_sent: Date.parse(data.created_at),
|
|
180
|
-
}
|
|
202
|
+
};
|
|
203
|
+
if (data.type === 'celebration' && data.metadata?.celebration) {
|
|
204
|
+
message.resubscription = {
|
|
205
|
+
id: data.metadata.celebration.id,
|
|
206
|
+
months: data.metadata.celebration.total_months,
|
|
207
|
+
subscribed_since_timestamp: data.metadata.celebration.created_at,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
this.public_listeners.message?.(message);
|
|
181
211
|
}
|
|
182
212
|
}
|
package/package.json
CHANGED
package/src/default/index.ts
CHANGED
package/src/default/kick.ts
CHANGED
|
@@ -7,11 +7,15 @@ import {
|
|
|
7
7
|
type Message,
|
|
8
8
|
} from './index.js';
|
|
9
9
|
|
|
10
|
+
type ConnectionState = 'initialized' | 'connecting' | 'connected' | 'unavailable' | 'failed';
|
|
11
|
+
type ConnectionStateEvent = { previous: ConnectionState; current: ConnectionState };
|
|
12
|
+
|
|
10
13
|
type EventCallbackFunctions = {
|
|
11
14
|
message: (message: Message) => unknown;
|
|
12
15
|
subscription: (data: ChatSubscriptionEvent) => unknown;
|
|
13
16
|
gifted: (data: ChatGiftedEvent) => unknown;
|
|
14
17
|
raw_message: (message: ChatMessageEvent) => unknown;
|
|
18
|
+
connection_state_changed: (state: ConnectionStateEvent) => unknown;
|
|
15
19
|
};
|
|
16
20
|
|
|
17
21
|
type EventNames = keyof EventCallbackFunctions;
|
|
@@ -65,15 +69,28 @@ export class KickPusher {
|
|
|
65
69
|
return this.assets.external_emotes;
|
|
66
70
|
}
|
|
67
71
|
|
|
68
|
-
public async connect(
|
|
72
|
+
public async connect(
|
|
73
|
+
channel?: { channelName?: string },
|
|
74
|
+
get_channel: (channelName: string) => Promise<GetChannelResponse | undefined> = async (
|
|
75
|
+
channelName,
|
|
76
|
+
) => {
|
|
77
|
+
const res = await fetch(`https://kick.com/api/v2/channels/${channelName}`, {
|
|
78
|
+
headers: {
|
|
79
|
+
accept: 'aplication/json',
|
|
80
|
+
'user-agent':
|
|
81
|
+
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
const json = await res.json();
|
|
85
|
+
return json as GetChannelResponse | undefined;
|
|
86
|
+
},
|
|
87
|
+
) {
|
|
69
88
|
if (channel?.channelName) this.channel_name = channel.channelName;
|
|
70
89
|
if (!this.channel_name) return console.error('channel_name not specified');
|
|
71
90
|
|
|
72
91
|
console.log(`connecting to ${this.channel_name}...`);
|
|
73
92
|
|
|
74
|
-
const channel_response = await
|
|
75
|
-
.then((res) => res.json())
|
|
76
|
-
.then((json) => json as GetChannelResponse | undefined);
|
|
93
|
+
const channel_response = await get_channel(this.channel_name);
|
|
77
94
|
|
|
78
95
|
if (!channel_response) return console.error('Failed to connect to Kick.com chat');
|
|
79
96
|
|
|
@@ -89,7 +106,6 @@ export class KickPusher {
|
|
|
89
106
|
this.socket = new Pusher(this.kick_pusher_key, {
|
|
90
107
|
cluster: 'us2',
|
|
91
108
|
});
|
|
92
|
-
|
|
93
109
|
/*
|
|
94
110
|
| 'App\\Events\\ChatMessageEvent'
|
|
95
111
|
| 'App\\Events\\ChatroomClearEvent'
|
|
@@ -107,7 +123,9 @@ export class KickPusher {
|
|
|
107
123
|
*/
|
|
108
124
|
this.socket
|
|
109
125
|
.subscribe(`chatrooms.${channel_response.chatroom.id}.v2`)
|
|
110
|
-
.bind('pusher:subscription_succeeded', () =>
|
|
126
|
+
.bind('pusher:subscription_succeeded', () =>
|
|
127
|
+
this.onSubscriptionSuccess('pusher:subscription_succeeded'),
|
|
128
|
+
)
|
|
111
129
|
.bind('App\\Events\\ChatMessageEvent', (data: ChatMessageEvent) => this.onChatMessage(data))
|
|
112
130
|
.bind('App\\Events\\SubscriptionEvent', (data: ChatSubscriptionEvent) =>
|
|
113
131
|
this.onChatSubscription(data),
|
|
@@ -115,6 +133,28 @@ export class KickPusher {
|
|
|
115
133
|
.bind('App\\Events\\GiftedSubscriptionsEvent', (data: ChatGiftedEvent) =>
|
|
116
134
|
this.onChatGifted(data),
|
|
117
135
|
);
|
|
136
|
+
|
|
137
|
+
this.socket.connection.bind('state_change', (state: ConnectionStateEvent) => {
|
|
138
|
+
switch (state.current) {
|
|
139
|
+
case 'connected': {
|
|
140
|
+
console.log(`Connected to Kick Pusher (${this.channel_name})!`);
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
case 'connecting': {
|
|
144
|
+
console.log(`Connecting to Kick Pusher (${this.channel_name})...`);
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
case 'failed': {
|
|
148
|
+
console.log(`Failed to connect to Kick Pusher (${this.channel_name})`);
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
case 'unavailable': {
|
|
152
|
+
console.log(`Disconnected from Kick Pusher (${this.channel_name})`);
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
this.public_listeners.connection_state_changed?.(state);
|
|
157
|
+
});
|
|
118
158
|
}
|
|
119
159
|
|
|
120
160
|
public disconnect() {
|
|
@@ -129,8 +169,8 @@ export class KickPusher {
|
|
|
129
169
|
this.public_listeners[event_name] = callback_fn;
|
|
130
170
|
}
|
|
131
171
|
|
|
132
|
-
private onSubscriptionSuccess() {
|
|
133
|
-
console.log(`
|
|
172
|
+
private onSubscriptionSuccess(channel: string) {
|
|
173
|
+
console.log(`Subscribed to Channel on Kick Pusher (${channel})`);
|
|
134
174
|
}
|
|
135
175
|
|
|
136
176
|
private onChatSubscription(data: ChatSubscriptionEvent) {
|
|
@@ -145,7 +185,6 @@ export class KickPusher {
|
|
|
145
185
|
this.public_listeners.raw_message?.(data);
|
|
146
186
|
const text = data.content;
|
|
147
187
|
const emote_matches = [...data.content.matchAll(/\[emote:\d+:[a-zA-Z0-9]*\]/g)];
|
|
148
|
-
console.log(emote_matches);
|
|
149
188
|
|
|
150
189
|
const body: BodyComponent[] = [];
|
|
151
190
|
|
|
@@ -203,8 +242,7 @@ export class KickPusher {
|
|
|
203
242
|
}
|
|
204
243
|
|
|
205
244
|
body.sort((a, b) => a.start_inclusive - b.start_inclusive);
|
|
206
|
-
|
|
207
|
-
this.public_listeners.message?.({
|
|
245
|
+
const message: Message = {
|
|
208
246
|
id: data.id,
|
|
209
247
|
user: {
|
|
210
248
|
id: `${data.sender.id}`,
|
|
@@ -241,7 +279,16 @@ export class KickPusher {
|
|
|
241
279
|
},
|
|
242
280
|
raw_text: data.content,
|
|
243
281
|
timestamp_sent: Date.parse(data.created_at),
|
|
244
|
-
}
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
if (data.type === 'celebration' && data.metadata?.celebration) {
|
|
285
|
+
message.resubscription = {
|
|
286
|
+
id: data.metadata.celebration.id,
|
|
287
|
+
months: data.metadata.celebration.total_months,
|
|
288
|
+
subscribed_since_timestamp: data.metadata.celebration.created_at,
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
this.public_listeners.message?.(message);
|
|
245
292
|
}
|
|
246
293
|
}
|
|
247
294
|
|
|
@@ -381,8 +428,16 @@ export interface ChatMessageEvent {
|
|
|
381
428
|
id: string;
|
|
382
429
|
chatroom_id: number;
|
|
383
430
|
content: string;
|
|
384
|
-
type:
|
|
431
|
+
type: 'message' | 'celebration';
|
|
385
432
|
created_at: string;
|
|
433
|
+
metadata?: {
|
|
434
|
+
celebration: {
|
|
435
|
+
created_at: string;
|
|
436
|
+
id: string;
|
|
437
|
+
total_months: number;
|
|
438
|
+
type: 'subscription_renewed';
|
|
439
|
+
};
|
|
440
|
+
};
|
|
386
441
|
sender: {
|
|
387
442
|
id: number;
|
|
388
443
|
username: string;
|
package/src/worker/index.ts
CHANGED
package/src/worker/kick.ts
CHANGED
|
@@ -7,11 +7,15 @@ import {
|
|
|
7
7
|
type Message,
|
|
8
8
|
} from './index.js';
|
|
9
9
|
|
|
10
|
+
type ConnectionState = 'initialized' | 'connecting' | 'connected' | 'unavailable' | 'failed';
|
|
11
|
+
type ConnectionStateEvent = { previous: ConnectionState; current: ConnectionState };
|
|
12
|
+
|
|
10
13
|
type EventCallbackFunctions = {
|
|
11
14
|
message: (message: Message) => unknown;
|
|
12
15
|
subscription: (data: ChatSubscriptionEvent) => unknown;
|
|
13
16
|
gifted: (data: ChatGiftedEvent) => unknown;
|
|
14
17
|
raw_message: (message: ChatMessageEvent) => unknown;
|
|
18
|
+
connection_state_changed: (state: ConnectionStateEvent) => unknown;
|
|
15
19
|
};
|
|
16
20
|
|
|
17
21
|
type EventNames = keyof EventCallbackFunctions;
|
|
@@ -65,21 +69,28 @@ export class KickPusher {
|
|
|
65
69
|
return this.assets.external_emotes;
|
|
66
70
|
}
|
|
67
71
|
|
|
68
|
-
public async connect(
|
|
72
|
+
public async connect(
|
|
73
|
+
channel?: { channelName?: string },
|
|
74
|
+
get_channel: (channelName: string) => Promise<GetChannelResponse | undefined> = async (
|
|
75
|
+
channelName,
|
|
76
|
+
) => {
|
|
77
|
+
const res = await fetch(`https://kick.com/api/v2/channels/${channelName}`, {
|
|
78
|
+
headers: {
|
|
79
|
+
accept: 'aplication/json',
|
|
80
|
+
'user-agent':
|
|
81
|
+
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
const json = await res.json();
|
|
85
|
+
return json as GetChannelResponse | undefined;
|
|
86
|
+
},
|
|
87
|
+
) {
|
|
69
88
|
if (channel?.channelName) this.channel_name = channel.channelName;
|
|
70
89
|
if (!this.channel_name) return console.error('channel_name not specified');
|
|
71
90
|
|
|
72
91
|
console.log(`connecting to ${this.channel_name}...`);
|
|
73
92
|
|
|
74
|
-
const channel_response = await
|
|
75
|
-
headers: {
|
|
76
|
-
accept: 'aplication/json',
|
|
77
|
-
'user-agent':
|
|
78
|
-
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
|
|
79
|
-
},
|
|
80
|
-
})
|
|
81
|
-
.then((res) => res.json())
|
|
82
|
-
.then((json) => json as GetChannelResponse | undefined);
|
|
93
|
+
const channel_response = await get_channel(this.channel_name);
|
|
83
94
|
|
|
84
95
|
if (!channel_response) return console.error('Failed to connect to Kick.com chat');
|
|
85
96
|
|
|
@@ -95,7 +106,6 @@ export class KickPusher {
|
|
|
95
106
|
this.socket = new Pusher(this.kick_pusher_key, {
|
|
96
107
|
cluster: 'us2',
|
|
97
108
|
});
|
|
98
|
-
|
|
99
109
|
/*
|
|
100
110
|
| 'App\\Events\\ChatMessageEvent'
|
|
101
111
|
| 'App\\Events\\ChatroomClearEvent'
|
|
@@ -113,7 +123,9 @@ export class KickPusher {
|
|
|
113
123
|
*/
|
|
114
124
|
this.socket
|
|
115
125
|
.subscribe(`chatrooms.${channel_response.chatroom.id}.v2`)
|
|
116
|
-
.bind('pusher:subscription_succeeded', () =>
|
|
126
|
+
.bind('pusher:subscription_succeeded', () =>
|
|
127
|
+
this.onSubscriptionSuccess('pusher:subscription_succeeded'),
|
|
128
|
+
)
|
|
117
129
|
.bind('App\\Events\\ChatMessageEvent', (data: ChatMessageEvent) => this.onChatMessage(data))
|
|
118
130
|
.bind('App\\Events\\SubscriptionEvent', (data: ChatSubscriptionEvent) =>
|
|
119
131
|
this.onChatSubscription(data),
|
|
@@ -121,6 +133,28 @@ export class KickPusher {
|
|
|
121
133
|
.bind('App\\Events\\GiftedSubscriptionsEvent', (data: ChatGiftedEvent) =>
|
|
122
134
|
this.onChatGifted(data),
|
|
123
135
|
);
|
|
136
|
+
|
|
137
|
+
this.socket.connection.bind('state_change', (state: ConnectionStateEvent) => {
|
|
138
|
+
switch (state.current) {
|
|
139
|
+
case 'connected': {
|
|
140
|
+
console.log(`Connected to Kick Pusher (${this.channel_name})!`);
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
case 'connecting': {
|
|
144
|
+
console.log(`Connecting to Kick Pusher (${this.channel_name})...`);
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
case 'failed': {
|
|
148
|
+
console.log(`Failed to connect to Kick Pusher (${this.channel_name})`);
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
case 'unavailable': {
|
|
152
|
+
console.log(`Disconnected from Kick Pusher (${this.channel_name})`);
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
this.public_listeners.connection_state_changed?.(state);
|
|
157
|
+
});
|
|
124
158
|
}
|
|
125
159
|
|
|
126
160
|
public disconnect() {
|
|
@@ -135,8 +169,8 @@ export class KickPusher {
|
|
|
135
169
|
this.public_listeners[event_name] = callback_fn;
|
|
136
170
|
}
|
|
137
171
|
|
|
138
|
-
private onSubscriptionSuccess() {
|
|
139
|
-
console.log(`
|
|
172
|
+
private onSubscriptionSuccess(channel: string) {
|
|
173
|
+
console.log(`Subscribed to Channel on Kick Pusher (${channel})`);
|
|
140
174
|
}
|
|
141
175
|
|
|
142
176
|
private onChatSubscription(data: ChatSubscriptionEvent) {
|
|
@@ -151,7 +185,6 @@ export class KickPusher {
|
|
|
151
185
|
this.public_listeners.raw_message?.(data);
|
|
152
186
|
const text = data.content;
|
|
153
187
|
const emote_matches = [...data.content.matchAll(/\[emote:\d+:[a-zA-Z0-9]*\]/g)];
|
|
154
|
-
console.log(emote_matches);
|
|
155
188
|
|
|
156
189
|
const body: BodyComponent[] = [];
|
|
157
190
|
|
|
@@ -209,8 +242,7 @@ export class KickPusher {
|
|
|
209
242
|
}
|
|
210
243
|
|
|
211
244
|
body.sort((a, b) => a.start_inclusive - b.start_inclusive);
|
|
212
|
-
|
|
213
|
-
this.public_listeners.message?.({
|
|
245
|
+
const message: Message = {
|
|
214
246
|
id: data.id,
|
|
215
247
|
user: {
|
|
216
248
|
id: `${data.sender.id}`,
|
|
@@ -247,7 +279,16 @@ export class KickPusher {
|
|
|
247
279
|
},
|
|
248
280
|
raw_text: data.content,
|
|
249
281
|
timestamp_sent: Date.parse(data.created_at),
|
|
250
|
-
}
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
if (data.type === 'celebration' && data.metadata?.celebration) {
|
|
285
|
+
message.resubscription = {
|
|
286
|
+
id: data.metadata.celebration.id,
|
|
287
|
+
months: data.metadata.celebration.total_months,
|
|
288
|
+
subscribed_since_timestamp: data.metadata.celebration.created_at,
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
this.public_listeners.message?.(message);
|
|
251
292
|
}
|
|
252
293
|
}
|
|
253
294
|
|
|
@@ -387,8 +428,16 @@ export interface ChatMessageEvent {
|
|
|
387
428
|
id: string;
|
|
388
429
|
chatroom_id: number;
|
|
389
430
|
content: string;
|
|
390
|
-
type:
|
|
431
|
+
type: 'message' | 'celebration';
|
|
391
432
|
created_at: string;
|
|
433
|
+
metadata?: {
|
|
434
|
+
celebration: {
|
|
435
|
+
created_at: string;
|
|
436
|
+
id: string;
|
|
437
|
+
total_months: number;
|
|
438
|
+
type: 'subscription_renewed';
|
|
439
|
+
};
|
|
440
|
+
};
|
|
392
441
|
sender: {
|
|
393
442
|
id: number;
|
|
394
443
|
username: string;
|