diff --git a/src/api/layers/listener.layer.ts b/src/api/layers/listener.layer.ts index 342ad3f04..c3e57cd13 100644 --- a/src/api/layers/listener.layer.ts +++ b/src/api/layers/listener.layer.ts @@ -324,8 +324,11 @@ export class ListenerLayer extends ProfileLayer { } /** - * @event Listens to messages received - * @returns Disposable object to stop the listening + * @event Escuta por ligações recebidas, seja de áudio ou vídeo. + * + * Para recusar a ligação, basta chamar o `rejectCall` {@link rejectCall} + * + * @returns Objeto descartável para parar de ouvir */ public onIncomingCall(callback: (call: any) => any) { return this.registerEvent('onIncomingCall', callback); diff --git a/src/api/whatsapp.ts b/src/api/whatsapp.ts index 22e7f5e6e..317f5ad4f 100644 --- a/src/api/whatsapp.ts +++ b/src/api/whatsapp.ts @@ -225,4 +225,19 @@ export class Whatsapp extends BusinessLayer { const buff = Buffer.from(res.data, 'binary'); return magix(buff, message.mediaKey, message.type, message.size); } + + /** + * Rejeita uma ligação recebida pelo WhatsApp + * @param callId string ID da ligação, caso não passado, todas ligações serão rejeitadas + * @returns Número de ligações rejeitadas + */ + public async rejectCall(callId?: string) { + return await evaluateAndReturn( + this.page, + ({ callId }) => WAPI.rejectCall(callId), + { + callId, + } + ); + } } diff --git a/src/lib/wapi/functions/index.js b/src/lib/wapi/functions/index.js index c53c222ca..4ff2d354f 100644 --- a/src/lib/wapi/functions/index.js +++ b/src/lib/wapi/functions/index.js @@ -114,6 +114,7 @@ export { getListMute, interfaceMute } from './get-list-mute'; export { downloadMedia } from './download-media'; export * from './phoneWatchdog'; export * from './presence'; +export * from './reject-call'; export * from './set-group-description'; export * from './set-group-property'; export * from './set-group-subject'; diff --git a/src/lib/wapi/functions/reject-call.js b/src/lib/wapi/functions/reject-call.js new file mode 100644 index 000000000..2793dbca5 --- /dev/null +++ b/src/lib/wapi/functions/reject-call.js @@ -0,0 +1,68 @@ +/* + * This file is part of WPPConnect. + * + * WPPConnect is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * WPPConnect is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with WPPConnect. If not, see . + */ + +async function rejectCallByCallId(callId) { + const call = await Store.Call.get(callId); + + if (!call) { + throw { + error: true, + code: 'call_not_found', + message: 'Call not found', + }; + } + + if (call.getState() !== 'INCOMING_RING') { + throw { + error: true, + code: 'call_is_not_incoming_ring', + message: 'Call is not incoming ring', + }; + } + + return await Store.sendCallSignalingMsg({ + common: { + peer_jid: call.peerJid, + }, + payload: [ + 'reject', + { + 'call-id': call.id, + 'call-creator': call.peerJid.toString({ legacy: true }), + count: '0', + }, + null, + ], + }); +} + +export async function rejectCall(callId) { + if (callId) { + await rejectCallByCallId(callId); + return 1; + } + + const calls = Store.Call.models.filter( + (c) => c.getState() === 'INCOMING_RING' + ); + + for (const call of calls) { + await rejectCallByCallId(call.id).catch((e) => null); + } + + return calls.lenth; +} diff --git a/src/lib/wapi/store/store-objects.js b/src/lib/wapi/store/store-objects.js index 08cbd32d6..0d132c009 100644 --- a/src/lib/wapi/store/store-objects.js +++ b/src/lib/wapi/store/store-objects.js @@ -407,4 +407,8 @@ export const storeObjects = [ id: 'changeEphemeralDuration', conditions: (module) => module.changeEphemeralDuration, }, + { + id: 'sendCallSignalingMsg', + conditions: (module) => module.sendCallSignalingMsg, + }, ]; diff --git a/src/lib/wapi/wapi.js b/src/lib/wapi/wapi.js index 99a0d96df..22169fb86 100644 --- a/src/lib/wapi/wapi.js +++ b/src/lib/wapi/wapi.js @@ -127,6 +127,7 @@ import { subscribePresence, unsubscribePresence, getMessages, + rejectCall, } from './functions'; import { base64ToFile, @@ -358,6 +359,9 @@ if (typeof window.WAPI === 'undefined') { window.WAPI.getBusinessProfilesProducts = getBusinessProfilesProducts; window.WAPI.getOrderbyMsg = getOrderbyMsg; + // call functions + window.WAPI.rejectCall = rejectCall; + // Listeners initialization window.WAPI._newMessagesQueue = []; window.WAPI._newMessagesBuffer = diff --git a/src/types/WAPI.d.ts b/src/types/WAPI.d.ts index 4e90bb3f9..2a9bd00e0 100644 --- a/src/types/WAPI.d.ts +++ b/src/types/WAPI.d.ts @@ -134,6 +134,7 @@ interface WAPI { promoteParticipant: (groupId: string, contactId: string | string[]) => void; removeParticipant: (groupId: string, contactId: string | string[]) => void; reply: (to: string, content: string, quotedMsg: string) => Promise; + rejectCall: (callId?: string) => Promise; revokeGroupInviteLink: (chatId: string) => Promise; restartService: () => boolean; sendChatstate: (chatState: string, chatId: string) => void;