@ipcom/asterisk-ari 0.0.139 → 0.0.141
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 +311 -0
- package/dist/cjs/index.cjs +1032 -269
- package/dist/cjs/index.cjs.map +3 -3
- package/dist/esm/index.js +1035 -270
- package/dist/esm/index.js.map +3 -3
- package/dist/types/ari-client/ariClient.d.ts +64 -15
- package/dist/types/ari-client/ariClient.d.ts.map +1 -1
- package/dist/types/ari-client/baseClient.d.ts +55 -22
- package/dist/types/ari-client/baseClient.d.ts.map +1 -1
- package/dist/types/ari-client/resources/channels.d.ts +351 -48
- package/dist/types/ari-client/resources/channels.d.ts.map +1 -1
- package/dist/types/ari-client/resources/playbacks.d.ts +93 -20
- package/dist/types/ari-client/resources/playbacks.d.ts.map +1 -1
- package/dist/types/ari-client/utils.d.ts.map +1 -1
- package/dist/types/ari-client/websocketClient.d.ts +44 -13
- package/dist/types/ari-client/websocketClient.d.ts.map +1 -1
- package/dist/types/index.d.ts +26 -2
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/cjs/index.cjs
CHANGED
|
@@ -594,29 +594,52 @@ module.exports = __toCommonJS(src_exports);
|
|
|
594
594
|
|
|
595
595
|
// src/ari-client/baseClient.ts
|
|
596
596
|
var import_axios = __toESM(require("axios"), 1);
|
|
597
|
+
var HTTPError = class extends Error {
|
|
598
|
+
constructor(message, status, method, url) {
|
|
599
|
+
super(message);
|
|
600
|
+
this.status = status;
|
|
601
|
+
this.method = method;
|
|
602
|
+
this.url = url;
|
|
603
|
+
this.name = "HTTPError";
|
|
604
|
+
}
|
|
605
|
+
};
|
|
597
606
|
var BaseClient = class {
|
|
607
|
+
/**
|
|
608
|
+
* Creates a new BaseClient instance.
|
|
609
|
+
*
|
|
610
|
+
* @param {string} baseUrl - The base URL for the API
|
|
611
|
+
* @param {string} username - Username for authentication
|
|
612
|
+
* @param {string} password - Password for authentication
|
|
613
|
+
* @param {number} [timeout=5000] - Request timeout in milliseconds
|
|
614
|
+
* @throws {Error} If the base URL format is invalid
|
|
615
|
+
*/
|
|
598
616
|
constructor(baseUrl, username, password, timeout = 5e3) {
|
|
599
617
|
this.baseUrl = baseUrl;
|
|
600
618
|
this.username = username;
|
|
601
619
|
this.password = password;
|
|
602
620
|
if (!/^https?:\/\/.+/.test(baseUrl)) {
|
|
603
|
-
throw new Error(
|
|
604
|
-
"Invalid base URL. It must start with http:// or https://"
|
|
605
|
-
);
|
|
621
|
+
throw new Error("Invalid base URL. It must start with http:// or https://");
|
|
606
622
|
}
|
|
607
623
|
this.client = import_axios.default.create({
|
|
608
624
|
baseURL: baseUrl,
|
|
609
625
|
auth: { username, password },
|
|
610
|
-
timeout
|
|
626
|
+
timeout,
|
|
627
|
+
headers: {
|
|
628
|
+
"Content-Type": "application/json"
|
|
629
|
+
}
|
|
611
630
|
});
|
|
612
631
|
this.addInterceptors();
|
|
632
|
+
console.log(`BaseClient initialized for ${baseUrl}`);
|
|
613
633
|
}
|
|
614
634
|
client;
|
|
635
|
+
/**
|
|
636
|
+
* Gets the base URL of the client.
|
|
637
|
+
*/
|
|
615
638
|
getBaseUrl() {
|
|
616
639
|
return this.baseUrl;
|
|
617
640
|
}
|
|
618
641
|
/**
|
|
619
|
-
*
|
|
642
|
+
* Gets the configured credentials.
|
|
620
643
|
*/
|
|
621
644
|
getCredentials() {
|
|
622
645
|
return {
|
|
@@ -626,123 +649,159 @@ var BaseClient = class {
|
|
|
626
649
|
};
|
|
627
650
|
}
|
|
628
651
|
/**
|
|
629
|
-
* Adds interceptors to the Axios instance.
|
|
652
|
+
* Adds request and response interceptors to the Axios instance.
|
|
630
653
|
*/
|
|
631
654
|
addInterceptors() {
|
|
632
655
|
this.client.interceptors.request.use(
|
|
633
656
|
(config) => {
|
|
657
|
+
console.log(`[Request] ${config.method?.toUpperCase()} ${config.url}`);
|
|
634
658
|
return config;
|
|
635
659
|
},
|
|
636
660
|
(error) => {
|
|
637
|
-
|
|
638
|
-
|
|
661
|
+
const message = this.getErrorMessage(error);
|
|
662
|
+
console.error("[Request Error]", message);
|
|
663
|
+
return Promise.reject(new HTTPError(message));
|
|
639
664
|
}
|
|
640
665
|
);
|
|
641
666
|
this.client.interceptors.response.use(
|
|
642
|
-
(response) =>
|
|
667
|
+
(response) => {
|
|
668
|
+
console.log(`[Response] ${response.status} ${response.config.url}`);
|
|
669
|
+
return response;
|
|
670
|
+
},
|
|
643
671
|
(error) => {
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
message
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
);
|
|
672
|
+
if ((0, import_axios.isAxiosError)(error)) {
|
|
673
|
+
const status = error.response?.status ?? 0;
|
|
674
|
+
const method = error.config?.method?.toUpperCase() ?? "UNKNOWN";
|
|
675
|
+
const url = error.config?.url ?? "unknown-url";
|
|
676
|
+
const message2 = error.response?.data?.message || error.message || "Unknown error";
|
|
677
|
+
if (status === 404) {
|
|
678
|
+
console.warn(`[404] Not Found: ${url}`);
|
|
679
|
+
} else if (status >= 500) {
|
|
680
|
+
console.error(`[${status}] Server Error: ${url}`);
|
|
681
|
+
} else if (status > 0) {
|
|
682
|
+
console.warn(`[${status}] ${method} ${url}: ${message2}`);
|
|
683
|
+
} else {
|
|
684
|
+
console.error(`[Network] Request failed: ${message2}`);
|
|
685
|
+
}
|
|
686
|
+
throw new HTTPError(message2, status || void 0, method, url);
|
|
660
687
|
}
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
)
|
|
665
|
-
);
|
|
688
|
+
const message = this.getErrorMessage(error);
|
|
689
|
+
console.error("[Unexpected Error]", message);
|
|
690
|
+
throw new Error(message);
|
|
666
691
|
}
|
|
667
692
|
);
|
|
668
693
|
}
|
|
669
694
|
/**
|
|
670
695
|
* Executes a GET request.
|
|
671
|
-
*
|
|
672
|
-
* @param
|
|
696
|
+
*
|
|
697
|
+
* @param path - API endpoint path
|
|
698
|
+
* @param config - Optional Axios request configuration
|
|
699
|
+
* @returns Promise with the response data
|
|
673
700
|
*/
|
|
674
701
|
async get(path, config) {
|
|
675
702
|
try {
|
|
676
703
|
const response = await this.client.get(path, config);
|
|
677
704
|
return response.data;
|
|
678
705
|
} catch (error) {
|
|
679
|
-
this.handleRequestError(error);
|
|
706
|
+
throw this.handleRequestError(error);
|
|
680
707
|
}
|
|
681
708
|
}
|
|
682
709
|
/**
|
|
683
710
|
* Executes a POST request.
|
|
684
|
-
*
|
|
685
|
-
* @param
|
|
686
|
-
* @param
|
|
711
|
+
*
|
|
712
|
+
* @param path - API endpoint path
|
|
713
|
+
* @param data - Request payload
|
|
714
|
+
* @param config - Optional Axios request configuration
|
|
715
|
+
* @returns Promise with the response data
|
|
687
716
|
*/
|
|
688
717
|
async post(path, data, config) {
|
|
689
718
|
try {
|
|
690
719
|
const response = await this.client.post(path, data, config);
|
|
691
720
|
return response.data;
|
|
692
721
|
} catch (error) {
|
|
693
|
-
this.handleRequestError(error);
|
|
722
|
+
throw this.handleRequestError(error);
|
|
694
723
|
}
|
|
695
724
|
}
|
|
696
725
|
/**
|
|
697
726
|
* Executes a PUT request.
|
|
698
|
-
*
|
|
699
|
-
* @param
|
|
700
|
-
* @param
|
|
727
|
+
*
|
|
728
|
+
* @param path - API endpoint path
|
|
729
|
+
* @param data - Request payload
|
|
730
|
+
* @param config - Optional Axios request configuration
|
|
731
|
+
* @returns Promise with the response data
|
|
701
732
|
*/
|
|
702
733
|
async put(path, data, config) {
|
|
703
734
|
try {
|
|
704
735
|
const response = await this.client.put(path, data, config);
|
|
705
736
|
return response.data;
|
|
706
737
|
} catch (error) {
|
|
707
|
-
this.handleRequestError(error);
|
|
738
|
+
throw this.handleRequestError(error);
|
|
708
739
|
}
|
|
709
740
|
}
|
|
710
741
|
/**
|
|
711
742
|
* Executes a DELETE request.
|
|
712
|
-
*
|
|
713
|
-
* @param
|
|
743
|
+
*
|
|
744
|
+
* @param path - API endpoint path
|
|
745
|
+
* @param config - Optional Axios request configuration
|
|
746
|
+
* @returns Promise with the response data
|
|
714
747
|
*/
|
|
715
748
|
async delete(path, config) {
|
|
716
749
|
try {
|
|
717
750
|
const response = await this.client.delete(path, config);
|
|
718
751
|
return response.data;
|
|
719
752
|
} catch (error) {
|
|
720
|
-
this.handleRequestError(error);
|
|
753
|
+
throw this.handleRequestError(error);
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
/**
|
|
757
|
+
* Handles and formats error messages from various error types.
|
|
758
|
+
*/
|
|
759
|
+
getErrorMessage(error) {
|
|
760
|
+
if ((0, import_axios.isAxiosError)(error)) {
|
|
761
|
+
return error.response?.data?.message || error.message || "HTTP Error";
|
|
721
762
|
}
|
|
763
|
+
if (error instanceof Error) {
|
|
764
|
+
return error.message;
|
|
765
|
+
}
|
|
766
|
+
return "An unknown error occurred";
|
|
722
767
|
}
|
|
723
768
|
/**
|
|
724
|
-
* Handles errors
|
|
725
|
-
* @param error - The error to handle.
|
|
769
|
+
* Handles errors from HTTP requests.
|
|
726
770
|
*/
|
|
727
771
|
handleRequestError(error) {
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
throw new
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
772
|
+
const message = this.getErrorMessage(error);
|
|
773
|
+
if ((0, import_axios.isAxiosError)(error)) {
|
|
774
|
+
throw new HTTPError(
|
|
775
|
+
message,
|
|
776
|
+
error.response?.status,
|
|
777
|
+
error.config?.method?.toUpperCase(),
|
|
778
|
+
error.config?.url
|
|
779
|
+
);
|
|
734
780
|
}
|
|
781
|
+
throw new Error(message);
|
|
735
782
|
}
|
|
736
783
|
/**
|
|
737
784
|
* Sets custom headers for the client instance.
|
|
738
|
-
* Useful for adding dynamic tokens or specific API headers.
|
|
739
|
-
* @param headers - Headers to merge with existing configuration.
|
|
740
785
|
*/
|
|
741
786
|
setHeaders(headers) {
|
|
742
787
|
this.client.defaults.headers.common = {
|
|
743
788
|
...this.client.defaults.headers.common,
|
|
744
789
|
...headers
|
|
745
790
|
};
|
|
791
|
+
console.log("Updated client headers");
|
|
792
|
+
}
|
|
793
|
+
/**
|
|
794
|
+
* Gets the current request timeout setting.
|
|
795
|
+
*/
|
|
796
|
+
getTimeout() {
|
|
797
|
+
return this.client.defaults.timeout || 5e3;
|
|
798
|
+
}
|
|
799
|
+
/**
|
|
800
|
+
* Updates the request timeout setting.
|
|
801
|
+
*/
|
|
802
|
+
setTimeout(timeout) {
|
|
803
|
+
this.client.defaults.timeout = timeout;
|
|
804
|
+
console.log(`Updated timeout to ${timeout}ms`);
|
|
746
805
|
}
|
|
747
806
|
};
|
|
748
807
|
|
|
@@ -966,6 +1025,7 @@ var Bridges = class {
|
|
|
966
1025
|
|
|
967
1026
|
// src/ari-client/resources/channels.ts
|
|
968
1027
|
var import_events = require("events");
|
|
1028
|
+
var import_axios2 = require("axios");
|
|
969
1029
|
|
|
970
1030
|
// node_modules/uuid/dist/esm/stringify.js
|
|
971
1031
|
var byteToHex = [];
|
|
@@ -1020,102 +1080,212 @@ function toQueryParams2(options) {
|
|
|
1020
1080
|
}
|
|
1021
1081
|
|
|
1022
1082
|
// src/ari-client/resources/channels.ts
|
|
1083
|
+
var getErrorMessage = (error) => {
|
|
1084
|
+
if ((0, import_axios2.isAxiosError)(error)) {
|
|
1085
|
+
return error.response?.data?.message || error.message || "An axios error occurred";
|
|
1086
|
+
}
|
|
1087
|
+
if (error instanceof Error) {
|
|
1088
|
+
return error.message;
|
|
1089
|
+
}
|
|
1090
|
+
return "An unknown error occurred";
|
|
1091
|
+
};
|
|
1023
1092
|
var ChannelInstance = class {
|
|
1024
|
-
|
|
1025
|
-
constructor(client, baseClient, channelId = `channel-${Date.now()}`) {
|
|
1093
|
+
constructor(client, baseClient, channelId) {
|
|
1026
1094
|
this.client = client;
|
|
1027
1095
|
this.baseClient = baseClient;
|
|
1028
|
-
this.channelId = channelId;
|
|
1029
1096
|
this.id = channelId || `channel-${Date.now()}`;
|
|
1097
|
+
console.log(`Channel instance initialized with ID: ${this.id}`);
|
|
1030
1098
|
}
|
|
1031
1099
|
eventEmitter = new import_events.EventEmitter();
|
|
1032
1100
|
channelData = null;
|
|
1033
1101
|
id;
|
|
1034
1102
|
/**
|
|
1035
|
-
*
|
|
1103
|
+
* Registers an event listener for specific channel events
|
|
1036
1104
|
*/
|
|
1037
1105
|
on(event, listener) {
|
|
1106
|
+
if (!event) {
|
|
1107
|
+
throw new Error("Event type is required");
|
|
1108
|
+
}
|
|
1038
1109
|
const wrappedListener = (data) => {
|
|
1039
1110
|
if ("channel" in data && data.channel?.id === this.id) {
|
|
1040
1111
|
listener(data);
|
|
1041
1112
|
}
|
|
1042
1113
|
};
|
|
1043
1114
|
this.eventEmitter.on(event, wrappedListener);
|
|
1115
|
+
console.log(`Event listener registered for ${event} on channel ${this.id}`);
|
|
1044
1116
|
}
|
|
1045
1117
|
/**
|
|
1046
|
-
*
|
|
1118
|
+
* Registers a one-time event listener
|
|
1047
1119
|
*/
|
|
1048
1120
|
once(event, listener) {
|
|
1121
|
+
if (!event) {
|
|
1122
|
+
throw new Error("Event type is required");
|
|
1123
|
+
}
|
|
1049
1124
|
const wrappedListener = (data) => {
|
|
1050
1125
|
if ("channel" in data && data.channel?.id === this.id) {
|
|
1051
1126
|
listener(data);
|
|
1052
1127
|
}
|
|
1053
1128
|
};
|
|
1054
1129
|
this.eventEmitter.once(event, wrappedListener);
|
|
1130
|
+
console.log(
|
|
1131
|
+
`One-time event listener registered for ${event} on channel ${this.id}`
|
|
1132
|
+
);
|
|
1055
1133
|
}
|
|
1056
1134
|
/**
|
|
1057
|
-
*
|
|
1135
|
+
* Removes event listener(s) for a specific WebSocket event type.
|
|
1136
|
+
* If a specific listener is provided, only that listener is removed.
|
|
1137
|
+
* Otherwise, all listeners for the given event type are removed.
|
|
1138
|
+
*
|
|
1139
|
+
* @param {T} event - The type of WebSocket event to remove listener(s) for
|
|
1140
|
+
* @param {Function} [listener] - Optional specific listener to remove
|
|
1141
|
+
* @throws {Error} If no event type is provided
|
|
1058
1142
|
*/
|
|
1059
1143
|
off(event, listener) {
|
|
1144
|
+
if (!event) {
|
|
1145
|
+
throw new Error("Event type is required");
|
|
1146
|
+
}
|
|
1060
1147
|
if (listener) {
|
|
1061
1148
|
this.eventEmitter.off(event, listener);
|
|
1149
|
+
console.log(
|
|
1150
|
+
`Specific listener removed for ${event} on channel ${this.id}`
|
|
1151
|
+
);
|
|
1062
1152
|
} else {
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
this.eventEmitter.off(event, fn);
|
|
1066
|
-
});
|
|
1153
|
+
this.eventEmitter.removeAllListeners(event);
|
|
1154
|
+
console.log(`All listeners removed for ${event} on channel ${this.id}`);
|
|
1067
1155
|
}
|
|
1068
1156
|
}
|
|
1069
1157
|
/**
|
|
1070
|
-
*
|
|
1071
|
-
*/
|
|
1072
|
-
getListenerCount(event) {
|
|
1073
|
-
return this.eventEmitter.listenerCount(event);
|
|
1074
|
-
}
|
|
1075
|
-
/**
|
|
1076
|
-
* Emite eventos internamente para o canal.
|
|
1077
|
-
* Verifica o ID do canal antes de emitir.
|
|
1158
|
+
* Emits an event if it matches the current channel
|
|
1078
1159
|
*/
|
|
1079
1160
|
emitEvent(event) {
|
|
1161
|
+
if (!event) {
|
|
1162
|
+
console.warn("Received invalid event");
|
|
1163
|
+
return;
|
|
1164
|
+
}
|
|
1080
1165
|
if ("channel" in event && event.channel?.id === this.id) {
|
|
1081
1166
|
this.eventEmitter.emit(event.type, event);
|
|
1167
|
+
console.log(`Event ${event.type} emitted for channel ${this.id}`);
|
|
1082
1168
|
}
|
|
1083
1169
|
}
|
|
1084
1170
|
/**
|
|
1085
|
-
*
|
|
1171
|
+
* Removes all event listeners associated with the current instance.
|
|
1172
|
+
* This ensures that there are no lingering event handlers for the channel.
|
|
1173
|
+
*
|
|
1174
|
+
* @return {void} This method does not return a value.
|
|
1086
1175
|
*/
|
|
1087
1176
|
removeAllListeners() {
|
|
1088
1177
|
console.log(`Removendo todos os listeners para o canal ${this.id}`);
|
|
1089
1178
|
this.eventEmitter.removeAllListeners();
|
|
1090
1179
|
}
|
|
1180
|
+
/**
|
|
1181
|
+
* Answers the channel
|
|
1182
|
+
*/
|
|
1091
1183
|
async answer() {
|
|
1092
|
-
|
|
1184
|
+
try {
|
|
1185
|
+
await this.baseClient.post(`/channels/${this.id}/answer`);
|
|
1186
|
+
console.log(`Channel ${this.id} answered`);
|
|
1187
|
+
} catch (error) {
|
|
1188
|
+
const message = getErrorMessage(error);
|
|
1189
|
+
console.error(`Error answering channel ${this.id}:`, message);
|
|
1190
|
+
throw new Error(`Failed to answer channel: ${message}`);
|
|
1191
|
+
}
|
|
1093
1192
|
}
|
|
1094
1193
|
/**
|
|
1095
|
-
*
|
|
1194
|
+
* Originates a new channel
|
|
1195
|
+
*
|
|
1196
|
+
* @param data - Channel origination configuration
|
|
1197
|
+
* @returns Promise resolving to the created channel
|
|
1198
|
+
* @throws Error if channel already exists or origination fails
|
|
1096
1199
|
*/
|
|
1097
1200
|
async originate(data) {
|
|
1098
1201
|
if (this.channelData) {
|
|
1099
|
-
throw new Error("
|
|
1202
|
+
throw new Error("Channel has already been created");
|
|
1203
|
+
}
|
|
1204
|
+
try {
|
|
1205
|
+
this.channelData = await this.baseClient.post(
|
|
1206
|
+
"/channels",
|
|
1207
|
+
data
|
|
1208
|
+
);
|
|
1209
|
+
console.log(
|
|
1210
|
+
`Channel originated successfully with ID: ${this.channelData.id}`
|
|
1211
|
+
);
|
|
1212
|
+
return this.channelData;
|
|
1213
|
+
} catch (error) {
|
|
1214
|
+
const message = getErrorMessage(error);
|
|
1215
|
+
console.error(`Error originating channel:`, message);
|
|
1216
|
+
throw new Error(`Failed to originate channel: ${message}`);
|
|
1100
1217
|
}
|
|
1101
|
-
const channel = await this.baseClient.post("/channels", data);
|
|
1102
|
-
this.channelData = channel;
|
|
1103
|
-
return channel;
|
|
1104
1218
|
}
|
|
1105
1219
|
/**
|
|
1106
|
-
*
|
|
1220
|
+
* Plays media on the channel
|
|
1107
1221
|
*/
|
|
1108
|
-
async
|
|
1109
|
-
if (
|
|
1110
|
-
|
|
1222
|
+
async play(options, playbackId) {
|
|
1223
|
+
if (!options.media) {
|
|
1224
|
+
throw new Error("Media URL is required");
|
|
1111
1225
|
}
|
|
1112
|
-
|
|
1113
|
-
|
|
1226
|
+
try {
|
|
1227
|
+
if (!this.channelData) {
|
|
1228
|
+
console.log("Initializing channel details...");
|
|
1229
|
+
this.channelData = await this.getDetails();
|
|
1230
|
+
}
|
|
1231
|
+
const playback = this.client.Playback(playbackId || v4_default());
|
|
1232
|
+
await this.baseClient.post(
|
|
1233
|
+
`/channels/${this.id}/play/${playback.id}`,
|
|
1234
|
+
options
|
|
1235
|
+
);
|
|
1236
|
+
console.log(`Media playback started on channel ${this.id}`);
|
|
1237
|
+
return playback;
|
|
1238
|
+
} catch (error) {
|
|
1239
|
+
const message = getErrorMessage(error);
|
|
1240
|
+
console.error(`Error playing media on channel ${this.id}:`, message);
|
|
1241
|
+
throw new Error(`Failed to play media: ${message}`);
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
/**
|
|
1245
|
+
* Gets the current channel details
|
|
1246
|
+
*/
|
|
1247
|
+
async getDetails() {
|
|
1248
|
+
try {
|
|
1249
|
+
if (this.channelData) {
|
|
1250
|
+
return this.channelData;
|
|
1251
|
+
}
|
|
1252
|
+
if (!this.id) {
|
|
1253
|
+
throw new Error("No channel ID associated with this instance");
|
|
1254
|
+
}
|
|
1255
|
+
const details = await this.baseClient.get(
|
|
1256
|
+
`/channels/${this.id}`
|
|
1257
|
+
);
|
|
1258
|
+
this.channelData = details;
|
|
1259
|
+
console.log(`Retrieved channel details for ${this.id}`);
|
|
1260
|
+
return details;
|
|
1261
|
+
} catch (error) {
|
|
1262
|
+
const message = getErrorMessage(error);
|
|
1263
|
+
console.error(
|
|
1264
|
+
`Error retrieving channel details for ${this.id}:`,
|
|
1265
|
+
message
|
|
1266
|
+
);
|
|
1267
|
+
throw new Error(`Failed to get channel details: ${message}`);
|
|
1114
1268
|
}
|
|
1115
|
-
const details = await this.baseClient.get(`/channels/${this.id}`);
|
|
1116
|
-
this.channelData = details;
|
|
1117
|
-
return details;
|
|
1118
1269
|
}
|
|
1270
|
+
/**
|
|
1271
|
+
* Checks if the channel has any listeners for a specific event
|
|
1272
|
+
*/
|
|
1273
|
+
hasListeners(event) {
|
|
1274
|
+
return this.eventEmitter.listenerCount(event) > 0;
|
|
1275
|
+
}
|
|
1276
|
+
/**
|
|
1277
|
+
* Gets the count of listeners for a specific event
|
|
1278
|
+
*/
|
|
1279
|
+
getListenerCount(event) {
|
|
1280
|
+
return this.eventEmitter.listenerCount(event);
|
|
1281
|
+
}
|
|
1282
|
+
/**
|
|
1283
|
+
* Fetches a specific channel variable.
|
|
1284
|
+
*
|
|
1285
|
+
* @param {string} variable - The name of the variable to retrieve. This parameter is required.
|
|
1286
|
+
* @return {Promise<ChannelVar>} A promise that resolves with the value of the requested channel variable.
|
|
1287
|
+
* @throws {Error} If the 'variable' parameter is not provided.
|
|
1288
|
+
*/
|
|
1119
1289
|
async getVariable(variable) {
|
|
1120
1290
|
if (!variable) {
|
|
1121
1291
|
throw new Error("The 'variable' parameter is required.");
|
|
@@ -1125,7 +1295,11 @@ var ChannelInstance = class {
|
|
|
1125
1295
|
);
|
|
1126
1296
|
}
|
|
1127
1297
|
/**
|
|
1128
|
-
*
|
|
1298
|
+
* Terminates the active call associated with the current channel.
|
|
1299
|
+
* This method ensures that channel details are initialized before attempting to hang up.
|
|
1300
|
+
* If the channel ID is invalid or cannot be determined, an error is thrown.
|
|
1301
|
+
*
|
|
1302
|
+
* @return {Promise<void>} A promise that resolves when the call is successfully terminated.
|
|
1129
1303
|
*/
|
|
1130
1304
|
async hangup() {
|
|
1131
1305
|
if (!this.channelData) {
|
|
@@ -1138,25 +1312,12 @@ var ChannelInstance = class {
|
|
|
1138
1312
|
await this.baseClient.delete(`/channels/${this.channelData.id}`);
|
|
1139
1313
|
}
|
|
1140
1314
|
/**
|
|
1141
|
-
*
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
}
|
|
1148
|
-
const playback = this.client.Playback(playbackId || v4_default());
|
|
1149
|
-
if (!this.channelData?.id) {
|
|
1150
|
-
throw new Error("N\xE3o foi poss\xEDvel inicializar o canal. ID inv\xE1lido.");
|
|
1151
|
-
}
|
|
1152
|
-
await this.baseClient.post(
|
|
1153
|
-
`/channels/${this.channelData.id}/play/${playback.id}`,
|
|
1154
|
-
options
|
|
1155
|
-
);
|
|
1156
|
-
return playback;
|
|
1157
|
-
}
|
|
1158
|
-
/**
|
|
1159
|
-
* Reproduz mídia em um canal.
|
|
1315
|
+
* Plays media on the specified channel using the provided media URL and optional playback options.
|
|
1316
|
+
*
|
|
1317
|
+
* @param {string} media - The URL or identifier of the media to be played.
|
|
1318
|
+
* @param {PlaybackOptions} [options] - Optional playback settings such as volume, playback speed, etc.
|
|
1319
|
+
* @return {Promise<ChannelPlayback>} A promise that resolves with the playback details for the channel.
|
|
1320
|
+
* @throws {Error} Throws an error if the channel has not been created.
|
|
1160
1321
|
*/
|
|
1161
1322
|
async playMedia(media, options) {
|
|
1162
1323
|
if (!this.channelData) {
|
|
@@ -1169,7 +1330,11 @@ var ChannelInstance = class {
|
|
|
1169
1330
|
);
|
|
1170
1331
|
}
|
|
1171
1332
|
/**
|
|
1172
|
-
*
|
|
1333
|
+
* Stops the playback for the given playback ID.
|
|
1334
|
+
*
|
|
1335
|
+
* @param {string} playbackId - The unique identifier for the playback to be stopped.
|
|
1336
|
+
* @return {Promise<void>} A promise that resolves when the playback is successfully stopped.
|
|
1337
|
+
* @throws {Error} Throws an error if the instance is not associated with a channel.
|
|
1173
1338
|
*/
|
|
1174
1339
|
async stopPlayback(playbackId) {
|
|
1175
1340
|
if (!this.channelData?.id) {
|
|
@@ -1180,7 +1345,11 @@ var ChannelInstance = class {
|
|
|
1180
1345
|
);
|
|
1181
1346
|
}
|
|
1182
1347
|
/**
|
|
1183
|
-
*
|
|
1348
|
+
* Pauses the playback of the specified media on a channel.
|
|
1349
|
+
*
|
|
1350
|
+
* @param {string} playbackId - The unique identifier of the playback to be paused.
|
|
1351
|
+
* @return {Promise<void>} A promise that resolves when the playback has been successfully paused.
|
|
1352
|
+
* @throws {Error} Throws an error if the channel is not associated with the current instance.
|
|
1184
1353
|
*/
|
|
1185
1354
|
async pausePlayback(playbackId) {
|
|
1186
1355
|
if (!this.channelData?.id) {
|
|
@@ -1191,7 +1360,11 @@ var ChannelInstance = class {
|
|
|
1191
1360
|
);
|
|
1192
1361
|
}
|
|
1193
1362
|
/**
|
|
1194
|
-
*
|
|
1363
|
+
* Resumes playback of the specified playback session on the associated channel.
|
|
1364
|
+
*
|
|
1365
|
+
* @param {string} playbackId - The unique identifier of the playback session to be resumed.
|
|
1366
|
+
* @return {Promise<void>} A promise that resolves when the playback has been successfully resumed.
|
|
1367
|
+
* @throws {Error} Throws an error if the channel is not associated with this instance.
|
|
1195
1368
|
*/
|
|
1196
1369
|
async resumePlayback(playbackId) {
|
|
1197
1370
|
if (!this.channelData?.id) {
|
|
@@ -1202,7 +1375,11 @@ var ChannelInstance = class {
|
|
|
1202
1375
|
);
|
|
1203
1376
|
}
|
|
1204
1377
|
/**
|
|
1205
|
-
*
|
|
1378
|
+
* Rewinds the playback of a media by a specified amount of milliseconds.
|
|
1379
|
+
*
|
|
1380
|
+
* @param {string} playbackId - The unique identifier for the playback session to be rewound.
|
|
1381
|
+
* @param {number} skipMs - The number of milliseconds to rewind the playback.
|
|
1382
|
+
* @return {Promise<void>} A promise that resolves when the rewind operation is complete.
|
|
1206
1383
|
*/
|
|
1207
1384
|
async rewindPlayback(playbackId, skipMs) {
|
|
1208
1385
|
if (!this.channelData?.id) {
|
|
@@ -1214,7 +1391,12 @@ var ChannelInstance = class {
|
|
|
1214
1391
|
);
|
|
1215
1392
|
}
|
|
1216
1393
|
/**
|
|
1217
|
-
*
|
|
1394
|
+
* Fast forwards the playback by a specific duration in milliseconds.
|
|
1395
|
+
*
|
|
1396
|
+
* @param {string} playbackId - The unique identifier of the playback to be fast-forwarded.
|
|
1397
|
+
* @param {number} skipMs - The number of milliseconds to fast forward the playback.
|
|
1398
|
+
* @return {Promise<void>} A Promise that resolves when the fast-forward operation is complete.
|
|
1399
|
+
* @throws {Error} If no channel is associated with this instance.
|
|
1218
1400
|
*/
|
|
1219
1401
|
async fastForwardPlayback(playbackId, skipMs) {
|
|
1220
1402
|
if (!this.channelData?.id) {
|
|
@@ -1226,7 +1408,11 @@ var ChannelInstance = class {
|
|
|
1226
1408
|
);
|
|
1227
1409
|
}
|
|
1228
1410
|
/**
|
|
1229
|
-
*
|
|
1411
|
+
* Mutes the specified channel for the given direction.
|
|
1412
|
+
*
|
|
1413
|
+
* @param {("both" | "in" | "out")} [direction="both"] - The direction to mute the channel. It can be "both" to mute incoming and outgoing, "in" to mute incoming, or "out" to mute outgoing.
|
|
1414
|
+
* @return {Promise<void>} A promise that resolves when the channel is successfully muted.
|
|
1415
|
+
* @throws {Error} If the channel is not associated with this instance.
|
|
1230
1416
|
*/
|
|
1231
1417
|
async muteChannel(direction = "both") {
|
|
1232
1418
|
if (!this.channelData?.id) {
|
|
@@ -1237,7 +1423,12 @@ var ChannelInstance = class {
|
|
|
1237
1423
|
);
|
|
1238
1424
|
}
|
|
1239
1425
|
/**
|
|
1240
|
-
*
|
|
1426
|
+
* Unmutes a previously muted channel in the specified direction.
|
|
1427
|
+
*
|
|
1428
|
+
* @param {"both" | "in" | "out"} direction - The direction in which to unmute the channel.
|
|
1429
|
+
* Defaults to "both", which unmutes both incoming and outgoing communication.
|
|
1430
|
+
* @return {Promise<void>} A promise that resolves once the channel has been successfully unmuted.
|
|
1431
|
+
* @throws {Error} If the channel is not associated with the current instance.
|
|
1241
1432
|
*/
|
|
1242
1433
|
async unmuteChannel(direction = "both") {
|
|
1243
1434
|
if (!this.channelData?.id) {
|
|
@@ -1248,7 +1439,10 @@ var ChannelInstance = class {
|
|
|
1248
1439
|
);
|
|
1249
1440
|
}
|
|
1250
1441
|
/**
|
|
1251
|
-
*
|
|
1442
|
+
* Places the associated channel on hold if the channel is valid and linked to this instance.
|
|
1443
|
+
*
|
|
1444
|
+
* @return {Promise<void>} A promise that resolves when the hold action is successfully executed.
|
|
1445
|
+
* @throws {Error} Throws an error if the channel is not associated with this instance.
|
|
1252
1446
|
*/
|
|
1253
1447
|
async holdChannel() {
|
|
1254
1448
|
if (!this.channelData?.id) {
|
|
@@ -1257,7 +1451,12 @@ var ChannelInstance = class {
|
|
|
1257
1451
|
await this.baseClient.post(`/channels/${this.channelData.id}/hold`);
|
|
1258
1452
|
}
|
|
1259
1453
|
/**
|
|
1260
|
-
*
|
|
1454
|
+
* Removes the hold status from a specific channel associated with this instance.
|
|
1455
|
+
* The method sends a delete request to the server to release the hold on the channel.
|
|
1456
|
+
* If no channel is associated with this instance, an error will be thrown.
|
|
1457
|
+
*
|
|
1458
|
+
* @return {Promise<void>} A promise that resolves when the channel hold has been successfully removed.
|
|
1459
|
+
* @throws {Error} If no channel is associated with this instance.
|
|
1261
1460
|
*/
|
|
1262
1461
|
async unholdChannel() {
|
|
1263
1462
|
if (!this.channelData?.id) {
|
|
@@ -1272,73 +1471,140 @@ var Channels = class {
|
|
|
1272
1471
|
this.client = client;
|
|
1273
1472
|
}
|
|
1274
1473
|
channelInstances = /* @__PURE__ */ new Map();
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1474
|
+
/**
|
|
1475
|
+
* Creates or retrieves a ChannelInstance.
|
|
1476
|
+
*
|
|
1477
|
+
* @param {Object} [params] - Optional parameters for getting/creating a channel instance
|
|
1478
|
+
* @param {string} [params.id] - Optional ID of an existing channel
|
|
1479
|
+
* @returns {ChannelInstance} The requested or new channel instance
|
|
1480
|
+
* @throws {Error} If channel creation/retrieval fails
|
|
1481
|
+
*
|
|
1482
|
+
* @example
|
|
1483
|
+
* // Create new channel without ID
|
|
1484
|
+
* const channel1 = client.channels.Channel();
|
|
1485
|
+
*
|
|
1486
|
+
* // Create/retrieve channel with specific ID
|
|
1487
|
+
* const channel2 = client.channels.Channel({ id: 'some-id' });
|
|
1488
|
+
*/
|
|
1489
|
+
Channel(params) {
|
|
1490
|
+
try {
|
|
1491
|
+
const id = params?.id;
|
|
1492
|
+
if (!id) {
|
|
1493
|
+
const instance = new ChannelInstance(this.client, this.baseClient);
|
|
1494
|
+
this.channelInstances.set(instance.id, instance);
|
|
1495
|
+
console.log(`New channel instance created with ID: ${instance.id}`);
|
|
1496
|
+
return instance;
|
|
1497
|
+
}
|
|
1498
|
+
if (!this.channelInstances.has(id)) {
|
|
1499
|
+
const instance = new ChannelInstance(this.client, this.baseClient, id);
|
|
1500
|
+
this.channelInstances.set(id, instance);
|
|
1501
|
+
console.log(`New channel instance created with provided ID: ${id}`);
|
|
1502
|
+
return instance;
|
|
1503
|
+
}
|
|
1504
|
+
console.log(`Returning existing channel instance: ${id}`);
|
|
1505
|
+
return this.channelInstances.get(id);
|
|
1506
|
+
} catch (error) {
|
|
1507
|
+
const message = getErrorMessage(error);
|
|
1508
|
+
console.error(`Error creating/retrieving channel instance:`, message);
|
|
1509
|
+
throw new Error(`Failed to manage channel instance: ${message}`);
|
|
1285
1510
|
}
|
|
1286
|
-
return this.channelInstances.get(id);
|
|
1287
1511
|
}
|
|
1288
1512
|
/**
|
|
1289
|
-
*
|
|
1513
|
+
* Removes a channel instance from the collection.
|
|
1290
1514
|
*/
|
|
1291
1515
|
removeChannelInstance(channelId) {
|
|
1516
|
+
if (!channelId) {
|
|
1517
|
+
throw new Error("Channel ID is required");
|
|
1518
|
+
}
|
|
1292
1519
|
if (this.channelInstances.has(channelId)) {
|
|
1293
1520
|
const instance = this.channelInstances.get(channelId);
|
|
1294
1521
|
instance?.removeAllListeners();
|
|
1295
1522
|
this.channelInstances.delete(channelId);
|
|
1296
|
-
console.log(`
|
|
1523
|
+
console.log(`Channel instance removed: ${channelId}`);
|
|
1297
1524
|
} else {
|
|
1298
|
-
console.warn(
|
|
1299
|
-
`Tentativa de remover uma inst\xE2ncia inexistente: ${channelId}`
|
|
1300
|
-
);
|
|
1525
|
+
console.warn(`Attempt to remove non-existent instance: ${channelId}`);
|
|
1301
1526
|
}
|
|
1302
1527
|
}
|
|
1303
1528
|
/**
|
|
1304
|
-
*
|
|
1529
|
+
* Propagates a WebSocket event to a specific channel.
|
|
1305
1530
|
*/
|
|
1306
1531
|
propagateEventToChannel(event) {
|
|
1532
|
+
if (!event) {
|
|
1533
|
+
console.warn("Invalid WebSocket event received");
|
|
1534
|
+
return;
|
|
1535
|
+
}
|
|
1307
1536
|
if ("channel" in event && event.channel?.id) {
|
|
1308
1537
|
const instance = this.channelInstances.get(event.channel.id);
|
|
1309
1538
|
if (instance) {
|
|
1310
1539
|
instance.emitEvent(event);
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
`Nenhuma inst\xE2ncia encontrada para o canal ${event.channel.id}`
|
|
1540
|
+
console.log(
|
|
1541
|
+
`Event propagated to channel ${event.channel.id}: ${event.type}`
|
|
1314
1542
|
);
|
|
1543
|
+
} else {
|
|
1544
|
+
console.warn(`No instance found for channel ${event.channel.id}`);
|
|
1315
1545
|
}
|
|
1316
1546
|
}
|
|
1317
1547
|
}
|
|
1318
1548
|
/**
|
|
1319
|
-
*
|
|
1549
|
+
* Initiates a new channel.
|
|
1320
1550
|
*/
|
|
1321
1551
|
async originate(data) {
|
|
1322
|
-
|
|
1552
|
+
if (!data.endpoint) {
|
|
1553
|
+
throw new Error("Endpoint is required for channel origination");
|
|
1554
|
+
}
|
|
1555
|
+
try {
|
|
1556
|
+
const channel = await this.baseClient.post("/channels", data);
|
|
1557
|
+
console.log(`Channel originated successfully with ID: ${channel.id}`);
|
|
1558
|
+
return channel;
|
|
1559
|
+
} catch (error) {
|
|
1560
|
+
const message = getErrorMessage(error);
|
|
1561
|
+
console.error(`Error originating channel:`, message);
|
|
1562
|
+
throw new Error(`Failed to originate channel: ${message}`);
|
|
1563
|
+
}
|
|
1323
1564
|
}
|
|
1324
1565
|
/**
|
|
1325
|
-
*
|
|
1566
|
+
* Lists all active channels.
|
|
1326
1567
|
*/
|
|
1327
|
-
async
|
|
1328
|
-
|
|
1568
|
+
async list() {
|
|
1569
|
+
try {
|
|
1570
|
+
const channels = await this.baseClient.get("/channels");
|
|
1571
|
+
if (!Array.isArray(channels)) {
|
|
1572
|
+
throw new Error("API response for /channels is not an array");
|
|
1573
|
+
}
|
|
1574
|
+
console.log(`Retrieved ${channels.length} active channels`);
|
|
1575
|
+
return channels;
|
|
1576
|
+
} catch (error) {
|
|
1577
|
+
const message = getErrorMessage(error);
|
|
1578
|
+
console.error(`Error listing channels:`, message);
|
|
1579
|
+
throw new Error(`Failed to list channels: ${message}`);
|
|
1580
|
+
}
|
|
1329
1581
|
}
|
|
1330
1582
|
/**
|
|
1331
|
-
*
|
|
1583
|
+
* Gets the count of active channel instances.
|
|
1332
1584
|
*/
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1585
|
+
getInstanceCount() {
|
|
1586
|
+
return this.channelInstances.size;
|
|
1587
|
+
}
|
|
1588
|
+
/**
|
|
1589
|
+
* Checks if a channel instance exists.
|
|
1590
|
+
*/
|
|
1591
|
+
hasInstance(channelId) {
|
|
1592
|
+
return this.channelInstances.has(channelId);
|
|
1593
|
+
}
|
|
1594
|
+
/**
|
|
1595
|
+
* Gets all active channel instances.
|
|
1596
|
+
*/
|
|
1597
|
+
getAllInstances() {
|
|
1598
|
+
return new Map(this.channelInstances);
|
|
1339
1599
|
}
|
|
1340
1600
|
/**
|
|
1341
|
-
*
|
|
1601
|
+
* Terminates an active call on the specified channel.
|
|
1602
|
+
*
|
|
1603
|
+
* @param {string} channelId - The unique identifier of the channel to hang up.
|
|
1604
|
+
* @param {Object} [options] - Optional parameters for the hangup request.
|
|
1605
|
+
* @param {string} [options.reason_code] - A code indicating the reason for the hangup.
|
|
1606
|
+
* @param {string} [options.reason] - A descriptive reason for the hangup.
|
|
1607
|
+
* @return {Promise<void>} A promise that resolves when the call has been successfully terminated.
|
|
1342
1608
|
*/
|
|
1343
1609
|
async hangup(channelId, options) {
|
|
1344
1610
|
const queryParams = new URLSearchParams({
|
|
@@ -1350,7 +1616,11 @@ var Channels = class {
|
|
|
1350
1616
|
);
|
|
1351
1617
|
}
|
|
1352
1618
|
/**
|
|
1353
|
-
*
|
|
1619
|
+
* Initiates snooping on a specified channel with the provided options.
|
|
1620
|
+
*
|
|
1621
|
+
* @param {string} channelId - The unique identifier of the channel to snoop on.
|
|
1622
|
+
* @param {SnoopOptions} options - Configuration options for the snooping operation.
|
|
1623
|
+
* @return {Promise<Channel>} A promise that resolves to the snooped channel data.
|
|
1354
1624
|
*/
|
|
1355
1625
|
async snoopChannel(channelId, options) {
|
|
1356
1626
|
const queryParams = toQueryParams2(options);
|
|
@@ -1358,23 +1628,56 @@ var Channels = class {
|
|
|
1358
1628
|
`/channels/${channelId}/snoop?${queryParams}`
|
|
1359
1629
|
);
|
|
1360
1630
|
}
|
|
1631
|
+
/**
|
|
1632
|
+
* Starts a silence mode for the specified channel.
|
|
1633
|
+
*
|
|
1634
|
+
* @param {string} channelId - The unique identifier of the channel where silence mode should be started.
|
|
1635
|
+
* @return {Promise<void>} A promise that resolves when the silence mode is successfully started.
|
|
1636
|
+
*/
|
|
1361
1637
|
async startSilence(channelId) {
|
|
1362
1638
|
return this.baseClient.post(`/channels/${channelId}/silence`);
|
|
1363
1639
|
}
|
|
1640
|
+
/**
|
|
1641
|
+
* Stops the silence mode for a specific channel.
|
|
1642
|
+
*
|
|
1643
|
+
* @param {string} channelId - The unique identifier of the channel for which silence mode should be stopped.
|
|
1644
|
+
* @return {Promise<void>} A promise that resolves when the operation is complete.
|
|
1645
|
+
*/
|
|
1364
1646
|
async stopSilence(channelId) {
|
|
1365
1647
|
return this.baseClient.delete(`/channels/${channelId}/silence`);
|
|
1366
1648
|
}
|
|
1649
|
+
/**
|
|
1650
|
+
* Retrieves the Real-Time Protocol (RTP) statistics for a specific channel.
|
|
1651
|
+
*
|
|
1652
|
+
* @param {string} channelId - The unique identifier of the channel for which RTP statistics are fetched.
|
|
1653
|
+
* @return {Promise<RTPStats>} A promise that resolves to the RTP statistics for the specified channel.
|
|
1654
|
+
*/
|
|
1367
1655
|
async getRTPStatistics(channelId) {
|
|
1368
1656
|
return this.baseClient.get(
|
|
1369
1657
|
`/channels/${channelId}/rtp_statistics`
|
|
1370
1658
|
);
|
|
1371
1659
|
}
|
|
1660
|
+
/**
|
|
1661
|
+
* Creates an external media channel with the given options.
|
|
1662
|
+
*
|
|
1663
|
+
* @param {ExternalMediaOptions} options - The configuration options for creating the external media channel.
|
|
1664
|
+
* @return {Promise<Channel>} A promise that resolves with the created external media channel.
|
|
1665
|
+
*/
|
|
1372
1666
|
async createExternalMedia(options) {
|
|
1373
1667
|
const queryParams = toQueryParams2(options);
|
|
1374
1668
|
return this.baseClient.post(
|
|
1375
1669
|
`/channels/externalMedia?${queryParams}`
|
|
1376
1670
|
);
|
|
1377
1671
|
}
|
|
1672
|
+
/**
|
|
1673
|
+
* Initiates playback of a specific media item on a channel using the provided playback ID.
|
|
1674
|
+
*
|
|
1675
|
+
* @param {string} channelId - The unique identifier of the channel where playback will occur.
|
|
1676
|
+
* @param {string} playbackId - The unique identifier for the specific playback session.
|
|
1677
|
+
* @param {string} media - The media content to be played.
|
|
1678
|
+
* @param {PlaybackOptions} [options] - Optional playback configuration parameters.
|
|
1679
|
+
* @return {Promise<ChannelPlayback>} A promise that resolves with the playback details for the channel.
|
|
1680
|
+
*/
|
|
1378
1681
|
async playWithId(channelId, playbackId, media, options) {
|
|
1379
1682
|
const queryParams = options ? `?${toQueryParams2(options)}` : "";
|
|
1380
1683
|
return this.baseClient.post(
|
|
@@ -1382,18 +1685,41 @@ var Channels = class {
|
|
|
1382
1685
|
{ media }
|
|
1383
1686
|
);
|
|
1384
1687
|
}
|
|
1688
|
+
/**
|
|
1689
|
+
* Initiates a snoop operation on a specific channel using the provided channel ID and snoop ID.
|
|
1690
|
+
*
|
|
1691
|
+
* @param {string} channelId - The unique identifier of the channel to snoop on.
|
|
1692
|
+
* @param {string} snoopId - The unique identifier for the snoop operation.
|
|
1693
|
+
* @param {SnoopOptions} options - Additional options and parameters for the snoop operation.
|
|
1694
|
+
* @return {Promise<Channel>} A promise that resolves to the channel details after the snoop operation is initiated.
|
|
1695
|
+
*/
|
|
1385
1696
|
async snoopChannelWithId(channelId, snoopId, options) {
|
|
1386
1697
|
const queryParams = toQueryParams2(options);
|
|
1387
1698
|
return this.baseClient.post(
|
|
1388
1699
|
`/channels/${channelId}/snoop/${snoopId}?${queryParams}`
|
|
1389
1700
|
);
|
|
1390
1701
|
}
|
|
1702
|
+
/**
|
|
1703
|
+
* Starts Music on Hold for the specified channel with the provided Music on Hold class.
|
|
1704
|
+
*
|
|
1705
|
+
* @param {string} channelId - The unique identifier of the channel.
|
|
1706
|
+
* @param {string} mohClass - The Music on Hold class to be applied.
|
|
1707
|
+
* @return {Promise<void>} A promise that resolves when the operation is complete.
|
|
1708
|
+
*/
|
|
1391
1709
|
async startMohWithClass(channelId, mohClass) {
|
|
1392
1710
|
const queryParams = `mohClass=${encodeURIComponent(mohClass)}`;
|
|
1393
1711
|
await this.baseClient.post(
|
|
1394
1712
|
`/channels/${channelId}/moh?${queryParams}`
|
|
1395
1713
|
);
|
|
1396
1714
|
}
|
|
1715
|
+
/**
|
|
1716
|
+
* Retrieves the value of a specified variable for a given channel.
|
|
1717
|
+
*
|
|
1718
|
+
* @param {string} channelId - The unique identifier of the channel.
|
|
1719
|
+
* @param {string} variable - The name of the variable to retrieve.
|
|
1720
|
+
* @return {Promise<ChannelVar>} A promise that resolves to the value of the channel variable.
|
|
1721
|
+
* @throws {Error} Throws an error if the 'variable' parameter is not provided.
|
|
1722
|
+
*/
|
|
1397
1723
|
async getChannelVariable(channelId, variable) {
|
|
1398
1724
|
if (!variable) {
|
|
1399
1725
|
throw new Error("The 'variable' parameter is required.");
|
|
@@ -1402,6 +1728,15 @@ var Channels = class {
|
|
|
1402
1728
|
`/channels/${channelId}/variable?variable=${encodeURIComponent(variable)}`
|
|
1403
1729
|
);
|
|
1404
1730
|
}
|
|
1731
|
+
/**
|
|
1732
|
+
* Sets a variable for a specific channel.
|
|
1733
|
+
*
|
|
1734
|
+
* @param {string} channelId - The unique identifier of the channel.
|
|
1735
|
+
* @param {string} variable - The name of the variable to be set. This parameter is required.
|
|
1736
|
+
* @param {string} [value] - The value of the variable to be set. This parameter is optional.
|
|
1737
|
+
* @return {Promise<void>} A promise that resolves when the variable is successfully set.
|
|
1738
|
+
* @throws {Error} Throws an error if the `variable` parameter is not provided.
|
|
1739
|
+
*/
|
|
1405
1740
|
async setChannelVariable(channelId, variable, value) {
|
|
1406
1741
|
if (!variable) {
|
|
1407
1742
|
throw new Error("The 'variable' parameter is required.");
|
|
@@ -1414,12 +1749,30 @@ var Channels = class {
|
|
|
1414
1749
|
`/channels/${channelId}/variable?${queryParams}`
|
|
1415
1750
|
);
|
|
1416
1751
|
}
|
|
1752
|
+
/**
|
|
1753
|
+
* Moves a specified channel to the given application with optional arguments.
|
|
1754
|
+
*
|
|
1755
|
+
* @param {string} channelId - The unique identifier of the channel to be moved.
|
|
1756
|
+
* @param {string} app - The target application to which the channel will be moved.
|
|
1757
|
+
* @param {string} [appArgs] - Optional arguments to be passed to the target application.
|
|
1758
|
+
* @return {Promise<void>} A promise that resolves when the operation is completed.
|
|
1759
|
+
*/
|
|
1417
1760
|
async moveToApplication(channelId, app, appArgs) {
|
|
1418
1761
|
await this.baseClient.post(`/channels/${channelId}/move`, {
|
|
1419
1762
|
app,
|
|
1420
1763
|
appArgs
|
|
1421
1764
|
});
|
|
1422
1765
|
}
|
|
1766
|
+
/**
|
|
1767
|
+
* Continues the execution of a dialplan for a specific channel.
|
|
1768
|
+
*
|
|
1769
|
+
* @param {string} channelId - The unique identifier of the channel.
|
|
1770
|
+
* @param {string} [context] - The dialplan context to continue execution in, if specified.
|
|
1771
|
+
* @param {string} [extension] - The dialplan extension to proceed with, if provided.
|
|
1772
|
+
* @param {number} [priority] - The priority within the dialplan extension to resume at, if specified.
|
|
1773
|
+
* @param {string} [label] - The label to start from within the dialplan, if given.
|
|
1774
|
+
* @return {Promise<void>} Resolves when the dialplan is successfully continued.
|
|
1775
|
+
*/
|
|
1423
1776
|
async continueDialplan(channelId, context, extension, priority, label) {
|
|
1424
1777
|
await this.baseClient.post(`/channels/${channelId}/continue`, {
|
|
1425
1778
|
context,
|
|
@@ -1428,18 +1781,45 @@ var Channels = class {
|
|
|
1428
1781
|
label
|
|
1429
1782
|
});
|
|
1430
1783
|
}
|
|
1784
|
+
/**
|
|
1785
|
+
* Stops the music on hold for the specified channel.
|
|
1786
|
+
*
|
|
1787
|
+
* @param {string} channelId - The unique identifier of the channel where music on hold should be stopped.
|
|
1788
|
+
* @return {Promise<void>} Resolves when the music on hold is successfully stopped.
|
|
1789
|
+
*/
|
|
1431
1790
|
async stopMusicOnHold(channelId) {
|
|
1432
1791
|
await this.baseClient.delete(`/channels/${channelId}/moh`);
|
|
1433
1792
|
}
|
|
1793
|
+
/**
|
|
1794
|
+
* Initiates the music on hold for the specified channel.
|
|
1795
|
+
*
|
|
1796
|
+
* @param {string} channelId - The unique identifier of the channel where the music on hold will be started.
|
|
1797
|
+
* @return {Promise<void>} A promise that resolves when the operation has been successfully invoked.
|
|
1798
|
+
*/
|
|
1434
1799
|
async startMusicOnHold(channelId) {
|
|
1435
1800
|
await this.baseClient.post(`/channels/${channelId}/moh`);
|
|
1436
1801
|
}
|
|
1802
|
+
/**
|
|
1803
|
+
* Starts recording for a specific channel based on the provided options.
|
|
1804
|
+
*
|
|
1805
|
+
* @param {string} channelId - The unique identifier of the channel to start recording.
|
|
1806
|
+
* @param {RecordingOptions} options - The recording options to configure the recording process.
|
|
1807
|
+
* @return {Promise<Channel>} A promise that resolves to the channel object with updated recording state.
|
|
1808
|
+
*/
|
|
1437
1809
|
async record(channelId, options) {
|
|
1438
1810
|
const queryParams = toQueryParams2(options);
|
|
1439
1811
|
return this.baseClient.post(
|
|
1440
1812
|
`/channels/${channelId}/record?${queryParams}`
|
|
1441
1813
|
);
|
|
1442
1814
|
}
|
|
1815
|
+
/**
|
|
1816
|
+
* Initiates a call on the specified channel with optional parameters for caller identification and timeout duration.
|
|
1817
|
+
*
|
|
1818
|
+
* @param {string} channelId - The ID of the channel where the call will be initiated.
|
|
1819
|
+
* @param {string} [caller] - Optional parameter specifying the name or identifier of the caller.
|
|
1820
|
+
* @param {number} [timeout] - Optional parameter defining the timeout duration for the call in seconds.
|
|
1821
|
+
* @return {Promise<void>} A promise that resolves when the call has been successfully initiated.
|
|
1822
|
+
*/
|
|
1443
1823
|
async dial(channelId, caller, timeout) {
|
|
1444
1824
|
const queryParams = new URLSearchParams({
|
|
1445
1825
|
...caller && { caller },
|
|
@@ -1449,45 +1829,126 @@ var Channels = class {
|
|
|
1449
1829
|
`/channels/${channelId}/dial?${queryParams}`
|
|
1450
1830
|
);
|
|
1451
1831
|
}
|
|
1832
|
+
/**
|
|
1833
|
+
* Redirects a channel to the specified endpoint.
|
|
1834
|
+
*
|
|
1835
|
+
* This method sends a POST request to update the redirect endpoint for the given channel.
|
|
1836
|
+
*
|
|
1837
|
+
* @param {string} channelId - The unique identifier of the channel to be redirected.
|
|
1838
|
+
* @param {string} endpoint - The new endpoint to redirect the channel to.
|
|
1839
|
+
* @return {Promise<void>} A promise that resolves when the operation is complete.
|
|
1840
|
+
*/
|
|
1452
1841
|
async redirectChannel(channelId, endpoint) {
|
|
1453
1842
|
await this.baseClient.post(
|
|
1454
1843
|
`/channels/${channelId}/redirect?endpoint=${encodeURIComponent(endpoint)}`
|
|
1455
1844
|
);
|
|
1456
1845
|
}
|
|
1846
|
+
/**
|
|
1847
|
+
* Answers a specified channel by sending a POST request to the corresponding endpoint.
|
|
1848
|
+
*
|
|
1849
|
+
* @param {string} channelId - The unique identifier of the channel to be answered.
|
|
1850
|
+
* @return {Promise<void>} A promise that resolves when the channel has been successfully answered.
|
|
1851
|
+
*/
|
|
1457
1852
|
async answerChannel(channelId) {
|
|
1458
1853
|
await this.baseClient.post(`/channels/${channelId}/answer`);
|
|
1459
1854
|
}
|
|
1855
|
+
/**
|
|
1856
|
+
* Rings the specified channel by sending a POST request to the appropriate endpoint.
|
|
1857
|
+
*
|
|
1858
|
+
* @param {string} channelId - The unique identifier of the channel to be rung.
|
|
1859
|
+
* @return {Promise<void>} A promise that resolves when the operation completes successfully.
|
|
1860
|
+
*/
|
|
1460
1861
|
async ringChannel(channelId) {
|
|
1461
1862
|
await this.baseClient.post(`/channels/${channelId}/ring`);
|
|
1462
1863
|
}
|
|
1864
|
+
/**
|
|
1865
|
+
* Stops the ring channel for the specified channel ID.
|
|
1866
|
+
*
|
|
1867
|
+
* This method sends a DELETE request to the server to stop the ring action
|
|
1868
|
+
* associated with the provided channel ID.
|
|
1869
|
+
*
|
|
1870
|
+
* @param {string} channelId - The unique identifier of the channel for which the ring action should be stopped.
|
|
1871
|
+
* @return {Promise<void>} A promise that resolves when the ring channel is successfully stopped.
|
|
1872
|
+
*/
|
|
1463
1873
|
async stopRingChannel(channelId) {
|
|
1464
1874
|
await this.baseClient.delete(`/channels/${channelId}/ring`);
|
|
1465
1875
|
}
|
|
1876
|
+
/**
|
|
1877
|
+
* Sends DTMF (Dual-Tone Multi-Frequency) signals to a specified channel.
|
|
1878
|
+
*
|
|
1879
|
+
* @param {string} channelId - The ID of the channel to which the DTMF signals should be sent.
|
|
1880
|
+
* @param {string} dtmf - The DTMF tones to be sent, represented as a string. Each character corresponds to a specific tone.
|
|
1881
|
+
* @param {Object} [options] - Optional configuration for the DTMF signal timing.
|
|
1882
|
+
* @param {number} [options.before] - Time in milliseconds to wait before sending the first DTMF tone.
|
|
1883
|
+
* @param {number} [options.between] - Time in milliseconds to wait between sending successive DTMF tones.
|
|
1884
|
+
* @param {number} [options.duration] - Duration in milliseconds for each DTMF tone.
|
|
1885
|
+
* @param {number} [options.after] - Time in milliseconds to wait after sending the last DTMF tone.
|
|
1886
|
+
* @return {Promise<void>} A promise that resolves when the DTMF signals are successfully sent.
|
|
1887
|
+
*/
|
|
1466
1888
|
async sendDTMF(channelId, dtmf, options) {
|
|
1467
1889
|
const queryParams = toQueryParams2({ dtmf, ...options });
|
|
1468
1890
|
await this.baseClient.post(
|
|
1469
1891
|
`/channels/${channelId}/dtmf?${queryParams}`
|
|
1470
1892
|
);
|
|
1471
1893
|
}
|
|
1894
|
+
/**
|
|
1895
|
+
* Mutes a specified channel in the given direction.
|
|
1896
|
+
*
|
|
1897
|
+
* @param {string} channelId - The unique identifier of the channel to be muted.
|
|
1898
|
+
* @param {"both" | "in" | "out"} [direction="both"] - The direction for muting, can be "both", "in", or "out". Default is "both".
|
|
1899
|
+
* @return {Promise<void>} A promise that resolves when the channel is successfully muted.
|
|
1900
|
+
*/
|
|
1472
1901
|
async muteChannel(channelId, direction = "both") {
|
|
1473
1902
|
await this.baseClient.post(
|
|
1474
1903
|
`/channels/${channelId}/mute?direction=${direction}`
|
|
1475
1904
|
);
|
|
1476
1905
|
}
|
|
1906
|
+
/**
|
|
1907
|
+
* Unmutes a previously muted channel, allowing communication in the specified direction(s).
|
|
1908
|
+
*
|
|
1909
|
+
* @param {string} channelId - The unique identifier of the channel to be unmuted.
|
|
1910
|
+
* @param {"both" | "in" | "out"} [direction="both"] - The direction of communication to unmute. Valid options are "both", "in" (incoming messages), or "out" (outgoing messages). Defaults to "both".
|
|
1911
|
+
* @return {Promise<void>} A promise that resolves when the channel is successfully unmuted.
|
|
1912
|
+
*/
|
|
1477
1913
|
async unmuteChannel(channelId, direction = "both") {
|
|
1478
1914
|
await this.baseClient.delete(
|
|
1479
1915
|
`/channels/${channelId}/mute?direction=${direction}`
|
|
1480
1916
|
);
|
|
1481
1917
|
}
|
|
1918
|
+
/**
|
|
1919
|
+
* Places a specific channel on hold by sending a POST request to the server.
|
|
1920
|
+
*
|
|
1921
|
+
* @param {string} channelId - The unique identifier of the channel to be placed on hold.
|
|
1922
|
+
* @return {Promise<void>} A promise that resolves when the channel hold operation is completed.
|
|
1923
|
+
*/
|
|
1482
1924
|
async holdChannel(channelId) {
|
|
1483
1925
|
await this.baseClient.post(`/channels/${channelId}/hold`);
|
|
1484
1926
|
}
|
|
1927
|
+
/**
|
|
1928
|
+
* Removes the hold status from a specific channel by its ID.
|
|
1929
|
+
*
|
|
1930
|
+
* @param {string} channelId - The unique identifier of the channel to unhold.
|
|
1931
|
+
* @return {Promise<void>} A promise that resolves when the channel hold is successfully removed.
|
|
1932
|
+
*/
|
|
1485
1933
|
async unholdChannel(channelId) {
|
|
1486
1934
|
await this.baseClient.delete(`/channels/${channelId}/hold`);
|
|
1487
1935
|
}
|
|
1936
|
+
/**
|
|
1937
|
+
* Creates a new communication channel with the specified configuration.
|
|
1938
|
+
*
|
|
1939
|
+
* @param {OriginateRequest} data - The configuration data required to create the channel, including relevant details such as endpoint and channel variables.
|
|
1940
|
+
* @return {Promise<Channel>} A promise that resolves with the details of the created channel.
|
|
1941
|
+
*/
|
|
1488
1942
|
async createChannel(data) {
|
|
1489
1943
|
return this.baseClient.post("/channels/create", data);
|
|
1490
1944
|
}
|
|
1945
|
+
/**
|
|
1946
|
+
* Initiates a new channel with the specified channel ID and originates a call using the provided data.
|
|
1947
|
+
*
|
|
1948
|
+
* @param {string} channelId - The unique identifier of the channel to be created.
|
|
1949
|
+
* @param {OriginateRequest} data - The data required to originate the call, including details such as endpoint and caller information.
|
|
1950
|
+
* @return {Promise<Channel>} A promise that resolves to the created Channel object.
|
|
1951
|
+
*/
|
|
1491
1952
|
async originateWithId(channelId, data) {
|
|
1492
1953
|
return this.baseClient.post(`/channels/${channelId}`, data);
|
|
1493
1954
|
}
|
|
@@ -1541,93 +2002,195 @@ var Endpoints = class {
|
|
|
1541
2002
|
|
|
1542
2003
|
// src/ari-client/resources/playbacks.ts
|
|
1543
2004
|
var import_events2 = require("events");
|
|
2005
|
+
var import_axios3 = require("axios");
|
|
2006
|
+
var getErrorMessage2 = (error) => {
|
|
2007
|
+
if ((0, import_axios3.isAxiosError)(error)) {
|
|
2008
|
+
return error.response?.data?.message || error.message || "An axios error occurred";
|
|
2009
|
+
}
|
|
2010
|
+
if (error instanceof Error) {
|
|
2011
|
+
return error.message;
|
|
2012
|
+
}
|
|
2013
|
+
return "An unknown error occurred";
|
|
2014
|
+
};
|
|
1544
2015
|
var PlaybackInstance = class {
|
|
2016
|
+
/**
|
|
2017
|
+
* Creates a new PlaybackInstance.
|
|
2018
|
+
*
|
|
2019
|
+
* @param {AriClient} client - ARI client for communication
|
|
2020
|
+
* @param {BaseClient} baseClient - Base client for HTTP requests
|
|
2021
|
+
* @param {string} [playbackId] - Optional playback ID, generates timestamp-based ID if not provided
|
|
2022
|
+
*/
|
|
1545
2023
|
constructor(client, baseClient, playbackId = `playback-${Date.now()}`) {
|
|
1546
2024
|
this.client = client;
|
|
1547
2025
|
this.baseClient = baseClient;
|
|
1548
2026
|
this.playbackId = playbackId;
|
|
1549
2027
|
this.id = playbackId;
|
|
2028
|
+
console.log(`PlaybackInstance initialized with ID: ${this.id}`);
|
|
1550
2029
|
}
|
|
1551
2030
|
eventEmitter = new import_events2.EventEmitter();
|
|
1552
2031
|
playbackData = null;
|
|
1553
2032
|
id;
|
|
1554
2033
|
/**
|
|
1555
|
-
*
|
|
2034
|
+
* Registers an event listener for a specific WebSocket event type.
|
|
2035
|
+
*
|
|
2036
|
+
* @param {T} event - Event type to listen for
|
|
2037
|
+
* @param {Function} listener - Callback function for the event
|
|
1556
2038
|
*/
|
|
1557
2039
|
on(event, listener) {
|
|
2040
|
+
if (!event) {
|
|
2041
|
+
throw new Error("Event type is required");
|
|
2042
|
+
}
|
|
1558
2043
|
const wrappedListener = (data) => {
|
|
1559
2044
|
if ("playback" in data && data.playback?.id === this.id) {
|
|
1560
2045
|
listener(data);
|
|
1561
2046
|
}
|
|
1562
2047
|
};
|
|
1563
2048
|
this.eventEmitter.on(event, wrappedListener);
|
|
2049
|
+
console.log(
|
|
2050
|
+
`Event listener registered for ${event} on playback ${this.id}`
|
|
2051
|
+
);
|
|
1564
2052
|
}
|
|
1565
2053
|
/**
|
|
1566
|
-
*
|
|
2054
|
+
* Registers a one-time event listener for a specific WebSocket event type.
|
|
2055
|
+
*
|
|
2056
|
+
* @param {T} event - Event type to listen for
|
|
2057
|
+
* @param {Function} listener - Callback function for the event
|
|
1567
2058
|
*/
|
|
1568
2059
|
once(event, listener) {
|
|
2060
|
+
if (!event) {
|
|
2061
|
+
throw new Error("Event type is required");
|
|
2062
|
+
}
|
|
1569
2063
|
const wrappedListener = (data) => {
|
|
1570
2064
|
if ("playback" in data && data.playback?.id === this.id) {
|
|
1571
2065
|
listener(data);
|
|
1572
2066
|
}
|
|
1573
2067
|
};
|
|
1574
2068
|
this.eventEmitter.once(event, wrappedListener);
|
|
2069
|
+
console.log(
|
|
2070
|
+
`One-time event listener registered for ${event} on playback ${this.id}`
|
|
2071
|
+
);
|
|
1575
2072
|
}
|
|
1576
2073
|
/**
|
|
1577
|
-
*
|
|
2074
|
+
* Removes event listener(s) for a specific WebSocket event type.
|
|
2075
|
+
*
|
|
2076
|
+
* @param {T} event - Event type to remove listener(s) for
|
|
2077
|
+
* @param {Function} [listener] - Optional specific listener to remove
|
|
1578
2078
|
*/
|
|
1579
2079
|
off(event, listener) {
|
|
2080
|
+
if (!event) {
|
|
2081
|
+
throw new Error("Event type is required");
|
|
2082
|
+
}
|
|
1580
2083
|
if (listener) {
|
|
1581
2084
|
this.eventEmitter.off(event, listener);
|
|
2085
|
+
console.log(
|
|
2086
|
+
`Specific listener removed for ${event} on playback ${this.id}`
|
|
2087
|
+
);
|
|
1582
2088
|
} else {
|
|
1583
2089
|
this.eventEmitter.removeAllListeners(event);
|
|
2090
|
+
console.log(`All listeners removed for ${event} on playback ${this.id}`);
|
|
1584
2091
|
}
|
|
1585
2092
|
}
|
|
1586
2093
|
/**
|
|
1587
|
-
*
|
|
2094
|
+
* Emits a WebSocket event if it matches the current playback instance.
|
|
2095
|
+
*
|
|
2096
|
+
* @param {WebSocketEvent} event - Event to emit
|
|
1588
2097
|
*/
|
|
1589
2098
|
emitEvent(event) {
|
|
2099
|
+
if (!event) {
|
|
2100
|
+
console.warn("Received invalid event");
|
|
2101
|
+
return;
|
|
2102
|
+
}
|
|
1590
2103
|
if ("playback" in event && event.playback?.id === this.id) {
|
|
1591
2104
|
this.eventEmitter.emit(event.type, event);
|
|
2105
|
+
console.log(`Event ${event.type} emitted for playback ${this.id}`);
|
|
1592
2106
|
}
|
|
1593
2107
|
}
|
|
1594
2108
|
/**
|
|
1595
|
-
*
|
|
2109
|
+
* Retrieves current playback data.
|
|
2110
|
+
*
|
|
2111
|
+
* @returns {Promise<Playback>} Current playback data
|
|
2112
|
+
* @throws {Error} If playback is not properly initialized
|
|
1596
2113
|
*/
|
|
1597
2114
|
async get() {
|
|
1598
2115
|
if (!this.id) {
|
|
1599
|
-
throw new Error("
|
|
2116
|
+
throw new Error("No playback associated with this instance");
|
|
2117
|
+
}
|
|
2118
|
+
try {
|
|
2119
|
+
this.playbackData = await this.baseClient.get(
|
|
2120
|
+
`/playbacks/${this.id}`
|
|
2121
|
+
);
|
|
2122
|
+
console.log(`Retrieved playback data for ${this.id}`);
|
|
2123
|
+
return this.playbackData;
|
|
2124
|
+
} catch (error) {
|
|
2125
|
+
const message = getErrorMessage2(error);
|
|
2126
|
+
console.error(`Error retrieving playback data for ${this.id}:`, message);
|
|
2127
|
+
throw new Error(`Failed to get playback data: ${message}`);
|
|
1600
2128
|
}
|
|
1601
|
-
this.playbackData = await this.baseClient.get(
|
|
1602
|
-
`/playbacks/${this.id}`
|
|
1603
|
-
);
|
|
1604
|
-
return this.playbackData;
|
|
1605
2129
|
}
|
|
1606
2130
|
/**
|
|
1607
|
-
*
|
|
2131
|
+
* Controls playback with specified operation.
|
|
2132
|
+
*
|
|
2133
|
+
* @param {"pause" | "unpause" | "reverse" | "forward"} operation - Control operation to perform
|
|
2134
|
+
* @throws {Error} If playback is not properly initialized or operation fails
|
|
1608
2135
|
*/
|
|
1609
2136
|
async control(operation) {
|
|
1610
2137
|
if (!this.id) {
|
|
1611
|
-
throw new Error("
|
|
2138
|
+
throw new Error("No playback associated with this instance");
|
|
2139
|
+
}
|
|
2140
|
+
try {
|
|
2141
|
+
await this.baseClient.post(
|
|
2142
|
+
`/playbacks/${this.id}/control?operation=${operation}`
|
|
2143
|
+
);
|
|
2144
|
+
console.log(
|
|
2145
|
+
`Operation ${operation} executed successfully on playback ${this.id}`
|
|
2146
|
+
);
|
|
2147
|
+
} catch (error) {
|
|
2148
|
+
const message = getErrorMessage2(error);
|
|
2149
|
+
console.error(`Error controlling playback ${this.id}:`, message);
|
|
2150
|
+
throw new Error(`Failed to control playback: ${message}`);
|
|
1612
2151
|
}
|
|
1613
|
-
await this.baseClient.post(
|
|
1614
|
-
`/playbacks/${this.id}/control?operation=${operation}`
|
|
1615
|
-
);
|
|
1616
2152
|
}
|
|
1617
2153
|
/**
|
|
1618
|
-
*
|
|
2154
|
+
* Stops the current playback.
|
|
2155
|
+
*
|
|
2156
|
+
* @throws {Error} If playback is not properly initialized or stop operation fails
|
|
1619
2157
|
*/
|
|
1620
2158
|
async stop() {
|
|
1621
2159
|
if (!this.id) {
|
|
1622
|
-
throw new Error("
|
|
2160
|
+
throw new Error("No playback associated with this instance");
|
|
2161
|
+
}
|
|
2162
|
+
try {
|
|
2163
|
+
await this.baseClient.delete(`/playbacks/${this.id}`);
|
|
2164
|
+
console.log(`Playback ${this.id} stopped successfully`);
|
|
2165
|
+
} catch (error) {
|
|
2166
|
+
const message = getErrorMessage2(error);
|
|
2167
|
+
console.error(`Error stopping playback ${this.id}:`, message);
|
|
2168
|
+
throw new Error(`Failed to stop playback: ${message}`);
|
|
1623
2169
|
}
|
|
1624
|
-
await this.baseClient.delete(`/playbacks/${this.id}`);
|
|
1625
2170
|
}
|
|
1626
2171
|
/**
|
|
1627
|
-
*
|
|
2172
|
+
* Removes all event listeners from this playback instance.
|
|
1628
2173
|
*/
|
|
1629
2174
|
removeAllListeners() {
|
|
1630
2175
|
this.eventEmitter.removeAllListeners();
|
|
2176
|
+
console.log(`All listeners removed from playback ${this.id}`);
|
|
2177
|
+
}
|
|
2178
|
+
/**
|
|
2179
|
+
* Checks if the playback instance has any listeners for a specific event.
|
|
2180
|
+
*
|
|
2181
|
+
* @param {string} event - Event type to check
|
|
2182
|
+
* @returns {boolean} True if there are listeners for the event
|
|
2183
|
+
*/
|
|
2184
|
+
hasListeners(event) {
|
|
2185
|
+
return this.eventEmitter.listenerCount(event) > 0;
|
|
2186
|
+
}
|
|
2187
|
+
/**
|
|
2188
|
+
* Gets the current playback data without making an API call.
|
|
2189
|
+
*
|
|
2190
|
+
* @returns {Playback | null} Current playback data or null if not available
|
|
2191
|
+
*/
|
|
2192
|
+
getCurrentData() {
|
|
2193
|
+
return this.playbackData;
|
|
1631
2194
|
}
|
|
1632
2195
|
};
|
|
1633
2196
|
var Playbacks = class {
|
|
@@ -1637,61 +2200,144 @@ var Playbacks = class {
|
|
|
1637
2200
|
}
|
|
1638
2201
|
playbackInstances = /* @__PURE__ */ new Map();
|
|
1639
2202
|
/**
|
|
1640
|
-
*
|
|
2203
|
+
* Gets or creates a playback instance
|
|
2204
|
+
* @param {Object} [params] - Optional parameters for getting/creating a playback instance
|
|
2205
|
+
* @param {string} [params.id] - Optional ID of an existing playback
|
|
2206
|
+
* @returns {PlaybackInstance} The requested or new playback instance
|
|
1641
2207
|
*/
|
|
1642
|
-
Playback(
|
|
1643
|
-
|
|
1644
|
-
const
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
2208
|
+
Playback(params) {
|
|
2209
|
+
try {
|
|
2210
|
+
const id = params?.id;
|
|
2211
|
+
if (!id) {
|
|
2212
|
+
const instance = new PlaybackInstance(this.client, this.baseClient);
|
|
2213
|
+
this.playbackInstances.set(instance.id, instance);
|
|
2214
|
+
console.log(`New playback instance created with ID: ${instance.id}`);
|
|
2215
|
+
return instance;
|
|
2216
|
+
}
|
|
2217
|
+
if (!this.playbackInstances.has(id)) {
|
|
2218
|
+
const instance = new PlaybackInstance(this.client, this.baseClient, id);
|
|
2219
|
+
this.playbackInstances.set(id, instance);
|
|
2220
|
+
console.log(`New playback instance created with provided ID: ${id}`);
|
|
2221
|
+
return instance;
|
|
2222
|
+
}
|
|
2223
|
+
console.log(`Returning existing playback instance: ${id}`);
|
|
2224
|
+
return this.playbackInstances.get(id);
|
|
2225
|
+
} catch (error) {
|
|
2226
|
+
const message = getErrorMessage2(error);
|
|
2227
|
+
console.error(`Error creating/retrieving playback instance:`, message);
|
|
2228
|
+
throw new Error(`Failed to manage playback instance: ${message}`);
|
|
1652
2229
|
}
|
|
1653
|
-
return this.playbackInstances.get(id);
|
|
1654
2230
|
}
|
|
1655
2231
|
/**
|
|
1656
|
-
*
|
|
2232
|
+
* Removes a playback instance and cleans up its resources
|
|
2233
|
+
* @param {string} playbackId - ID of the playback instance to remove
|
|
2234
|
+
* @throws {Error} If the playback instance doesn't exist
|
|
1657
2235
|
*/
|
|
1658
2236
|
removePlaybackInstance(playbackId) {
|
|
2237
|
+
if (!playbackId) {
|
|
2238
|
+
throw new Error("Playback ID is required");
|
|
2239
|
+
}
|
|
1659
2240
|
if (this.playbackInstances.has(playbackId)) {
|
|
1660
2241
|
const instance = this.playbackInstances.get(playbackId);
|
|
1661
2242
|
instance?.removeAllListeners();
|
|
1662
2243
|
this.playbackInstances.delete(playbackId);
|
|
2244
|
+
console.log(`Playback instance removed: ${playbackId}`);
|
|
2245
|
+
} else {
|
|
2246
|
+
console.warn(`Attempt to remove non-existent instance: ${playbackId}`);
|
|
1663
2247
|
}
|
|
1664
2248
|
}
|
|
1665
2249
|
/**
|
|
1666
|
-
*
|
|
2250
|
+
* Propagates WebSocket events to the corresponding playback instance
|
|
2251
|
+
* @param {WebSocketEvent} event - The WebSocket event to propagate
|
|
1667
2252
|
*/
|
|
1668
2253
|
propagateEventToPlayback(event) {
|
|
2254
|
+
if (!event) {
|
|
2255
|
+
console.warn("Invalid WebSocket event received");
|
|
2256
|
+
return;
|
|
2257
|
+
}
|
|
1669
2258
|
if ("playback" in event && event.playback?.id) {
|
|
1670
2259
|
const instance = this.playbackInstances.get(event.playback.id);
|
|
1671
2260
|
if (instance) {
|
|
1672
2261
|
instance.emitEvent(event);
|
|
2262
|
+
console.log(
|
|
2263
|
+
`Event propagated to playback ${event.playback.id}: ${event.type}`
|
|
2264
|
+
);
|
|
2265
|
+
} else {
|
|
2266
|
+
console.warn(`No instance found for playback ${event.playback.id}`);
|
|
1673
2267
|
}
|
|
1674
2268
|
}
|
|
1675
2269
|
}
|
|
1676
2270
|
/**
|
|
1677
|
-
*
|
|
2271
|
+
* Retrieves details of a specific playback
|
|
2272
|
+
* @param {string} playbackId - ID of the playback to get details for
|
|
2273
|
+
* @returns {Promise<Playback>} Promise resolving to playback details
|
|
2274
|
+
* @throws {Error} If the playback ID is invalid or the request fails
|
|
1678
2275
|
*/
|
|
1679
2276
|
async getDetails(playbackId) {
|
|
1680
|
-
|
|
2277
|
+
if (!playbackId) {
|
|
2278
|
+
throw new Error("Playback ID is required");
|
|
2279
|
+
}
|
|
2280
|
+
try {
|
|
2281
|
+
return await this.baseClient.get(`/playbacks/${playbackId}`);
|
|
2282
|
+
} catch (error) {
|
|
2283
|
+
const message = getErrorMessage2(error);
|
|
2284
|
+
console.error(`Error getting playback details ${playbackId}:`, message);
|
|
2285
|
+
throw new Error(`Failed to get playback details: ${message}`);
|
|
2286
|
+
}
|
|
1681
2287
|
}
|
|
1682
2288
|
/**
|
|
1683
|
-
*
|
|
2289
|
+
* Controls a specific playback instance
|
|
2290
|
+
* @param {string} playbackId - ID of the playback to control
|
|
2291
|
+
* @param {"pause" | "unpause" | "reverse" | "forward"} operation - Operation to perform
|
|
2292
|
+
* @throws {Error} If the playback ID is invalid or the operation fails
|
|
1684
2293
|
*/
|
|
1685
2294
|
async control(playbackId, operation) {
|
|
1686
|
-
|
|
1687
|
-
|
|
2295
|
+
if (!playbackId) {
|
|
2296
|
+
throw new Error("Playback ID is required");
|
|
2297
|
+
}
|
|
2298
|
+
try {
|
|
2299
|
+
const playback = this.Playback({ id: playbackId });
|
|
2300
|
+
await playback.control(operation);
|
|
2301
|
+
console.log(`Operation ${operation} executed on playback ${playbackId}`);
|
|
2302
|
+
} catch (error) {
|
|
2303
|
+
const message = getErrorMessage2(error);
|
|
2304
|
+
console.error(`Error controlling playback ${playbackId}:`, message);
|
|
2305
|
+
throw new Error(`Failed to control playback: ${message}`);
|
|
2306
|
+
}
|
|
1688
2307
|
}
|
|
1689
2308
|
/**
|
|
1690
|
-
*
|
|
2309
|
+
* Stops a specific playback instance
|
|
2310
|
+
* @param {string} playbackId - ID of the playback to stop
|
|
2311
|
+
* @throws {Error} If the playback ID is invalid or the stop operation fails
|
|
1691
2312
|
*/
|
|
1692
2313
|
async stop(playbackId) {
|
|
1693
|
-
|
|
1694
|
-
|
|
2314
|
+
if (!playbackId) {
|
|
2315
|
+
throw new Error("Playback ID is required");
|
|
2316
|
+
}
|
|
2317
|
+
try {
|
|
2318
|
+
const playback = this.Playback({ id: playbackId });
|
|
2319
|
+
await playback.stop();
|
|
2320
|
+
console.log(`Playback ${playbackId} stopped`);
|
|
2321
|
+
} catch (error) {
|
|
2322
|
+
const message = getErrorMessage2(error);
|
|
2323
|
+
console.error(`Error stopping playback ${playbackId}:`, message);
|
|
2324
|
+
throw new Error(`Failed to stop playback: ${message}`);
|
|
2325
|
+
}
|
|
2326
|
+
}
|
|
2327
|
+
/**
|
|
2328
|
+
* Gets the count of active playback instances
|
|
2329
|
+
* @returns {number} Number of active playback instances
|
|
2330
|
+
*/
|
|
2331
|
+
getInstanceCount() {
|
|
2332
|
+
return this.playbackInstances.size;
|
|
2333
|
+
}
|
|
2334
|
+
/**
|
|
2335
|
+
* Checks if a playback instance exists
|
|
2336
|
+
* @param {string} playbackId - ID of the playback to check
|
|
2337
|
+
* @returns {boolean} True if the playback instance exists
|
|
2338
|
+
*/
|
|
2339
|
+
hasInstance(playbackId) {
|
|
2340
|
+
return this.playbackInstances.has(playbackId);
|
|
1695
2341
|
}
|
|
1696
2342
|
};
|
|
1697
2343
|
|
|
@@ -1730,40 +2376,51 @@ var Sounds = class {
|
|
|
1730
2376
|
var import_events3 = require("events");
|
|
1731
2377
|
var import_exponential_backoff = __toESM(require_backoff(), 1);
|
|
1732
2378
|
var import_ws = __toESM(require("ws"), 1);
|
|
2379
|
+
var DEFAULT_MAX_RECONNECT_ATTEMPTS = 10;
|
|
2380
|
+
var DEFAULT_STARTING_DELAY = 500;
|
|
2381
|
+
var DEFAULT_MAX_DELAY = 1e4;
|
|
1733
2382
|
var WebSocketClient = class extends import_events3.EventEmitter {
|
|
2383
|
+
/**
|
|
2384
|
+
* Creates a new WebSocket client instance.
|
|
2385
|
+
*
|
|
2386
|
+
* @param {BaseClient} baseClient - The base client containing connection details
|
|
2387
|
+
* @param {string[]} apps - List of applications to connect to
|
|
2388
|
+
* @param {WebSocketEventType[]} [subscribedEvents] - Optional list of events to subscribe to
|
|
2389
|
+
* @param {AriClient} [ariClient] - Optional ARI client for handling channel and playback events
|
|
2390
|
+
*/
|
|
1734
2391
|
constructor(baseClient, apps, subscribedEvents, ariClient) {
|
|
1735
2392
|
super();
|
|
1736
2393
|
this.baseClient = baseClient;
|
|
1737
2394
|
this.apps = apps;
|
|
1738
2395
|
this.subscribedEvents = subscribedEvents;
|
|
1739
2396
|
this.ariClient = ariClient;
|
|
2397
|
+
if (!apps.length) {
|
|
2398
|
+
throw new Error("At least one application name is required");
|
|
2399
|
+
}
|
|
1740
2400
|
}
|
|
1741
2401
|
ws;
|
|
1742
2402
|
isReconnecting = false;
|
|
1743
|
-
maxReconnectAttempts =
|
|
2403
|
+
maxReconnectAttempts = DEFAULT_MAX_RECONNECT_ATTEMPTS;
|
|
1744
2404
|
backOffOptions = {
|
|
1745
|
-
numOfAttempts:
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
// Início com 500ms de atraso
|
|
1749
|
-
maxDelay: 1e4,
|
|
1750
|
-
// Limite máximo de atraso de 10s
|
|
2405
|
+
numOfAttempts: DEFAULT_MAX_RECONNECT_ATTEMPTS,
|
|
2406
|
+
startingDelay: DEFAULT_STARTING_DELAY,
|
|
2407
|
+
maxDelay: DEFAULT_MAX_DELAY,
|
|
1751
2408
|
timeMultiple: 2,
|
|
1752
|
-
// Atraso aumenta exponencialmente
|
|
1753
2409
|
jitter: "full",
|
|
1754
|
-
// Randomização para evitar colisões
|
|
1755
2410
|
delayFirstAttempt: false,
|
|
1756
|
-
// Não atrase a primeira tentativa
|
|
1757
2411
|
retry: (error, attemptNumber) => {
|
|
1758
2412
|
console.warn(
|
|
1759
|
-
`
|
|
1760
|
-
error.message || error
|
|
2413
|
+
`Connection attempt #${attemptNumber} failed:`,
|
|
2414
|
+
error.message || "Unknown error"
|
|
1761
2415
|
);
|
|
1762
|
-
return
|
|
2416
|
+
return attemptNumber < this.maxReconnectAttempts;
|
|
1763
2417
|
}
|
|
1764
2418
|
};
|
|
1765
2419
|
/**
|
|
1766
|
-
*
|
|
2420
|
+
* Establishes a WebSocket connection.
|
|
2421
|
+
*
|
|
2422
|
+
* @returns {Promise<void>} Resolves when connection is established
|
|
2423
|
+
* @throws {Error} If connection fails
|
|
1767
2424
|
*/
|
|
1768
2425
|
async connect() {
|
|
1769
2426
|
const { baseUrl, username, password } = this.baseClient.getCredentials();
|
|
@@ -1771,7 +2428,7 @@ var WebSocketClient = class extends import_events3.EventEmitter {
|
|
|
1771
2428
|
const normalizedHost = baseUrl.replace(/^https?:\/\//, "").replace(/\/ari$/, "");
|
|
1772
2429
|
const queryParams = new URLSearchParams();
|
|
1773
2430
|
queryParams.append("app", this.apps.join(","));
|
|
1774
|
-
if (this.subscribedEvents
|
|
2431
|
+
if (this.subscribedEvents?.length) {
|
|
1775
2432
|
this.subscribedEvents.forEach(
|
|
1776
2433
|
(event) => queryParams.append("event", event)
|
|
1777
2434
|
);
|
|
@@ -1779,48 +2436,57 @@ var WebSocketClient = class extends import_events3.EventEmitter {
|
|
|
1779
2436
|
queryParams.append("subscribeAll", "true");
|
|
1780
2437
|
}
|
|
1781
2438
|
const wsUrl = `${protocol}://${encodeURIComponent(username)}:${encodeURIComponent(password)}@${normalizedHost}/ari/events?${queryParams.toString()}`;
|
|
1782
|
-
console.log("
|
|
2439
|
+
console.log("Connecting to WebSocket...");
|
|
1783
2440
|
return this.initializeWebSocket(wsUrl);
|
|
1784
2441
|
}
|
|
1785
2442
|
/**
|
|
1786
|
-
*
|
|
2443
|
+
* Initializes WebSocket connection with reconnection logic.
|
|
2444
|
+
*
|
|
2445
|
+
* @param {string} wsUrl - The WebSocket URL to connect to
|
|
2446
|
+
* @returns {Promise<void>} Resolves when connection is established
|
|
1787
2447
|
*/
|
|
1788
2448
|
async initializeWebSocket(wsUrl) {
|
|
1789
2449
|
return (0, import_exponential_backoff.backOff)(async () => {
|
|
1790
2450
|
return new Promise((resolve, reject) => {
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
this.
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
this.
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
2451
|
+
try {
|
|
2452
|
+
this.ws = new import_ws.default(wsUrl);
|
|
2453
|
+
this.ws.on("open", () => {
|
|
2454
|
+
console.log("WebSocket connection established successfully");
|
|
2455
|
+
this.isReconnecting = false;
|
|
2456
|
+
this.emit("connected");
|
|
2457
|
+
resolve();
|
|
2458
|
+
});
|
|
2459
|
+
this.ws.on("message", (data) => this.handleMessage(data.toString()));
|
|
2460
|
+
this.ws.on("close", (code) => {
|
|
2461
|
+
console.warn(
|
|
2462
|
+
`WebSocket disconnected with code ${code}. Attempting to reconnect...`
|
|
2463
|
+
);
|
|
2464
|
+
if (!this.isReconnecting) {
|
|
2465
|
+
this.reconnect(wsUrl);
|
|
2466
|
+
}
|
|
2467
|
+
});
|
|
2468
|
+
this.ws.on("error", (err) => {
|
|
2469
|
+
console.error("WebSocket error:", err.message);
|
|
2470
|
+
if (!this.isReconnecting) {
|
|
2471
|
+
this.reconnect(wsUrl);
|
|
2472
|
+
}
|
|
2473
|
+
reject(err);
|
|
2474
|
+
});
|
|
2475
|
+
} catch (error) {
|
|
2476
|
+
reject(error);
|
|
2477
|
+
}
|
|
1814
2478
|
});
|
|
1815
2479
|
}, this.backOffOptions);
|
|
1816
2480
|
}
|
|
1817
2481
|
/**
|
|
1818
|
-
*
|
|
2482
|
+
* Processes incoming WebSocket messages.
|
|
2483
|
+
*
|
|
2484
|
+
* @param {string} rawMessage - The raw message received from WebSocket
|
|
1819
2485
|
*/
|
|
1820
2486
|
handleMessage(rawMessage) {
|
|
1821
2487
|
try {
|
|
1822
2488
|
const event = JSON.parse(rawMessage);
|
|
1823
|
-
if (this.subscribedEvents && !this.subscribedEvents.includes(event.type)) {
|
|
2489
|
+
if (this.subscribedEvents?.length && !this.subscribedEvents.includes(event.type)) {
|
|
1824
2490
|
return;
|
|
1825
2491
|
}
|
|
1826
2492
|
if ("channel" in event && event.channel?.id && this.ariClient) {
|
|
@@ -1834,40 +2500,77 @@ var WebSocketClient = class extends import_events3.EventEmitter {
|
|
|
1834
2500
|
event.instancePlayback = instancePlayback;
|
|
1835
2501
|
}
|
|
1836
2502
|
this.emit(event.type, event);
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
2503
|
+
console.log(`Event processed: ${event.type}`);
|
|
2504
|
+
} catch (error) {
|
|
2505
|
+
console.error("Error processing WebSocket message:", error instanceof Error ? error.message : "Unknown error");
|
|
2506
|
+
this.emit("error", new Error("Failed to decode WebSocket message"));
|
|
1840
2507
|
}
|
|
1841
2508
|
}
|
|
1842
2509
|
/**
|
|
1843
|
-
*
|
|
2510
|
+
* Attempts to reconnect to the WebSocket.
|
|
2511
|
+
*
|
|
2512
|
+
* @param {string} wsUrl - The WebSocket URL to reconnect to
|
|
1844
2513
|
*/
|
|
1845
2514
|
reconnect(wsUrl) {
|
|
1846
2515
|
this.isReconnecting = true;
|
|
1847
|
-
console.log("
|
|
2516
|
+
console.log("Initiating reconnection attempt...");
|
|
1848
2517
|
this.removeAllListeners();
|
|
1849
|
-
(0, import_exponential_backoff.backOff)(() => this.initializeWebSocket(wsUrl), this.backOffOptions).catch(
|
|
1850
|
-
(
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
);
|
|
2518
|
+
(0, import_exponential_backoff.backOff)(() => this.initializeWebSocket(wsUrl), this.backOffOptions).catch((error) => {
|
|
2519
|
+
console.error(
|
|
2520
|
+
"Failed to reconnect after multiple attempts:",
|
|
2521
|
+
error instanceof Error ? error.message : "Unknown error"
|
|
2522
|
+
);
|
|
2523
|
+
this.emit("reconnectFailed", error);
|
|
2524
|
+
});
|
|
1857
2525
|
}
|
|
1858
2526
|
/**
|
|
1859
|
-
*
|
|
2527
|
+
* Manually closes the WebSocket connection.
|
|
1860
2528
|
*/
|
|
1861
2529
|
close() {
|
|
1862
|
-
|
|
1863
|
-
|
|
2530
|
+
try {
|
|
2531
|
+
if (this.ws) {
|
|
2532
|
+
this.ws.close();
|
|
2533
|
+
this.ws = void 0;
|
|
2534
|
+
console.log("WebSocket connection closed");
|
|
2535
|
+
}
|
|
2536
|
+
} catch (error) {
|
|
2537
|
+
console.error(
|
|
2538
|
+
"Error closing WebSocket:",
|
|
2539
|
+
error instanceof Error ? error.message : "Unknown error"
|
|
2540
|
+
);
|
|
2541
|
+
}
|
|
2542
|
+
}
|
|
2543
|
+
/**
|
|
2544
|
+
* Checks if the WebSocket is currently connected.
|
|
2545
|
+
*
|
|
2546
|
+
* @returns {boolean} True if connected, false otherwise
|
|
2547
|
+
*/
|
|
2548
|
+
isConnected() {
|
|
2549
|
+
return this.ws?.readyState === import_ws.default.OPEN;
|
|
2550
|
+
}
|
|
2551
|
+
/**
|
|
2552
|
+
* Gets the current connection state.
|
|
2553
|
+
*
|
|
2554
|
+
* @returns {number} The WebSocket ready state
|
|
2555
|
+
*/
|
|
2556
|
+
getState() {
|
|
2557
|
+
return this.ws?.readyState ?? import_ws.default.CLOSED;
|
|
1864
2558
|
}
|
|
1865
2559
|
};
|
|
1866
2560
|
|
|
1867
2561
|
// src/ari-client/ariClient.ts
|
|
1868
2562
|
var AriClient = class {
|
|
2563
|
+
/**
|
|
2564
|
+
* Creates a new instance of the ARI client.
|
|
2565
|
+
*
|
|
2566
|
+
* @param {AriClientConfig} config - Configuration options for the ARI client
|
|
2567
|
+
* @throws {Error} If required configuration parameters are missing
|
|
2568
|
+
*/
|
|
1869
2569
|
constructor(config) {
|
|
1870
2570
|
this.config = config;
|
|
2571
|
+
if (!config.host || !config.port || !config.username || !config.password) {
|
|
2572
|
+
throw new Error("Missing required configuration parameters");
|
|
2573
|
+
}
|
|
1871
2574
|
const httpProtocol = config.secure ? "https" : "http";
|
|
1872
2575
|
const normalizedHost = config.host.replace(/^https?:\/\//, "");
|
|
1873
2576
|
const baseUrl = `${httpProtocol}://${normalizedHost}:${config.port}/ari`;
|
|
@@ -1879,6 +2582,7 @@ var AriClient = class {
|
|
|
1879
2582
|
this.sounds = new Sounds(this.baseClient);
|
|
1880
2583
|
this.asterisk = new Asterisk(this.baseClient);
|
|
1881
2584
|
this.bridges = new Bridges(this.baseClient);
|
|
2585
|
+
console.log(`ARI Client initialized with base URL: ${baseUrl}`);
|
|
1882
2586
|
}
|
|
1883
2587
|
baseClient;
|
|
1884
2588
|
webSocketClient;
|
|
@@ -1890,58 +2594,117 @@ var AriClient = class {
|
|
|
1890
2594
|
asterisk;
|
|
1891
2595
|
bridges;
|
|
1892
2596
|
/**
|
|
1893
|
-
*
|
|
2597
|
+
* Initializes a WebSocket connection for receiving events.
|
|
2598
|
+
*
|
|
2599
|
+
* @param {string[]} apps - List of application names to subscribe to
|
|
2600
|
+
* @param {WebSocketEventType[]} [subscribedEvents] - Optional list of specific event types to subscribe to
|
|
2601
|
+
* @returns {Promise<void>} Resolves when connection is established
|
|
2602
|
+
* @throws {Error} If connection fails or if WebSocket is already connected
|
|
1894
2603
|
*/
|
|
1895
2604
|
async connectWebSocket(apps, subscribedEvents) {
|
|
2605
|
+
if (!apps.length) {
|
|
2606
|
+
throw new Error("At least one application name is required");
|
|
2607
|
+
}
|
|
1896
2608
|
if (this.webSocketClient) {
|
|
1897
|
-
console.warn("WebSocket
|
|
2609
|
+
console.warn("WebSocket is already connected");
|
|
1898
2610
|
return;
|
|
1899
2611
|
}
|
|
1900
|
-
|
|
1901
|
-
this.
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
2612
|
+
try {
|
|
2613
|
+
this.webSocketClient = new WebSocketClient(
|
|
2614
|
+
this.baseClient,
|
|
2615
|
+
apps,
|
|
2616
|
+
subscribedEvents,
|
|
2617
|
+
this
|
|
2618
|
+
);
|
|
2619
|
+
await this.webSocketClient.connect();
|
|
2620
|
+
console.log("WebSocket connection established successfully");
|
|
2621
|
+
} catch (error) {
|
|
2622
|
+
console.error("Failed to establish WebSocket connection:", error);
|
|
2623
|
+
this.webSocketClient = void 0;
|
|
2624
|
+
throw error;
|
|
2625
|
+
}
|
|
1907
2626
|
}
|
|
1908
2627
|
/**
|
|
1909
|
-
*
|
|
2628
|
+
* Registers an event listener for WebSocket events.
|
|
2629
|
+
*
|
|
2630
|
+
* @param {T} event - The event type to listen for
|
|
2631
|
+
* @param {Function} listener - Callback function for handling the event
|
|
2632
|
+
* @throws {Error} If WebSocket is not connected
|
|
1910
2633
|
*/
|
|
1911
2634
|
on(event, listener) {
|
|
1912
|
-
this.webSocketClient
|
|
2635
|
+
if (!this.webSocketClient) {
|
|
2636
|
+
throw new Error("WebSocket is not connected");
|
|
2637
|
+
}
|
|
2638
|
+
this.webSocketClient.on(event, listener);
|
|
2639
|
+
console.log(`Event listener registered for ${event}`);
|
|
1913
2640
|
}
|
|
1914
2641
|
/**
|
|
1915
|
-
*
|
|
2642
|
+
* Registers a one-time event listener for WebSocket events.
|
|
2643
|
+
*
|
|
2644
|
+
* @param {T} event - The event type to listen for
|
|
2645
|
+
* @param {Function} listener - Callback function for handling the event
|
|
2646
|
+
* @throws {Error} If WebSocket is not connected
|
|
1916
2647
|
*/
|
|
1917
2648
|
once(event, listener) {
|
|
1918
|
-
this.webSocketClient
|
|
2649
|
+
if (!this.webSocketClient) {
|
|
2650
|
+
throw new Error("WebSocket is not connected");
|
|
2651
|
+
}
|
|
2652
|
+
this.webSocketClient.once(event, listener);
|
|
2653
|
+
console.log(`One-time event listener registered for ${event}`);
|
|
1919
2654
|
}
|
|
1920
2655
|
/**
|
|
1921
|
-
*
|
|
2656
|
+
* Removes an event listener for WebSocket events.
|
|
2657
|
+
*
|
|
2658
|
+
* @param {T} event - The event type to remove listener for
|
|
2659
|
+
* @param {Function} listener - The listener function to remove
|
|
1922
2660
|
*/
|
|
1923
2661
|
off(event, listener) {
|
|
1924
|
-
this.webSocketClient
|
|
2662
|
+
if (!this.webSocketClient) {
|
|
2663
|
+
console.warn("No WebSocket connection to remove listener from");
|
|
2664
|
+
return;
|
|
2665
|
+
}
|
|
2666
|
+
this.webSocketClient.off(event, listener);
|
|
2667
|
+
console.log(`Event listener removed for ${event}`);
|
|
1925
2668
|
}
|
|
1926
2669
|
/**
|
|
1927
|
-
*
|
|
2670
|
+
* Closes the WebSocket connection if one exists.
|
|
1928
2671
|
*/
|
|
1929
2672
|
closeWebSocket() {
|
|
1930
|
-
this.webSocketClient
|
|
2673
|
+
if (!this.webSocketClient) {
|
|
2674
|
+
console.warn("No WebSocket connection to close");
|
|
2675
|
+
return;
|
|
2676
|
+
}
|
|
2677
|
+
this.webSocketClient.close();
|
|
1931
2678
|
this.webSocketClient = void 0;
|
|
2679
|
+
console.log("WebSocket connection closed");
|
|
1932
2680
|
}
|
|
1933
2681
|
/**
|
|
1934
|
-
*
|
|
2682
|
+
* Creates or retrieves a Channel instance.
|
|
2683
|
+
*
|
|
2684
|
+
* @param {string} [channelId] - Optional ID of an existing channel
|
|
2685
|
+
* @returns {ChannelInstance} A new or existing channel instance
|
|
1935
2686
|
*/
|
|
1936
2687
|
Channel(channelId) {
|
|
1937
2688
|
return this.channels.Channel({ id: channelId });
|
|
1938
2689
|
}
|
|
1939
2690
|
/**
|
|
1940
|
-
*
|
|
2691
|
+
* Creates or retrieves a Playback instance.
|
|
2692
|
+
*
|
|
2693
|
+
* @param {string} [playbackId] - Optional ID of an existing playback
|
|
2694
|
+
* @param {string} [_app] - Optional application name (deprecated)
|
|
2695
|
+
* @returns {PlaybackInstance} A new or existing playback instance
|
|
1941
2696
|
*/
|
|
1942
2697
|
Playback(playbackId, _app) {
|
|
1943
2698
|
return this.playbacks.Playback({ id: playbackId });
|
|
1944
2699
|
}
|
|
2700
|
+
/**
|
|
2701
|
+
* Gets the current WebSocket connection status.
|
|
2702
|
+
*
|
|
2703
|
+
* @returns {boolean} True if WebSocket is connected, false otherwise
|
|
2704
|
+
*/
|
|
2705
|
+
isWebSocketConnected() {
|
|
2706
|
+
return !!this.webSocketClient;
|
|
2707
|
+
}
|
|
1945
2708
|
};
|
|
1946
2709
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1947
2710
|
0 && (module.exports = {
|