diff options
| author | George Hazan <ghazan@miranda.im> | 2022-10-23 13:01:28 +0300 | 
|---|---|---|
| committer | George Hazan <ghazan@miranda.im> | 2022-10-23 13:01:28 +0300 | 
| commit | 8834935d6dbfd190b0a39ac8f30cce571f08750e (patch) | |
| tree | d04ee1d79df3b535aa5b502b18933cd77c0ff467 /protocols | |
| parent | ee4c113c7ce309a92b39e2d8f9fcb8c73877aa65 (diff) | |
WhatsApp: sending acks & read receipts
Diffstat (limited to 'protocols')
| -rw-r--r-- | protocols/WhatsApp/src/appsync.cpp | 1 | ||||
| -rw-r--r-- | protocols/WhatsApp/src/iq.cpp | 35 | ||||
| -rw-r--r-- | protocols/WhatsApp/src/main.cpp | 12 | ||||
| -rw-r--r-- | protocols/WhatsApp/src/message.cpp | 8 | ||||
| -rw-r--r-- | protocols/WhatsApp/src/proto.h | 6 | ||||
| -rw-r--r-- | protocols/WhatsApp/src/server.cpp | 17 | ||||
| -rw-r--r-- | protocols/WhatsApp/src/stdafx.h | 1 | 
7 files changed, 78 insertions, 2 deletions
diff --git a/protocols/WhatsApp/src/appsync.cpp b/protocols/WhatsApp/src/appsync.cpp index 9785dbff65..3659917ea2 100644 --- a/protocols/WhatsApp/src/appsync.cpp +++ b/protocols/WhatsApp/src/appsync.cpp @@ -46,6 +46,7 @@ void WhatsAppProto::OnServerSync(const WANode &node)  			task.insert(new WACollection(it->getAttr("name"), it->getAttrInt("version")));  	ResyncServer(task); +	SendAck(node);  }  void WhatsAppProto::ResyncAll() diff --git a/protocols/WhatsApp/src/iq.cpp b/protocols/WhatsApp/src/iq.cpp index 258b466ac3..063a71264c 100644 --- a/protocols/WhatsApp/src/iq.cpp +++ b/protocols/WhatsApp/src/iq.cpp @@ -14,6 +14,8 @@ void WhatsAppProto::OnAccountSync(const WANode &node)  	for (auto &it : node.getChild("devices")->getChildren())  		if (it->title == "device")  			m_arDevices.insert(new WADevice(it->getAttr("jid"), it->getAttrInt("key-index"))); + +	SendAck(node);  }  ///////////////////////////////////////////////////////////////////////////////////////// @@ -84,6 +86,7 @@ void WhatsAppProto::OnNotifyDevices(const WANode &node)  {  	if (!mir_strcmp(node.getAttr("jid"), m_szJid))  		debugLogA("received list of my own devices"); +	SendAck(node);  }  ///////////////////////////////////////////////////////////////////////////////////////// @@ -92,6 +95,7 @@ void WhatsAppProto::OnNotifyEncrypt(const WANode &node)  {  	if (!mir_strcmp(node.getAttr("from"), S_WHATSAPP_NET))  		OnIqCountPrekeys(node); +	SendAck(node);  }  ///////////////////////////////////////////////////////////////////////////////////////// @@ -119,6 +123,36 @@ void WhatsAppProto::OnReceiveInfo(const WANode &node)  ///////////////////////////////////////////////////////////////////////////////////////// +void WhatsAppProto::ProcessReceipt(MCONTACT hContact, const char *msgId, bool bRead) +{ +	MEVENT hEvent = db_event_getById(m_szModuleName, msgId); +	if (hEvent == 0) +		return; + +	if (g_plugin.bHasMessageState) +		CallService(MS_MESSAGESTATE_UPDATE, hContact, bRead ? MRD_TYPE_READ : MRD_TYPE_DELIVERED); + +	if (bRead) +		db_event_markRead(hContact, hEvent); +} + +void WhatsAppProto::OnReceiveReceipt(const WANode &node) +{ +	if (auto *pUser = FindUser(node.getAttr("from"))) { +		bool bRead = mir_strcmp(node.getAttr("type"), "read") == 0; +		ProcessReceipt(pUser->hContact, node.getAttr("id"), bRead); + +		if (auto *pList = node.getChild("list")) +			for (auto &it : pList->getChildren()) +				if (it->title == "item") +					ProcessReceipt(pUser->hContact, it->getAttr("id"), bRead); +	} + +	SendAck(node); +} + +///////////////////////////////////////////////////////////////////////////////////////// +  void WhatsAppProto::OnStreamError(const WANode &node)  {  	m_bTerminated = true; @@ -436,6 +470,7 @@ void WhatsAppProto::InitPersistentHandlers()  	m_arPersistent.insert(new WAPersistentHandler("ib", 0, 0, 0, &WhatsAppProto::OnReceiveInfo));  	m_arPersistent.insert(new WAPersistentHandler("message", 0, 0, 0, &WhatsAppProto::OnReceiveMessage)); +	m_arPersistent.insert(new WAPersistentHandler("receipt", 0, 0, 0, &WhatsAppProto::OnReceiveReceipt));  	m_arPersistent.insert(new WAPersistentHandler("stream:error", 0, 0, 0, &WhatsAppProto::OnStreamError));  	m_arPersistent.insert(new WAPersistentHandler("success", 0, 0, 0, &WhatsAppProto::OnSuccess)); diff --git a/protocols/WhatsApp/src/main.cpp b/protocols/WhatsApp/src/main.cpp index ffd3766719..99bf1e37f8 100644 --- a/protocols/WhatsApp/src/main.cpp +++ b/protocols/WhatsApp/src/main.cpp @@ -45,11 +45,19 @@ CMPlugin::CMPlugin() :  /////////////////////////////////////////////////////////////////////////////////////////  // Load +static int OnPluginLoaded(WPARAM, LPARAM) +{ +	g_plugin.bHasMessageState = ServiceExists(MS_MESSAGESTATE_UPDATE); +	return 0; +} +  int CMPlugin::Load()  { -	// InitIcons(); -	// InitContactMenus(); +	HookEvent(ME_SYSTEM_MODULELOAD, OnPluginLoaded); +	HookEvent(ME_SYSTEM_MODULEUNLOAD, OnPluginLoaded); +	OnPluginLoaded(0, 0); +	// special netlib user for reading avatars, blobs etc via HTTP protocol  	NETLIBUSER nlu = {};  	nlu.flags = NUF_INCOMING | NUF_OUTGOING | NUF_HTTPCONNS | NUF_UNICODE;  	nlu.szSettingsModule = "WhatsApp"; diff --git a/protocols/WhatsApp/src/message.cpp b/protocols/WhatsApp/src/message.cpp index 1952e57fc4..abaaa89faf 100644 --- a/protocols/WhatsApp/src/message.cpp +++ b/protocols/WhatsApp/src/message.cpp @@ -21,6 +21,14 @@ void WhatsAppProto::OnReceiveMessage(const WANode &node)  		return;  	} +	MEVENT hEvent = db_event_getById(m_szModuleName, msgId); +	if (hEvent) { +		debugLogA("this message is already processed: %s", msgId); +		return; +	} + +	SendAck(node); +  	WAMSG type;  	WAJid jid(msgFrom);  	CMStringA szAuthor, szChatId; diff --git a/protocols/WhatsApp/src/proto.h b/protocols/WhatsApp/src/proto.h index a5b6a60f57..35200ad61e 100644 --- a/protocols/WhatsApp/src/proto.h +++ b/protocols/WhatsApp/src/proto.h @@ -305,6 +305,8 @@ class WhatsAppProto : public PROTO<WhatsAppProto>  	CMStringA GenerateMessageId();  	void ProcessMessage(WAMSG type, const proto::WebMessageInfo &msg); +	void ProcessReceipt(MCONTACT hContact, const char *msgId, bool bRead); +  	bool WSReadPacket(const WSHeader &hdr, MBinBuffer &buf);  	int  WSSend(const MessageLite &msg);  	int  WSSendNode(WANode &node, WA_PKT_HANDLER = nullptr); @@ -317,6 +319,7 @@ class WhatsAppProto : public PROTO<WhatsAppProto>  	void ServerThreadWorker(void);  	void ShutdownSession(void); +	void SendAck(const WANode &node);  	void SendReceipt(const char *pszTo, const char *pszParticipant, const char *pszId, const char *pszType);  	void SendKeepAlive();  	void SetServerStatus(int iStatus); @@ -350,6 +353,7 @@ class WhatsAppProto : public PROTO<WhatsAppProto>  	void OnNotifyEncrypt(const WANode &node);  	void OnReceiveInfo(const WANode &node);  	void OnReceiveMessage(const WANode &node); +	void OnReceiveReceipt(const WANode &node);  	void OnServerSync(const WANode &node);  	void OnStreamError(const WANode &node);  	void OnSuccess(const WANode &node); @@ -426,6 +430,8 @@ struct CMPlugin : public ACCPROTOPLUGIN<WhatsAppProto>  	HNETLIBCONN hAvatarConn = nullptr;  	bool SaveFile(const char *pszUrl, PROTO_AVATAR_INFORMATION &ai); +	bool bHasMessageState = false; +  	CMPlugin();  	int Load() override; diff --git a/protocols/WhatsApp/src/server.cpp b/protocols/WhatsApp/src/server.cpp index efe293c5b0..f5590a4e77 100644 --- a/protocols/WhatsApp/src/server.cpp +++ b/protocols/WhatsApp/src/server.cpp @@ -262,6 +262,23 @@ void WhatsAppProto::OnLoggedOut(void)  	setAllContactStatuses(ID_STATUS_OFFLINE, false);  } +///////////////////////////////////////////////////////////////////////////////////////// +// Service packets sending + +void WhatsAppProto::SendAck(const WANode &node) +{ +	WANode ack("ack"); +	ack << CHAR_PARAM("to", node.getAttr("from")) << CHAR_PARAM("id", node.getAttr("id")) << CHAR_PARAM("class", node.title); +	if (node.title != "message") +		if (auto *param = node.getAttr("type")) +			ack << CHAR_PARAM("type", param); +	if (auto *param = node.getAttr("participant")) +		ack << CHAR_PARAM("participant", param); +	if (auto *param = node.getAttr("recipient")) +		ack << CHAR_PARAM("recipient", param); +	WSSendNode(ack); +} +  void WhatsAppProto::SendKeepAlive()  {  	time_t now = time(0); diff --git a/protocols/WhatsApp/src/stdafx.h b/protocols/WhatsApp/src/stdafx.h index 80d130a5ec..73fc82d435 100644 --- a/protocols/WhatsApp/src/stdafx.h +++ b/protocols/WhatsApp/src/stdafx.h @@ -46,6 +46,7 @@ Copyright © 2019-22 George Hazan  #include <m_folders.h>  #include <m_json.h>  #include <m_gui.h> +#include <m_messagestate.h>  #include <openssl/evp.h>  #include <openssl/hmac.h>  | 
