@softtynet/zca-js 2.3.4 → 2.3.6
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 +47 -11
- package/dist/apis/call/addUserGroupCall.d.ts +11 -0
- package/dist/apis/call/addUserGroupCall.js +48 -0
- package/dist/apis/call/answerAckVoiceCall.d.ts +5 -0
- package/dist/apis/call/answerAckVoiceCall.js +38 -0
- package/dist/apis/call/answerGroupCall.d.ts +10 -0
- package/dist/apis/call/answerGroupCall.js +45 -0
- package/dist/apis/call/answerVoiceCall.d.ts +11 -0
- package/dist/apis/call/answerVoiceCall.js +50 -0
- package/dist/apis/call/broadcastGroupCallState.d.ts +10 -0
- package/dist/apis/call/broadcastGroupCallState.js +45 -0
- package/dist/apis/call/cancelGroupCall.d.ts +10 -0
- package/dist/apis/call/cancelGroupCall.js +45 -0
- package/dist/apis/call/cancelVoiceCall.d.ts +1 -1
- package/dist/apis/call/cancelVoiceCall.js +5 -1
- package/dist/apis/call/createController.d.ts +7 -0
- package/dist/apis/call/createController.js +9 -0
- package/dist/apis/call/createRtcSession.d.ts +8 -0
- package/dist/apis/call/createRtcSession.js +10 -0
- package/dist/apis/call/endGroupCall.d.ts +10 -0
- package/dist/apis/call/endGroupCall.js +45 -0
- package/dist/apis/call/finishGroupCall.d.ts +12 -0
- package/dist/apis/call/finishGroupCall.js +47 -0
- package/dist/apis/call/getGroupCallState.d.ts +3 -0
- package/dist/apis/call/getGroupCallState.js +38 -0
- package/dist/apis/call/holdVoiceCall.d.ts +5 -0
- package/dist/apis/call/holdVoiceCall.js +34 -0
- package/dist/apis/call/joinGroupCall.d.ts +11 -0
- package/dist/apis/call/joinGroupCall.js +46 -0
- package/dist/apis/call/logEndVoiceCall.d.ts +8 -0
- package/dist/apis/call/logEndVoiceCall.js +46 -0
- package/dist/apis/call/notifyGroupCall.d.ts +9 -0
- package/dist/apis/call/notifyGroupCall.js +44 -0
- package/dist/apis/call/pingGroupCall.d.ts +10 -0
- package/dist/apis/call/pingGroupCall.js +45 -0
- package/dist/apis/call/requestAudioToVideoCall.d.ts +5 -0
- package/dist/apis/call/requestAudioToVideoCall.js +37 -0
- package/dist/apis/call/requestGroupCall.d.ts +9 -0
- package/dist/apis/call/requestGroupCall.js +46 -0
- package/dist/apis/call/requestShareScreenCall.d.ts +5 -0
- package/dist/apis/call/requestShareScreenCall.js +37 -0
- package/dist/apis/call/requestVoiceCall.d.ts +10 -0
- package/dist/apis/call/requestVoiceCall.js +47 -0
- package/dist/apis/call/ringRingGroupCall.d.ts +10 -0
- package/dist/apis/call/ringRingGroupCall.js +45 -0
- package/dist/apis/call/ringRingVoiceCall.d.ts +5 -0
- package/dist/apis/call/ringRingVoiceCall.js +38 -0
- package/dist/apis/call/sendRequestGroupCall.d.ts +11 -0
- package/dist/apis/call/sendRequestGroupCall.js +48 -0
- package/dist/apis/call/sendRequestVoiceCall.d.ts +11 -0
- package/dist/apis/call/sendRequestVoiceCall.js +51 -0
- package/dist/apis/call/sendVoiceCall.d.ts +8 -1
- package/dist/apis/call/sendVoiceCall.js +10 -8
- package/dist/apis/call/shareScreenGroupCall.d.ts +10 -0
- package/dist/apis/call/shareScreenGroupCall.js +45 -0
- package/dist/apis/call/unholdVoiceCall.d.ts +5 -0
- package/dist/apis/call/unholdVoiceCall.js +34 -0
- package/dist/apis/call/updateCallMediaState.d.ts +7 -0
- package/dist/apis/call/updateCallMediaState.js +61 -0
- package/dist/apis/sync/downloadTransferSync.js +19 -1
- package/dist/apis.d.ts +81 -0
- package/dist/apis.js +135 -0
- package/dist/call-engine/ZRTPPacketCodec.d.ts +262 -0
- package/dist/call-engine/ZRTPPacketCodec.js +506 -0
- package/dist/call-engine/ZaloCallController.d.ts +134 -0
- package/dist/call-engine/ZaloCallController.js +638 -0
- package/dist/call-engine/ZaloCallTransport.d.ts +83 -0
- package/dist/call-engine/ZaloCallTransport.js +259 -0
- package/dist/call-engine/ZaloRtcSession.d.ts +609 -0
- package/dist/call-engine/ZaloRtcSession.js +2939 -0
- package/dist/call-engine/ZaloSrtpSession.d.ts +80 -0
- package/dist/call-engine/ZaloSrtpSession.js +278 -0
- package/dist/call-engine/index.d.ts +18 -0
- package/dist/call-engine/index.js +24 -0
- package/dist/cjs/apis/call/addUserGroupCall.cjs +53 -0
- package/dist/cjs/apis/call/answerAckVoiceCall.cjs +43 -0
- package/dist/cjs/apis/call/answerGroupCall.cjs +50 -0
- package/dist/cjs/apis/call/answerVoiceCall.cjs +55 -0
- package/dist/cjs/apis/call/broadcastGroupCallState.cjs +50 -0
- package/dist/cjs/apis/call/cancelGroupCall.cjs +50 -0
- package/dist/cjs/apis/call/cancelVoiceCall.cjs +5 -1
- package/dist/cjs/apis/call/createController.cjs +14 -0
- package/dist/cjs/apis/call/createRtcSession.cjs +15 -0
- package/dist/cjs/apis/call/endGroupCall.cjs +50 -0
- package/dist/cjs/apis/call/finishGroupCall.cjs +52 -0
- package/dist/cjs/apis/call/getGroupCallState.cjs +43 -0
- package/dist/cjs/apis/call/holdVoiceCall.cjs +39 -0
- package/dist/cjs/apis/call/joinGroupCall.cjs +51 -0
- package/dist/cjs/apis/call/logEndVoiceCall.cjs +51 -0
- package/dist/cjs/apis/call/notifyGroupCall.cjs +49 -0
- package/dist/cjs/apis/call/pingGroupCall.cjs +50 -0
- package/dist/cjs/apis/call/requestAudioToVideoCall.cjs +42 -0
- package/dist/cjs/apis/call/requestGroupCall.cjs +51 -0
- package/dist/cjs/apis/call/requestShareScreenCall.cjs +42 -0
- package/dist/cjs/apis/call/requestVoiceCall.cjs +52 -0
- package/dist/cjs/apis/call/ringRingGroupCall.cjs +50 -0
- package/dist/cjs/apis/call/ringRingVoiceCall.cjs +43 -0
- package/dist/cjs/apis/call/sendRequestGroupCall.cjs +53 -0
- package/dist/cjs/apis/call/sendRequestVoiceCall.cjs +56 -0
- package/dist/cjs/apis/call/sendVoiceCall.cjs +10 -8
- package/dist/cjs/apis/call/shareScreenGroupCall.cjs +50 -0
- package/dist/cjs/apis/call/unholdVoiceCall.cjs +39 -0
- package/dist/cjs/apis/call/updateCallMediaState.cjs +66 -0
- package/dist/cjs/apis/sync/downloadTransferSync.cjs +19 -1
- package/dist/cjs/apis.cjs +135 -0
- package/dist/cjs/call-engine/ZRTPPacketCodec.cjs +525 -0
- package/dist/cjs/call-engine/ZaloCallController.cjs +643 -0
- package/dist/cjs/call-engine/ZaloCallTransport.cjs +265 -0
- package/dist/cjs/call-engine/ZaloRtcSession.cjs +2945 -0
- package/dist/cjs/call-engine/ZaloSrtpSession.cjs +287 -0
- package/dist/cjs/constants/protocol.cjs +1 -1
- package/dist/cjs/crypto/aes.cjs +3 -1
- package/dist/cjs/crypto/zdb-cipher.cjs +10 -3
- package/dist/cjs/index.cjs +61 -11
- package/dist/cjs/models/CallEvent.cjs +95 -1
- package/dist/cjs/realtime/handlers/control.handler.cjs +17 -3
- package/dist/cjs/realtime/listener.cjs +19 -0
- package/dist/constants/protocol.d.ts +1 -1
- package/dist/constants/protocol.js +1 -1
- package/dist/crypto/aes.js +3 -1
- package/dist/crypto/zdb-cipher.js +10 -3
- package/dist/index.d.ts +32 -4
- package/dist/index.js +2 -0
- package/dist/models/CallEvent.d.ts +15 -0
- package/dist/models/CallEvent.js +95 -1
- package/dist/realtime/handlers/control.handler.js +17 -3
- package/dist/realtime/listener.d.ts +5 -0
- package/dist/realtime/listener.js +19 -0
- package/package.json +2 -1
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { ZaloApiError } from "../../Errors/ZaloApiError.js";
|
|
2
|
+
import { apiFactory } from "../../utils.js";
|
|
3
|
+
import { CallType } from "./sendVoiceCall.js";
|
|
4
|
+
export const sendRequestGroupCallFactory = apiFactory()((api, _ctx, utils) => {
|
|
5
|
+
const voiceCallService = api.zpwServiceMap.voice_call?.[0];
|
|
6
|
+
/**
|
|
7
|
+
* Gửi tín hiệu mời tham gia / đổ chuông cuộc gọi nhóm (`/api/voicecall/group/request`, command `12434`).
|
|
8
|
+
*
|
|
9
|
+
* @param groupId ID của nhóm
|
|
10
|
+
* @param options Thông tin `callId`, `session`, `partners`, `callType` và `data`
|
|
11
|
+
* @throws {ZaloApiError}
|
|
12
|
+
*/
|
|
13
|
+
return async function sendRequestGroupCall(groupId, options) {
|
|
14
|
+
if (!groupId)
|
|
15
|
+
throw new ZaloApiError("Missing groupId");
|
|
16
|
+
if (!options?.callId)
|
|
17
|
+
throw new ZaloApiError("Missing callId");
|
|
18
|
+
if (!options?.session)
|
|
19
|
+
throw new ZaloApiError("Missing session");
|
|
20
|
+
if (!voiceCallService)
|
|
21
|
+
throw new ZaloApiError("Missing voice_call service URL in zpwServiceMap");
|
|
22
|
+
const dataStr = options.data === undefined
|
|
23
|
+
? "{}"
|
|
24
|
+
: typeof options.data === "string"
|
|
25
|
+
? options.data
|
|
26
|
+
: JSON.stringify(options.data);
|
|
27
|
+
const params = {
|
|
28
|
+
calleeId: options.calleeId ?? "",
|
|
29
|
+
callId: options.callId,
|
|
30
|
+
callType: options.callType ?? CallType.GroupAudio,
|
|
31
|
+
data: dataStr,
|
|
32
|
+
session: options.session,
|
|
33
|
+
partners: (options.partners ?? []).map(String),
|
|
34
|
+
groupId: String(groupId),
|
|
35
|
+
};
|
|
36
|
+
const encryptedParams = utils.encodeAES(JSON.stringify(params));
|
|
37
|
+
if (!encryptedParams)
|
|
38
|
+
throw new ZaloApiError("Failed to encrypt sendRequestGroupCall params");
|
|
39
|
+
const url = utils.makeURL(`${voiceCallService}/api/voicecall/group/request`, {
|
|
40
|
+
zpw_type: 24,
|
|
41
|
+
params: encryptedParams,
|
|
42
|
+
});
|
|
43
|
+
const response = await utils.request(url, {
|
|
44
|
+
method: "GET",
|
|
45
|
+
});
|
|
46
|
+
return utils.resolve(response);
|
|
47
|
+
};
|
|
48
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type SendRequestVoiceCallOptions = {
|
|
2
|
+
callId: number;
|
|
3
|
+
session: string;
|
|
4
|
+
rtpAddress: string;
|
|
5
|
+
rtcpAddress: string;
|
|
6
|
+
codec?: string;
|
|
7
|
+
extendData?: string | Record<string, unknown>;
|
|
8
|
+
subCommand?: number;
|
|
9
|
+
};
|
|
10
|
+
export type SendRequestVoiceCallResponse = Record<string, unknown>;
|
|
11
|
+
export declare const sendRequestVoiceCallFactory: (ctx: import("../../context.js").ContextBase, api: import("../../apis.js").API) => (calleeId: string, options: SendRequestVoiceCallOptions) => Promise<SendRequestVoiceCallResponse>;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { ZaloApiError } from "../../Errors/ZaloApiError.js";
|
|
2
|
+
import { apiFactory } from "../../utils.js";
|
|
3
|
+
export const sendRequestVoiceCallFactory = apiFactory()((api, ctx, utils) => {
|
|
4
|
+
const voiceCallService = api.zpwServiceMap.voice_call?.[0];
|
|
5
|
+
/**
|
|
6
|
+
* Gửi tín hiệu đổ chuông kèm thông tin kết nối RTP/RTCP & `extendData` (`/api/voicecall/request`, command `11301`, signal `416`).
|
|
7
|
+
*
|
|
8
|
+
* @param calleeId User ID của người nhận cuộc gọi
|
|
9
|
+
* @param options Thông tin `callId`, `session`, `rtpAddress`, `rtcpAddress`, `codec` và `extendData`
|
|
10
|
+
* @throws {ZaloApiError}
|
|
11
|
+
*/
|
|
12
|
+
return async function sendRequestVoiceCall(calleeId, options) {
|
|
13
|
+
if (!calleeId)
|
|
14
|
+
throw new ZaloApiError("Missing calleeId");
|
|
15
|
+
if (!options?.callId)
|
|
16
|
+
throw new ZaloApiError("Missing callId");
|
|
17
|
+
if (!options?.session)
|
|
18
|
+
throw new ZaloApiError("Missing session");
|
|
19
|
+
if (!voiceCallService)
|
|
20
|
+
throw new ZaloApiError("Missing voice_call service URL in zpwServiceMap");
|
|
21
|
+
const extendDataStr = options.extendData === undefined
|
|
22
|
+
? undefined
|
|
23
|
+
: typeof options.extendData === "string"
|
|
24
|
+
? options.extendData
|
|
25
|
+
: JSON.stringify(options.extendData);
|
|
26
|
+
const params = {
|
|
27
|
+
calleeId: String(calleeId),
|
|
28
|
+
rtcpAddress: options.rtcpAddress ?? "",
|
|
29
|
+
rtpAddress: options.rtpAddress ?? "",
|
|
30
|
+
codec: options.codec ?? "[]",
|
|
31
|
+
session: options.session,
|
|
32
|
+
callId: options.callId,
|
|
33
|
+
imei: ctx.imei,
|
|
34
|
+
};
|
|
35
|
+
if (extendDataStr) {
|
|
36
|
+
params.extendData = extendDataStr;
|
|
37
|
+
params.subCommand = options.subCommand ?? 3;
|
|
38
|
+
}
|
|
39
|
+
const encryptedParams = utils.encodeAES(JSON.stringify(params));
|
|
40
|
+
if (!encryptedParams)
|
|
41
|
+
throw new ZaloApiError("Failed to encrypt sendRequestVoiceCall params");
|
|
42
|
+
const url = utils.makeURL(`${voiceCallService}/api/voicecall/request`, {
|
|
43
|
+
zpw_type: 24,
|
|
44
|
+
params: encryptedParams,
|
|
45
|
+
});
|
|
46
|
+
const response = await utils.request(url, {
|
|
47
|
+
method: "GET",
|
|
48
|
+
});
|
|
49
|
+
return utils.resolve(response);
|
|
50
|
+
};
|
|
51
|
+
});
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export declare enum CallType {
|
|
2
2
|
Audio = 1,
|
|
3
|
-
Video = 3
|
|
3
|
+
Video = 3,
|
|
4
|
+
GroupAudio = 5,
|
|
5
|
+
GroupVideo = 6
|
|
4
6
|
}
|
|
5
7
|
export type SendVoiceCallOptions = {
|
|
6
8
|
callType?: CallType;
|
|
@@ -18,6 +20,9 @@ export type RequestCallServerEntry = {
|
|
|
18
20
|
};
|
|
19
21
|
export type RequestCallServerInfo = {
|
|
20
22
|
sessId: string;
|
|
23
|
+
fromId?: number;
|
|
24
|
+
toId?: number;
|
|
25
|
+
protocol?: number;
|
|
21
26
|
rtpServer?: string;
|
|
22
27
|
rtcpServer?: string;
|
|
23
28
|
rtpIP?: string;
|
|
@@ -26,6 +31,8 @@ export type RequestCallServerInfo = {
|
|
|
26
31
|
rtcpIPv6?: string;
|
|
27
32
|
servers?: RequestCallServerEntry[];
|
|
28
33
|
zrtpKey?: string;
|
|
34
|
+
zrtc_config?: Record<string, unknown> | string;
|
|
35
|
+
settings?: Record<string, unknown>;
|
|
29
36
|
expiredTime?: number;
|
|
30
37
|
codec?: string;
|
|
31
38
|
[key: string]: unknown;
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { ZaloApiError } from "../../Errors/ZaloApiError.js";
|
|
2
|
+
import { DEFAULT_ZALO_AUDIO_CODEC, buildZrtcExtendData } from "../../call-engine/ZRTPPacketCodec.js";
|
|
2
3
|
import { apiFactory, resolveResponse } from "../../utils.js";
|
|
3
4
|
export var CallType;
|
|
4
5
|
(function (CallType) {
|
|
5
6
|
CallType[CallType["Audio"] = 1] = "Audio";
|
|
6
7
|
CallType[CallType["Video"] = 3] = "Video";
|
|
8
|
+
CallType[CallType["GroupAudio"] = 5] = "GroupAudio";
|
|
9
|
+
CallType[CallType["GroupVideo"] = 6] = "GroupVideo";
|
|
7
10
|
})(CallType || (CallType = {}));
|
|
8
11
|
function parseServerEndpoint(addr) {
|
|
9
12
|
if (!addr)
|
|
@@ -32,7 +35,7 @@ export const sendVoiceCallFactory = apiFactory()((api, ctx, utils) => {
|
|
|
32
35
|
throw new ZaloApiError("Missing voice_call service URL in zpwServiceMap");
|
|
33
36
|
const callType = options.callType ?? CallType.Audio;
|
|
34
37
|
const callId = options.callId ?? Math.floor(Math.random() * 2_000_000_000);
|
|
35
|
-
const codec = options.codec ??
|
|
38
|
+
const codec = options.codec ?? DEFAULT_ZALO_AUDIO_CODEC;
|
|
36
39
|
const normalizedCalleeId = String(calleeId);
|
|
37
40
|
// Step 1: Allocate call session & RTP/RTCP relay endpoints (/api/voicecall/requestcall, command 11300)
|
|
38
41
|
const step1Params = {
|
|
@@ -61,16 +64,15 @@ export const sendVoiceCallFactory = apiFactory()((api, ctx, utils) => {
|
|
|
61
64
|
const rtp = parseServerEndpoint(resolvedRtpServer);
|
|
62
65
|
const rtcp = parseServerEndpoint(resolvedRtcpServer);
|
|
63
66
|
const sessId = serverInfo?.sessId ?? `${normalizedCalleeId}_${callId}_401`;
|
|
64
|
-
const resolvedCodec = serverInfo?.codec
|
|
67
|
+
const resolvedCodec = serverInfo?.codec && serverInfo.codec !== "[]" ? serverInfo.codec : codec;
|
|
65
68
|
// Step 2: Send ringing signaling request (/api/voicecall/request, command 11301)
|
|
66
69
|
const isVideo = callType === CallType.Video;
|
|
67
70
|
const extendData = JSON.stringify({
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
platform: 5,
|
|
71
|
+
...buildZrtcExtendData({
|
|
72
|
+
rtpAddress: rtp.host,
|
|
73
|
+
rtcpAddress: rtcp.host,
|
|
74
|
+
isVideo,
|
|
75
|
+
}),
|
|
74
76
|
rtcpDiff: 0,
|
|
75
77
|
rtcp: [{ ip: rtcp.ip, port: rtcp.port }],
|
|
76
78
|
rtp: [{ ip: rtp.ip, port: rtp.port }],
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type ShareScreenGroupCallOptions = {
|
|
2
|
+
userId?: string;
|
|
3
|
+
hostCall: string;
|
|
4
|
+
status?: number;
|
|
5
|
+
audioState?: number;
|
|
6
|
+
videoState?: number;
|
|
7
|
+
data?: string | Record<string, unknown>;
|
|
8
|
+
};
|
|
9
|
+
export type ShareScreenGroupCallResponse = Record<string, unknown>;
|
|
10
|
+
export declare const shareScreenGroupCallFactory: (ctx: import("../../context.js").ContextBase, api: import("../../apis.js").API) => (callId: number, options: ShareScreenGroupCallOptions) => Promise<ShareScreenGroupCallResponse>;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { ZaloApiError } from "../../Errors/ZaloApiError.js";
|
|
2
|
+
import { apiFactory } from "../../utils.js";
|
|
3
|
+
export const shareScreenGroupCallFactory = apiFactory()((api, ctx, utils) => {
|
|
4
|
+
const voiceCallService = api.zpwServiceMap.voice_call?.[0];
|
|
5
|
+
/**
|
|
6
|
+
* Bật/tắt chia sẻ màn hình trong cuộc gọi nhóm (`/api/voicecall/group/sharescreen`, command `12044`).
|
|
7
|
+
*
|
|
8
|
+
* @param callId ID của cuộc gọi nhóm
|
|
9
|
+
* @param options Thông tin `hostCall`, `userId`, `status`, `audioState`, `videoState` và `data`
|
|
10
|
+
* @throws {ZaloApiError}
|
|
11
|
+
*/
|
|
12
|
+
return async function shareScreenGroupCall(callId, options) {
|
|
13
|
+
if (!callId)
|
|
14
|
+
throw new ZaloApiError("Missing callId");
|
|
15
|
+
if (!options?.hostCall)
|
|
16
|
+
throw new ZaloApiError("Missing hostCall");
|
|
17
|
+
if (!voiceCallService)
|
|
18
|
+
throw new ZaloApiError("Missing voice_call service URL in zpwServiceMap");
|
|
19
|
+
const dataStr = options.data === undefined
|
|
20
|
+
? "{}"
|
|
21
|
+
: typeof options.data === "string"
|
|
22
|
+
? options.data
|
|
23
|
+
: JSON.stringify(options.data);
|
|
24
|
+
const params = {
|
|
25
|
+
userId: String(options.userId ?? ctx.uid),
|
|
26
|
+
callId,
|
|
27
|
+
hostCall: String(options.hostCall),
|
|
28
|
+
status: options.status ?? 1,
|
|
29
|
+
audiostate: options.audioState ?? 1,
|
|
30
|
+
videostate: options.videoState ?? 1,
|
|
31
|
+
data: dataStr,
|
|
32
|
+
};
|
|
33
|
+
const encryptedParams = utils.encodeAES(JSON.stringify(params));
|
|
34
|
+
if (!encryptedParams)
|
|
35
|
+
throw new ZaloApiError("Failed to encrypt shareScreenGroupCall params");
|
|
36
|
+
const url = utils.makeURL(`${voiceCallService}/api/voicecall/group/sharescreen`, {
|
|
37
|
+
zpw_type: 24,
|
|
38
|
+
params: encryptedParams,
|
|
39
|
+
});
|
|
40
|
+
const response = await utils.request(url, {
|
|
41
|
+
method: "GET",
|
|
42
|
+
});
|
|
43
|
+
return utils.resolve(response);
|
|
44
|
+
};
|
|
45
|
+
});
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type UnholdVoiceCallOptions = {
|
|
2
|
+
isResponse?: boolean;
|
|
3
|
+
};
|
|
4
|
+
export type UnholdVoiceCallResponse = Record<string, unknown>;
|
|
5
|
+
export declare const unholdVoiceCallFactory: (ctx: import("../../context.js").ContextBase, api: import("../../apis.js").API) => (toId: string, options?: UnholdVoiceCallOptions) => Promise<UnholdVoiceCallResponse>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ZaloApiError } from "../../Errors/ZaloApiError.js";
|
|
2
|
+
import { apiFactory } from "../../utils.js";
|
|
3
|
+
export const unholdVoiceCallFactory = apiFactory()((api, _ctx, utils) => {
|
|
4
|
+
const voiceCallService = api.zpwServiceMap.voice_call?.[0];
|
|
5
|
+
/**
|
|
6
|
+
* Gửi yêu cầu tiếp tục cuộc gọi đang tạm giữ (`/api/voicecall/unholdreq`, command `11309`, signal `413`)
|
|
7
|
+
* hoặc phản hồi tiếp tục cuộc gọi (`/api/voicecall/unholdresp`, command `11310`, signal `414`).
|
|
8
|
+
*
|
|
9
|
+
* @param toId User ID của đối phương trong cuộc gọi
|
|
10
|
+
* @param options Đặt `isResponse = true` nếu là gói phản hồi (`unholdresp`)
|
|
11
|
+
* @throws {ZaloApiError}
|
|
12
|
+
*/
|
|
13
|
+
return async function unholdVoiceCall(toId, options = {}) {
|
|
14
|
+
if (!toId)
|
|
15
|
+
throw new ZaloApiError("Missing toId");
|
|
16
|
+
if (!voiceCallService)
|
|
17
|
+
throw new ZaloApiError("Missing voice_call service URL in zpwServiceMap");
|
|
18
|
+
const params = {
|
|
19
|
+
toId: String(toId),
|
|
20
|
+
};
|
|
21
|
+
const encryptedParams = utils.encodeAES(JSON.stringify(params));
|
|
22
|
+
if (!encryptedParams)
|
|
23
|
+
throw new ZaloApiError("Failed to encrypt unholdVoiceCall params");
|
|
24
|
+
const endpoint = options.isResponse ? "unholdresp" : "unholdreq";
|
|
25
|
+
const url = utils.makeURL(`${voiceCallService}/api/voicecall/${endpoint}`, {
|
|
26
|
+
zpw_type: 24,
|
|
27
|
+
params: encryptedParams,
|
|
28
|
+
});
|
|
29
|
+
const response = await utils.request(url, {
|
|
30
|
+
method: "GET",
|
|
31
|
+
});
|
|
32
|
+
return utils.resolve(response);
|
|
33
|
+
};
|
|
34
|
+
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type UpdateCallMediaStateOptions = {
|
|
2
|
+
isOnCam?: boolean | number;
|
|
3
|
+
isOnMic?: boolean | number;
|
|
4
|
+
data?: string | Record<string, unknown>;
|
|
5
|
+
};
|
|
6
|
+
export type UpdateCallMediaStateResponse = Record<string, unknown>;
|
|
7
|
+
export declare const updateCallMediaStateFactory: (ctx: import("../../context.js").ContextBase, api: import("../../apis.js").API) => (calleeId: string, callId: number, options: UpdateCallMediaStateOptions) => Promise<UpdateCallMediaStateResponse>;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { ZaloApiError } from "../../Errors/ZaloApiError.js";
|
|
2
|
+
import { apiFactory } from "../../utils.js";
|
|
3
|
+
export const updateCallMediaStateFactory = apiFactory()((api, _ctx, utils) => {
|
|
4
|
+
const voiceCallService = api.zpwServiceMap.voice_call?.[0];
|
|
5
|
+
/**
|
|
6
|
+
* Đồng bộ trạng thái bật/tắt Camera và Microphone trong cuộc gọi 1-1 (`/api/voicecall/conf`, command `12006`).
|
|
7
|
+
* Khớp chính xác với `ZMessageSerializer::sendOnOffMicCam` (`0x100026cdc`):
|
|
8
|
+
* - Khi bật/tắt Camera (`UiOnOffCameraEvent`): `isOnCam = 1 | 0`, `isOnMic = -1`, `data = ""`
|
|
9
|
+
* - Khi bật/tắt Mic (`UiMuteEvent`): `isOnCam = -1`, `isOnMic = 1 | 0`, `data = ""`
|
|
10
|
+
*
|
|
11
|
+
* @param calleeId User ID của đối phương
|
|
12
|
+
* @param callId ID của cuộc gọi
|
|
13
|
+
* @param options Trạng thái `isOnCam`, `isOnMic` và `data` bổ sung
|
|
14
|
+
* @throws {ZaloApiError}
|
|
15
|
+
*/
|
|
16
|
+
return async function updateCallMediaState(calleeId, callId, options) {
|
|
17
|
+
if (!calleeId)
|
|
18
|
+
throw new ZaloApiError("Missing calleeId");
|
|
19
|
+
if (!callId)
|
|
20
|
+
throw new ZaloApiError("Missing callId");
|
|
21
|
+
if (!voiceCallService)
|
|
22
|
+
throw new ZaloApiError("Missing voice_call service URL in zpwServiceMap");
|
|
23
|
+
const dataStr = options.data === undefined
|
|
24
|
+
? ""
|
|
25
|
+
: typeof options.data === "string"
|
|
26
|
+
? options.data
|
|
27
|
+
: JSON.stringify(options.data);
|
|
28
|
+
const isOnCamVal = options.isOnCam === undefined
|
|
29
|
+
? -1
|
|
30
|
+
: typeof options.isOnCam === "boolean"
|
|
31
|
+
? options.isOnCam
|
|
32
|
+
? 1
|
|
33
|
+
: 0
|
|
34
|
+
: Number(options.isOnCam);
|
|
35
|
+
const isOnMicVal = options.isOnMic === undefined
|
|
36
|
+
? -1
|
|
37
|
+
: typeof options.isOnMic === "boolean"
|
|
38
|
+
? options.isOnMic
|
|
39
|
+
? 1
|
|
40
|
+
: 0
|
|
41
|
+
: Number(options.isOnMic);
|
|
42
|
+
const params = {
|
|
43
|
+
calleeId: String(calleeId),
|
|
44
|
+
callId,
|
|
45
|
+
isOnCam: isOnCamVal,
|
|
46
|
+
isOnMic: isOnMicVal,
|
|
47
|
+
data: dataStr,
|
|
48
|
+
};
|
|
49
|
+
const encryptedParams = utils.encodeAES(JSON.stringify(params));
|
|
50
|
+
if (!encryptedParams)
|
|
51
|
+
throw new ZaloApiError("Failed to encrypt updateCallMediaState params");
|
|
52
|
+
const url = utils.makeURL(`${voiceCallService}/api/voicecall/conf`, {
|
|
53
|
+
zpw_type: 24,
|
|
54
|
+
params: encryptedParams,
|
|
55
|
+
});
|
|
56
|
+
const response = await utils.request(url, {
|
|
57
|
+
method: "GET",
|
|
58
|
+
});
|
|
59
|
+
return utils.resolve(response);
|
|
60
|
+
};
|
|
61
|
+
});
|
|
@@ -10,13 +10,31 @@ export const downloadTransferSyncFactory = apiFactory()((api, ctx, utils) => {
|
|
|
10
10
|
return async function downloadTransferSync(options) {
|
|
11
11
|
let downloadUrl = "";
|
|
12
12
|
if (typeof options === "string") {
|
|
13
|
+
let parsedUrl;
|
|
14
|
+
try {
|
|
15
|
+
parsedUrl = new URL(options);
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
throw new ZaloApiError("Invalid downloadTransferSync URL");
|
|
19
|
+
}
|
|
20
|
+
if (parsedUrl.protocol !== "https:" && parsedUrl.protocol !== "http:") {
|
|
21
|
+
throw new ZaloApiError(`Unsupported protocol in downloadTransferSync URL: ${parsedUrl.protocol}`);
|
|
22
|
+
}
|
|
23
|
+
if (parsedUrl.hostname === "169.254.169.254" || parsedUrl.hostname === "metadata.google.internal") {
|
|
24
|
+
throw new ZaloApiError("Blocked internal metadata hostname in downloadTransferSync URL");
|
|
25
|
+
}
|
|
13
26
|
downloadUrl = options;
|
|
14
27
|
}
|
|
15
28
|
else {
|
|
16
29
|
if (!options.key || !options.exp || !options.sig) {
|
|
17
30
|
throw new ZaloApiError("Missing key, exp or sig in options");
|
|
18
31
|
}
|
|
19
|
-
|
|
32
|
+
const qs = new URLSearchParams({
|
|
33
|
+
key: String(options.key),
|
|
34
|
+
exp: String(options.exp),
|
|
35
|
+
sig: String(options.sig),
|
|
36
|
+
});
|
|
37
|
+
downloadUrl = `${ZALO_DOMAINS.TRANSFER_SYNC}${ZALO_ENDPOINTS.TRANSFER_SYNC.DOWNLOAD_V2}?${qs.toString()}`;
|
|
20
38
|
}
|
|
21
39
|
const response = await utils.request(downloadUrl, {
|
|
22
40
|
method: "GET",
|