summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2022-10-27 18:57:02 +0300
committerGeorge Hazan <ghazan@miranda.im>2022-10-27 18:57:02 +0300
commit382f44ca43fb631be7ba14adb9f643ef99f4c2d3 (patch)
tree3f7f76c964c8905ea0daaae4cbde9422940ba6b8
parentcf060f6cb5fe153912bb8889c628c6087715e8ef (diff)
WhatsApp: contacts' avatar fetching
-rw-r--r--protocols/WhatsApp/src/avatars.cpp43
-rw-r--r--protocols/WhatsApp/src/iq.cpp8
-rw-r--r--protocols/WhatsApp/src/proto.h4
3 files changed, 38 insertions, 17 deletions
diff --git a/protocols/WhatsApp/src/avatars.cpp b/protocols/WhatsApp/src/avatars.cpp
index f7f97de7ea..d2eda4014a 100644
--- a/protocols/WhatsApp/src/avatars.cpp
+++ b/protocols/WhatsApp/src/avatars.cpp
@@ -7,45 +7,47 @@ Copyright © 2019-22 George Hazan
#include "stdafx.h"
-void WhatsAppProto::OnGetAvatarInfo(const JSONNode &root, void *pUserInfo)
+void WhatsAppProto::OnIqGetAvatar(const WANode &node)
{
- if (!root) return;
-
- MCONTACT hContact = (UINT_PTR)pUserInfo;
+ auto *pUser = FindUser(node.getAttr("from"));
+ if (pUser == nullptr)
+ return;
PROTO_AVATAR_INFORMATION ai = {};
- ai.hContact = hContact;
+ ai.hContact = pUser->hContact;
ai.format = PA_FORMAT_JPEG;
- wcsncpy_s(ai.filename, GetAvatarFileName(hContact), _TRUNCATE);
+ wcsncpy_s(ai.filename, GetAvatarFileName(pUser->hContact), _TRUNCATE);
- DWORD dwLastChangeTime = _wtoi(root["tag"].as_mstring());
+ auto *pNode = node.getChild("picture");
- CMStringA szUrl(root["eurl"].as_mstring());
+ DWORD dwLastChangeTime = pNode->getAttrInt("id");
+
+ CMStringA szUrl(pNode->getAttr("url"));
if (szUrl.IsEmpty()) {
- setDword(hContact, DBKEY_AVATAR_TAG, 0); // avatar doesn't exist, don't check it later
+ setDword(pUser->hContact, DBKEY_AVATAR_TAG, 0); // avatar doesn't exist, don't check it later
LBL_Error:
- ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_FAILED, HANDLE(&ai));
+ ProtoBroadcastAck(pUser->hContact, ACKTYPE_AVATAR, ACKRESULT_FAILED, HANDLE(&ai));
return;
}
// if avatar was changed or not present at all, download it
- if (dwLastChangeTime > getDword(hContact, DBKEY_AVATAR_TAG)) {
+ if (dwLastChangeTime > getDword(pUser->hContact, DBKEY_AVATAR_TAG)) {
if (!g_plugin.SaveFile(szUrl, ai))
goto LBL_Error;
// set timestamp of avatar being saved
- setDword(hContact, DBKEY_AVATAR_TAG, dwLastChangeTime);
+ setDword(pUser->hContact, DBKEY_AVATAR_TAG, dwLastChangeTime);
}
- ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, HANDLE(&ai));
+ ProtoBroadcastAck(pUser->hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, HANDLE(&ai));
}
INT_PTR WhatsAppProto::GetAvatarInfo(WPARAM wParam, LPARAM lParam)
{
PROTO_AVATAR_INFORMATION *pai = (PROTO_AVATAR_INFORMATION*)lParam;
- ptrA id(getStringA(pai->hContact, isChatRoom(pai->hContact) ? "ChatRoomID" : DBKEY_ID));
- if (id == NULL)
+ ptrA jid(getStringA(pai->hContact, isChatRoom(pai->hContact) ? "ChatRoomID" : DBKEY_ID));
+ if (jid == NULL)
return GAIR_NOAVATAR;
CMStringW tszFileName(GetAvatarFileName(pai->hContact));
@@ -55,7 +57,7 @@ INT_PTR WhatsAppProto::GetAvatarInfo(WPARAM wParam, LPARAM lParam)
DWORD dwTag = getDword(pai->hContact, DBKEY_AVATAR_TAG, -1);
if (dwTag == -1 || (wParam & GAIF_FORCE) != 0)
if (pai->hContact != NULL && isOnline()) {
- // WSSend(CMStringA(FORMAT, "[\"query\",\"ProfilePicThumb\",\"%s\"]", id.get()), &WhatsAppProto::OnGetAvatarInfo, (void*)pai->hContact);
+ ServerFetchAvatar(jid);
return GAIR_WAITFOR;
}
@@ -117,6 +119,15 @@ INT_PTR WhatsAppProto::SetMyAvatar(WPARAM, LPARAM)
/////////////////////////////////////////////////////////////////////////////////////////
+void WhatsAppProto::ServerFetchAvatar(const char *jid)
+{
+ WANodeIq iq(IQ::GET, "w:profile:picture", jid);
+ *iq.addChild("picture") << CHAR_PARAM("type", "preview") << CHAR_PARAM("query", "url");
+ WSSendNode(iq, &WhatsAppProto::OnIqGetAvatar);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
bool CMPlugin::SaveFile(const char *pszUrl, PROTO_AVATAR_INFORMATION &ai)
{
NETLIBHTTPREQUEST req = {};
diff --git a/protocols/WhatsApp/src/iq.cpp b/protocols/WhatsApp/src/iq.cpp
index 207fa8bd80..f2a8fce306 100644
--- a/protocols/WhatsApp/src/iq.cpp
+++ b/protocols/WhatsApp/src/iq.cpp
@@ -269,6 +269,13 @@ void WhatsAppProto::OnNotifyEncrypt(const WANode &node)
/////////////////////////////////////////////////////////////////////////////////////////
+void WhatsAppProto::OnNotifyPicture(const WANode &node)
+{
+ SendAck(node);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
void WhatsAppProto::OnProcessHandshake(const uint8_t *pData, int cbLen)
{
proto::HandshakeMessage msg(pData, cbLen);
@@ -508,6 +515,7 @@ void WhatsAppProto::InitPersistentHandlers()
m_arPersistent.insert(new WAPersistentHandler("notification", "devices", 0, 0, &WhatsAppProto::OnNotifyDevices));
m_arPersistent.insert(new WAPersistentHandler("notification", "encrypt", 0, 0, &WhatsAppProto::OnNotifyEncrypt));
+ m_arPersistent.insert(new WAPersistentHandler("notification", "picture", 0, 0, &WhatsAppProto::OnNotifyPicture));
m_arPersistent.insert(new WAPersistentHandler("notification", "account_sync", 0, 0, &WhatsAppProto::OnAccountSync));
m_arPersistent.insert(new WAPersistentHandler("notification", "server_sync", 0, 0, &WhatsAppProto::OnServerSync));
m_arPersistent.insert(new WAPersistentHandler("notification", 0, 0, 0, &WhatsAppProto::OnNotifyAny));
diff --git a/protocols/WhatsApp/src/proto.h b/protocols/WhatsApp/src/proto.h
index 4a4ca4676c..db86428a28 100644
--- a/protocols/WhatsApp/src/proto.h
+++ b/protocols/WhatsApp/src/proto.h
@@ -331,7 +331,6 @@ class WhatsAppProto : public PROTO<WhatsAppProto>
/// Request handlers ///////////////////////////////////////////////////////////////////
- void OnGetAvatarInfo(const JSONNode &node, void*);
void OnGetChatInfo(const JSONNode &node, void*);
void OnProcessHandshake(const uint8_t *pData, int cbLen);
@@ -341,6 +340,7 @@ class WhatsAppProto : public PROTO<WhatsAppProto>
void OnIqBlockList(const WANode &node);
void OnIqCountPrekeys(const WANode &node);
void OnIqDoNothing(const WANode &node);
+ void OnIqGetAvatar(const WANode &node);
void OnIqGetUsync(const WANode &node);
void OnIqPairDevice(const WANode &node);
void OnIqPairSuccess(const WANode &node);
@@ -349,6 +349,7 @@ class WhatsAppProto : public PROTO<WhatsAppProto>
void OnNotifyAny(const WANode &node);
void OnNotifyDevices(const WANode &node);
void OnNotifyEncrypt(const WANode &node);
+ void OnNotifyPicture(const WANode &node);
void OnReceiveAck(const WANode &node);
void OnReceiveChatState(const WANode &node);
void OnReceiveInfo(const WANode &node);
@@ -369,6 +370,7 @@ class WhatsAppProto : public PROTO<WhatsAppProto>
/// Avatars ////////////////////////////////////////////////////////////////////////////
CMStringW GetAvatarFileName(MCONTACT hContact);
+ void ServerFetchAvatar(const char *jid);
INT_PTR __cdecl GetAvatarInfo(WPARAM, LPARAM);
INT_PTR __cdecl GetAvatarCaps(WPARAM, LPARAM);