From 13f2aa77b69f33cf30c00f815e21e886b26a097f Mon Sep 17 00:00:00 2001 From: Coffee Weed Date: Sat, 28 Dec 2024 20:12:25 +0100 Subject: [PATCH] working reactions --- src/spaces/core/ChatClient.ts | 32 ++++++++++++++++++++++++++++++++ src/spaces/core/Space.ts | 10 ++++++++++ src/spaces/test.ts | 14 +++++++++++--- src/spaces/types.ts | 5 +++++ 4 files changed, 58 insertions(+), 3 deletions(-) diff --git a/src/spaces/core/ChatClient.ts b/src/spaces/core/ChatClient.ts index c2ea89e..fdb4930 100644 --- a/src/spaces/core/ChatClient.ts +++ b/src/spaces/core/ChatClient.ts @@ -82,6 +82,30 @@ export class ChatClient extends EventEmitter { ); } + reactWithEmoji(emoji: string) { + if (!this.ws) return; + const payload = JSON.stringify({ + body: JSON.stringify({ body: emoji, type: 2, v: 2 }), + kind: 1, + /* + // The 'sender' field is not required, it's not even verified by the server + // Instead of passing attributes down here it's easier to ignore it + sender: { + user_id: null, + twitter_id: null, + username: null, + display_name: null, + }, + */ + payload: JSON.stringify({ + room: this.spaceId, + body: JSON.stringify({ body: emoji, type: 2, v: 2 }), + }), + type: 2, + }); + this.ws.send(payload); + } + private handleMessage(raw: string) { let msg: any; try { @@ -129,6 +153,14 @@ export class ChatClient extends EventEmitter { muted: false, }); } + // Example of guest reaction + if (body?.type === 2) { + console.log('[ChatClient] Emiting guest reaction event =>', body); + this.emit('guestReaction', { + displayName: body.displayName, + emoji: body.body, + }); + } } async disconnect() { diff --git a/src/spaces/core/Space.ts b/src/spaces/core/Space.ts index 42c50df..283de55 100644 --- a/src/spaces/core/Space.ts +++ b/src/spaces/core/Space.ts @@ -15,6 +15,7 @@ import type { BroadcastCreated, SpeakerRequest, OccupancyUpdate, + GuestReaction, Plugin, AudioDataWithUser, PluginRegistration, @@ -144,6 +145,11 @@ export class Space extends EventEmitter { return broadcast; } + reactWithEmoji(emoji: string) { + if (!this.chatClient) return; + this.chatClient.reactWithEmoji(emoji); + } + private setupChatEvents() { if (!this.chatClient) return; @@ -157,6 +163,10 @@ export class Space extends EventEmitter { this.chatClient.on('muteStateChanged', (evt) => { this.emit('muteStateChanged', evt); }); + this.chatClient.on('guestReaction', (reaction: GuestReaction) => { + console.log('[Space] Guest reaction =>', reaction); + this.emit('guestReaction', reaction); + }); } /** diff --git a/src/spaces/test.ts b/src/spaces/test.ts index ab93281..183dfb5 100644 --- a/src/spaces/test.ts +++ b/src/spaces/test.ts @@ -66,6 +66,13 @@ async function main() { console.log('[Test] Speaker request =>', req); await space.approveSpeaker(req.userId, req.sessionUUID); }); + // When a user react, reply with some reactions to test the flow + space.on('guestReaction', (evt) => { + // Pick a random emoji from the list + const emojis = ['💯', '✨', '🙏', '🎮']; + const emoji = emojis[Math.floor(Math.random() * emojis.length)]; + space.reactWithEmoji(emoji); + }); space.on('error', (err) => { console.error('[Test] Space Error =>', err); }); @@ -109,9 +116,10 @@ async function main() { } // 5) Send beep every 5s - // setInterval(() => { - // sendBeep().catch((err) => console.error('[Test] beep error =>', err)); - // }, 5000); + //setInterval(() => { + // sendBeep().catch((err) => console.error('[Test] beep error =>', err)); + //}, 5000); + console.log('[Test] Space is running... press Ctrl+C to exit.'); diff --git a/src/spaces/types.ts b/src/spaces/types.ts index 55a0416..54963ba 100644 --- a/src/spaces/types.ts +++ b/src/spaces/types.ts @@ -26,6 +26,11 @@ export interface OccupancyUpdate { totalParticipants: number; } +export interface GuestReaction { + displayName: string; + emoji: string; +} + export interface SpaceConfig { mode: 'BROADCAST' | 'LISTEN' | 'INTERACTIVE'; title?: string;