diff --git a/goneonize/main.go b/goneonize/main.go index 0fd08ef7..bffe089e 100644 --- a/goneonize/main.go +++ b/goneonize/main.go @@ -1408,6 +1408,22 @@ func SetGroupName(id *C.char, JIDByte *C.uchar, JIDSize C.int, name *C.char) *C. return C.CString("") } +//export RejectCall +func RejectCall(id *C.char, JIDByte *C.uchar, JIDSize C.int, callID *C.char) *C.char { + jidbyte := getByteByAddr(JIDByte, JIDSize) + var neoJIDProto defproto.JID + err := proto.Unmarshal(jidbyte, &neoJIDProto) + if err != nil { + return C.CString(err.Error()) + } + // callFrom is the caller's JID (the CallOffer creator); whatsmeow addresses the to it. + status_err := clients[C.GoString(id)].RejectCall(context.Background(), utils.DecodeJidProto(&neoJIDProto), C.GoString(callID)) + if status_err != nil { + return C.CString(status_err.Error()) + } + return C.CString("") +} + //export SetGroupPhoto func SetGroupPhoto(id *C.char, JIDByte *C.uchar, JIDSize C.int, Photo *C.uchar, PhotoSize C.int) *C.struct_BytesReturn { var neoJIDProto defproto.JID diff --git a/neonize/_binder.py b/neonize/_binder.py index 4a10beda..bea6950a 100644 --- a/neonize/_binder.py +++ b/neonize/_binder.py @@ -200,6 +200,13 @@ def _to_c_struct(self) -> "_CProxySettings": ctypes.c_char_p, ] gocode.SetGroupName.restype = ctypes.c_void_p + gocode.RejectCall.argtypes = [ + ctypes.c_char_p, + ctypes.c_char_p, + ctypes.c_int, + ctypes.c_char_p, + ] + gocode.RejectCall.restype = ctypes.c_void_p gocode.GetGroupInviteLink.argtypes = [ ctypes.c_char_p, ctypes.c_char_p, @@ -612,6 +619,7 @@ def consume_cstring(result, func, arguments): "Neonize", "LeaveGroup", "SetGroupName", + "RejectCall", "SendChatPresence", "GenerateMessageID", "FollowNewsletter", diff --git a/neonize/aioze/client.py b/neonize/aioze/client.py index a5f7940a..73f680f6 100644 --- a/neonize/aioze/client.py +++ b/neonize/aioze/client.py @@ -823,6 +823,30 @@ async def revoke_message(self, chat: JID, sender: JID, message_id: str) -> SendR """ return await self.send_message(chat, await self.build_revoke(chat, sender, message_id)) + async def reject_call(self, call_from: JID, call_id: str) -> str: + """Reject (decline) an incoming call. + + Wraps whatsmeow's ``Client.RejectCall``: the call is terminated on the same + connection that received the offer. ``call_from`` must be the caller's JID + exactly as delivered in the CallOffer (a phone-number or a hosted ``@lid`` JID). + + :param call_from: JID of the caller (the CallOffer creator). + :type call_from: JID + :param call_id: The call id (CallOffer id). + :type call_id: str + :return: An empty string on success, otherwise the error text. + :rtype: str + """ + jidbuf = call_from.SerializeToString() + return ( + await self.__client.RejectCall( + self.uuid, + jidbuf, + len(jidbuf), + ctypes.create_string_buffer(call_id.encode()), + ) + ).decode() + async def build_poll_vote_creation( self, name: str, diff --git a/neonize/client.py b/neonize/client.py index 8dc105b5..411be373 100644 --- a/neonize/client.py +++ b/neonize/client.py @@ -764,6 +764,25 @@ def revoke_message(self, chat: JID, sender: JID, message_id: str) -> SendRespons """ return self.send_message(chat, self.build_revoke(chat, sender, message_id)) + def reject_call(self, call_from: JID, call_id: str) -> str: + """Reject (decline) an incoming call. + + Wraps whatsmeow's ``Client.RejectCall``: the call is terminated on the same + connection that received the offer. ``call_from`` must be the caller's JID + exactly as delivered in the CallOffer (a phone-number or a hosted ``@lid`` JID). + + :param call_from: JID of the caller (the CallOffer creator). + :type call_from: JID + :param call_id: The call id (CallOffer id). + :type call_id: str + :return: An empty string on success, otherwise the error text. + :rtype: str + """ + jidbuf = call_from.SerializeToString() + return self.__client.RejectCall( + self.uuid, jidbuf, len(jidbuf), ctypes.create_string_buffer(call_id.encode()) + ).decode() + def build_poll_vote_creation( self, name: str,