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