summaryrefslogtreecommitdiff
path: root/protocols/Facebook/src/server.cpp
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2021-05-15 20:24:46 +0300
committerGeorge Hazan <ghazan@miranda.im>2021-05-15 20:24:46 +0300
commit73aeb6a522d433953f936a24ee0f98cf17e5fcbc (patch)
tree55688e402f286e08463c9048d814469187d000ce /protocols/Facebook/src/server.cpp
parentd3e9d8a3be07d9d644b7240ed33ce957145e9756 (diff)
Facebook: fix for reading more than 500 contacts from Friends list
Diffstat (limited to 'protocols/Facebook/src/server.cpp')
-rw-r--r--protocols/Facebook/src/server.cpp134
1 files changed, 79 insertions, 55 deletions
diff --git a/protocols/Facebook/src/server.cpp b/protocols/Facebook/src/server.cpp
index eee0b7bddf..2b80a4bcae 100644
--- a/protocols/Facebook/src/server.cpp
+++ b/protocols/Facebook/src/server.cpp
@@ -130,69 +130,93 @@ FacebookUser* FacebookProto::UserFromJson(const JSONNode &root, CMStringW &wszUs
int FacebookProto::RefreshContacts()
{
- auto *pReq = CreateRequestGQL(FB_API_QUERY_CONTACTS);
- pReq->flags |= NLHRF_NODUMPSEND;
- pReq << CHAR_PARAM("query_params", "{\"0\":[\"user\"],\"1\":\"" FB_API_CONTACTS_COUNT "\"}");
- pReq->CalcSig();
+ CMStringA szCursor;
+ bool bNeedUpdate = false;
- JsonReply reply(ExecuteRequest(pReq));
- if (int iErrorCode = reply.error())
- return iErrorCode; // unknown error
+ while (true) {
+ JSONNode root; root << CHAR_PARAM("0", "user");
- bool bNeedUpdate = false;
- bool bLoadAll = m_bLoadAll;
-
- for (auto &it : reply.data()["viewer"]["messenger_contacts"]["nodes"]) {
- auto &n = it["represented_profile"];
- CMStringW wszId(n["id"].as_mstring());
- __int64 id = _wtoi64(wszId);
-
- MCONTACT hContact;
- if (id != m_uid) {
- bool bIsFriend = bLoadAll || n["friendship_status"].as_mstring() == L"ARE_FRIENDS";
-
- auto *pUser = FindUser(id);
- if (pUser == nullptr) {
- if (!bIsFriend)
- continue;
- pUser = AddContact(wszId, false);
- }
- else if (!bIsFriend)
- Contact_RemoveFromList(pUser->hContact); // adios!
+ AsyncHttpRequest *pReq;
+ pReq->flags |= NLHRF_NODUMPSEND;
- hContact = pUser->hContact;
+ if (szCursor.IsEmpty()) {
+ pReq = CreateRequestGQL(FB_API_QUERY_CONTACTS);
+ root << INT_PARAM("1", FB_API_CONTACTS_COUNT);
}
- else hContact = 0;
-
- if (auto &nName = it["structured_name"]) {
- CMStringW wszName(nName["text"].as_mstring());
- setWString(hContact, DBKEY_NICK, wszName);
- for (auto &nn : nName["parts"]) {
- CMStringW wszPart(nn["part"].as_mstring());
- int offset = nn["offset"].as_int(), length = nn["length"].as_int();
- if (wszPart == L"first")
- setWString(hContact, "FirstName", wszName.Mid(offset, length));
- else if (wszPart == L"last")
- setWString(hContact, "LastName", wszName.Mid(offset, length));
- }
+ else {
+ pReq = CreateRequestGQL(FB_API_QUERY_CONTACTS_AFTER);
+ root << CHAR_PARAM("1", szCursor) << INT_PARAM("2", FB_API_CONTACTS_COUNT);
}
+ pReq << CHAR_PARAM("query_params", root.write().c_str());
+ pReq->CalcSig();
- if (auto &nBirth = n["birthdate"]) {
- setDword(hContact, "BirthDay", nBirth["day"].as_int());
- setDword(hContact, "BirthMonth", nBirth["month"].as_int());
- }
+ JsonReply reply(ExecuteRequest(pReq));
+ if (int iErrorCode = reply.error())
+ return iErrorCode; // unknown error
+
+ bool bLoadAll = m_bLoadAll;
+ auto &data = reply.data()["viewer"]["messenger_contacts"];
+
+ for (auto &it : data["nodes"]) {
+ auto &n = it["represented_profile"];
+ CMStringW wszId(n["id"].as_mstring());
+ __int64 id = _wtoi64(wszId);
+
+ MCONTACT hContact;
+ if (id != m_uid) {
+ bool bIsFriend = bLoadAll || n["friendship_status"].as_mstring() == L"ARE_FRIENDS";
+
+ auto *pUser = FindUser(id);
+ if (pUser == nullptr) {
+ if (!bIsFriend)
+ continue;
+ pUser = AddContact(wszId, false);
+ }
+ else if (!bIsFriend)
+ Contact_RemoveFromList(pUser->hContact); // adios!
- if (auto &nCity = n["current_city"])
- setWString(hContact, "City", nCity["name"].as_mstring());
+ hContact = pUser->hContact;
+ }
+ else hContact = 0;
+
+ if (auto &nName = it["structured_name"]) {
+ CMStringW wszName(nName["text"].as_mstring());
+ setWString(hContact, DBKEY_NICK, wszName);
+ for (auto &nn : nName["parts"]) {
+ CMStringW wszPart(nn["part"].as_mstring());
+ int offset = nn["offset"].as_int(), length = nn["length"].as_int();
+ if (wszPart == L"first")
+ setWString(hContact, "FirstName", wszName.Mid(offset, length));
+ else if (wszPart == L"last")
+ setWString(hContact, "LastName", wszName.Mid(offset, length));
+ }
+ }
+
+ if (auto &nBirth = n["birthdate"]) {
+ setDword(hContact, "BirthDay", nBirth["day"].as_int());
+ setDword(hContact, "BirthMonth", nBirth["month"].as_int());
+ }
+
+ if (auto &nCity = n["current_city"])
+ setWString(hContact, "City", nCity["name"].as_mstring());
- if (auto &nAva = it[(m_bUseBigAvatars) ? "hugePictureUrl" : "bigPictureUrl"]) {
- CMStringW wszOldUrl(getMStringW(hContact, DBKEY_AVATAR)), wszNewUrl(nAva["uri"].as_mstring());
- if (wszOldUrl != wszNewUrl) {
- bNeedUpdate = true;
- setByte(hContact, "UpdateNeeded", 1);
- setWString(hContact, DBKEY_AVATAR, wszNewUrl);
+ if (auto &nAva = it[(m_bUseBigAvatars) ? "hugePictureUrl" : "bigPictureUrl"]) {
+ CMStringW wszOldUrl(getMStringW(hContact, DBKEY_AVATAR)), wszNewUrl(nAva["uri"].as_mstring());
+ if (wszOldUrl != wszNewUrl) {
+ bNeedUpdate = true;
+ setByte(hContact, "UpdateNeeded", 1);
+ setWString(hContact, DBKEY_AVATAR, wszNewUrl);
+ }
}
}
+
+ if (!data["page_info"]["has_next_page"].as_bool()) {
+ debugLogA("Got no next page, exiting", szCursor.c_str());
+ break;
+ }
+
+ szCursor = data["page_info"]["end_cursor"].as_mstring();
+ debugLogA("Got cursor: %s", szCursor.c_str());
}
if (bNeedUpdate)
@@ -203,7 +227,8 @@ int FacebookProto::RefreshContacts()
bool FacebookProto::RefreshSid()
{
auto *pReq = CreateRequestGQL(FB_API_QUERY_SEQ_ID);
- pReq << CHAR_PARAM("query_params", "{\"1\":\"0\"}");
+ JSONNode root; root << CHAR_PARAM("1", "0");
+ pReq << CHAR_PARAM("query_params", root.write().c_str());
pReq->CalcSig();
JsonReply reply(ExecuteRequest(pReq));
@@ -286,7 +311,6 @@ FacebookUser* FacebookProto::RefreshThread(JSONNode &n)
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();