@ipcom/asterisk-ari 0.0.153 → 0.0.155
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/README.md +117 -32
- package/dist/cjs/index.cjs +755 -95
- package/dist/cjs/index.cjs.map +4 -4
- package/dist/esm/index.js +754 -95
- package/dist/esm/index.js.map +4 -4
- package/dist/types/ari-client/ariClient.d.ts +13 -1
- package/dist/types/ari-client/ariClient.d.ts.map +1 -1
- package/dist/types/ari-client/interfaces/events.types.d.ts +5 -0
- package/dist/types/ari-client/interfaces/events.types.d.ts.map +1 -1
- package/dist/types/ari-client/interfaces/index.d.ts +1 -1
- package/dist/types/ari-client/interfaces/index.d.ts.map +1 -1
- package/dist/types/ari-client/resources/bridges.d.ts +365 -14
- package/dist/types/ari-client/resources/bridges.d.ts.map +1 -1
- package/dist/types/ari-client/websocketClient.d.ts +73 -20
- package/dist/types/ari-client/websocketClient.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/esm/index.js
CHANGED
|
@@ -789,7 +789,7 @@ var Applications = class {
|
|
|
789
789
|
}
|
|
790
790
|
/**
|
|
791
791
|
* Lists all applications.
|
|
792
|
-
*
|
|
792
|
+
*
|
|
793
793
|
* @returns A promise that resolves to an array of Application objects.
|
|
794
794
|
* @throws {Error} If the API response is not an array.
|
|
795
795
|
*/
|
|
@@ -802,7 +802,7 @@ var Applications = class {
|
|
|
802
802
|
}
|
|
803
803
|
/**
|
|
804
804
|
* Retrieves details of a specific application.
|
|
805
|
-
*
|
|
805
|
+
*
|
|
806
806
|
* @param appName - The name of the application to retrieve details for.
|
|
807
807
|
* @returns A promise that resolves to an ApplicationDetails object.
|
|
808
808
|
* @throws {Error} If there's an error fetching the application details.
|
|
@@ -819,7 +819,7 @@ var Applications = class {
|
|
|
819
819
|
}
|
|
820
820
|
/**
|
|
821
821
|
* Sends a message to a specific application.
|
|
822
|
-
*
|
|
822
|
+
*
|
|
823
823
|
* @param appName - The name of the application to send the message to.
|
|
824
824
|
* @param body - The message to be sent, containing an event and optional data.
|
|
825
825
|
* @returns A promise that resolves when the message is successfully sent.
|
|
@@ -912,97 +912,681 @@ var Asterisk = class {
|
|
|
912
912
|
};
|
|
913
913
|
|
|
914
914
|
// src/ari-client/resources/bridges.ts
|
|
915
|
+
import { EventEmitter } from "events";
|
|
916
|
+
import { isAxiosError as isAxiosError2 } from "axios";
|
|
917
|
+
|
|
918
|
+
// src/ari-client/interfaces/events.types.ts
|
|
919
|
+
var bridgeEvents = [
|
|
920
|
+
"BridgeCreated",
|
|
921
|
+
"BridgeDestroyed",
|
|
922
|
+
"BridgeMerged",
|
|
923
|
+
"BridgeBlindTransfer",
|
|
924
|
+
"BridgeAttendedTransfer",
|
|
925
|
+
"BridgeVideoSourceChanged"
|
|
926
|
+
];
|
|
927
|
+
|
|
928
|
+
// src/ari-client/utils.ts
|
|
929
|
+
function toQueryParams2(options) {
|
|
930
|
+
return new URLSearchParams(
|
|
931
|
+
Object.entries(options).filter(([, value]) => value !== void 0).map(([key, value]) => [key, value])
|
|
932
|
+
).toString();
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
// src/ari-client/resources/bridges.ts
|
|
936
|
+
var getErrorMessage = (error) => {
|
|
937
|
+
if (isAxiosError2(error)) {
|
|
938
|
+
return error.response?.data?.message || error.message || "Um erro do axios ocorreu";
|
|
939
|
+
}
|
|
940
|
+
if (error instanceof Error) {
|
|
941
|
+
return error.message;
|
|
942
|
+
}
|
|
943
|
+
return "Um erro desconhecido ocorreu";
|
|
944
|
+
};
|
|
945
|
+
var BridgeInstance = class {
|
|
946
|
+
/**
|
|
947
|
+
* Creates a new BridgeInstance.
|
|
948
|
+
*
|
|
949
|
+
* @param client - The AriClient instance for making API calls.
|
|
950
|
+
* @param baseClient - The BaseClient instance for making HTTP requests.
|
|
951
|
+
* @param bridgeId - Optional. The ID of the bridge. If not provided, a new ID will be generated.
|
|
952
|
+
*/
|
|
953
|
+
constructor(client, baseClient, bridgeId) {
|
|
954
|
+
this.client = client;
|
|
955
|
+
this.baseClient = baseClient;
|
|
956
|
+
this.id = bridgeId || `bridge-${Date.now()}`;
|
|
957
|
+
console.log(`BridgeInstance inicializada com ID: ${this.id}`);
|
|
958
|
+
}
|
|
959
|
+
eventEmitter = new EventEmitter();
|
|
960
|
+
bridgeData = null;
|
|
961
|
+
id;
|
|
962
|
+
/**
|
|
963
|
+
* Registers a listener for specific bridge events.
|
|
964
|
+
*
|
|
965
|
+
* @param event - The type of event to listen for.
|
|
966
|
+
* @param listener - The callback function to be called when the event occurs.
|
|
967
|
+
*/
|
|
968
|
+
/**
|
|
969
|
+
* Registers a listener for specific bridge events.
|
|
970
|
+
*
|
|
971
|
+
* This method allows you to attach an event listener to the bridge instance for a specific event type.
|
|
972
|
+
* When the specified event occurs, the provided listener function will be called with the event data.
|
|
973
|
+
*
|
|
974
|
+
* @template T - The specific type of WebSocketEvent to listen for.
|
|
975
|
+
* It receives the event data as its parameter.
|
|
976
|
+
* @returns {void}
|
|
977
|
+
*
|
|
978
|
+
* @example
|
|
979
|
+
* bridge.on('BridgeCreated', (event) => {
|
|
980
|
+
* console.log('Bridge created:', event.bridge.id);
|
|
981
|
+
* });
|
|
982
|
+
* @param event
|
|
983
|
+
* @param listener
|
|
984
|
+
*/
|
|
985
|
+
on(event, listener) {
|
|
986
|
+
if (!event) {
|
|
987
|
+
throw new Error("Event type is required");
|
|
988
|
+
}
|
|
989
|
+
const wrappedListener = (data) => {
|
|
990
|
+
if ("bridge" in data && data.bridge?.id === this.id) {
|
|
991
|
+
listener(data);
|
|
992
|
+
}
|
|
993
|
+
};
|
|
994
|
+
this.eventEmitter.on(event, wrappedListener);
|
|
995
|
+
console.log(`Event listener registered for ${event} on bridge ${this.id}`);
|
|
996
|
+
}
|
|
997
|
+
/**
|
|
998
|
+
* Registers a one-time listener for specific bridge events.
|
|
999
|
+
*
|
|
1000
|
+
* @param event - The type of event to listen for.
|
|
1001
|
+
* @param listener - The callback function to be called when the event occurs.
|
|
1002
|
+
*/
|
|
1003
|
+
once(event, listener) {
|
|
1004
|
+
if (!event) {
|
|
1005
|
+
throw new Error("Event type is required");
|
|
1006
|
+
}
|
|
1007
|
+
const wrappedListener = (data) => {
|
|
1008
|
+
if ("bridge" in data && data.bridge?.id === this.id) {
|
|
1009
|
+
listener(data);
|
|
1010
|
+
}
|
|
1011
|
+
};
|
|
1012
|
+
this.eventEmitter.once(event, wrappedListener);
|
|
1013
|
+
console.log(
|
|
1014
|
+
`One-time listener registered for ${event} on bridge ${this.id}`
|
|
1015
|
+
);
|
|
1016
|
+
}
|
|
1017
|
+
/**
|
|
1018
|
+
* Removes event listener(s) from the bridge.
|
|
1019
|
+
*
|
|
1020
|
+
* @param event - The type of event to remove listeners for.
|
|
1021
|
+
* @param listener - Optional. The specific listener to remove. If not provided, all listeners for the event will be removed.
|
|
1022
|
+
*/
|
|
1023
|
+
off(event, listener) {
|
|
1024
|
+
if (!event) {
|
|
1025
|
+
throw new Error("Event type is required");
|
|
1026
|
+
}
|
|
1027
|
+
if (listener) {
|
|
1028
|
+
this.eventEmitter.off(event, listener);
|
|
1029
|
+
console.log(
|
|
1030
|
+
`Specific listener removed for ${event} on bridge ${this.id}`
|
|
1031
|
+
);
|
|
1032
|
+
} else {
|
|
1033
|
+
this.eventEmitter.removeAllListeners(event);
|
|
1034
|
+
console.log(`All listeners removed for ${event} on bridge ${this.id}`);
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
/**
|
|
1038
|
+
* Emits an event if it corresponds to the current bridge.
|
|
1039
|
+
*
|
|
1040
|
+
* @param event - The WebSocketEvent to emit.
|
|
1041
|
+
*/
|
|
1042
|
+
emitEvent(event) {
|
|
1043
|
+
if (!event) {
|
|
1044
|
+
console.warn("Invalid event received");
|
|
1045
|
+
return;
|
|
1046
|
+
}
|
|
1047
|
+
if ("bridge" in event && event.bridge?.id === this.id) {
|
|
1048
|
+
this.eventEmitter.emit(event.type, event);
|
|
1049
|
+
console.log(`Event ${event.type} emitted for bridge ${this.id}`);
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
/**
|
|
1053
|
+
* Removes all event listeners from this bridge instance.
|
|
1054
|
+
*/
|
|
1055
|
+
removeAllListeners() {
|
|
1056
|
+
this.eventEmitter.removeAllListeners();
|
|
1057
|
+
console.log(`All listeners removed from bridge ${this.id}`);
|
|
1058
|
+
}
|
|
1059
|
+
/**
|
|
1060
|
+
* Retrieves the current details of the bridge.
|
|
1061
|
+
*
|
|
1062
|
+
* @returns A Promise that resolves to the Bridge object containing the current details.
|
|
1063
|
+
* @throws An error if the retrieval fails.
|
|
1064
|
+
*/
|
|
1065
|
+
async get() {
|
|
1066
|
+
try {
|
|
1067
|
+
if (!this.id) {
|
|
1068
|
+
throw new Error("No bridge associated with this instance");
|
|
1069
|
+
}
|
|
1070
|
+
this.bridgeData = await this.baseClient.get(
|
|
1071
|
+
`/bridges/${this.id}`
|
|
1072
|
+
);
|
|
1073
|
+
console.log(`Details retrieved for bridge ${this.id}`);
|
|
1074
|
+
return this.bridgeData;
|
|
1075
|
+
} catch (error) {
|
|
1076
|
+
const message = getErrorMessage(error);
|
|
1077
|
+
console.error(`Error retrieving details for bridge ${this.id}:`, message);
|
|
1078
|
+
throw new Error(`Failed to get bridge details: ${message}`);
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
/**
|
|
1082
|
+
* Adds channels to the bridge.
|
|
1083
|
+
*
|
|
1084
|
+
* @param request - The AddChannelRequest object containing the channels to add.
|
|
1085
|
+
* @throws An error if the operation fails.
|
|
1086
|
+
*/
|
|
1087
|
+
async add(request) {
|
|
1088
|
+
try {
|
|
1089
|
+
const queryParams = toQueryParams2({
|
|
1090
|
+
channel: Array.isArray(request.channel) ? request.channel.join(",") : request.channel,
|
|
1091
|
+
...request.role && { role: request.role }
|
|
1092
|
+
});
|
|
1093
|
+
await this.baseClient.post(
|
|
1094
|
+
`/bridges/${this.id}/addChannel?${queryParams}`
|
|
1095
|
+
);
|
|
1096
|
+
console.log(`Channels added to bridge ${this.id}`);
|
|
1097
|
+
} catch (error) {
|
|
1098
|
+
const message = getErrorMessage(error);
|
|
1099
|
+
console.error(`Error adding channels to bridge ${this.id}:`, message);
|
|
1100
|
+
throw new Error(`Failed to add channels: ${message}`);
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
/**
|
|
1104
|
+
* Removes channels from the bridge.
|
|
1105
|
+
*
|
|
1106
|
+
* @param request - The RemoveChannelRequest object containing the channels to remove.
|
|
1107
|
+
* @throws An error if the operation fails.
|
|
1108
|
+
*/
|
|
1109
|
+
async remove(request) {
|
|
1110
|
+
try {
|
|
1111
|
+
const queryParams = toQueryParams2({
|
|
1112
|
+
channel: Array.isArray(request.channel) ? request.channel.join(",") : request.channel
|
|
1113
|
+
});
|
|
1114
|
+
await this.baseClient.post(
|
|
1115
|
+
`/bridges/${this.id}/removeChannel?${queryParams}`
|
|
1116
|
+
);
|
|
1117
|
+
console.log(`Channels removed from bridge ${this.id}`);
|
|
1118
|
+
} catch (error) {
|
|
1119
|
+
const message = getErrorMessage(error);
|
|
1120
|
+
console.error(`Error removing channels from bridge ${this.id}:`, message);
|
|
1121
|
+
throw new Error(`Failed to remove channels: ${message}`);
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
/**
|
|
1125
|
+
* Plays media on the bridge.
|
|
1126
|
+
*
|
|
1127
|
+
* @param request - The PlayMediaRequest object containing the media details to play.
|
|
1128
|
+
* @returns A Promise that resolves to a BridgePlayback object.
|
|
1129
|
+
* @throws An error if the operation fails.
|
|
1130
|
+
*/
|
|
1131
|
+
async playMedia(request) {
|
|
1132
|
+
try {
|
|
1133
|
+
const queryParams = new URLSearchParams({
|
|
1134
|
+
...request.lang && { lang: request.lang },
|
|
1135
|
+
...request.offsetms && { offsetms: request.offsetms.toString() },
|
|
1136
|
+
...request.skipms && { skipms: request.skipms.toString() },
|
|
1137
|
+
...request.playbackId && { playbackId: request.playbackId }
|
|
1138
|
+
}).toString();
|
|
1139
|
+
const result = await this.baseClient.post(
|
|
1140
|
+
`/bridges/${this.id}/play?${queryParams}`,
|
|
1141
|
+
{ media: request.media }
|
|
1142
|
+
);
|
|
1143
|
+
console.log(`Media playback started on bridge ${this.id}`);
|
|
1144
|
+
return result;
|
|
1145
|
+
} catch (error) {
|
|
1146
|
+
const message = getErrorMessage(error);
|
|
1147
|
+
console.error(`Error playing media on bridge ${this.id}:`, message);
|
|
1148
|
+
throw new Error(`Failed to play media: ${message}`);
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
/**
|
|
1152
|
+
* Stops media playback on the bridge.
|
|
1153
|
+
*
|
|
1154
|
+
* @param playbackId - The ID of the playback to stop.
|
|
1155
|
+
* @throws An error if the operation fails.
|
|
1156
|
+
*/
|
|
1157
|
+
async stopPlayback(playbackId) {
|
|
1158
|
+
try {
|
|
1159
|
+
await this.baseClient.delete(
|
|
1160
|
+
`/bridges/${this.id}/play/${playbackId}`
|
|
1161
|
+
);
|
|
1162
|
+
console.log(`Playback ${playbackId} stopped on bridge ${this.id}`);
|
|
1163
|
+
} catch (error) {
|
|
1164
|
+
const message = getErrorMessage(error);
|
|
1165
|
+
console.error(`Error stopping playback on bridge ${this.id}:`, message);
|
|
1166
|
+
throw new Error(`Failed to stop playback: ${message}`);
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
/**
|
|
1170
|
+
* Sets the video source for the bridge.
|
|
1171
|
+
*
|
|
1172
|
+
* @param channelId - The ID of the channel to set as the video source.
|
|
1173
|
+
* @throws An error if the operation fails.
|
|
1174
|
+
*/
|
|
1175
|
+
async setVideoSource(channelId) {
|
|
1176
|
+
try {
|
|
1177
|
+
await this.baseClient.post(
|
|
1178
|
+
`/bridges/${this.id}/videoSource/${channelId}`
|
|
1179
|
+
);
|
|
1180
|
+
console.log(`Video source set for bridge ${this.id}`);
|
|
1181
|
+
} catch (error) {
|
|
1182
|
+
const message = getErrorMessage(error);
|
|
1183
|
+
console.error(
|
|
1184
|
+
`Error setting video source for bridge ${this.id}:`,
|
|
1185
|
+
message
|
|
1186
|
+
);
|
|
1187
|
+
throw new Error(`Failed to set video source: ${message}`);
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
/**
|
|
1191
|
+
* Removes the video source from the bridge.
|
|
1192
|
+
*
|
|
1193
|
+
* @throws An error if the operation fails.
|
|
1194
|
+
*/
|
|
1195
|
+
async clearVideoSource() {
|
|
1196
|
+
try {
|
|
1197
|
+
await this.baseClient.delete(`/bridges/${this.id}/videoSource`);
|
|
1198
|
+
console.log(`Video source removed from bridge ${this.id}`);
|
|
1199
|
+
} catch (error) {
|
|
1200
|
+
const message = getErrorMessage(error);
|
|
1201
|
+
console.error(
|
|
1202
|
+
`Error removing video source from bridge ${this.id}:`,
|
|
1203
|
+
message
|
|
1204
|
+
);
|
|
1205
|
+
throw new Error(`Failed to remove video source: ${message}`);
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
/**
|
|
1209
|
+
* Checks if the bridge has listeners for a specific event.
|
|
1210
|
+
*
|
|
1211
|
+
* @param event - The event type to check for listeners.
|
|
1212
|
+
* @returns A boolean indicating whether there are listeners for the event.
|
|
1213
|
+
*/
|
|
1214
|
+
hasListeners(event) {
|
|
1215
|
+
return this.eventEmitter.listenerCount(event) > 0;
|
|
1216
|
+
}
|
|
1217
|
+
/**
|
|
1218
|
+
* Retrieves the current bridge data without making an API call.
|
|
1219
|
+
*
|
|
1220
|
+
* @returns The current Bridge object or null if no data is available.
|
|
1221
|
+
*/
|
|
1222
|
+
getCurrentData() {
|
|
1223
|
+
return this.bridgeData;
|
|
1224
|
+
}
|
|
1225
|
+
};
|
|
915
1226
|
var Bridges = class {
|
|
916
|
-
constructor(client) {
|
|
1227
|
+
constructor(baseClient, client) {
|
|
1228
|
+
this.baseClient = baseClient;
|
|
917
1229
|
this.client = client;
|
|
918
1230
|
}
|
|
1231
|
+
bridgeInstances = /* @__PURE__ */ new Map();
|
|
919
1232
|
/**
|
|
920
|
-
*
|
|
1233
|
+
* Creates or retrieves a Bridge instance.
|
|
1234
|
+
*
|
|
1235
|
+
* This method manages the creation and retrieval of BridgeInstance objects.
|
|
1236
|
+
* If an ID is provided and an instance with that ID already exists, it returns the existing instance.
|
|
1237
|
+
* If an ID is provided but no instance exists, it creates a new instance with that ID.
|
|
1238
|
+
* If no ID is provided, it creates a new instance with a generated ID.
|
|
1239
|
+
*
|
|
1240
|
+
* @param {Object} params - The parameters for creating or retrieving a Bridge instance.
|
|
1241
|
+
* @param {string} [params.id] - Optional. The ID of the Bridge instance to create or retrieve.
|
|
1242
|
+
*
|
|
1243
|
+
* @returns {BridgeInstance} A BridgeInstance object, either newly created or retrieved from existing instances.
|
|
1244
|
+
*
|
|
1245
|
+
* @throws {Error} If there's an error in creating or retrieving the Bridge instance.
|
|
1246
|
+
*/
|
|
1247
|
+
Bridge({ id }) {
|
|
1248
|
+
try {
|
|
1249
|
+
if (!id) {
|
|
1250
|
+
const instance = new BridgeInstance(this.client, this.baseClient);
|
|
1251
|
+
this.bridgeInstances.set(instance.id, instance);
|
|
1252
|
+
console.log(`New bridge instance created with ID: ${instance.id}`);
|
|
1253
|
+
return instance;
|
|
1254
|
+
}
|
|
1255
|
+
if (!this.bridgeInstances.has(id)) {
|
|
1256
|
+
const instance = new BridgeInstance(this.client, this.baseClient, id);
|
|
1257
|
+
this.bridgeInstances.set(id, instance);
|
|
1258
|
+
console.log(`New bridge instance created with provided ID: ${id}`);
|
|
1259
|
+
return instance;
|
|
1260
|
+
}
|
|
1261
|
+
console.log(`Returning existing bridge instance: ${id}`);
|
|
1262
|
+
return this.bridgeInstances.get(id);
|
|
1263
|
+
} catch (error) {
|
|
1264
|
+
const message = getErrorMessage(error);
|
|
1265
|
+
console.error(`Error creating/retrieving bridge instance:`, message);
|
|
1266
|
+
throw new Error(`Failed to manage bridge instance: ${message}`);
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
/**
|
|
1270
|
+
* Removes a bridge instance from the collection of managed bridges.
|
|
1271
|
+
*
|
|
1272
|
+
* This function removes the specified bridge instance, cleans up its event listeners,
|
|
1273
|
+
* and logs the removal. If the bridge instance doesn't exist, it logs a warning.
|
|
1274
|
+
*
|
|
1275
|
+
* @param {string} bridgeId - The unique identifier of the bridge instance to be removed.
|
|
1276
|
+
* @throws {Error} Throws an error if the bridgeId is not provided.
|
|
1277
|
+
* @returns {void}
|
|
1278
|
+
*/
|
|
1279
|
+
removeBridgeInstance(bridgeId) {
|
|
1280
|
+
if (!bridgeId) {
|
|
1281
|
+
throw new Error("ID da bridge \xE9 obrigat\xF3rio");
|
|
1282
|
+
}
|
|
1283
|
+
if (this.bridgeInstances.has(bridgeId)) {
|
|
1284
|
+
const instance = this.bridgeInstances.get(bridgeId);
|
|
1285
|
+
instance?.removeAllListeners();
|
|
1286
|
+
this.bridgeInstances.delete(bridgeId);
|
|
1287
|
+
console.log(`Inst\xE2ncia de bridge removida: ${bridgeId}`);
|
|
1288
|
+
} else {
|
|
1289
|
+
console.warn(`Tentativa de remover inst\xE2ncia inexistente: ${bridgeId}`);
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
/**
|
|
1293
|
+
* Propagates a WebSocket event to a specific bridge instance.
|
|
1294
|
+
*
|
|
1295
|
+
* This function checks if the received event is valid and related to a bridge,
|
|
1296
|
+
* then emits the event to the corresponding bridge instance if it exists.
|
|
1297
|
+
*
|
|
1298
|
+
* @param {WebSocketEvent} event - The WebSocket event to be propagated.
|
|
1299
|
+
* This should be an object containing information about the event,
|
|
1300
|
+
* including the bridge ID and event type.
|
|
1301
|
+
*
|
|
1302
|
+
* @returns {void}
|
|
1303
|
+
*
|
|
1304
|
+
* @remarks
|
|
1305
|
+
* - If the event is invalid (null or undefined), a warning is logged and the function returns early.
|
|
1306
|
+
* - The function checks if the event is bridge-related and if the event type is included in the predefined bridge events.
|
|
1307
|
+
* - If a matching bridge instance is found, the event is emitted to that instance.
|
|
1308
|
+
* - If no matching bridge instance is found, a warning is logged.
|
|
1309
|
+
*/
|
|
1310
|
+
propagateEventToBridge(event) {
|
|
1311
|
+
if (!event) {
|
|
1312
|
+
console.warn("Evento WebSocket inv\xE1lido recebido");
|
|
1313
|
+
return;
|
|
1314
|
+
}
|
|
1315
|
+
if ("bridge" in event && event.bridge?.id && bridgeEvents.includes(event.type)) {
|
|
1316
|
+
const instance = this.bridgeInstances.get(event.bridge.id);
|
|
1317
|
+
if (instance) {
|
|
1318
|
+
instance.emitEvent(event);
|
|
1319
|
+
console.log(
|
|
1320
|
+
`Evento propagado para bridge ${event.bridge.id}: ${event.type}`
|
|
1321
|
+
);
|
|
1322
|
+
} else {
|
|
1323
|
+
console.warn(
|
|
1324
|
+
`Nenhuma inst\xE2ncia encontrada para bridge ${event.bridge.id}`
|
|
1325
|
+
);
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
/**
|
|
1330
|
+
* Lists all active bridges in the system.
|
|
1331
|
+
*
|
|
1332
|
+
* This asynchronous function retrieves a list of all currently active bridges
|
|
1333
|
+
* by making a GET request to the "/bridges" endpoint using the base client.
|
|
1334
|
+
*
|
|
1335
|
+
* @returns {Promise<Bridge[]>} A promise that resolves to an array of Bridge objects.
|
|
1336
|
+
* Each Bridge object represents an active bridge in the system.
|
|
1337
|
+
*
|
|
1338
|
+
* @throws {Error} If there's an error in fetching the bridges or if the request fails.
|
|
1339
|
+
*
|
|
1340
|
+
* @example
|
|
1341
|
+
* try {
|
|
1342
|
+
* const bridges = await bridgesInstance.list();
|
|
1343
|
+
* console.log('Active bridges:', bridges);
|
|
1344
|
+
* } catch (error) {
|
|
1345
|
+
* console.error('Failed to fetch bridges:', error);
|
|
1346
|
+
* }
|
|
921
1347
|
*/
|
|
922
1348
|
async list() {
|
|
923
|
-
return this.
|
|
1349
|
+
return this.baseClient.get("/bridges");
|
|
924
1350
|
}
|
|
925
1351
|
/**
|
|
926
|
-
* Creates a new bridge.
|
|
1352
|
+
* Creates a new bridge in the system.
|
|
1353
|
+
*
|
|
1354
|
+
* This asynchronous function sends a POST request to create a new bridge
|
|
1355
|
+
* using the provided configuration details.
|
|
1356
|
+
*
|
|
1357
|
+
* @param request - The configuration details for creating the new bridge.
|
|
1358
|
+
* @param request.type - The type of bridge to create (e.g., 'mixing', 'holding').
|
|
1359
|
+
* @param request.name - Optional. A custom name for the bridge.
|
|
1360
|
+
* @param request.bridgeId - Optional. A specific ID for the bridge. If not provided, one will be generated.
|
|
1361
|
+
*
|
|
1362
|
+
* @returns A Promise that resolves to a Bridge object representing the newly created bridge.
|
|
1363
|
+
* The Bridge object contains details such as id, technology, bridge_type, bridge_class, channels, etc.
|
|
1364
|
+
*
|
|
1365
|
+
* @throws Will throw an error if the bridge creation fails or if there's a network issue.
|
|
927
1366
|
*/
|
|
928
1367
|
async createBridge(request) {
|
|
929
|
-
return this.
|
|
1368
|
+
return this.baseClient.post("/bridges", request);
|
|
930
1369
|
}
|
|
931
1370
|
/**
|
|
932
|
-
* Retrieves
|
|
1371
|
+
* Retrieves detailed information about a specific bridge.
|
|
1372
|
+
*
|
|
1373
|
+
* This asynchronous function fetches the complete details of a bridge
|
|
1374
|
+
* identified by its unique ID. It makes a GET request to the ARI endpoint
|
|
1375
|
+
* for the specified bridge.
|
|
1376
|
+
*
|
|
1377
|
+
* @param bridgeId - The unique identifier of the bridge to retrieve details for.
|
|
1378
|
+
* This should be a string that uniquely identifies the bridge in the system.
|
|
1379
|
+
*
|
|
1380
|
+
* @returns A Promise that resolves to a Bridge object containing all the details
|
|
1381
|
+
* of the specified bridge. This includes information such as the bridge's
|
|
1382
|
+
* ID, type, channels, and other relevant properties.
|
|
1383
|
+
*
|
|
1384
|
+
* @throws Will throw an error if the bridge cannot be found, if there's a network issue,
|
|
1385
|
+
* or if the server responds with an error.
|
|
933
1386
|
*/
|
|
934
|
-
async
|
|
935
|
-
return this.
|
|
1387
|
+
async get(bridgeId) {
|
|
1388
|
+
return this.baseClient.get(`/bridges/${bridgeId}`);
|
|
936
1389
|
}
|
|
937
1390
|
/**
|
|
938
|
-
* Destroys (deletes) a specific bridge.
|
|
1391
|
+
* Destroys (deletes) a specific bridge in the system.
|
|
1392
|
+
*
|
|
1393
|
+
* This asynchronous function sends a DELETE request to remove a bridge
|
|
1394
|
+
* identified by its unique ID. Once destroyed, the bridge and all its
|
|
1395
|
+
* associated resources are permanently removed from the system.
|
|
1396
|
+
*
|
|
1397
|
+
* @param bridgeId - The unique identifier of the bridge to be destroyed.
|
|
1398
|
+
* This should be a string that uniquely identifies the bridge in the system.
|
|
1399
|
+
*
|
|
1400
|
+
* @returns A Promise that resolves to void when the bridge is successfully destroyed.
|
|
1401
|
+
* If the operation is successful, the bridge no longer exists in the system.
|
|
1402
|
+
*
|
|
1403
|
+
* @throws Will throw an error if the bridge cannot be found, if there's a network issue,
|
|
1404
|
+
* or if the server responds with an error during the deletion process.
|
|
939
1405
|
*/
|
|
940
1406
|
async destroy(bridgeId) {
|
|
941
|
-
return this.
|
|
1407
|
+
return this.baseClient.delete(`/bridges/${bridgeId}`);
|
|
942
1408
|
}
|
|
943
1409
|
/**
|
|
944
|
-
* Adds
|
|
1410
|
+
* Adds one or more channels to a specified bridge.
|
|
1411
|
+
*
|
|
1412
|
+
* This asynchronous function sends a POST request to add channels to an existing bridge.
|
|
1413
|
+
* It can handle adding a single channel or multiple channels in one operation.
|
|
1414
|
+
*
|
|
1415
|
+
* @param bridgeId - The unique identifier of the bridge to which channels will be added.
|
|
1416
|
+
* @param request - An object containing the details of the channel(s) to be added.
|
|
1417
|
+
* @param request.channel - A single channel ID or an array of channel IDs to add to the bridge.
|
|
1418
|
+
* @param request.role - Optional. Specifies the role of the channel(s) in the bridge.
|
|
1419
|
+
*
|
|
1420
|
+
* @returns A Promise that resolves to void when the operation is successful.
|
|
1421
|
+
*
|
|
1422
|
+
* @throws Will throw an error if the request fails, such as if the bridge doesn't exist
|
|
1423
|
+
* or if there's a network issue.
|
|
945
1424
|
*/
|
|
946
1425
|
async addChannels(bridgeId, request) {
|
|
947
|
-
const queryParams =
|
|
1426
|
+
const queryParams = toQueryParams2({
|
|
948
1427
|
channel: Array.isArray(request.channel) ? request.channel.join(",") : request.channel,
|
|
949
1428
|
...request.role && { role: request.role }
|
|
950
|
-
})
|
|
951
|
-
await this.
|
|
1429
|
+
});
|
|
1430
|
+
await this.baseClient.post(
|
|
952
1431
|
`/bridges/${bridgeId}/addChannel?${queryParams}`
|
|
953
1432
|
);
|
|
954
1433
|
}
|
|
955
1434
|
/**
|
|
956
|
-
* Removes
|
|
1435
|
+
* Removes one or more channels from a specified bridge.
|
|
1436
|
+
*
|
|
1437
|
+
* This asynchronous function sends a POST request to remove channels from an existing bridge.
|
|
1438
|
+
* It can handle removing a single channel or multiple channels in one operation.
|
|
1439
|
+
*
|
|
1440
|
+
* @param bridgeId - The unique identifier of the bridge from which channels will be removed.
|
|
1441
|
+
* @param request - An object containing the details of the channel(s) to be removed.
|
|
1442
|
+
* @param request.channel - A single channel ID or an array of channel IDs to remove from the bridge.
|
|
1443
|
+
*
|
|
1444
|
+
* @returns A Promise that resolves to void when the operation is successful.
|
|
1445
|
+
*
|
|
1446
|
+
* @throws Will throw an error if the request fails, such as if the bridge doesn't exist,
|
|
1447
|
+
* if the channels are not in the bridge, or if there's a network issue.
|
|
957
1448
|
*/
|
|
958
1449
|
async removeChannels(bridgeId, request) {
|
|
959
|
-
const queryParams =
|
|
1450
|
+
const queryParams = toQueryParams2({
|
|
960
1451
|
channel: Array.isArray(request.channel) ? request.channel.join(",") : request.channel
|
|
961
|
-
})
|
|
962
|
-
await this.
|
|
1452
|
+
});
|
|
1453
|
+
await this.baseClient.post(
|
|
963
1454
|
`/bridges/${bridgeId}/removeChannel?${queryParams}`
|
|
964
1455
|
);
|
|
965
1456
|
}
|
|
966
1457
|
/**
|
|
967
|
-
* Plays media
|
|
1458
|
+
* Plays media on a specified bridge.
|
|
1459
|
+
*
|
|
1460
|
+
* This asynchronous function initiates media playback on a bridge identified by its ID.
|
|
1461
|
+
* It allows for customization of the playback through various options in the request.
|
|
1462
|
+
*
|
|
1463
|
+
* @param bridgeId - The unique identifier of the bridge on which to play the media.
|
|
1464
|
+
* @param request - An object containing the media playback request details.
|
|
1465
|
+
* @param request.media - The media to be played (e.g., sound file, URL).
|
|
1466
|
+
* @param request.lang - Optional. The language of the media content.
|
|
1467
|
+
* @param request.offsetms - Optional. The offset in milliseconds to start playing from.
|
|
1468
|
+
* @param request.skipms - Optional. The number of milliseconds to skip before playing.
|
|
1469
|
+
* @param request.playbackId - Optional. A custom ID for the playback session.
|
|
1470
|
+
*
|
|
1471
|
+
* @returns A Promise that resolves to a BridgePlayback object, containing details about the initiated playback.
|
|
1472
|
+
*
|
|
1473
|
+
* @throws Will throw an error if the playback request fails or if there's a network issue.
|
|
968
1474
|
*/
|
|
969
1475
|
async playMedia(bridgeId, request) {
|
|
970
|
-
const queryParams =
|
|
1476
|
+
const queryParams = toQueryParams2({
|
|
971
1477
|
...request.lang && { lang: request.lang },
|
|
972
1478
|
...request.offsetms && { offsetms: request.offsetms.toString() },
|
|
973
1479
|
...request.skipms && { skipms: request.skipms.toString() },
|
|
974
1480
|
...request.playbackId && { playbackId: request.playbackId }
|
|
975
|
-
})
|
|
976
|
-
return this.
|
|
1481
|
+
});
|
|
1482
|
+
return this.baseClient.post(
|
|
977
1483
|
`/bridges/${bridgeId}/play?${queryParams}`,
|
|
978
1484
|
{ media: request.media }
|
|
979
1485
|
);
|
|
980
1486
|
}
|
|
981
1487
|
/**
|
|
982
|
-
* Stops media playback on a bridge.
|
|
1488
|
+
* Stops media playback on a specified bridge.
|
|
1489
|
+
*
|
|
1490
|
+
* This asynchronous function sends a DELETE request to stop the playback of media
|
|
1491
|
+
* on a bridge identified by its ID and a specific playback session.
|
|
1492
|
+
*
|
|
1493
|
+
* @param bridgeId - The unique identifier of the bridge where the playback is to be stopped.
|
|
1494
|
+
* @param playbackId - The unique identifier of the playback session to be stopped.
|
|
1495
|
+
*
|
|
1496
|
+
* @returns A Promise that resolves to void when the playback is successfully stopped.
|
|
1497
|
+
*
|
|
1498
|
+
* @throws Will throw an error if the request fails, such as if the bridge or playback session
|
|
1499
|
+
* doesn't exist, or if there's a network issue.
|
|
983
1500
|
*/
|
|
984
1501
|
async stopPlayback(bridgeId, playbackId) {
|
|
985
|
-
await this.
|
|
1502
|
+
await this.baseClient.delete(
|
|
1503
|
+
`/bridges/${bridgeId}/play/${playbackId}`
|
|
1504
|
+
);
|
|
986
1505
|
}
|
|
987
1506
|
/**
|
|
988
|
-
* Sets the video source for a bridge.
|
|
1507
|
+
* Sets the video source for a specified bridge.
|
|
1508
|
+
*
|
|
1509
|
+
* This asynchronous function configures a channel as the video source for a given bridge.
|
|
1510
|
+
* It sends a POST request to the ARI endpoint to update the bridge's video source.
|
|
1511
|
+
*
|
|
1512
|
+
* @param bridgeId - The unique identifier of the bridge for which to set the video source.
|
|
1513
|
+
* @param channelId - The unique identifier of the channel to be set as the video source.
|
|
1514
|
+
*
|
|
1515
|
+
* @returns A Promise that resolves to void when the video source is successfully set.
|
|
1516
|
+
*
|
|
1517
|
+
* @throws Will throw an error if the request fails, such as if the bridge or channel
|
|
1518
|
+
* doesn't exist, or if there's a network issue.
|
|
989
1519
|
*/
|
|
990
1520
|
async setVideoSource(bridgeId, channelId) {
|
|
991
|
-
|
|
992
|
-
|
|
1521
|
+
const queryParams = toQueryParams2({ channelId });
|
|
1522
|
+
await this.baseClient.post(
|
|
1523
|
+
`/bridges/${bridgeId}/videoSource?${queryParams}`
|
|
993
1524
|
);
|
|
994
1525
|
}
|
|
995
1526
|
/**
|
|
996
|
-
* Clears the video source for a bridge.
|
|
1527
|
+
* Clears the video source for a specified bridge.
|
|
1528
|
+
*
|
|
1529
|
+
* This asynchronous function removes the currently set video source from a bridge.
|
|
1530
|
+
* It sends a DELETE request to the ARI endpoint to clear the video source configuration.
|
|
1531
|
+
*
|
|
1532
|
+
* @param bridgeId - The unique identifier of the bridge from which to clear the video source.
|
|
1533
|
+
* This should be a string that uniquely identifies the bridge in the system.
|
|
1534
|
+
*
|
|
1535
|
+
* @returns A Promise that resolves to void when the video source is successfully cleared.
|
|
1536
|
+
* If the operation is successful, the bridge will no longer have a designated video source.
|
|
1537
|
+
*
|
|
1538
|
+
* @throws Will throw an error if the request fails, such as if the bridge doesn't exist,
|
|
1539
|
+
* if there's no video source set, or if there's a network issue.
|
|
997
1540
|
*/
|
|
998
1541
|
async clearVideoSource(bridgeId) {
|
|
999
|
-
await this.
|
|
1542
|
+
await this.baseClient.delete(`/bridges/${bridgeId}/videoSource`);
|
|
1543
|
+
}
|
|
1544
|
+
/**
|
|
1545
|
+
* Retrieves the count of active bridge instances.
|
|
1546
|
+
*
|
|
1547
|
+
* This function returns the total number of bridge instances currently
|
|
1548
|
+
* managed by the Bridges class. It provides a quick way to check how many
|
|
1549
|
+
* active bridges are present in the system.
|
|
1550
|
+
*
|
|
1551
|
+
* @returns {number} The count of active bridge instances.
|
|
1552
|
+
*/
|
|
1553
|
+
getInstanceCount() {
|
|
1554
|
+
return this.bridgeInstances.size;
|
|
1555
|
+
}
|
|
1556
|
+
/**
|
|
1557
|
+
* Checks if a bridge instance exists in the collection of managed bridges.
|
|
1558
|
+
*
|
|
1559
|
+
* This function verifies whether a bridge instance with the specified ID
|
|
1560
|
+
* is currently being managed by the Bridges class.
|
|
1561
|
+
*
|
|
1562
|
+
* @param bridgeId - The unique identifier of the bridge instance to check.
|
|
1563
|
+
* This should be a string that uniquely identifies the bridge in the system.
|
|
1564
|
+
*
|
|
1565
|
+
* @returns A boolean value indicating whether the bridge instance exists.
|
|
1566
|
+
* Returns true if the bridge instance is found, false otherwise.
|
|
1567
|
+
*/
|
|
1568
|
+
hasInstance(bridgeId) {
|
|
1569
|
+
return this.bridgeInstances.has(bridgeId);
|
|
1570
|
+
}
|
|
1571
|
+
/**
|
|
1572
|
+
* Retrieves all active bridge instances currently managed by the Bridges class.
|
|
1573
|
+
*
|
|
1574
|
+
* This method provides a way to access all the BridgeInstance objects that are
|
|
1575
|
+
* currently active and being managed. It returns a new Map to prevent direct
|
|
1576
|
+
* modification of the internal bridgeInstances collection.
|
|
1577
|
+
*
|
|
1578
|
+
* @returns A new Map object containing all active bridge instances, where the keys
|
|
1579
|
+
* are the bridge IDs (strings) and the values are the corresponding
|
|
1580
|
+
* BridgeInstance objects. If no bridges are active, an empty Map is returned.
|
|
1581
|
+
*/
|
|
1582
|
+
getAllInstances() {
|
|
1583
|
+
return new Map(this.bridgeInstances);
|
|
1000
1584
|
}
|
|
1001
1585
|
};
|
|
1002
1586
|
|
|
1003
1587
|
// src/ari-client/resources/channels.ts
|
|
1004
|
-
import { EventEmitter } from "events";
|
|
1005
|
-
import { isAxiosError as
|
|
1588
|
+
import { EventEmitter as EventEmitter2 } from "events";
|
|
1589
|
+
import { isAxiosError as isAxiosError3 } from "axios";
|
|
1006
1590
|
|
|
1007
1591
|
// node_modules/uuid/dist/esm/stringify.js
|
|
1008
1592
|
var byteToHex = [];
|
|
@@ -1049,16 +1633,9 @@ function v4(options, buf, offset) {
|
|
|
1049
1633
|
}
|
|
1050
1634
|
var v4_default = v4;
|
|
1051
1635
|
|
|
1052
|
-
// src/ari-client/utils.ts
|
|
1053
|
-
function toQueryParams2(options) {
|
|
1054
|
-
return new URLSearchParams(
|
|
1055
|
-
Object.entries(options).filter(([, value]) => value !== void 0).map(([key, value]) => [key, value])
|
|
1056
|
-
).toString();
|
|
1057
|
-
}
|
|
1058
|
-
|
|
1059
1636
|
// src/ari-client/resources/channels.ts
|
|
1060
|
-
var
|
|
1061
|
-
if (
|
|
1637
|
+
var getErrorMessage2 = (error) => {
|
|
1638
|
+
if (isAxiosError3(error)) {
|
|
1062
1639
|
return error.response?.data?.message || error.message || "An axios error occurred";
|
|
1063
1640
|
}
|
|
1064
1641
|
if (error instanceof Error) {
|
|
@@ -1072,7 +1649,7 @@ var ChannelInstance = class {
|
|
|
1072
1649
|
this.baseClient = baseClient;
|
|
1073
1650
|
this.id = channelId || `channel-${Date.now()}`;
|
|
1074
1651
|
}
|
|
1075
|
-
eventEmitter = new
|
|
1652
|
+
eventEmitter = new EventEmitter2();
|
|
1076
1653
|
channelData = null;
|
|
1077
1654
|
id;
|
|
1078
1655
|
/**
|
|
@@ -1150,7 +1727,7 @@ var ChannelInstance = class {
|
|
|
1150
1727
|
try {
|
|
1151
1728
|
await this.baseClient.post(`/channels/${this.id}/answer`);
|
|
1152
1729
|
} catch (error) {
|
|
1153
|
-
const message =
|
|
1730
|
+
const message = getErrorMessage2(error);
|
|
1154
1731
|
console.error(`Error answering channel ${this.id}:`, message);
|
|
1155
1732
|
throw new Error(`Failed to answer channel: ${message}`);
|
|
1156
1733
|
}
|
|
@@ -1173,7 +1750,7 @@ var ChannelInstance = class {
|
|
|
1173
1750
|
);
|
|
1174
1751
|
return this.channelData;
|
|
1175
1752
|
} catch (error) {
|
|
1176
|
-
const message =
|
|
1753
|
+
const message = getErrorMessage2(error);
|
|
1177
1754
|
console.error(`Error originating channel:`, message);
|
|
1178
1755
|
throw new Error(`Failed to originate channel: ${message}`);
|
|
1179
1756
|
}
|
|
@@ -1196,7 +1773,7 @@ var ChannelInstance = class {
|
|
|
1196
1773
|
);
|
|
1197
1774
|
return playback;
|
|
1198
1775
|
} catch (error) {
|
|
1199
|
-
const message =
|
|
1776
|
+
const message = getErrorMessage2(error);
|
|
1200
1777
|
console.error(`Error playing media on channel ${this.id}:`, message);
|
|
1201
1778
|
throw new Error(`Failed to play media: ${message}`);
|
|
1202
1779
|
}
|
|
@@ -1218,7 +1795,7 @@ var ChannelInstance = class {
|
|
|
1218
1795
|
this.channelData = details;
|
|
1219
1796
|
return details;
|
|
1220
1797
|
} catch (error) {
|
|
1221
|
-
const message =
|
|
1798
|
+
const message = getErrorMessage2(error);
|
|
1222
1799
|
console.error(
|
|
1223
1800
|
`Error retrieving channel details for ${this.id}:`,
|
|
1224
1801
|
message
|
|
@@ -1459,7 +2036,7 @@ var Channels = class {
|
|
|
1459
2036
|
}
|
|
1460
2037
|
return this.channelInstances.get(id);
|
|
1461
2038
|
} catch (error) {
|
|
1462
|
-
const message =
|
|
2039
|
+
const message = getErrorMessage2(error);
|
|
1463
2040
|
console.error(`Error creating/retrieving channel instance:`, message);
|
|
1464
2041
|
throw new Error(`Failed to manage channel instance: ${message}`);
|
|
1465
2042
|
}
|
|
@@ -1478,7 +2055,7 @@ var Channels = class {
|
|
|
1478
2055
|
}
|
|
1479
2056
|
return await this.baseClient.get(`/channels/${id}`);
|
|
1480
2057
|
} catch (error) {
|
|
1481
|
-
const message =
|
|
2058
|
+
const message = getErrorMessage2(error);
|
|
1482
2059
|
console.error(`Error retrieving channel details for ${id}:`, message);
|
|
1483
2060
|
throw new Error(`Failed to get channel details: ${message}`);
|
|
1484
2061
|
}
|
|
@@ -1525,7 +2102,7 @@ var Channels = class {
|
|
|
1525
2102
|
try {
|
|
1526
2103
|
return await this.baseClient.post("/channels", data);
|
|
1527
2104
|
} catch (error) {
|
|
1528
|
-
const message =
|
|
2105
|
+
const message = getErrorMessage2(error);
|
|
1529
2106
|
console.error(`Error originating channel:`, message);
|
|
1530
2107
|
throw new Error(`Failed to originate channel: ${message}`);
|
|
1531
2108
|
}
|
|
@@ -1541,7 +2118,7 @@ var Channels = class {
|
|
|
1541
2118
|
}
|
|
1542
2119
|
return channels;
|
|
1543
2120
|
} catch (error) {
|
|
1544
|
-
const message =
|
|
2121
|
+
const message = getErrorMessage2(error);
|
|
1545
2122
|
console.error(`Error listing channels:`, message);
|
|
1546
2123
|
throw new Error(`Failed to list channels: ${message}`);
|
|
1547
2124
|
}
|
|
@@ -1968,10 +2545,10 @@ var Endpoints = class {
|
|
|
1968
2545
|
};
|
|
1969
2546
|
|
|
1970
2547
|
// src/ari-client/resources/playbacks.ts
|
|
1971
|
-
import { EventEmitter as
|
|
1972
|
-
import { isAxiosError as
|
|
1973
|
-
var
|
|
1974
|
-
if (
|
|
2548
|
+
import { EventEmitter as EventEmitter3 } from "events";
|
|
2549
|
+
import { isAxiosError as isAxiosError4 } from "axios";
|
|
2550
|
+
var getErrorMessage3 = (error) => {
|
|
2551
|
+
if (isAxiosError4(error)) {
|
|
1975
2552
|
return error.response?.data?.message || error.message || "An axios error occurred";
|
|
1976
2553
|
}
|
|
1977
2554
|
if (error instanceof Error) {
|
|
@@ -1993,7 +2570,7 @@ var PlaybackInstance = class {
|
|
|
1993
2570
|
this.playbackId = playbackId;
|
|
1994
2571
|
this.id = playbackId;
|
|
1995
2572
|
}
|
|
1996
|
-
eventEmitter = new
|
|
2573
|
+
eventEmitter = new EventEmitter3();
|
|
1997
2574
|
playbackData = null;
|
|
1998
2575
|
id;
|
|
1999
2576
|
/**
|
|
@@ -2076,7 +2653,7 @@ var PlaybackInstance = class {
|
|
|
2076
2653
|
);
|
|
2077
2654
|
return this.playbackData;
|
|
2078
2655
|
} catch (error) {
|
|
2079
|
-
const message =
|
|
2656
|
+
const message = getErrorMessage3(error);
|
|
2080
2657
|
console.warn(`Error retrieving playback data for ${this.id}:`, message);
|
|
2081
2658
|
throw new Error(`Failed to get playback data: ${message}`);
|
|
2082
2659
|
}
|
|
@@ -2096,7 +2673,7 @@ var PlaybackInstance = class {
|
|
|
2096
2673
|
`/playbacks/${this.id}/control?operation=${operation}`
|
|
2097
2674
|
);
|
|
2098
2675
|
} catch (error) {
|
|
2099
|
-
const message =
|
|
2676
|
+
const message = getErrorMessage3(error);
|
|
2100
2677
|
console.warn(`Error controlling playback ${this.id}:`, message);
|
|
2101
2678
|
throw new Error(`Failed to control playback: ${message}`);
|
|
2102
2679
|
}
|
|
@@ -2113,7 +2690,7 @@ var PlaybackInstance = class {
|
|
|
2113
2690
|
try {
|
|
2114
2691
|
await this.baseClient.delete(`/playbacks/${this.id}`);
|
|
2115
2692
|
} catch (error) {
|
|
2116
|
-
const message =
|
|
2693
|
+
const message = getErrorMessage3(error);
|
|
2117
2694
|
console.warn(`Error stopping playback ${this.id}:`, message);
|
|
2118
2695
|
throw new Error(`Failed to stop playback: ${message}`);
|
|
2119
2696
|
}
|
|
@@ -2169,7 +2746,7 @@ var Playbacks = class {
|
|
|
2169
2746
|
}
|
|
2170
2747
|
return this.playbackInstances.get(id);
|
|
2171
2748
|
} catch (error) {
|
|
2172
|
-
const message =
|
|
2749
|
+
const message = getErrorMessage3(error);
|
|
2173
2750
|
console.warn(`Error creating/retrieving playback instance:`, message);
|
|
2174
2751
|
throw new Error(`Failed to manage playback instance: ${message}`);
|
|
2175
2752
|
}
|
|
@@ -2221,7 +2798,7 @@ var Playbacks = class {
|
|
|
2221
2798
|
try {
|
|
2222
2799
|
return await this.baseClient.get(`/playbacks/${playbackId}`);
|
|
2223
2800
|
} catch (error) {
|
|
2224
|
-
const message =
|
|
2801
|
+
const message = getErrorMessage3(error);
|
|
2225
2802
|
console.warn(`Error getting playback details ${playbackId}:`, message);
|
|
2226
2803
|
throw new Error(`Failed to get playback details: ${message}`);
|
|
2227
2804
|
}
|
|
@@ -2240,7 +2817,7 @@ var Playbacks = class {
|
|
|
2240
2817
|
const playback = this.Playback({ id: playbackId });
|
|
2241
2818
|
await playback.control(operation);
|
|
2242
2819
|
} catch (error) {
|
|
2243
|
-
const message =
|
|
2820
|
+
const message = getErrorMessage3(error);
|
|
2244
2821
|
console.warn(`Error controlling playback ${playbackId}:`, message);
|
|
2245
2822
|
throw new Error(`Failed to control playback: ${message}`);
|
|
2246
2823
|
}
|
|
@@ -2258,7 +2835,7 @@ var Playbacks = class {
|
|
|
2258
2835
|
const playback = this.Playback({ id: playbackId });
|
|
2259
2836
|
await playback.stop();
|
|
2260
2837
|
} catch (error) {
|
|
2261
|
-
const message =
|
|
2838
|
+
const message = getErrorMessage3(error);
|
|
2262
2839
|
console.warn(`Error stopping playback ${playbackId}:`, message);
|
|
2263
2840
|
throw new Error(`Failed to stop playback: ${message}`);
|
|
2264
2841
|
}
|
|
@@ -2313,19 +2890,24 @@ var Sounds = class {
|
|
|
2313
2890
|
|
|
2314
2891
|
// src/ari-client/websocketClient.ts
|
|
2315
2892
|
var import_exponential_backoff = __toESM(require_backoff(), 1);
|
|
2316
|
-
import { EventEmitter as
|
|
2893
|
+
import { EventEmitter as EventEmitter4 } from "events";
|
|
2317
2894
|
import WebSocket from "ws";
|
|
2318
|
-
var DEFAULT_MAX_RECONNECT_ATTEMPTS =
|
|
2895
|
+
var DEFAULT_MAX_RECONNECT_ATTEMPTS = 30;
|
|
2319
2896
|
var DEFAULT_STARTING_DELAY = 500;
|
|
2320
2897
|
var DEFAULT_MAX_DELAY = 1e4;
|
|
2321
|
-
var WebSocketClient = class extends
|
|
2898
|
+
var WebSocketClient = class extends EventEmitter4 {
|
|
2322
2899
|
/**
|
|
2323
|
-
* Creates a new
|
|
2900
|
+
* Creates a new WebSocketClient instance.
|
|
2324
2901
|
*
|
|
2325
|
-
*
|
|
2326
|
-
*
|
|
2327
|
-
*
|
|
2328
|
-
* @param
|
|
2902
|
+
* This constructor initializes a WebSocketClient with the necessary dependencies and configuration.
|
|
2903
|
+
* It ensures that at least one application name is provided.
|
|
2904
|
+
*
|
|
2905
|
+
* @param baseClient - The BaseClient instance used for basic ARI operations and authentication.
|
|
2906
|
+
* @param apps - An array of application names to connect to via the WebSocket.
|
|
2907
|
+
* @param subscribedEvents - Optional. An array of WebSocketEventTypes to subscribe to. If not provided, all events will be subscribed.
|
|
2908
|
+
* @param ariClient - Optional. The AriClient instance, used for creating Channel and Playback instances when processing events.
|
|
2909
|
+
*
|
|
2910
|
+
* @throws {Error} Throws an error if the apps array is empty.
|
|
2329
2911
|
*/
|
|
2330
2912
|
constructor(baseClient, apps, subscribedEvents, ariClient) {
|
|
2331
2913
|
super();
|
|
@@ -2340,6 +2922,8 @@ var WebSocketClient = class extends EventEmitter3 {
|
|
|
2340
2922
|
ws;
|
|
2341
2923
|
isReconnecting = false;
|
|
2342
2924
|
maxReconnectAttempts = DEFAULT_MAX_RECONNECT_ATTEMPTS;
|
|
2925
|
+
reconnectionAttempts = 0;
|
|
2926
|
+
lastWsUrl = "";
|
|
2343
2927
|
backOffOptions = {
|
|
2344
2928
|
numOfAttempts: DEFAULT_MAX_RECONNECT_ATTEMPTS,
|
|
2345
2929
|
startingDelay: DEFAULT_STARTING_DELAY,
|
|
@@ -2356,10 +2940,14 @@ var WebSocketClient = class extends EventEmitter3 {
|
|
|
2356
2940
|
}
|
|
2357
2941
|
};
|
|
2358
2942
|
/**
|
|
2359
|
-
* Establishes a WebSocket connection.
|
|
2943
|
+
* Establishes a WebSocket connection to the Asterisk server.
|
|
2360
2944
|
*
|
|
2361
|
-
*
|
|
2362
|
-
*
|
|
2945
|
+
* This method constructs the WebSocket URL using the base URL, credentials,
|
|
2946
|
+
* application names, and subscribed events. It then initiates the connection
|
|
2947
|
+
* using the constructed URL.
|
|
2948
|
+
*
|
|
2949
|
+
* @returns A Promise that resolves when the WebSocket connection is successfully established.
|
|
2950
|
+
* @throws Will throw an error if the connection cannot be established.
|
|
2363
2951
|
*/
|
|
2364
2952
|
async connect() {
|
|
2365
2953
|
const { baseUrl, username, password } = this.baseClient.getCredentials();
|
|
@@ -2374,15 +2962,24 @@ var WebSocketClient = class extends EventEmitter3 {
|
|
|
2374
2962
|
} else {
|
|
2375
2963
|
queryParams.append("subscribeAll", "true");
|
|
2376
2964
|
}
|
|
2377
|
-
|
|
2965
|
+
this.lastWsUrl = `${protocol}://${encodeURIComponent(username)}:${encodeURIComponent(password)}@${normalizedHost}/ari/events?${queryParams.toString()}`;
|
|
2378
2966
|
console.log("Connecting to WebSocket...");
|
|
2379
|
-
return this.initializeWebSocket(
|
|
2967
|
+
return this.initializeWebSocket(this.lastWsUrl);
|
|
2380
2968
|
}
|
|
2381
2969
|
/**
|
|
2382
|
-
* Initializes WebSocket connection with
|
|
2970
|
+
* Initializes a WebSocket connection with exponential backoff retry mechanism.
|
|
2383
2971
|
*
|
|
2384
|
-
*
|
|
2385
|
-
*
|
|
2972
|
+
* This method attempts to establish a WebSocket connection to the specified URL.
|
|
2973
|
+
* It sets up event listeners for the WebSocket's 'open', 'message', 'close', and 'error' events.
|
|
2974
|
+
* If the connection is successful, it emits a 'connected' event. If it's a reconnection,
|
|
2975
|
+
* it also emits a 'reconnected' event with the current apps and subscribed events.
|
|
2976
|
+
* In case of connection failure, it uses an exponential backoff strategy to retry.
|
|
2977
|
+
*
|
|
2978
|
+
* @param wsUrl - The WebSocket URL to connect to.
|
|
2979
|
+
* @returns A Promise that resolves when the connection is successfully established,
|
|
2980
|
+
* or rejects if an error occurs during the connection process.
|
|
2981
|
+
* @throws Will throw an error if the WebSocket connection cannot be established
|
|
2982
|
+
* after the maximum number of retry attempts.
|
|
2386
2983
|
*/
|
|
2387
2984
|
async initializeWebSocket(wsUrl) {
|
|
2388
2985
|
return (0, import_exponential_backoff.backOff)(async () => {
|
|
@@ -2391,7 +2988,14 @@ var WebSocketClient = class extends EventEmitter3 {
|
|
|
2391
2988
|
this.ws = new WebSocket(wsUrl);
|
|
2392
2989
|
this.ws.on("open", () => {
|
|
2393
2990
|
console.log("WebSocket connection established successfully");
|
|
2991
|
+
if (this.isReconnecting) {
|
|
2992
|
+
this.emit("reconnected", {
|
|
2993
|
+
apps: this.apps,
|
|
2994
|
+
subscribedEvents: this.subscribedEvents
|
|
2995
|
+
});
|
|
2996
|
+
}
|
|
2394
2997
|
this.isReconnecting = false;
|
|
2998
|
+
this.reconnectionAttempts = 0;
|
|
2395
2999
|
this.emit("connected");
|
|
2396
3000
|
resolve();
|
|
2397
3001
|
});
|
|
@@ -2401,13 +3005,13 @@ var WebSocketClient = class extends EventEmitter3 {
|
|
|
2401
3005
|
`WebSocket disconnected with code ${code}. Attempting to reconnect...`
|
|
2402
3006
|
);
|
|
2403
3007
|
if (!this.isReconnecting) {
|
|
2404
|
-
this.reconnect(
|
|
3008
|
+
this.reconnect(this.lastWsUrl);
|
|
2405
3009
|
}
|
|
2406
3010
|
});
|
|
2407
3011
|
this.ws.on("error", (err) => {
|
|
2408
3012
|
console.error("WebSocket error:", err.message);
|
|
2409
3013
|
if (!this.isReconnecting) {
|
|
2410
|
-
this.reconnect(
|
|
3014
|
+
this.reconnect(this.lastWsUrl);
|
|
2411
3015
|
}
|
|
2412
3016
|
reject(err);
|
|
2413
3017
|
});
|
|
@@ -2418,9 +3022,16 @@ var WebSocketClient = class extends EventEmitter3 {
|
|
|
2418
3022
|
}, this.backOffOptions);
|
|
2419
3023
|
}
|
|
2420
3024
|
/**
|
|
2421
|
-
*
|
|
3025
|
+
* Handles incoming WebSocket messages by parsing and processing events.
|
|
3026
|
+
*
|
|
3027
|
+
* This method parses the raw message into a WebSocketEvent, filters it based on
|
|
3028
|
+
* subscribed events (if any), processes channel and playback events, and emits
|
|
3029
|
+
* the event to listeners. It also handles any errors that occur during processing.
|
|
3030
|
+
*
|
|
3031
|
+
* @param rawMessage - The raw message string received from the WebSocket connection.
|
|
3032
|
+
* @returns void This method doesn't return a value but emits events.
|
|
2422
3033
|
*
|
|
2423
|
-
* @
|
|
3034
|
+
* @throws Will emit an 'error' event if the message cannot be parsed or processed.
|
|
2424
3035
|
*/
|
|
2425
3036
|
handleMessage(rawMessage) {
|
|
2426
3037
|
try {
|
|
@@ -2438,6 +3049,11 @@ var WebSocketClient = class extends EventEmitter3 {
|
|
|
2438
3049
|
instancePlayback.emitEvent(event);
|
|
2439
3050
|
event.instancePlayback = instancePlayback;
|
|
2440
3051
|
}
|
|
3052
|
+
if ("bridge" in event && event.bridge?.id && this.ariClient) {
|
|
3053
|
+
const instanceBridge = this.ariClient.Bridge(event.bridge.id);
|
|
3054
|
+
instanceBridge.emitEvent(event);
|
|
3055
|
+
event.instanceBridge = instanceBridge;
|
|
3056
|
+
}
|
|
2441
3057
|
this.emit(event.type, event);
|
|
2442
3058
|
} catch (error) {
|
|
2443
3059
|
console.error(
|
|
@@ -2448,18 +3064,27 @@ var WebSocketClient = class extends EventEmitter3 {
|
|
|
2448
3064
|
}
|
|
2449
3065
|
}
|
|
2450
3066
|
/**
|
|
2451
|
-
* Attempts to reconnect to the WebSocket.
|
|
3067
|
+
* Attempts to reconnect to the WebSocket server using an exponential backoff strategy.
|
|
3068
|
+
*
|
|
3069
|
+
* This method is called when the WebSocket connection is closed unexpectedly.
|
|
3070
|
+
* It increments the reconnection attempt counter, logs the attempt, and uses
|
|
3071
|
+
* the backOff utility to retry the connection with exponential delays between attempts.
|
|
3072
|
+
*
|
|
3073
|
+
* @param wsUrl - The WebSocket URL to reconnect to.
|
|
3074
|
+
* @returns void - This method doesn't return a value.
|
|
2452
3075
|
*
|
|
2453
|
-
* @
|
|
3076
|
+
* @emits reconnectFailed - Emitted if all reconnection attempts fail.
|
|
2454
3077
|
*/
|
|
2455
3078
|
reconnect(wsUrl) {
|
|
2456
3079
|
this.isReconnecting = true;
|
|
2457
|
-
|
|
2458
|
-
|
|
3080
|
+
this.reconnectionAttempts++;
|
|
3081
|
+
console.log(
|
|
3082
|
+
`Initiating reconnection attempt #${this.reconnectionAttempts}...`
|
|
3083
|
+
);
|
|
2459
3084
|
(0, import_exponential_backoff.backOff)(() => this.initializeWebSocket(wsUrl), this.backOffOptions).catch(
|
|
2460
3085
|
(error) => {
|
|
2461
3086
|
console.error(
|
|
2462
|
-
|
|
3087
|
+
`Failed to reconnect after ${this.reconnectionAttempts} attempts:`,
|
|
2463
3088
|
error instanceof Error ? error.message : "Unknown error"
|
|
2464
3089
|
);
|
|
2465
3090
|
this.emit("reconnectFailed", error);
|
|
@@ -2467,7 +3092,13 @@ var WebSocketClient = class extends EventEmitter3 {
|
|
|
2467
3092
|
);
|
|
2468
3093
|
}
|
|
2469
3094
|
/**
|
|
2470
|
-
*
|
|
3095
|
+
* Closes the WebSocket connection if it exists.
|
|
3096
|
+
*
|
|
3097
|
+
* This method attempts to gracefully close the WebSocket connection
|
|
3098
|
+
* and sets the WebSocket instance to undefined. If an error occurs
|
|
3099
|
+
* during the closing process, it will be caught and logged.
|
|
3100
|
+
*
|
|
3101
|
+
* @throws {Error} Logs an error message if closing the WebSocket fails.
|
|
2471
3102
|
*/
|
|
2472
3103
|
close() {
|
|
2473
3104
|
try {
|
|
@@ -2484,17 +3115,30 @@ var WebSocketClient = class extends EventEmitter3 {
|
|
|
2484
3115
|
}
|
|
2485
3116
|
}
|
|
2486
3117
|
/**
|
|
2487
|
-
* Checks if the WebSocket is currently
|
|
3118
|
+
* Checks if the WebSocket connection is currently open and active.
|
|
2488
3119
|
*
|
|
2489
|
-
*
|
|
3120
|
+
* This method provides a way to determine the current state of the WebSocket connection.
|
|
3121
|
+
* It checks if the WebSocket's readyState property is equal to WebSocket.OPEN,
|
|
3122
|
+
* which indicates an active connection.
|
|
3123
|
+
*
|
|
3124
|
+
* @returns {boolean} True if the WebSocket connection is open and active, false otherwise.
|
|
2490
3125
|
*/
|
|
2491
3126
|
isConnected() {
|
|
2492
3127
|
return this.ws?.readyState === WebSocket.OPEN;
|
|
2493
3128
|
}
|
|
2494
3129
|
/**
|
|
2495
|
-
*
|
|
3130
|
+
* Retrieves the current state of the WebSocket connection.
|
|
3131
|
+
*
|
|
3132
|
+
* This method provides a way to check the current state of the WebSocket connection.
|
|
3133
|
+
* It returns a number corresponding to one of the WebSocket readyState values:
|
|
3134
|
+
* - 0 (CONNECTING): The connection is not yet open.
|
|
3135
|
+
* - 1 (OPEN): The connection is open and ready to communicate.
|
|
3136
|
+
* - 2 (CLOSING): The connection is in the process of closing.
|
|
3137
|
+
* - 3 (CLOSED): The connection is closed or couldn't be opened.
|
|
3138
|
+
*
|
|
3139
|
+
* If the WebSocket instance doesn't exist, it returns WebSocket.CLOSED (3).
|
|
2496
3140
|
*
|
|
2497
|
-
* @returns {number}
|
|
3141
|
+
* @returns {number} A number representing the current state of the WebSocket connection.
|
|
2498
3142
|
*/
|
|
2499
3143
|
getState() {
|
|
2500
3144
|
return this.ws?.readyState ?? WebSocket.CLOSED;
|
|
@@ -2520,11 +3164,11 @@ var AriClient = class {
|
|
|
2520
3164
|
this.baseClient = new BaseClient(baseUrl, config.username, config.password);
|
|
2521
3165
|
this.channels = new Channels(this.baseClient, this);
|
|
2522
3166
|
this.playbacks = new Playbacks(this.baseClient, this);
|
|
3167
|
+
this.bridges = new Bridges(this.baseClient, this);
|
|
2523
3168
|
this.endpoints = new Endpoints(this.baseClient);
|
|
2524
3169
|
this.applications = new Applications(this.baseClient);
|
|
2525
3170
|
this.sounds = new Sounds(this.baseClient);
|
|
2526
3171
|
this.asterisk = new Asterisk(this.baseClient);
|
|
2527
|
-
this.bridges = new Bridges(this.baseClient);
|
|
2528
3172
|
console.log(`ARI Client initialized with base URL: ${baseUrl}`);
|
|
2529
3173
|
}
|
|
2530
3174
|
baseClient;
|
|
@@ -2640,6 +3284,20 @@ var AriClient = class {
|
|
|
2640
3284
|
Playback(playbackId, _app) {
|
|
2641
3285
|
return this.playbacks.Playback({ id: playbackId });
|
|
2642
3286
|
}
|
|
3287
|
+
/**
|
|
3288
|
+
* Creates or retrieves a Bridge instance.
|
|
3289
|
+
*
|
|
3290
|
+
* This function allows you to create a new Bridge instance or retrieve an existing one
|
|
3291
|
+
* based on the provided bridge ID.
|
|
3292
|
+
*
|
|
3293
|
+
* @param {string} [bridgeId] - Optional ID of an existing bridge. If provided, retrieves the
|
|
3294
|
+
* existing bridge with this ID. If omitted, creates a new bridge.
|
|
3295
|
+
* @returns {BridgeInstance} A new or existing Bridge instance that can be used to interact
|
|
3296
|
+
* with the Asterisk bridge.
|
|
3297
|
+
*/
|
|
3298
|
+
Bridge(bridgeId) {
|
|
3299
|
+
return this.bridges.Bridge({ id: bridgeId });
|
|
3300
|
+
}
|
|
2643
3301
|
/**
|
|
2644
3302
|
* Gets the current WebSocket connection status.
|
|
2645
3303
|
*
|
|
@@ -2653,6 +3311,7 @@ export {
|
|
|
2653
3311
|
Applications,
|
|
2654
3312
|
AriClient,
|
|
2655
3313
|
Asterisk,
|
|
3314
|
+
BridgeInstance,
|
|
2656
3315
|
Bridges,
|
|
2657
3316
|
ChannelInstance,
|
|
2658
3317
|
Channels,
|