@whereby.com/assistant-sdk 0.0.0-canary-20250917154617 → 0.0.0-canary-20250923130059
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/index.cjs +53 -11
- package/dist/index.d.cts +28 -2
- package/dist/index.d.mts +28 -2
- package/dist/index.d.ts +28 -2
- package/dist/index.mjs +50 -12
- package/dist/legacy-esm.js +50 -12
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -35,6 +35,10 @@ const TRIGGER_EVENT_SUCCESS = "trigger_event_success";
|
|
|
35
35
|
const AUDIO_STREAM_READY = "AUDIO_STREAM_READY";
|
|
36
36
|
const ASSISTANT_JOINED_ROOM = "ASSISTANT_JOINED_ROOM";
|
|
37
37
|
const ASSISTANT_LEFT_ROOM = "ASSISTANT_LEFT_ROOM";
|
|
38
|
+
const PARTICIPANT_VIDEO_TRACK_ADDED = "PARTICIPANT_VIDEO_TRACK_ADDED";
|
|
39
|
+
const PARTICIPANT_VIDEO_TRACK_REMOVED = "PARTICIPANT_VIDEO_TRACK_REMOVED";
|
|
40
|
+
const PARTICIPANT_AUDIO_TRACK_ADDED = "PARTICIPANT_AUDIO_TRACK_ADDED";
|
|
41
|
+
const PARTICIPANT_AUDIO_TRACK_REMOVED = "PARTICIPANT_AUDIO_TRACK_REMOVED";
|
|
38
42
|
|
|
39
43
|
/******************************************************************************
|
|
40
44
|
Copyright (c) Microsoft Corporation.
|
|
@@ -580,6 +584,7 @@ class Assistant extends EventEmitter {
|
|
|
580
584
|
this.mediaStream = null;
|
|
581
585
|
this.audioSource = null;
|
|
582
586
|
this.combinedStream = null;
|
|
587
|
+
this.remoteMediaTracks = {};
|
|
583
588
|
this.roomUrl = null;
|
|
584
589
|
this.handleConnectionStatusChange = (status) => {
|
|
585
590
|
if (status === "connected") {
|
|
@@ -589,6 +594,41 @@ class Assistant extends EventEmitter {
|
|
|
589
594
|
this.emit(ASSISTANT_LEFT_ROOM, { roomUrl: this.roomUrl || "" });
|
|
590
595
|
}
|
|
591
596
|
};
|
|
597
|
+
this.handleRemoteParticipantsTracksChange = (remoteParticipants) => {
|
|
598
|
+
const currentRemoteMediaTracks = remoteParticipants.flatMap(({ id: participantId, stream }) => {
|
|
599
|
+
if (!stream) {
|
|
600
|
+
return [];
|
|
601
|
+
}
|
|
602
|
+
const tracks = stream.getTracks();
|
|
603
|
+
tracks.forEach((track) => {
|
|
604
|
+
if (!this.remoteMediaTracks[track.id]) {
|
|
605
|
+
const eventName = track.kind === "video" ? PARTICIPANT_VIDEO_TRACK_ADDED : PARTICIPANT_AUDIO_TRACK_ADDED;
|
|
606
|
+
this.emit(eventName, {
|
|
607
|
+
participantId,
|
|
608
|
+
stream,
|
|
609
|
+
track,
|
|
610
|
+
});
|
|
611
|
+
this.remoteMediaTracks[track.id] = {
|
|
612
|
+
participantId,
|
|
613
|
+
stream,
|
|
614
|
+
track,
|
|
615
|
+
};
|
|
616
|
+
}
|
|
617
|
+
});
|
|
618
|
+
return tracks;
|
|
619
|
+
});
|
|
620
|
+
Object.values(this.remoteMediaTracks).forEach(({ participantId, stream, track }) => {
|
|
621
|
+
if (!currentRemoteMediaTracks.includes(track)) {
|
|
622
|
+
const eventName = track.kind === "video" ? PARTICIPANT_VIDEO_TRACK_REMOVED : PARTICIPANT_AUDIO_TRACK_REMOVED;
|
|
623
|
+
this.emit(eventName, {
|
|
624
|
+
participantId,
|
|
625
|
+
stream,
|
|
626
|
+
track,
|
|
627
|
+
});
|
|
628
|
+
delete this.remoteMediaTracks[track.id];
|
|
629
|
+
}
|
|
630
|
+
});
|
|
631
|
+
};
|
|
592
632
|
this.assistantKey = assistantKey;
|
|
593
633
|
this.client = new core.WherebyClient();
|
|
594
634
|
this.roomConnection = this.client.getRoomConnection();
|
|
@@ -613,8 +653,9 @@ class Assistant extends EventEmitter {
|
|
|
613
653
|
const audioMixer = new AudioMixer(handleStreamReady);
|
|
614
654
|
this.combinedStream = audioMixer.getCombinedAudioStream();
|
|
615
655
|
this.roomConnection.subscribeToRemoteParticipants(audioMixer.handleRemoteParticipants.bind(audioMixer));
|
|
616
|
-
this.roomConnection.subscribeToConnectionStatus(this.handleConnectionStatusChange);
|
|
617
656
|
}
|
|
657
|
+
this.roomConnection.subscribeToConnectionStatus(this.handleConnectionStatusChange);
|
|
658
|
+
this.roomConnection.subscribeToRemoteParticipants(this.handleRemoteParticipantsTracksChange);
|
|
618
659
|
}
|
|
619
660
|
joinRoom(roomUrl) {
|
|
620
661
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -731,7 +772,7 @@ const webhookRouter = (webhookTriggers, emitter) => {
|
|
|
731
772
|
res.status(200);
|
|
732
773
|
res.end();
|
|
733
774
|
});
|
|
734
|
-
router.post("/", jsonParser, (req, res) => {
|
|
775
|
+
router.post("/", jsonParser, (req, res) => __awaiter(void 0, void 0, void 0, function* () {
|
|
735
776
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
736
777
|
assert(req.body, "message body is required");
|
|
737
778
|
assert("type" in req.body, "webhook type is required");
|
|
@@ -739,19 +780,19 @@ const webhookRouter = (webhookTriggers, emitter) => {
|
|
|
739
780
|
switch (req.body.type) {
|
|
740
781
|
case "room.client.joined":
|
|
741
782
|
shouldTriggerOnReceivedWebhook =
|
|
742
|
-
(_b = (_a = webhookTriggers["room.client.joined"]) === null || _a === void 0 ? void 0 : _a.call(webhookTriggers, req.body)) !== null && _b !== void 0 ? _b : false;
|
|
783
|
+
(_b = (yield ((_a = webhookTriggers["room.client.joined"]) === null || _a === void 0 ? void 0 : _a.call(webhookTriggers, req.body)))) !== null && _b !== void 0 ? _b : false;
|
|
743
784
|
break;
|
|
744
785
|
case "room.client.left":
|
|
745
786
|
shouldTriggerOnReceivedWebhook =
|
|
746
|
-
(_d = (_c = webhookTriggers["room.client.left"]) === null || _c === void 0 ? void 0 : _c.call(webhookTriggers, req.body)) !== null && _d !== void 0 ? _d : false;
|
|
787
|
+
(_d = (yield ((_c = webhookTriggers["room.client.left"]) === null || _c === void 0 ? void 0 : _c.call(webhookTriggers, req.body)))) !== null && _d !== void 0 ? _d : false;
|
|
747
788
|
break;
|
|
748
789
|
case "room.session.started":
|
|
749
790
|
shouldTriggerOnReceivedWebhook =
|
|
750
|
-
(_f = (_e = webhookTriggers["room.session.started"]) === null || _e === void 0 ? void 0 : _e.call(webhookTriggers, req.body)) !== null && _f !== void 0 ? _f : false;
|
|
791
|
+
(_f = (yield ((_e = webhookTriggers["room.session.started"]) === null || _e === void 0 ? void 0 : _e.call(webhookTriggers, req.body)))) !== null && _f !== void 0 ? _f : false;
|
|
751
792
|
break;
|
|
752
793
|
case "room.session.ended":
|
|
753
794
|
shouldTriggerOnReceivedWebhook =
|
|
754
|
-
(_h = (_g = webhookTriggers["room.session.ended"]) === null || _g === void 0 ? void 0 : _g.call(webhookTriggers, req.body)) !== null && _h !== void 0 ? _h : false;
|
|
795
|
+
(_h = (yield ((_g = webhookTriggers["room.session.ended"]) === null || _g === void 0 ? void 0 : _g.call(webhookTriggers, req.body)))) !== null && _h !== void 0 ? _h : false;
|
|
755
796
|
break;
|
|
756
797
|
}
|
|
757
798
|
if (shouldTriggerOnReceivedWebhook) {
|
|
@@ -760,7 +801,7 @@ const webhookRouter = (webhookTriggers, emitter) => {
|
|
|
760
801
|
}
|
|
761
802
|
res.status(200);
|
|
762
803
|
res.end();
|
|
763
|
-
});
|
|
804
|
+
}));
|
|
764
805
|
return router;
|
|
765
806
|
};
|
|
766
807
|
class Trigger extends EventEmitter.EventEmitter {
|
|
@@ -773,12 +814,9 @@ class Trigger extends EventEmitter.EventEmitter {
|
|
|
773
814
|
const app = express();
|
|
774
815
|
const router = webhookRouter(this.webhookTriggers, this);
|
|
775
816
|
app.use(router);
|
|
776
|
-
|
|
817
|
+
app.listen(this.port, () => {
|
|
777
818
|
// console.log(`Bot trigger server now running on port[${this.port}]`);
|
|
778
819
|
});
|
|
779
|
-
process.on("SIGTERM", () => {
|
|
780
|
-
server.close();
|
|
781
|
-
});
|
|
782
820
|
}
|
|
783
821
|
}
|
|
784
822
|
|
|
@@ -788,5 +826,9 @@ exports.AUDIO_STREAM_READY = AUDIO_STREAM_READY;
|
|
|
788
826
|
exports.Assistant = Assistant;
|
|
789
827
|
exports.AudioSink = AudioSink;
|
|
790
828
|
exports.AudioSource = AudioSource;
|
|
829
|
+
exports.PARTICIPANT_AUDIO_TRACK_ADDED = PARTICIPANT_AUDIO_TRACK_ADDED;
|
|
830
|
+
exports.PARTICIPANT_AUDIO_TRACK_REMOVED = PARTICIPANT_AUDIO_TRACK_REMOVED;
|
|
831
|
+
exports.PARTICIPANT_VIDEO_TRACK_ADDED = PARTICIPANT_VIDEO_TRACK_ADDED;
|
|
832
|
+
exports.PARTICIPANT_VIDEO_TRACK_REMOVED = PARTICIPANT_VIDEO_TRACK_REMOVED;
|
|
791
833
|
exports.TRIGGER_EVENT_SUCCESS = TRIGGER_EVENT_SUCCESS;
|
|
792
834
|
exports.Trigger = Trigger;
|
package/dist/index.d.cts
CHANGED
|
@@ -88,12 +88,16 @@ type WherebyWebhookTriggerTypes = {
|
|
|
88
88
|
"room.session.ended": WherebyWebhookRoomSessionEnded;
|
|
89
89
|
};
|
|
90
90
|
type WherebyWebhookTriggers = Partial<{
|
|
91
|
-
[Type in keyof WherebyWebhookTriggerTypes]: (data: WherebyWebhookTriggerTypes[Type]) => boolean;
|
|
91
|
+
[Type in keyof WherebyWebhookTriggerTypes]: (data: WherebyWebhookTriggerTypes[Type]) => Promise<boolean> | boolean;
|
|
92
92
|
}>;
|
|
93
93
|
|
|
94
94
|
declare const AUDIO_STREAM_READY = "AUDIO_STREAM_READY";
|
|
95
95
|
declare const ASSISTANT_JOINED_ROOM = "ASSISTANT_JOINED_ROOM";
|
|
96
96
|
declare const ASSISTANT_LEFT_ROOM = "ASSISTANT_LEFT_ROOM";
|
|
97
|
+
declare const PARTICIPANT_VIDEO_TRACK_ADDED = "PARTICIPANT_VIDEO_TRACK_ADDED";
|
|
98
|
+
declare const PARTICIPANT_VIDEO_TRACK_REMOVED = "PARTICIPANT_VIDEO_TRACK_REMOVED";
|
|
99
|
+
declare const PARTICIPANT_AUDIO_TRACK_ADDED = "PARTICIPANT_AUDIO_TRACK_ADDED";
|
|
100
|
+
declare const PARTICIPANT_AUDIO_TRACK_REMOVED = "PARTICIPANT_AUDIO_TRACK_REMOVED";
|
|
97
101
|
type AssistantEvents = {
|
|
98
102
|
[ASSISTANT_JOINED_ROOM]: [{
|
|
99
103
|
roomUrl: string;
|
|
@@ -105,6 +109,26 @@ type AssistantEvents = {
|
|
|
105
109
|
stream: MediaStream;
|
|
106
110
|
track: MediaStreamTrack;
|
|
107
111
|
}];
|
|
112
|
+
[PARTICIPANT_VIDEO_TRACK_ADDED]: [{
|
|
113
|
+
participantId: string;
|
|
114
|
+
stream: MediaStream;
|
|
115
|
+
track: MediaStreamTrack;
|
|
116
|
+
}];
|
|
117
|
+
[PARTICIPANT_VIDEO_TRACK_REMOVED]: [{
|
|
118
|
+
participantId: string;
|
|
119
|
+
stream: MediaStream;
|
|
120
|
+
track: MediaStreamTrack;
|
|
121
|
+
}];
|
|
122
|
+
[PARTICIPANT_AUDIO_TRACK_ADDED]: [{
|
|
123
|
+
participantId: string;
|
|
124
|
+
stream: MediaStream;
|
|
125
|
+
track: MediaStreamTrack;
|
|
126
|
+
}];
|
|
127
|
+
[PARTICIPANT_AUDIO_TRACK_REMOVED]: [{
|
|
128
|
+
participantId: string;
|
|
129
|
+
stream: MediaStream;
|
|
130
|
+
track: MediaStreamTrack;
|
|
131
|
+
}];
|
|
108
132
|
};
|
|
109
133
|
|
|
110
134
|
type AssistantOptions = {
|
|
@@ -120,9 +144,11 @@ declare class Assistant extends EventEmitter<AssistantEvents> {
|
|
|
120
144
|
private mediaStream;
|
|
121
145
|
private audioSource;
|
|
122
146
|
private combinedStream;
|
|
147
|
+
private remoteMediaTracks;
|
|
123
148
|
private roomUrl;
|
|
124
149
|
constructor({ assistantKey, startCombinedAudioStream, startLocalMedia }: AssistantOptions);
|
|
125
150
|
private handleConnectionStatusChange;
|
|
151
|
+
private handleRemoteParticipantsTracksChange;
|
|
126
152
|
joinRoom(roomUrl: string): Promise<void>;
|
|
127
153
|
startLocalMedia(): void;
|
|
128
154
|
getLocalMediaStream(): MediaStream | null;
|
|
@@ -169,5 +195,5 @@ declare class AudioSink extends wrtc__default.nonstandard.RTCAudioSink {
|
|
|
169
195
|
}) => void): () => void;
|
|
170
196
|
}
|
|
171
197
|
|
|
172
|
-
export { ASSISTANT_JOINED_ROOM, ASSISTANT_LEFT_ROOM, AUDIO_STREAM_READY, Assistant, AudioSink, AudioSource, TRIGGER_EVENT_SUCCESS, Trigger };
|
|
198
|
+
export { ASSISTANT_JOINED_ROOM, ASSISTANT_LEFT_ROOM, AUDIO_STREAM_READY, Assistant, AudioSink, AudioSource, PARTICIPANT_AUDIO_TRACK_ADDED, PARTICIPANT_AUDIO_TRACK_REMOVED, PARTICIPANT_VIDEO_TRACK_ADDED, PARTICIPANT_VIDEO_TRACK_REMOVED, TRIGGER_EVENT_SUCCESS, Trigger };
|
|
173
199
|
export type { AssistantEvents };
|
package/dist/index.d.mts
CHANGED
|
@@ -88,12 +88,16 @@ type WherebyWebhookTriggerTypes = {
|
|
|
88
88
|
"room.session.ended": WherebyWebhookRoomSessionEnded;
|
|
89
89
|
};
|
|
90
90
|
type WherebyWebhookTriggers = Partial<{
|
|
91
|
-
[Type in keyof WherebyWebhookTriggerTypes]: (data: WherebyWebhookTriggerTypes[Type]) => boolean;
|
|
91
|
+
[Type in keyof WherebyWebhookTriggerTypes]: (data: WherebyWebhookTriggerTypes[Type]) => Promise<boolean> | boolean;
|
|
92
92
|
}>;
|
|
93
93
|
|
|
94
94
|
declare const AUDIO_STREAM_READY = "AUDIO_STREAM_READY";
|
|
95
95
|
declare const ASSISTANT_JOINED_ROOM = "ASSISTANT_JOINED_ROOM";
|
|
96
96
|
declare const ASSISTANT_LEFT_ROOM = "ASSISTANT_LEFT_ROOM";
|
|
97
|
+
declare const PARTICIPANT_VIDEO_TRACK_ADDED = "PARTICIPANT_VIDEO_TRACK_ADDED";
|
|
98
|
+
declare const PARTICIPANT_VIDEO_TRACK_REMOVED = "PARTICIPANT_VIDEO_TRACK_REMOVED";
|
|
99
|
+
declare const PARTICIPANT_AUDIO_TRACK_ADDED = "PARTICIPANT_AUDIO_TRACK_ADDED";
|
|
100
|
+
declare const PARTICIPANT_AUDIO_TRACK_REMOVED = "PARTICIPANT_AUDIO_TRACK_REMOVED";
|
|
97
101
|
type AssistantEvents = {
|
|
98
102
|
[ASSISTANT_JOINED_ROOM]: [{
|
|
99
103
|
roomUrl: string;
|
|
@@ -105,6 +109,26 @@ type AssistantEvents = {
|
|
|
105
109
|
stream: MediaStream;
|
|
106
110
|
track: MediaStreamTrack;
|
|
107
111
|
}];
|
|
112
|
+
[PARTICIPANT_VIDEO_TRACK_ADDED]: [{
|
|
113
|
+
participantId: string;
|
|
114
|
+
stream: MediaStream;
|
|
115
|
+
track: MediaStreamTrack;
|
|
116
|
+
}];
|
|
117
|
+
[PARTICIPANT_VIDEO_TRACK_REMOVED]: [{
|
|
118
|
+
participantId: string;
|
|
119
|
+
stream: MediaStream;
|
|
120
|
+
track: MediaStreamTrack;
|
|
121
|
+
}];
|
|
122
|
+
[PARTICIPANT_AUDIO_TRACK_ADDED]: [{
|
|
123
|
+
participantId: string;
|
|
124
|
+
stream: MediaStream;
|
|
125
|
+
track: MediaStreamTrack;
|
|
126
|
+
}];
|
|
127
|
+
[PARTICIPANT_AUDIO_TRACK_REMOVED]: [{
|
|
128
|
+
participantId: string;
|
|
129
|
+
stream: MediaStream;
|
|
130
|
+
track: MediaStreamTrack;
|
|
131
|
+
}];
|
|
108
132
|
};
|
|
109
133
|
|
|
110
134
|
type AssistantOptions = {
|
|
@@ -120,9 +144,11 @@ declare class Assistant extends EventEmitter<AssistantEvents> {
|
|
|
120
144
|
private mediaStream;
|
|
121
145
|
private audioSource;
|
|
122
146
|
private combinedStream;
|
|
147
|
+
private remoteMediaTracks;
|
|
123
148
|
private roomUrl;
|
|
124
149
|
constructor({ assistantKey, startCombinedAudioStream, startLocalMedia }: AssistantOptions);
|
|
125
150
|
private handleConnectionStatusChange;
|
|
151
|
+
private handleRemoteParticipantsTracksChange;
|
|
126
152
|
joinRoom(roomUrl: string): Promise<void>;
|
|
127
153
|
startLocalMedia(): void;
|
|
128
154
|
getLocalMediaStream(): MediaStream | null;
|
|
@@ -169,5 +195,5 @@ declare class AudioSink extends wrtc__default.nonstandard.RTCAudioSink {
|
|
|
169
195
|
}) => void): () => void;
|
|
170
196
|
}
|
|
171
197
|
|
|
172
|
-
export { ASSISTANT_JOINED_ROOM, ASSISTANT_LEFT_ROOM, AUDIO_STREAM_READY, Assistant, AudioSink, AudioSource, TRIGGER_EVENT_SUCCESS, Trigger };
|
|
198
|
+
export { ASSISTANT_JOINED_ROOM, ASSISTANT_LEFT_ROOM, AUDIO_STREAM_READY, Assistant, AudioSink, AudioSource, PARTICIPANT_AUDIO_TRACK_ADDED, PARTICIPANT_AUDIO_TRACK_REMOVED, PARTICIPANT_VIDEO_TRACK_ADDED, PARTICIPANT_VIDEO_TRACK_REMOVED, TRIGGER_EVENT_SUCCESS, Trigger };
|
|
173
199
|
export type { AssistantEvents };
|
package/dist/index.d.ts
CHANGED
|
@@ -88,12 +88,16 @@ type WherebyWebhookTriggerTypes = {
|
|
|
88
88
|
"room.session.ended": WherebyWebhookRoomSessionEnded;
|
|
89
89
|
};
|
|
90
90
|
type WherebyWebhookTriggers = Partial<{
|
|
91
|
-
[Type in keyof WherebyWebhookTriggerTypes]: (data: WherebyWebhookTriggerTypes[Type]) => boolean;
|
|
91
|
+
[Type in keyof WherebyWebhookTriggerTypes]: (data: WherebyWebhookTriggerTypes[Type]) => Promise<boolean> | boolean;
|
|
92
92
|
}>;
|
|
93
93
|
|
|
94
94
|
declare const AUDIO_STREAM_READY = "AUDIO_STREAM_READY";
|
|
95
95
|
declare const ASSISTANT_JOINED_ROOM = "ASSISTANT_JOINED_ROOM";
|
|
96
96
|
declare const ASSISTANT_LEFT_ROOM = "ASSISTANT_LEFT_ROOM";
|
|
97
|
+
declare const PARTICIPANT_VIDEO_TRACK_ADDED = "PARTICIPANT_VIDEO_TRACK_ADDED";
|
|
98
|
+
declare const PARTICIPANT_VIDEO_TRACK_REMOVED = "PARTICIPANT_VIDEO_TRACK_REMOVED";
|
|
99
|
+
declare const PARTICIPANT_AUDIO_TRACK_ADDED = "PARTICIPANT_AUDIO_TRACK_ADDED";
|
|
100
|
+
declare const PARTICIPANT_AUDIO_TRACK_REMOVED = "PARTICIPANT_AUDIO_TRACK_REMOVED";
|
|
97
101
|
type AssistantEvents = {
|
|
98
102
|
[ASSISTANT_JOINED_ROOM]: [{
|
|
99
103
|
roomUrl: string;
|
|
@@ -105,6 +109,26 @@ type AssistantEvents = {
|
|
|
105
109
|
stream: MediaStream;
|
|
106
110
|
track: MediaStreamTrack;
|
|
107
111
|
}];
|
|
112
|
+
[PARTICIPANT_VIDEO_TRACK_ADDED]: [{
|
|
113
|
+
participantId: string;
|
|
114
|
+
stream: MediaStream;
|
|
115
|
+
track: MediaStreamTrack;
|
|
116
|
+
}];
|
|
117
|
+
[PARTICIPANT_VIDEO_TRACK_REMOVED]: [{
|
|
118
|
+
participantId: string;
|
|
119
|
+
stream: MediaStream;
|
|
120
|
+
track: MediaStreamTrack;
|
|
121
|
+
}];
|
|
122
|
+
[PARTICIPANT_AUDIO_TRACK_ADDED]: [{
|
|
123
|
+
participantId: string;
|
|
124
|
+
stream: MediaStream;
|
|
125
|
+
track: MediaStreamTrack;
|
|
126
|
+
}];
|
|
127
|
+
[PARTICIPANT_AUDIO_TRACK_REMOVED]: [{
|
|
128
|
+
participantId: string;
|
|
129
|
+
stream: MediaStream;
|
|
130
|
+
track: MediaStreamTrack;
|
|
131
|
+
}];
|
|
108
132
|
};
|
|
109
133
|
|
|
110
134
|
type AssistantOptions = {
|
|
@@ -120,9 +144,11 @@ declare class Assistant extends EventEmitter<AssistantEvents> {
|
|
|
120
144
|
private mediaStream;
|
|
121
145
|
private audioSource;
|
|
122
146
|
private combinedStream;
|
|
147
|
+
private remoteMediaTracks;
|
|
123
148
|
private roomUrl;
|
|
124
149
|
constructor({ assistantKey, startCombinedAudioStream, startLocalMedia }: AssistantOptions);
|
|
125
150
|
private handleConnectionStatusChange;
|
|
151
|
+
private handleRemoteParticipantsTracksChange;
|
|
126
152
|
joinRoom(roomUrl: string): Promise<void>;
|
|
127
153
|
startLocalMedia(): void;
|
|
128
154
|
getLocalMediaStream(): MediaStream | null;
|
|
@@ -169,5 +195,5 @@ declare class AudioSink extends wrtc__default.nonstandard.RTCAudioSink {
|
|
|
169
195
|
}) => void): () => void;
|
|
170
196
|
}
|
|
171
197
|
|
|
172
|
-
export { ASSISTANT_JOINED_ROOM, ASSISTANT_LEFT_ROOM, AUDIO_STREAM_READY, Assistant, AudioSink, AudioSource, TRIGGER_EVENT_SUCCESS, Trigger };
|
|
198
|
+
export { ASSISTANT_JOINED_ROOM, ASSISTANT_LEFT_ROOM, AUDIO_STREAM_READY, Assistant, AudioSink, AudioSource, PARTICIPANT_AUDIO_TRACK_ADDED, PARTICIPANT_AUDIO_TRACK_REMOVED, PARTICIPANT_VIDEO_TRACK_ADDED, PARTICIPANT_VIDEO_TRACK_REMOVED, TRIGGER_EVENT_SUCCESS, Trigger };
|
|
173
199
|
export type { AssistantEvents };
|
package/dist/index.mjs
CHANGED
|
@@ -14,6 +14,10 @@ const TRIGGER_EVENT_SUCCESS = "trigger_event_success";
|
|
|
14
14
|
const AUDIO_STREAM_READY = "AUDIO_STREAM_READY";
|
|
15
15
|
const ASSISTANT_JOINED_ROOM = "ASSISTANT_JOINED_ROOM";
|
|
16
16
|
const ASSISTANT_LEFT_ROOM = "ASSISTANT_LEFT_ROOM";
|
|
17
|
+
const PARTICIPANT_VIDEO_TRACK_ADDED = "PARTICIPANT_VIDEO_TRACK_ADDED";
|
|
18
|
+
const PARTICIPANT_VIDEO_TRACK_REMOVED = "PARTICIPANT_VIDEO_TRACK_REMOVED";
|
|
19
|
+
const PARTICIPANT_AUDIO_TRACK_ADDED = "PARTICIPANT_AUDIO_TRACK_ADDED";
|
|
20
|
+
const PARTICIPANT_AUDIO_TRACK_REMOVED = "PARTICIPANT_AUDIO_TRACK_REMOVED";
|
|
17
21
|
|
|
18
22
|
/******************************************************************************
|
|
19
23
|
Copyright (c) Microsoft Corporation.
|
|
@@ -559,6 +563,7 @@ class Assistant extends EventEmitter$1 {
|
|
|
559
563
|
this.mediaStream = null;
|
|
560
564
|
this.audioSource = null;
|
|
561
565
|
this.combinedStream = null;
|
|
566
|
+
this.remoteMediaTracks = {};
|
|
562
567
|
this.roomUrl = null;
|
|
563
568
|
this.handleConnectionStatusChange = (status) => {
|
|
564
569
|
if (status === "connected") {
|
|
@@ -568,6 +573,41 @@ class Assistant extends EventEmitter$1 {
|
|
|
568
573
|
this.emit(ASSISTANT_LEFT_ROOM, { roomUrl: this.roomUrl || "" });
|
|
569
574
|
}
|
|
570
575
|
};
|
|
576
|
+
this.handleRemoteParticipantsTracksChange = (remoteParticipants) => {
|
|
577
|
+
const currentRemoteMediaTracks = remoteParticipants.flatMap(({ id: participantId, stream }) => {
|
|
578
|
+
if (!stream) {
|
|
579
|
+
return [];
|
|
580
|
+
}
|
|
581
|
+
const tracks = stream.getTracks();
|
|
582
|
+
tracks.forEach((track) => {
|
|
583
|
+
if (!this.remoteMediaTracks[track.id]) {
|
|
584
|
+
const eventName = track.kind === "video" ? PARTICIPANT_VIDEO_TRACK_ADDED : PARTICIPANT_AUDIO_TRACK_ADDED;
|
|
585
|
+
this.emit(eventName, {
|
|
586
|
+
participantId,
|
|
587
|
+
stream,
|
|
588
|
+
track,
|
|
589
|
+
});
|
|
590
|
+
this.remoteMediaTracks[track.id] = {
|
|
591
|
+
participantId,
|
|
592
|
+
stream,
|
|
593
|
+
track,
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
});
|
|
597
|
+
return tracks;
|
|
598
|
+
});
|
|
599
|
+
Object.values(this.remoteMediaTracks).forEach(({ participantId, stream, track }) => {
|
|
600
|
+
if (!currentRemoteMediaTracks.includes(track)) {
|
|
601
|
+
const eventName = track.kind === "video" ? PARTICIPANT_VIDEO_TRACK_REMOVED : PARTICIPANT_AUDIO_TRACK_REMOVED;
|
|
602
|
+
this.emit(eventName, {
|
|
603
|
+
participantId,
|
|
604
|
+
stream,
|
|
605
|
+
track,
|
|
606
|
+
});
|
|
607
|
+
delete this.remoteMediaTracks[track.id];
|
|
608
|
+
}
|
|
609
|
+
});
|
|
610
|
+
};
|
|
571
611
|
this.assistantKey = assistantKey;
|
|
572
612
|
this.client = new WherebyClient();
|
|
573
613
|
this.roomConnection = this.client.getRoomConnection();
|
|
@@ -592,8 +632,9 @@ class Assistant extends EventEmitter$1 {
|
|
|
592
632
|
const audioMixer = new AudioMixer(handleStreamReady);
|
|
593
633
|
this.combinedStream = audioMixer.getCombinedAudioStream();
|
|
594
634
|
this.roomConnection.subscribeToRemoteParticipants(audioMixer.handleRemoteParticipants.bind(audioMixer));
|
|
595
|
-
this.roomConnection.subscribeToConnectionStatus(this.handleConnectionStatusChange);
|
|
596
635
|
}
|
|
636
|
+
this.roomConnection.subscribeToConnectionStatus(this.handleConnectionStatusChange);
|
|
637
|
+
this.roomConnection.subscribeToRemoteParticipants(this.handleRemoteParticipantsTracksChange);
|
|
597
638
|
}
|
|
598
639
|
joinRoom(roomUrl) {
|
|
599
640
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -710,7 +751,7 @@ const webhookRouter = (webhookTriggers, emitter) => {
|
|
|
710
751
|
res.status(200);
|
|
711
752
|
res.end();
|
|
712
753
|
});
|
|
713
|
-
router.post("/", jsonParser, (req, res) => {
|
|
754
|
+
router.post("/", jsonParser, (req, res) => __awaiter(void 0, void 0, void 0, function* () {
|
|
714
755
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
715
756
|
assert(req.body, "message body is required");
|
|
716
757
|
assert("type" in req.body, "webhook type is required");
|
|
@@ -718,19 +759,19 @@ const webhookRouter = (webhookTriggers, emitter) => {
|
|
|
718
759
|
switch (req.body.type) {
|
|
719
760
|
case "room.client.joined":
|
|
720
761
|
shouldTriggerOnReceivedWebhook =
|
|
721
|
-
(_b = (_a = webhookTriggers["room.client.joined"]) === null || _a === void 0 ? void 0 : _a.call(webhookTriggers, req.body)) !== null && _b !== void 0 ? _b : false;
|
|
762
|
+
(_b = (yield ((_a = webhookTriggers["room.client.joined"]) === null || _a === void 0 ? void 0 : _a.call(webhookTriggers, req.body)))) !== null && _b !== void 0 ? _b : false;
|
|
722
763
|
break;
|
|
723
764
|
case "room.client.left":
|
|
724
765
|
shouldTriggerOnReceivedWebhook =
|
|
725
|
-
(_d = (_c = webhookTriggers["room.client.left"]) === null || _c === void 0 ? void 0 : _c.call(webhookTriggers, req.body)) !== null && _d !== void 0 ? _d : false;
|
|
766
|
+
(_d = (yield ((_c = webhookTriggers["room.client.left"]) === null || _c === void 0 ? void 0 : _c.call(webhookTriggers, req.body)))) !== null && _d !== void 0 ? _d : false;
|
|
726
767
|
break;
|
|
727
768
|
case "room.session.started":
|
|
728
769
|
shouldTriggerOnReceivedWebhook =
|
|
729
|
-
(_f = (_e = webhookTriggers["room.session.started"]) === null || _e === void 0 ? void 0 : _e.call(webhookTriggers, req.body)) !== null && _f !== void 0 ? _f : false;
|
|
770
|
+
(_f = (yield ((_e = webhookTriggers["room.session.started"]) === null || _e === void 0 ? void 0 : _e.call(webhookTriggers, req.body)))) !== null && _f !== void 0 ? _f : false;
|
|
730
771
|
break;
|
|
731
772
|
case "room.session.ended":
|
|
732
773
|
shouldTriggerOnReceivedWebhook =
|
|
733
|
-
(_h = (_g = webhookTriggers["room.session.ended"]) === null || _g === void 0 ? void 0 : _g.call(webhookTriggers, req.body)) !== null && _h !== void 0 ? _h : false;
|
|
774
|
+
(_h = (yield ((_g = webhookTriggers["room.session.ended"]) === null || _g === void 0 ? void 0 : _g.call(webhookTriggers, req.body)))) !== null && _h !== void 0 ? _h : false;
|
|
734
775
|
break;
|
|
735
776
|
}
|
|
736
777
|
if (shouldTriggerOnReceivedWebhook) {
|
|
@@ -739,7 +780,7 @@ const webhookRouter = (webhookTriggers, emitter) => {
|
|
|
739
780
|
}
|
|
740
781
|
res.status(200);
|
|
741
782
|
res.end();
|
|
742
|
-
});
|
|
783
|
+
}));
|
|
743
784
|
return router;
|
|
744
785
|
};
|
|
745
786
|
class Trigger extends EventEmitter {
|
|
@@ -752,13 +793,10 @@ class Trigger extends EventEmitter {
|
|
|
752
793
|
const app = express();
|
|
753
794
|
const router = webhookRouter(this.webhookTriggers, this);
|
|
754
795
|
app.use(router);
|
|
755
|
-
|
|
796
|
+
app.listen(this.port, () => {
|
|
756
797
|
// console.log(`Bot trigger server now running on port[${this.port}]`);
|
|
757
798
|
});
|
|
758
|
-
process.on("SIGTERM", () => {
|
|
759
|
-
server.close();
|
|
760
|
-
});
|
|
761
799
|
}
|
|
762
800
|
}
|
|
763
801
|
|
|
764
|
-
export { ASSISTANT_JOINED_ROOM, ASSISTANT_LEFT_ROOM, AUDIO_STREAM_READY, Assistant, AudioSink, AudioSource, TRIGGER_EVENT_SUCCESS, Trigger };
|
|
802
|
+
export { ASSISTANT_JOINED_ROOM, ASSISTANT_LEFT_ROOM, AUDIO_STREAM_READY, Assistant, AudioSink, AudioSource, PARTICIPANT_AUDIO_TRACK_ADDED, PARTICIPANT_AUDIO_TRACK_REMOVED, PARTICIPANT_VIDEO_TRACK_ADDED, PARTICIPANT_VIDEO_TRACK_REMOVED, TRIGGER_EVENT_SUCCESS, Trigger };
|
package/dist/legacy-esm.js
CHANGED
|
@@ -14,6 +14,10 @@ const TRIGGER_EVENT_SUCCESS = "trigger_event_success";
|
|
|
14
14
|
const AUDIO_STREAM_READY = "AUDIO_STREAM_READY";
|
|
15
15
|
const ASSISTANT_JOINED_ROOM = "ASSISTANT_JOINED_ROOM";
|
|
16
16
|
const ASSISTANT_LEFT_ROOM = "ASSISTANT_LEFT_ROOM";
|
|
17
|
+
const PARTICIPANT_VIDEO_TRACK_ADDED = "PARTICIPANT_VIDEO_TRACK_ADDED";
|
|
18
|
+
const PARTICIPANT_VIDEO_TRACK_REMOVED = "PARTICIPANT_VIDEO_TRACK_REMOVED";
|
|
19
|
+
const PARTICIPANT_AUDIO_TRACK_ADDED = "PARTICIPANT_AUDIO_TRACK_ADDED";
|
|
20
|
+
const PARTICIPANT_AUDIO_TRACK_REMOVED = "PARTICIPANT_AUDIO_TRACK_REMOVED";
|
|
17
21
|
|
|
18
22
|
/******************************************************************************
|
|
19
23
|
Copyright (c) Microsoft Corporation.
|
|
@@ -559,6 +563,7 @@ class Assistant extends EventEmitter$1 {
|
|
|
559
563
|
this.mediaStream = null;
|
|
560
564
|
this.audioSource = null;
|
|
561
565
|
this.combinedStream = null;
|
|
566
|
+
this.remoteMediaTracks = {};
|
|
562
567
|
this.roomUrl = null;
|
|
563
568
|
this.handleConnectionStatusChange = (status) => {
|
|
564
569
|
if (status === "connected") {
|
|
@@ -568,6 +573,41 @@ class Assistant extends EventEmitter$1 {
|
|
|
568
573
|
this.emit(ASSISTANT_LEFT_ROOM, { roomUrl: this.roomUrl || "" });
|
|
569
574
|
}
|
|
570
575
|
};
|
|
576
|
+
this.handleRemoteParticipantsTracksChange = (remoteParticipants) => {
|
|
577
|
+
const currentRemoteMediaTracks = remoteParticipants.flatMap(({ id: participantId, stream }) => {
|
|
578
|
+
if (!stream) {
|
|
579
|
+
return [];
|
|
580
|
+
}
|
|
581
|
+
const tracks = stream.getTracks();
|
|
582
|
+
tracks.forEach((track) => {
|
|
583
|
+
if (!this.remoteMediaTracks[track.id]) {
|
|
584
|
+
const eventName = track.kind === "video" ? PARTICIPANT_VIDEO_TRACK_ADDED : PARTICIPANT_AUDIO_TRACK_ADDED;
|
|
585
|
+
this.emit(eventName, {
|
|
586
|
+
participantId,
|
|
587
|
+
stream,
|
|
588
|
+
track,
|
|
589
|
+
});
|
|
590
|
+
this.remoteMediaTracks[track.id] = {
|
|
591
|
+
participantId,
|
|
592
|
+
stream,
|
|
593
|
+
track,
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
});
|
|
597
|
+
return tracks;
|
|
598
|
+
});
|
|
599
|
+
Object.values(this.remoteMediaTracks).forEach(({ participantId, stream, track }) => {
|
|
600
|
+
if (!currentRemoteMediaTracks.includes(track)) {
|
|
601
|
+
const eventName = track.kind === "video" ? PARTICIPANT_VIDEO_TRACK_REMOVED : PARTICIPANT_AUDIO_TRACK_REMOVED;
|
|
602
|
+
this.emit(eventName, {
|
|
603
|
+
participantId,
|
|
604
|
+
stream,
|
|
605
|
+
track,
|
|
606
|
+
});
|
|
607
|
+
delete this.remoteMediaTracks[track.id];
|
|
608
|
+
}
|
|
609
|
+
});
|
|
610
|
+
};
|
|
571
611
|
this.assistantKey = assistantKey;
|
|
572
612
|
this.client = new WherebyClient();
|
|
573
613
|
this.roomConnection = this.client.getRoomConnection();
|
|
@@ -592,8 +632,9 @@ class Assistant extends EventEmitter$1 {
|
|
|
592
632
|
const audioMixer = new AudioMixer(handleStreamReady);
|
|
593
633
|
this.combinedStream = audioMixer.getCombinedAudioStream();
|
|
594
634
|
this.roomConnection.subscribeToRemoteParticipants(audioMixer.handleRemoteParticipants.bind(audioMixer));
|
|
595
|
-
this.roomConnection.subscribeToConnectionStatus(this.handleConnectionStatusChange);
|
|
596
635
|
}
|
|
636
|
+
this.roomConnection.subscribeToConnectionStatus(this.handleConnectionStatusChange);
|
|
637
|
+
this.roomConnection.subscribeToRemoteParticipants(this.handleRemoteParticipantsTracksChange);
|
|
597
638
|
}
|
|
598
639
|
joinRoom(roomUrl) {
|
|
599
640
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -710,7 +751,7 @@ const webhookRouter = (webhookTriggers, emitter) => {
|
|
|
710
751
|
res.status(200);
|
|
711
752
|
res.end();
|
|
712
753
|
});
|
|
713
|
-
router.post("/", jsonParser, (req, res) => {
|
|
754
|
+
router.post("/", jsonParser, (req, res) => __awaiter(void 0, void 0, void 0, function* () {
|
|
714
755
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
715
756
|
assert(req.body, "message body is required");
|
|
716
757
|
assert("type" in req.body, "webhook type is required");
|
|
@@ -718,19 +759,19 @@ const webhookRouter = (webhookTriggers, emitter) => {
|
|
|
718
759
|
switch (req.body.type) {
|
|
719
760
|
case "room.client.joined":
|
|
720
761
|
shouldTriggerOnReceivedWebhook =
|
|
721
|
-
(_b = (_a = webhookTriggers["room.client.joined"]) === null || _a === void 0 ? void 0 : _a.call(webhookTriggers, req.body)) !== null && _b !== void 0 ? _b : false;
|
|
762
|
+
(_b = (yield ((_a = webhookTriggers["room.client.joined"]) === null || _a === void 0 ? void 0 : _a.call(webhookTriggers, req.body)))) !== null && _b !== void 0 ? _b : false;
|
|
722
763
|
break;
|
|
723
764
|
case "room.client.left":
|
|
724
765
|
shouldTriggerOnReceivedWebhook =
|
|
725
|
-
(_d = (_c = webhookTriggers["room.client.left"]) === null || _c === void 0 ? void 0 : _c.call(webhookTriggers, req.body)) !== null && _d !== void 0 ? _d : false;
|
|
766
|
+
(_d = (yield ((_c = webhookTriggers["room.client.left"]) === null || _c === void 0 ? void 0 : _c.call(webhookTriggers, req.body)))) !== null && _d !== void 0 ? _d : false;
|
|
726
767
|
break;
|
|
727
768
|
case "room.session.started":
|
|
728
769
|
shouldTriggerOnReceivedWebhook =
|
|
729
|
-
(_f = (_e = webhookTriggers["room.session.started"]) === null || _e === void 0 ? void 0 : _e.call(webhookTriggers, req.body)) !== null && _f !== void 0 ? _f : false;
|
|
770
|
+
(_f = (yield ((_e = webhookTriggers["room.session.started"]) === null || _e === void 0 ? void 0 : _e.call(webhookTriggers, req.body)))) !== null && _f !== void 0 ? _f : false;
|
|
730
771
|
break;
|
|
731
772
|
case "room.session.ended":
|
|
732
773
|
shouldTriggerOnReceivedWebhook =
|
|
733
|
-
(_h = (_g = webhookTriggers["room.session.ended"]) === null || _g === void 0 ? void 0 : _g.call(webhookTriggers, req.body)) !== null && _h !== void 0 ? _h : false;
|
|
774
|
+
(_h = (yield ((_g = webhookTriggers["room.session.ended"]) === null || _g === void 0 ? void 0 : _g.call(webhookTriggers, req.body)))) !== null && _h !== void 0 ? _h : false;
|
|
734
775
|
break;
|
|
735
776
|
}
|
|
736
777
|
if (shouldTriggerOnReceivedWebhook) {
|
|
@@ -739,7 +780,7 @@ const webhookRouter = (webhookTriggers, emitter) => {
|
|
|
739
780
|
}
|
|
740
781
|
res.status(200);
|
|
741
782
|
res.end();
|
|
742
|
-
});
|
|
783
|
+
}));
|
|
743
784
|
return router;
|
|
744
785
|
};
|
|
745
786
|
class Trigger extends EventEmitter {
|
|
@@ -752,13 +793,10 @@ class Trigger extends EventEmitter {
|
|
|
752
793
|
const app = express();
|
|
753
794
|
const router = webhookRouter(this.webhookTriggers, this);
|
|
754
795
|
app.use(router);
|
|
755
|
-
|
|
796
|
+
app.listen(this.port, () => {
|
|
756
797
|
// console.log(`Bot trigger server now running on port[${this.port}]`);
|
|
757
798
|
});
|
|
758
|
-
process.on("SIGTERM", () => {
|
|
759
|
-
server.close();
|
|
760
|
-
});
|
|
761
799
|
}
|
|
762
800
|
}
|
|
763
801
|
|
|
764
|
-
export { ASSISTANT_JOINED_ROOM, ASSISTANT_LEFT_ROOM, AUDIO_STREAM_READY, Assistant, AudioSink, AudioSource, TRIGGER_EVENT_SUCCESS, Trigger };
|
|
802
|
+
export { ASSISTANT_JOINED_ROOM, ASSISTANT_LEFT_ROOM, AUDIO_STREAM_READY, Assistant, AudioSink, AudioSource, PARTICIPANT_AUDIO_TRACK_ADDED, PARTICIPANT_AUDIO_TRACK_REMOVED, PARTICIPANT_VIDEO_TRACK_ADDED, PARTICIPANT_VIDEO_TRACK_REMOVED, TRIGGER_EVENT_SUCCESS, Trigger };
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@whereby.com/assistant-sdk",
|
|
3
3
|
"description": "Assistant SDK for whereby.com",
|
|
4
4
|
"author": "Whereby AS",
|
|
5
|
-
"version": "0.0.0-canary-
|
|
5
|
+
"version": "0.0.0-canary-20250923130059",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"files": [
|
|
8
8
|
"dist",
|
|
@@ -51,10 +51,10 @@
|
|
|
51
51
|
"prettier": "^3.5.3",
|
|
52
52
|
"typescript": "^5.8.3",
|
|
53
53
|
"@whereby.com/eslint-config": "0.1.0",
|
|
54
|
+
"@whereby.com/jest-config": "0.1.0",
|
|
54
55
|
"@whereby.com/prettier-config": "0.1.0",
|
|
55
56
|
"@whereby.com/rollup-config": "0.1.0",
|
|
56
|
-
"@whereby.com/tsconfig": "0.1.0"
|
|
57
|
-
"@whereby.com/jest-config": "0.1.0"
|
|
57
|
+
"@whereby.com/tsconfig": "0.1.0"
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
60
|
"@roamhq/wrtc": "github:whereby/node-webrtc#patch/rtc_audio_source",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"express": "5.1.0",
|
|
65
65
|
"uuid": "^11.0.3",
|
|
66
66
|
"ws": "^8.18.0",
|
|
67
|
-
"@whereby.com/core": "0.0.0-canary-
|
|
67
|
+
"@whereby.com/core": "0.0.0-canary-20250923130059"
|
|
68
68
|
},
|
|
69
69
|
"prettier": "@whereby.com/prettier-config",
|
|
70
70
|
"scripts": {
|