@overlaysymphony/twitch 0.3.3 → 0.4.0
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/package.json +3 -2
- package/src/authentication/authentication.ts +2 -2
- package/src/chat/chat.ts +6 -2
- package/src/eventsub/events/automod.message.hold-2.ts +3 -3
- package/src/eventsub/events/automod.message.update-2.ts +3 -3
- package/src/eventsub/events/automod.settings.update-1.ts +3 -3
- package/src/eventsub/events/automod.terms.update-1.ts +3 -3
- package/src/eventsub/events/channel.ad_break.begin-1.ts +2 -2
- package/src/eventsub/events/channel.ban-1.ts +2 -2
- package/src/eventsub/events/channel.bits.use-1.ts +2 -2
- package/src/eventsub/events/channel.channel_points_automatic_reward_redemption.add-2.ts +2 -2
- package/src/eventsub/events/channel.channel_points_custom_reward.add-1.ts +2 -2
- package/src/eventsub/events/channel.channel_points_custom_reward.remove-1.ts +2 -2
- package/src/eventsub/events/channel.channel_points_custom_reward.update-1.ts +2 -2
- package/src/eventsub/events/channel.channel_points_custom_reward_redemption.add-1.ts +2 -2
- package/src/eventsub/events/channel.channel_points_custom_reward_redemption.update-1.ts +2 -2
- package/src/eventsub/events/channel.charity_campaign.donate-1.ts +2 -2
- package/src/eventsub/events/channel.charity_campaign.progress-1.ts +2 -2
- package/src/eventsub/events/channel.charity_campaign.start-1.ts +2 -2
- package/src/eventsub/events/channel.charity_campaign.stop-1.ts +2 -2
- package/src/eventsub/events/channel.chat.clear-1.ts +3 -3
- package/src/eventsub/events/channel.chat.clear_user_messages-1.ts +3 -3
- package/src/eventsub/events/channel.chat.message-1.ts +3 -3
- package/src/eventsub/events/channel.chat.message_delete-1.ts +3 -3
- package/src/eventsub/events/channel.chat.notification-1.ts +3 -3
- package/src/eventsub/events/channel.chat.user_message_hold-1.ts +3 -3
- package/src/eventsub/events/channel.chat.user_message_update-1.ts +3 -3
- package/src/eventsub/events/channel.chat_settings.update-1.ts +3 -3
- package/src/eventsub/events/channel.cheer-1.ts +2 -2
- package/src/eventsub/events/channel.follow-2.ts +3 -3
- package/src/eventsub/events/channel.goal.begin-1.ts +2 -2
- package/src/eventsub/events/channel.goal.end-1.ts +2 -2
- package/src/eventsub/events/channel.goal.progress-1.ts +2 -2
- package/src/eventsub/events/channel.guest_star_guest.update-beta.ts +3 -3
- package/src/eventsub/events/channel.guest_star_session.begin-beta.ts +3 -3
- package/src/eventsub/events/channel.guest_star_session.end-beta.ts +3 -3
- package/src/eventsub/events/channel.guest_star_settings.update-beta.ts +3 -3
- package/src/eventsub/events/channel.hype_train.begin-2.ts +2 -2
- package/src/eventsub/events/channel.hype_train.end-2.ts +2 -2
- package/src/eventsub/events/channel.hype_train.progress-2.ts +2 -2
- package/src/eventsub/events/channel.moderate-2.ts +3 -3
- package/src/eventsub/events/channel.moderator.add-1.ts +2 -2
- package/src/eventsub/events/channel.moderator.remove-1.ts +2 -2
- package/src/eventsub/events/channel.poll.begin-1.ts +2 -2
- package/src/eventsub/events/channel.poll.end-1.ts +2 -2
- package/src/eventsub/events/channel.poll.progress-1.ts +2 -2
- package/src/eventsub/events/channel.prediction.begin-1.ts +2 -2
- package/src/eventsub/events/channel.prediction.end-1.ts +2 -2
- package/src/eventsub/events/channel.prediction.lock-1.ts +2 -2
- package/src/eventsub/events/channel.prediction.progress-1.ts +2 -2
- package/src/eventsub/events/channel.raid-1.ts +2 -2
- package/src/eventsub/events/channel.shared_chat.begin-1.ts +2 -2
- package/src/eventsub/events/channel.shared_chat.end-1.ts +2 -2
- package/src/eventsub/events/channel.shared_chat.update-1.ts +2 -2
- package/src/eventsub/events/channel.shield_mode.begin-1.ts +3 -3
- package/src/eventsub/events/channel.shield_mode.end-1.ts +3 -3
- package/src/eventsub/events/channel.shoutout.create-1.ts +3 -3
- package/src/eventsub/events/channel.shoutout.receive-1.ts +3 -3
- package/src/eventsub/events/channel.subscribe-1.ts +2 -2
- package/src/eventsub/events/channel.subscription.end-1.ts +2 -2
- package/src/eventsub/events/channel.subscription.gift-1.ts +2 -2
- package/src/eventsub/events/channel.subscription.message-1.ts +2 -2
- package/src/eventsub/events/channel.suspicious_user.message-1.ts +3 -3
- package/src/eventsub/events/channel.suspicious_user.update-1.ts +3 -3
- package/src/eventsub/events/channel.unban-1.ts +2 -2
- package/src/eventsub/events/channel.unban_request.create-1.ts +3 -3
- package/src/eventsub/events/channel.unban_request.resolve-1.ts +3 -3
- package/src/eventsub/events/channel.update-2.ts +2 -2
- package/src/eventsub/events/channel.vip.add-1.ts +2 -2
- package/src/eventsub/events/channel.vip.remove-1.ts +2 -2
- package/src/eventsub/events/channel.warning.acknowledge-1.ts +3 -3
- package/src/eventsub/events/channel.warning.send-1.ts +3 -3
- package/src/eventsub/events/stream.offline-1.ts +2 -2
- package/src/eventsub/events/stream.online-1.ts +2 -2
- package/src/eventsub/events/user.update-1.ts +2 -2
- package/src/eventsub/events/user.whisper.message-1.ts +2 -2
- package/src/eventsub/events-helpers.ts +11 -4
- package/src/eventsub/eventsub.ts +52 -34
- package/src/eventsub/index.ts +1 -0
- package/src/helix/chat/emotes.ts +59 -22
- package/src/helix/index.ts +1 -0
- package/src/helix/streams/index.ts +1 -0
- package/src/helix/streams/streams.ts +48 -0
- package/src/helix/users/users.ts +51 -0
- package/src/helpers/alerts/alerts.ts +3 -3
- package/src/helpers/charity/charity.ts +2 -2
- package/src/helpers/goal/goal.ts +2 -2
- package/src/helpers/hype-train/hype-train.ts +2 -2
- package/src/helpers/poll/poll.ts +2 -2
- package/src/helpers/prediction/prediction.ts +2 -2
- package/src/helpers/redemption/redemption.ts +2 -2
- package/src/helpers/status/status.ts +2 -2
package/src/eventsub/eventsub.ts
CHANGED
|
@@ -9,42 +9,60 @@ import { createSubscription } from "../helix/subscriptions/index.ts"
|
|
|
9
9
|
import { type EventPayload, buildSubscription } from "./events-helpers.ts"
|
|
10
10
|
import { type TwitchMessage } from "./messages.ts"
|
|
11
11
|
|
|
12
|
-
export type TwitchEventSub = Events<EventPayload>
|
|
12
|
+
export type TwitchEventSub = Events<EventPayload> & {
|
|
13
|
+
targetUserId: string
|
|
14
|
+
}
|
|
13
15
|
|
|
16
|
+
// TODO: connection instead of authentication
|
|
14
17
|
export default async function createEventSub(
|
|
15
18
|
authentication: Authentication,
|
|
19
|
+
targetUserId?: string,
|
|
16
20
|
): Promise<TwitchEventSub> {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
|
|
21
|
+
const currentUserId = authentication.user.id
|
|
22
|
+
targetUserId ??= currentUserId
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
targetUserId,
|
|
26
|
+
...(await createEvents<EventPayload, string>(
|
|
27
|
+
async (pubsub) => {
|
|
28
|
+
const socket = new WebSocket("wss://eventsub.wss.twitch.tv/ws")
|
|
29
|
+
|
|
30
|
+
const { promise, resolve } = createDefer<string>()
|
|
31
|
+
socket.addEventListener("message", ({ data: rawData }) => {
|
|
32
|
+
const data = JSON.parse(rawData as string) as TwitchMessage
|
|
33
|
+
data.type = data.metadata.message_type
|
|
34
|
+
|
|
35
|
+
if (data.type === "session_welcome") {
|
|
36
|
+
resolve(data.payload.session.id)
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (data.type === "notification") {
|
|
41
|
+
data.payload.id = data.metadata.message_id
|
|
42
|
+
data.payload.type = data.payload.subscription.type
|
|
43
|
+
|
|
44
|
+
pubsub.dispatch(data.payload)
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
return await promise
|
|
50
|
+
},
|
|
51
|
+
async (pubsub, sessionId, type) => {
|
|
52
|
+
await createSubscription(
|
|
53
|
+
authentication,
|
|
54
|
+
{ method: "websocket", session_id: sessionId },
|
|
55
|
+
buildSubscription(type, currentUserId, targetUserId),
|
|
56
|
+
)
|
|
57
|
+
},
|
|
58
|
+
(type) => {
|
|
59
|
+
const subscription = buildSubscription(
|
|
60
|
+
type,
|
|
61
|
+
currentUserId,
|
|
62
|
+
targetUserId,
|
|
63
|
+
)
|
|
64
|
+
return `${type}-${JSON.stringify(subscription)}`
|
|
65
|
+
},
|
|
66
|
+
)),
|
|
67
|
+
}
|
|
50
68
|
}
|
package/src/eventsub/index.ts
CHANGED
package/src/helix/chat/emotes.ts
CHANGED
|
@@ -1,34 +1,37 @@
|
|
|
1
1
|
import { type Authentication } from "../../authentication/index.ts"
|
|
2
2
|
import { helix } from "../helix.ts"
|
|
3
3
|
|
|
4
|
-
interface
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
4
|
+
interface Emote {
|
|
5
|
+
/** An ID that identifies this emote. */
|
|
6
|
+
id: string
|
|
7
|
+
/** The name of the emote. This is the name that viewers type in the chat window to get the emote to appear. */
|
|
8
|
+
name: string
|
|
9
|
+
/** A generator for the image URLs for the emote. */
|
|
10
|
+
image: (config?: { format?: string; mode?: string; scale?: string }) => string
|
|
11
|
+
/** The subscriber tier at which the emote is unlocked. This field contains the tier information only if emote_type is set to subscriptions, otherwise, it's an empty string. */
|
|
12
|
+
tier: string
|
|
13
|
+
/** The type of emote. Possible values are:\n* bitstier — A custom Bits tier emote.\n* follower — A custom follower emote.\n* subscriptions — A custom subscriber emote. */
|
|
14
|
+
emote_type: string
|
|
15
|
+
/** An ID that identifies the emote set that the emote belongs to. */
|
|
16
|
+
emote_set_id: string
|
|
17
|
+
/** The ID of the broadcaster who owns the emote. */
|
|
18
|
+
owner_id: string
|
|
19
|
+
/** The formats that the emote is available in. Possible values are:\n* animated — An animated GIF is available for this emote.\n* static — A static PNG file is available for this emote. */
|
|
20
|
+
format: string[]
|
|
21
|
+
/** The sizes that the emote is available in.\n* 1.0 — A small version (28px x 28px) is available.\n* 2.0 — A medium version (56px x 56px) is available.\n* 3.0 — A large version (112px x 112px) is available. */
|
|
22
|
+
scale: string[]
|
|
23
|
+
/** The background themes that the emote is available in. Possible values are:\n* dark\n* light */
|
|
24
|
+
theme_mode: string[]
|
|
14
25
|
}
|
|
15
26
|
|
|
16
27
|
interface ChannelEmoteResponse {
|
|
17
|
-
data: Array<
|
|
18
|
-
Omit<ChannelEmote, "image"> & {
|
|
19
|
-
images: {
|
|
20
|
-
url_1x: string
|
|
21
|
-
url_2x: string
|
|
22
|
-
url_4x: string
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
>
|
|
28
|
+
data: Array<Omit<Emote, "image" | "owner_id">>
|
|
26
29
|
template: string
|
|
27
30
|
}
|
|
28
31
|
|
|
29
32
|
export async function getChannelEmotes(
|
|
30
33
|
authentication: Authentication,
|
|
31
|
-
): Promise<
|
|
34
|
+
): Promise<Emote[]> {
|
|
32
35
|
const { data: emotes, template } = await helix<
|
|
33
36
|
ChannelEmoteResponse,
|
|
34
37
|
{
|
|
@@ -42,8 +45,42 @@ export async function getChannelEmotes(
|
|
|
42
45
|
},
|
|
43
46
|
})
|
|
44
47
|
|
|
45
|
-
return emotes.map((
|
|
48
|
+
return emotes.map((emote) => ({
|
|
49
|
+
owner_id: authentication.user.id,
|
|
50
|
+
...emote,
|
|
51
|
+
image: ({ format, mode, scale } = {}) =>
|
|
52
|
+
template
|
|
53
|
+
.replace("{{id}}", emote.id)
|
|
54
|
+
.replace("{{format}}", format ?? emote.format[0])
|
|
55
|
+
.replace("{{theme_mode}}", mode ?? emote.theme_mode[0])
|
|
56
|
+
.replace("{{scale}}", scale ?? emote.scale[emote.scale.length - 1]),
|
|
57
|
+
}))
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export async function getUserEmotes(
|
|
61
|
+
authentication: Authentication,
|
|
62
|
+
): Promise<Emote[]> {
|
|
63
|
+
const { data: emotes, template } = await helix<
|
|
64
|
+
ChannelEmoteResponse,
|
|
65
|
+
{
|
|
66
|
+
user_id: string
|
|
67
|
+
}
|
|
68
|
+
>(authentication, {
|
|
69
|
+
method: "GET",
|
|
70
|
+
path: "/chat/emotes/user",
|
|
71
|
+
params: {
|
|
72
|
+
user_id: authentication.user.id,
|
|
73
|
+
},
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
return emotes.map((emote) => ({
|
|
77
|
+
owner_id: authentication.user.id,
|
|
46
78
|
...emote,
|
|
47
|
-
image: () =>
|
|
79
|
+
image: ({ format, mode, scale } = {}) =>
|
|
80
|
+
template
|
|
81
|
+
.replace("{{id}}", emote.id)
|
|
82
|
+
.replace("{{format}}", format ?? emote.format[0])
|
|
83
|
+
.replace("{{theme_mode}}", mode ?? emote.theme_mode[0])
|
|
84
|
+
.replace("{{scale}}", scale ?? emote.scale[emote.scale.length - 1]),
|
|
48
85
|
}))
|
|
49
86
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { helix as default } from "./helix.ts"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./streams.ts"
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { type Authentication } from "../../authentication/index.ts"
|
|
2
|
+
import { helix } from "../helix.ts"
|
|
3
|
+
|
|
4
|
+
export interface TwitchStream {
|
|
5
|
+
id: string
|
|
6
|
+
user_id: string
|
|
7
|
+
user_login: string
|
|
8
|
+
user_name: string
|
|
9
|
+
game_id: string
|
|
10
|
+
game_name: string
|
|
11
|
+
type: string
|
|
12
|
+
title: string
|
|
13
|
+
tags: string[]
|
|
14
|
+
viewer_count: number
|
|
15
|
+
started_at: string
|
|
16
|
+
language: string
|
|
17
|
+
thumbnail_url: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface StreamsResponse {
|
|
21
|
+
data: TwitchStream[]
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export async function getStream(
|
|
25
|
+
authentication: Authentication,
|
|
26
|
+
login?: string | string[],
|
|
27
|
+
id?: string | string[],
|
|
28
|
+
): Promise<TwitchStream | undefined> {
|
|
29
|
+
if (!login && !id) return undefined
|
|
30
|
+
|
|
31
|
+
if (typeof login === "string" && login.startsWith("@")) {
|
|
32
|
+
login = login.slice(1)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const { data: streams } = await helix<
|
|
36
|
+
StreamsResponse,
|
|
37
|
+
{ user_id?: string | string[]; user_login?: string | string[] }
|
|
38
|
+
>(authentication, {
|
|
39
|
+
method: "GET",
|
|
40
|
+
path: "/users",
|
|
41
|
+
params: {
|
|
42
|
+
user_id: id,
|
|
43
|
+
user_login: login,
|
|
44
|
+
},
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
return streams[0]
|
|
48
|
+
}
|
package/src/helix/users/users.ts
CHANGED
|
@@ -26,6 +26,12 @@ export async function getUser(
|
|
|
26
26
|
login?: string | string[],
|
|
27
27
|
id?: string | string[],
|
|
28
28
|
): Promise<TwitchUser | undefined> {
|
|
29
|
+
if (!login && !id) return undefined
|
|
30
|
+
|
|
31
|
+
if (typeof login === "string" && login.startsWith("@")) {
|
|
32
|
+
login = login.slice(1)
|
|
33
|
+
}
|
|
34
|
+
|
|
29
35
|
const { data: users } = await helix<
|
|
30
36
|
UsersResponse,
|
|
31
37
|
{ id?: string | string[]; login?: string | string[] }
|
|
@@ -45,3 +51,48 @@ export async function getUser(
|
|
|
45
51
|
created_at: new Date(created_at),
|
|
46
52
|
}
|
|
47
53
|
}
|
|
54
|
+
|
|
55
|
+
export async function getUsers(
|
|
56
|
+
authentication: Authentication,
|
|
57
|
+
login?: string | string[],
|
|
58
|
+
id?: string | string[],
|
|
59
|
+
): Promise<TwitchUser[] | undefined> {
|
|
60
|
+
if (!login && !id) return undefined
|
|
61
|
+
|
|
62
|
+
if (typeof login === "string" && login.startsWith("@")) {
|
|
63
|
+
login = login.slice(1)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const { data: users } = await helix<
|
|
67
|
+
UsersResponse,
|
|
68
|
+
{ id?: string | string[]; login?: string | string[] }
|
|
69
|
+
>(authentication, {
|
|
70
|
+
method: "GET",
|
|
71
|
+
path: "/users",
|
|
72
|
+
params: {
|
|
73
|
+
id,
|
|
74
|
+
login,
|
|
75
|
+
},
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
return users.map(({ created_at, ...user }) => ({
|
|
79
|
+
...user,
|
|
80
|
+
created_at: new Date(created_at),
|
|
81
|
+
}))
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export async function getCurrentUser(
|
|
85
|
+
authentication: Authentication,
|
|
86
|
+
): Promise<TwitchUser | undefined> {
|
|
87
|
+
const { data: users } = await helix<UsersResponse>(authentication, {
|
|
88
|
+
method: "GET",
|
|
89
|
+
path: "/users",
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
const [{ created_at, ...user }] = users
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
...user,
|
|
96
|
+
created_at: new Date(created_at),
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -24,8 +24,8 @@ export const mapTypeToPriority = {
|
|
|
24
24
|
export function onAlert(
|
|
25
25
|
eventsub: TwitchEventSub,
|
|
26
26
|
handleAlert: (alert: Alert) => void,
|
|
27
|
-
): void {
|
|
28
|
-
eventsub.on(
|
|
27
|
+
): () => void {
|
|
28
|
+
return eventsub.on(
|
|
29
29
|
[
|
|
30
30
|
"channel.cheer",
|
|
31
31
|
"channel.follow",
|
|
@@ -47,7 +47,7 @@ export function onAlert(
|
|
|
47
47
|
|
|
48
48
|
export default function createAlertQueue(
|
|
49
49
|
eventsub: TwitchEventSub,
|
|
50
|
-
handleAlert: (alert: Alert) =>
|
|
50
|
+
handleAlert: (alert: Alert) => unknown,
|
|
51
51
|
): Queue<Alert>["dismiss"] {
|
|
52
52
|
const queue = createQueue<Alert>()
|
|
53
53
|
queue.listen(handleAlert)
|
|
@@ -31,7 +31,7 @@ export function onCharity(
|
|
|
31
31
|
trigger: "progress" | "start" | "stop",
|
|
32
32
|
) => void,
|
|
33
33
|
handleDonation: (donation: CharityDonation, charity: Charity) => void,
|
|
34
|
-
): void {
|
|
34
|
+
): () => void {
|
|
35
35
|
const charity: Charity = {
|
|
36
36
|
name: "",
|
|
37
37
|
description: "",
|
|
@@ -42,7 +42,7 @@ export function onCharity(
|
|
|
42
42
|
targetAmount: 0,
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
eventsub.on(
|
|
45
|
+
return eventsub.on(
|
|
46
46
|
[
|
|
47
47
|
"channel.charity_campaign.start",
|
|
48
48
|
"channel.charity_campaign.progress",
|
package/src/helpers/goal/goal.ts
CHANGED
|
@@ -16,7 +16,7 @@ const mapTypeToTrigger = {
|
|
|
16
16
|
export function onGoal(
|
|
17
17
|
eventsub: TwitchEventSub,
|
|
18
18
|
handleGoal: (goal: Goal, trigger: "begin" | "progress" | "end") => void,
|
|
19
|
-
): void {
|
|
19
|
+
): () => void {
|
|
20
20
|
const goal: Goal = {
|
|
21
21
|
type: "",
|
|
22
22
|
description: "",
|
|
@@ -24,7 +24,7 @@ export function onGoal(
|
|
|
24
24
|
targetAmount: 0,
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
eventsub.on(
|
|
27
|
+
return eventsub.on(
|
|
28
28
|
["channel.goal.begin", "channel.goal.progress", "channel.goal.end"],
|
|
29
29
|
(payload) => {
|
|
30
30
|
goal.type = payload.event.type
|
|
@@ -19,7 +19,7 @@ export function onHypeTrain(
|
|
|
19
19
|
hypeTrain: HypeTrain,
|
|
20
20
|
trigger: "begin" | "progress" | "end",
|
|
21
21
|
) => void,
|
|
22
|
-
): void {
|
|
22
|
+
): () => void {
|
|
23
23
|
const hypeTrain: HypeTrain = {
|
|
24
24
|
level: 0,
|
|
25
25
|
total: 0,
|
|
@@ -27,7 +27,7 @@ export function onHypeTrain(
|
|
|
27
27
|
goal: 0,
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
eventsub.on(
|
|
30
|
+
return eventsub.on(
|
|
31
31
|
[
|
|
32
32
|
"channel.hype_train.begin",
|
|
33
33
|
"channel.hype_train.progress",
|
package/src/helpers/poll/poll.ts
CHANGED
|
@@ -23,7 +23,7 @@ const mapTypeToTrigger = {
|
|
|
23
23
|
export function onPoll(
|
|
24
24
|
eventsub: TwitchEventSub,
|
|
25
25
|
handlePoll: (poll: Poll, trigger: "begin" | "progress" | "end") => void,
|
|
26
|
-
): void {
|
|
26
|
+
): () => void {
|
|
27
27
|
const poll: Poll = {
|
|
28
28
|
id: "",
|
|
29
29
|
title: "",
|
|
@@ -31,7 +31,7 @@ export function onPoll(
|
|
|
31
31
|
endsAt: undefined,
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
eventsub.on(
|
|
34
|
+
return eventsub.on(
|
|
35
35
|
["channel.poll.begin", "channel.poll.progress", "channel.poll.end"],
|
|
36
36
|
(payload) => {
|
|
37
37
|
// Twitch sometimes sends duplicate end events.
|
|
@@ -25,14 +25,14 @@ export function onPrediction(
|
|
|
25
25
|
prediction: Prediction,
|
|
26
26
|
trigger: "begin" | "progress" | "lock" | "end",
|
|
27
27
|
) => void,
|
|
28
|
-
): void {
|
|
28
|
+
): () => void {
|
|
29
29
|
const prediction: Prediction = {
|
|
30
30
|
title: "",
|
|
31
31
|
outcomes: [],
|
|
32
32
|
locksAt: new Date(""),
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
eventsub.on(
|
|
35
|
+
return eventsub.on(
|
|
36
36
|
[
|
|
37
37
|
"channel.prediction.begin",
|
|
38
38
|
"channel.prediction.progress",
|
|
@@ -29,7 +29,7 @@ export function onRedemption(
|
|
|
29
29
|
...config:
|
|
30
30
|
| [string, (redemption: Redemption) => void]
|
|
31
31
|
| [(redemption: Redemption) => void]
|
|
32
|
-
): void {
|
|
32
|
+
): () => void {
|
|
33
33
|
const id = typeof config[0] === "string" ? config[0] : undefined
|
|
34
34
|
const handleRedemption =
|
|
35
35
|
typeof config[0] === "function"
|
|
@@ -38,7 +38,7 @@ export function onRedemption(
|
|
|
38
38
|
? config[1]
|
|
39
39
|
: undefined
|
|
40
40
|
|
|
41
|
-
eventsub.on(
|
|
41
|
+
return eventsub.on(
|
|
42
42
|
["channel.channel_points_custom_reward_redemption.add"],
|
|
43
43
|
(payload) => {
|
|
44
44
|
if (typeof id === "undefined" || payload.event.reward.id === id) {
|
|
@@ -13,7 +13,7 @@ export interface Status {
|
|
|
13
13
|
export function onStatus(
|
|
14
14
|
eventsub: TwitchEventSub,
|
|
15
15
|
handleStatus: (status: Status) => void,
|
|
16
|
-
): void {
|
|
16
|
+
): () => void {
|
|
17
17
|
const status: Status = {
|
|
18
18
|
online: false,
|
|
19
19
|
shieldMode: false,
|
|
@@ -22,7 +22,7 @@ export function onStatus(
|
|
|
22
22
|
labels: [],
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
eventsub.on(
|
|
25
|
+
return eventsub.on(
|
|
26
26
|
[
|
|
27
27
|
"channel.update",
|
|
28
28
|
"stream.online",
|