Skip to content

Commit e0dd136

Browse files
committed
add: "end" method for force ending call + jsdocs
1 parent 16a04ea commit e0dd136

File tree

2 files changed

+62
-10
lines changed

2 files changed

+62
-10
lines changed

example/src/App.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ function App() {
175175
};
176176

177177
const stopCall = () => {
178-
vapi.stop();
178+
vapi.end();
179179
};
180180

181181
const reconnectCall = async () => {

vapi.ts

Lines changed: 61 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ import {
2828
safeSetInputDevicesAsync,
2929
} from './daily-guards';
3030

31+
export interface EndCallMessage {
32+
type: 'end-call';
33+
}
34+
3135
export interface AddMessageMessage {
3236
type: 'add-message';
3337
message: ChatCompletionMessageParam;
@@ -51,7 +55,8 @@ export interface SayMessage {
5155
type VapiClientToServerMessage =
5256
| AddMessageMessage
5357
| ControlMessages
54-
| SayMessage;
58+
| SayMessage
59+
| EndCallMessage;
5560

5661
type VapiEventNames =
5762
| 'call-end'
@@ -123,6 +128,31 @@ type StartCallOptions = {
123128
roomDeleteOnUserLeaveEnabled?: boolean;
124129
}
125130

131+
type WebCall = {
132+
/**
133+
* The Vapi WebCall URL. This is the URL that the call will be joined on.
134+
*
135+
* call.webCallUrl or call.transport.callUrl
136+
*/
137+
webCallUrl: string;
138+
/**
139+
* The Vapi WebCall ID. This is the ID of the call.
140+
*
141+
* call.id
142+
*/
143+
id?: string;
144+
/**
145+
* The Vapi WebCall artifact plan. This is the artifact plan of the call.
146+
*/
147+
artifactPlan?: { videoRecordingEnabled?: boolean };
148+
/**
149+
* The Vapi WebCall assistant. This is the assistant of the call.
150+
*
151+
* call.assistant
152+
*/
153+
assistant?: { voice?: { provider?: string } };
154+
}
155+
126156
async function startAudioPlayer(
127157
player: HTMLAudioElement,
128158
track: MediaStreamTrack,
@@ -816,6 +846,12 @@ export default class Vapi extends VapiEventEmitter {
816846
}, 1000);
817847
}
818848

849+
/**
850+
* Stops the call by destroying the Daily call object.
851+
*
852+
* If `roomDeleteOnUserLeaveEnabled` is set to `false`, the Vapi call will be kept alive, allowing reconnections to the same call using the `reconnect` method.
853+
* If `roomDeleteOnUserLeaveEnabled` is set to `true`, the Vapi call will also be destroyed, preventing any reconnections.
854+
*/
819855
async stop(): Promise<void> {
820856
this.started = false;
821857
if (this.call) {
@@ -825,6 +861,11 @@ export default class Vapi extends VapiEventEmitter {
825861
this.speakingTimeout = null;
826862
}
827863

864+
/**
865+
* Sends a Live Call Control message to the Vapi server.
866+
*
867+
* Docs: https://docs.vapi.ai/calls/call-features
868+
*/
828869
send(message: VapiClientToServerMessage): void {
829870
this.call?.sendAppMessage(JSON.stringify(message));
830871
}
@@ -851,6 +892,18 @@ export default class Vapi extends VapiEventEmitter {
851892
});
852893
}
853894

895+
/**
896+
* Ends the call immediately by sending a `end-call` message using Live Call Control, and destroys the Daily call object.
897+
*
898+
* This method always ends the call, regardless of the `roomDeleteOnUserLeaveEnabled` option.
899+
*/
900+
public end() {
901+
this.send({
902+
type: 'end-call',
903+
});
904+
this.stop();
905+
}
906+
854907
public setInputDevicesAsync(
855908
options: Parameters<DailyCall['setInputDevicesAsync']>[0],
856909
) {
@@ -904,12 +957,13 @@ export default class Vapi extends VapiEventEmitter {
904957
this.call?.stopScreenShare();
905958
}
906959

907-
async reconnect(webCall: {
908-
webCallUrl: string;
909-
id?: string;
910-
artifactPlan?: { videoRecordingEnabled?: boolean };
911-
assistant?: { voice?: { provider?: string } };
912-
}): Promise<void> {
960+
/**
961+
* Reconnects to an active call.
962+
*
963+
*
964+
* @param webCall
965+
*/
966+
async reconnect(webCall: WebCall): Promise<void> {
913967
const startTime = Date.now();
914968

915969
if (this.started) {
@@ -1272,8 +1326,6 @@ export default class Vapi extends VapiEventEmitter {
12721326
timestamp: new Date().toISOString()
12731327
});
12741328

1275-
// For reconnection, manually emit call-start since 'listening' message may not be sent
1276-
console.log('Reconnect completed successfully - manually emitting call-start event');
12771329
this.emit('call-start');
12781330

12791331
} catch (e) {

0 commit comments

Comments
 (0)