@overlaysymphony/twitch 0.3.4 → 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.
Files changed (88) hide show
  1. package/package.json +3 -2
  2. package/src/chat/chat.ts +5 -3
  3. package/src/eventsub/events/automod.message.hold-2.ts +3 -3
  4. package/src/eventsub/events/automod.message.update-2.ts +3 -3
  5. package/src/eventsub/events/automod.settings.update-1.ts +3 -3
  6. package/src/eventsub/events/automod.terms.update-1.ts +3 -3
  7. package/src/eventsub/events/channel.ad_break.begin-1.ts +2 -2
  8. package/src/eventsub/events/channel.ban-1.ts +2 -2
  9. package/src/eventsub/events/channel.bits.use-1.ts +2 -2
  10. package/src/eventsub/events/channel.channel_points_automatic_reward_redemption.add-2.ts +2 -2
  11. package/src/eventsub/events/channel.channel_points_custom_reward.add-1.ts +2 -2
  12. package/src/eventsub/events/channel.channel_points_custom_reward.remove-1.ts +2 -2
  13. package/src/eventsub/events/channel.channel_points_custom_reward.update-1.ts +2 -2
  14. package/src/eventsub/events/channel.channel_points_custom_reward_redemption.add-1.ts +2 -2
  15. package/src/eventsub/events/channel.channel_points_custom_reward_redemption.update-1.ts +2 -2
  16. package/src/eventsub/events/channel.charity_campaign.donate-1.ts +2 -2
  17. package/src/eventsub/events/channel.charity_campaign.progress-1.ts +2 -2
  18. package/src/eventsub/events/channel.charity_campaign.start-1.ts +2 -2
  19. package/src/eventsub/events/channel.charity_campaign.stop-1.ts +2 -2
  20. package/src/eventsub/events/channel.chat.clear-1.ts +3 -3
  21. package/src/eventsub/events/channel.chat.clear_user_messages-1.ts +3 -3
  22. package/src/eventsub/events/channel.chat.message-1.ts +3 -3
  23. package/src/eventsub/events/channel.chat.message_delete-1.ts +3 -3
  24. package/src/eventsub/events/channel.chat.notification-1.ts +3 -3
  25. package/src/eventsub/events/channel.chat.user_message_hold-1.ts +3 -3
  26. package/src/eventsub/events/channel.chat.user_message_update-1.ts +3 -3
  27. package/src/eventsub/events/channel.chat_settings.update-1.ts +3 -3
  28. package/src/eventsub/events/channel.cheer-1.ts +2 -2
  29. package/src/eventsub/events/channel.follow-2.ts +3 -3
  30. package/src/eventsub/events/channel.goal.begin-1.ts +2 -2
  31. package/src/eventsub/events/channel.goal.end-1.ts +2 -2
  32. package/src/eventsub/events/channel.goal.progress-1.ts +2 -2
  33. package/src/eventsub/events/channel.guest_star_guest.update-beta.ts +3 -3
  34. package/src/eventsub/events/channel.guest_star_session.begin-beta.ts +3 -3
  35. package/src/eventsub/events/channel.guest_star_session.end-beta.ts +3 -3
  36. package/src/eventsub/events/channel.guest_star_settings.update-beta.ts +3 -3
  37. package/src/eventsub/events/channel.hype_train.begin-2.ts +2 -2
  38. package/src/eventsub/events/channel.hype_train.end-2.ts +2 -2
  39. package/src/eventsub/events/channel.hype_train.progress-2.ts +2 -2
  40. package/src/eventsub/events/channel.moderate-2.ts +3 -3
  41. package/src/eventsub/events/channel.moderator.add-1.ts +2 -2
  42. package/src/eventsub/events/channel.moderator.remove-1.ts +2 -2
  43. package/src/eventsub/events/channel.poll.begin-1.ts +2 -2
  44. package/src/eventsub/events/channel.poll.end-1.ts +2 -2
  45. package/src/eventsub/events/channel.poll.progress-1.ts +2 -2
  46. package/src/eventsub/events/channel.prediction.begin-1.ts +2 -2
  47. package/src/eventsub/events/channel.prediction.end-1.ts +2 -2
  48. package/src/eventsub/events/channel.prediction.lock-1.ts +2 -2
  49. package/src/eventsub/events/channel.prediction.progress-1.ts +2 -2
  50. package/src/eventsub/events/channel.raid-1.ts +2 -2
  51. package/src/eventsub/events/channel.shared_chat.begin-1.ts +2 -2
  52. package/src/eventsub/events/channel.shared_chat.end-1.ts +2 -2
  53. package/src/eventsub/events/channel.shared_chat.update-1.ts +2 -2
  54. package/src/eventsub/events/channel.shield_mode.begin-1.ts +3 -3
  55. package/src/eventsub/events/channel.shield_mode.end-1.ts +3 -3
  56. package/src/eventsub/events/channel.shoutout.create-1.ts +3 -3
  57. package/src/eventsub/events/channel.shoutout.receive-1.ts +3 -3
  58. package/src/eventsub/events/channel.subscribe-1.ts +2 -2
  59. package/src/eventsub/events/channel.subscription.end-1.ts +2 -2
  60. package/src/eventsub/events/channel.subscription.gift-1.ts +2 -2
  61. package/src/eventsub/events/channel.subscription.message-1.ts +2 -2
  62. package/src/eventsub/events/channel.suspicious_user.message-1.ts +3 -3
  63. package/src/eventsub/events/channel.suspicious_user.update-1.ts +3 -3
  64. package/src/eventsub/events/channel.unban-1.ts +2 -2
  65. package/src/eventsub/events/channel.unban_request.create-1.ts +3 -3
  66. package/src/eventsub/events/channel.unban_request.resolve-1.ts +3 -3
  67. package/src/eventsub/events/channel.update-2.ts +2 -2
  68. package/src/eventsub/events/channel.vip.add-1.ts +2 -2
  69. package/src/eventsub/events/channel.vip.remove-1.ts +2 -2
  70. package/src/eventsub/events/channel.warning.acknowledge-1.ts +3 -3
  71. package/src/eventsub/events/channel.warning.send-1.ts +3 -3
  72. package/src/eventsub/events/stream.offline-1.ts +2 -2
  73. package/src/eventsub/events/stream.online-1.ts +2 -2
  74. package/src/eventsub/events/user.update-1.ts +2 -2
  75. package/src/eventsub/events/user.whisper.message-1.ts +2 -2
  76. package/src/eventsub/events-helpers.ts +11 -4
  77. package/src/eventsub/eventsub.ts +52 -34
  78. package/src/eventsub/index.ts +1 -0
  79. package/src/helix/index.ts +1 -0
  80. package/src/helix/users/users.ts +29 -0
  81. package/src/helpers/alerts/alerts.ts +2 -2
  82. package/src/helpers/charity/charity.ts +2 -2
  83. package/src/helpers/goal/goal.ts +2 -2
  84. package/src/helpers/hype-train/hype-train.ts +2 -2
  85. package/src/helpers/poll/poll.ts +2 -2
  86. package/src/helpers/prediction/prediction.ts +2 -2
  87. package/src/helpers/redemption/redemption.ts +2 -2
  88. package/src/helpers/status/status.ts +2 -2
@@ -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
- return createEvents<EventPayload, string>(
18
- async (pubsub) => {
19
- const socket = new WebSocket("wss://eventsub.wss.twitch.tv/ws")
20
-
21
- const { promise, resolve } = createDefer<string>()
22
- socket.addEventListener("message", ({ data: rawData }) => {
23
- const data = JSON.parse(rawData as string) as TwitchMessage
24
- data.type = data.metadata.message_type
25
-
26
- if (data.type === "session_welcome") {
27
- resolve(data.payload.session.id)
28
- return
29
- }
30
-
31
- if (data.type === "notification") {
32
- data.payload.id = data.metadata.message_id
33
- data.payload.type = data.payload.subscription.type
34
-
35
- pubsub.dispatch(data.payload)
36
- return
37
- }
38
- })
39
-
40
- return await promise
41
- },
42
- async (pubsub, sessionId, type) => {
43
- await createSubscription(
44
- authentication,
45
- { method: "websocket", session_id: sessionId },
46
- buildSubscription(type, authentication.user.id),
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
  }
@@ -1,6 +1,7 @@
1
1
  export {
2
2
  type EventConfig,
3
3
  type EventConfigs,
4
+ type EventPayload,
4
5
  type EventType,
5
6
  registerEvent,
6
7
  } from "./events-helpers.ts"
@@ -0,0 +1 @@
1
+ export { helix as default } from "./helix.ts"
@@ -52,6 +52,35 @@ export async function getUser(
52
52
  }
53
53
  }
54
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
+
55
84
  export async function getCurrentUser(
56
85
  authentication: Authentication,
57
86
  ): Promise<TwitchUser | undefined> {
@@ -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",
@@ -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",
@@ -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",
@@ -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",