diff options
author | ikeblaster <ike@thez.info> | 2020-02-20 01:32:34 +0100 |
---|---|---|
committer | ikeblaster <ike@thez.info> | 2020-02-20 01:32:34 +0100 |
commit | 9137bfd8d560226146de1390e12db02aa63c1c31 (patch) | |
tree | 1d206714650da2ae51154919f20dcb9c25563a32 | |
parent | 335e9c37736b04411d79abb6bb5a62a1f7166c4a (diff) |
fixes #2224 (Facebook - each group chat message as a new conversation)
-rw-r--r-- | protocols/Facebook/src/proto.h | 4 | ||||
-rw-r--r-- | protocols/Facebook/src/server.cpp | 150 |
2 files changed, 97 insertions, 57 deletions
diff --git a/protocols/Facebook/src/proto.h b/protocols/Facebook/src/proto.h index 95be0e2696..2f6df655b3 100644 --- a/protocols/Facebook/src/proto.h +++ b/protocols/Facebook/src/proto.h @@ -460,7 +460,7 @@ class FacebookProto : public PROTO<FacebookProto> return m_users.find((FacebookUser *)&id); } - FacebookUser* UserFromJson(const JSONNode &root, CMStringW &wszId); + FacebookUser* UserFromJson(const JSONNode &root, CMStringW &wszId, bool &bIsChat); void FetchAttach(const CMStringA &mid, __int64 fbid, CMStringA &szBody); @@ -468,6 +468,8 @@ class FacebookProto : public PROTO<FacebookProto> void OnLoggedOut(); bool RefreshToken(); + FacebookUser* RefreshThread(JSONNode& n); + FacebookUser* RefreshThread(CMStringW& wszId); void RefreshThreads(); int RefreshContacts(); diff --git a/protocols/Facebook/src/server.cpp b/protocols/Facebook/src/server.cpp index 17f0ace5c9..27a3a5d229 100644 --- a/protocols/Facebook/src/server.cpp +++ b/protocols/Facebook/src/server.cpp @@ -93,14 +93,15 @@ FacebookUser* FacebookProto::AddContact(const CMStringW &wszId, bool bTemp) if (bTemp) Contact_RemoveFromList(hContact); - auto *ret = new FacebookUser(_wtoi64(wszId), hContact); + auto* ret = new FacebookUser(_wtoi64(wszId), hContact); + m_users.insert(ret); return ret; } -FacebookUser* FacebookProto::UserFromJson(const JSONNode &root, CMStringW &wszUserId) +FacebookUser* FacebookProto::UserFromJson(const JSONNode &root, CMStringW &wszUserId, bool &bIsChat) { - bool bIsChat = false; + bIsChat = false; wszUserId = root["threadKey"]["otherUserFbId"].as_mstring(); if (wszUserId.IsEmpty()) { // if only thread id is present, it must be a group chat @@ -185,6 +186,78 @@ int FacebookProto::RefreshContacts() return 0; } +FacebookUser* FacebookProto::RefreshThread(JSONNode& n) { + if (!n["is_group_thread"].as_bool()) + return nullptr; + + CMStringW chatId(n["thread_key"]["thread_fbid"].as_mstring()); + CMStringW name(n["name"].as_mstring()); + if (name.IsEmpty()) { + for (auto& u : n["all_participants"]["nodes"]) { + auto& ur = u["messaging_actor"]; + CMStringW userId(ur["id"].as_mstring()); + if (_wtoi64(userId) == m_uid) + continue; + + if (!name.IsEmpty()) + name.Append(L", "); + name += ur["name"].as_mstring(); + } + + if (name.GetLength() > 128) { + name.Truncate(125); + name.Append(L"..."); + } + } + + auto* si = Chat_NewSession(GCW_CHATROOM, m_szModuleName, chatId, name); + if (si == nullptr) + return nullptr; + + setWString(si->hContact, DBKEY_ID, chatId); + Chat_AddGroup(si, TranslateT("Participant")); + + for (auto& u : n["all_participants"]["nodes"]) { + auto& ur = u["messaging_actor"]; + CMStringW userId(ur["id"].as_mstring()); + CMStringW userName(ur["name"].as_mstring()); + + GCEVENT gce = { m_szModuleName, 0, GC_EVENT_JOIN }; + gce.pszID.w = chatId; + gce.pszUID.w = userId; + gce.pszNick.w = userName; + gce.bIsMe = _wtoi64(userId) == m_uid; + gce.time = time(0); + Chat_Event(&gce); + } + + Chat_Control(m_szModuleName, chatId, m_bHideGroupchats ? WINDOW_HIDDEN : SESSION_INITDONE); + Chat_Control(m_szModuleName, chatId, SESSION_ONLINE); + + auto* ret = new FacebookUser(_wtoi64(chatId), si->hContact, true); + m_users.insert(ret); + + return ret; +} + +FacebookUser* FacebookProto::RefreshThread(CMStringW& wszId) { + auto* pReq = CreateRequestGQL(FB_API_QUERY_THREAD); + + pReq << WCHAR_PARAM("query_params", CMStringW(FORMAT, L"{\"0\":[\"%s\"], \"12\":0, \"13\":\"false\"}", wszId.c_str())); + pReq->CalcSig(); + + JsonReply reply(ExecuteRequest(pReq)); + if (!reply.error()) { + auto& root = reply.data(); + + for (auto& n : root) { + return RefreshThread(n); + } + } + + return nullptr; +} + void FacebookProto::RefreshThreads() { auto * pReq = CreateRequestGQL(FB_API_QUERY_THREADS); @@ -197,54 +270,7 @@ void FacebookProto::RefreshThreads() auto &root = reply.data()["viewer"]["message_threads"]; for (auto &n : root["nodes"]) { - if (!n["is_group_thread"].as_bool()) - continue; - - CMStringW chatId(n["thread_key"]["thread_fbid"].as_mstring()); - CMStringW name(n["name"].as_mstring()); - if (name.IsEmpty()) { - for (auto &u : n["all_participants"]["nodes"]) { - auto &ur = u["messaging_actor"]; - CMStringW userId(ur["id"].as_mstring()); - if (_wtoi64(userId) == m_uid) - continue; - - if (!name.IsEmpty()) - name.Append(L", "); - name += ur["name"].as_mstring(); - } - - if (name.GetLength() > 128) { - name.Truncate(125); - name.Append(L"..."); - } - } - - auto *si = Chat_NewSession(GCW_CHATROOM, m_szModuleName, chatId, name); - if (si == nullptr) - continue; - - setWString(si->hContact, DBKEY_ID, chatId); - Chat_AddGroup(si, TranslateT("Participant")); - - for (auto &u : n["all_participants"]["nodes"]) { - auto &ur = u["messaging_actor"]; - CMStringW userId(ur["id"].as_mstring()); - CMStringW userName(ur["name"].as_mstring()); - - GCEVENT gce = { m_szModuleName, 0, GC_EVENT_JOIN }; - gce.pszID.w = chatId; - gce.pszUID.w = userId; - gce.pszNick.w = userName; - gce.bIsMe = _wtoi64(userId) == m_uid; - gce.time = time(0); - Chat_Event(&gce); - } - - Chat_Control(m_szModuleName, chatId, m_bHideGroupchats ? WINDOW_HIDDEN : SESSION_INITDONE); - Chat_Control(m_szModuleName, chatId, SESSION_ONLINE); - - m_users.insert(new FacebookUser(_wtoi64(chatId), si->hContact, true)); + RefreshThread(n); } } } @@ -580,9 +606,17 @@ void FacebookProto::OnPublishPrivateMessage(const JSONNode &root) } CMStringW wszUserId; - auto *pUser = UserFromJson(metadata, wszUserId); - if (pUser == nullptr) - pUser = AddContact(wszUserId); + bool bIsChat; + auto *pUser = UserFromJson(metadata, wszUserId, bIsChat); + if (pUser == nullptr) { + if (bIsChat) + pUser = RefreshThread(wszUserId); + else + pUser = AddContact(wszUserId, true); + } + else if (bIsChat && Chat_GetUserInfo(m_szModuleName, wszUserId) == nullptr) // user already exists, but room is not initialized + pUser = RefreshThread(wszUserId); + for (auto &it : metadata["tags"]) { auto *szTagName = it.name(); @@ -735,6 +769,8 @@ void FacebookProto::OnPublishPrivateMessage(const JSONNode &root) szBody.Replace("%", "%%"); ptrW wszText(mir_utf8decodeW(szBody)); + // TODO: GC_EVENT_JOIN for chat participants which are missing (for example added later during group chat) + GCEVENT gce = { m_szModuleName, 0, GC_EVENT_MESSAGE }; gce.pszID.w = wszUserId; gce.dwFlags = GCEF_ADDTOLOG; @@ -763,7 +799,8 @@ void FacebookProto::OnPublishPrivateMessage(const JSONNode &root) void FacebookProto::OnPublishReadReceipt(const JSONNode &root) { CMStringW wszUserId; - auto *pUser = UserFromJson(root, wszUserId); + bool bIsChat; + auto *pUser = UserFromJson(root, wszUserId, bIsChat); if (pUser == nullptr) { debugLogA("Message from unknown contact %S, ignored", wszUserId.c_str()); return; @@ -792,7 +829,8 @@ void FacebookProto::OnPublishSentMessage(const JSONNode &root) std::string szId(metadata["messageId"].as_string()); CMStringW wszUserId; - auto *pUser = UserFromJson(metadata, wszUserId); + bool bIsChat; + auto *pUser = UserFromJson(metadata, wszUserId, bIsChat); if (pUser == nullptr) { debugLogA("Message from unknown contact %s, ignored", wszUserId.c_str()); return; |