From 42f6d47af11bb7af26cbd9a45b1d2d293f9fae4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20P=C3=B6sel?= Date: Sun, 10 Dec 2017 11:38:21 +0100 Subject: Wip - Fix receiving messages attachments --- protocols/FacebookRM/src/json.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/protocols/FacebookRM/src/json.cpp b/protocols/FacebookRM/src/json.cpp index 2deb45172f..0495cdaaeb 100644 --- a/protocols/FacebookRM/src/json.cpp +++ b/protocols/FacebookRM/src/json.cpp @@ -282,6 +282,11 @@ void parseAttachments(FacebookProto *proto, std::string *message_text, const JSO for (auto itAttachment = attachments_.begin(); itAttachment != attachments_.end(); ++itAttachment) { const JSONNode &attach_ = legacy ? (*itAttachment) : (*itAttachment)["mercury"]; + // FIXME: FB now doesn't have single "attach_type" node that we can check, but it's separated in different nodes. So we must check existence of different nodes for different types of attachments (or iterate over all existing nodes and check if some attachment node exists) + const JSONNode sticker_ = attach_["sticker_attachment"]; + const JSONNode blob_ = attach_["blob_attachment"]; + const JSONNode todo_ = attach_["todo"]; + type = attach_["attach_type"].as_string(); // "sticker", "photo", "file", "share", "animated_image", "video" if (type == "photo") { -- cgit v1.2.3 From f6c14ec9ec02d5eec251f20463aeb2e091978cd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20P=C3=B6sel?= Date: Sun, 10 Dec 2017 11:38:39 +0100 Subject: Wip - Fix loading group chats, unread messages, etc. --- protocols/FacebookRM/src/client.h | 2 +- protocols/FacebookRM/src/json.cpp | 40 ++++++++++++++++ protocols/FacebookRM/src/json.h | 60 ++++++++++++++++++++++++ protocols/FacebookRM/src/requests/contacts.h | 8 +++- protocols/FacebookRM/src/requests/history.h | 70 +++++++++++++++++++--------- 5 files changed, 156 insertions(+), 24 deletions(-) diff --git a/protocols/FacebookRM/src/client.h b/protocols/FacebookRM/src/client.h index 4d7fe6ef1e..8d80ea72ef 100644 --- a/protocols/FacebookRM/src/client.h +++ b/protocols/FacebookRM/src/client.h @@ -161,7 +161,7 @@ public: } __inline const char *__rev() { - return "2828561"; // FIXME: Some version of communication protocol? This version is from 12.2.2017 + return "3496859"; // FIXME: Some version of communication protocol? This version is from 3.12.2017 } //////////////////////////////////////////////////////////// diff --git a/protocols/FacebookRM/src/json.cpp b/protocols/FacebookRM/src/json.cpp index 0495cdaaeb..aabf0823f1 100644 --- a/protocols/FacebookRM/src/json.cpp +++ b/protocols/FacebookRM/src/json.cpp @@ -1462,3 +1462,43 @@ int facebook_json_parser::parse_messages_count(std::string *data, int *messagesC return EXIT_SUCCESS; } + +///////////////////////////////////////////////////////////////////////////////////////// + +JSONNode& operator<<(JSONNode &json, const NULL_PARAM ¶m) +{ + json.push_back(JSONNode(param.szName, nullptr)); + return json; +} + +JSONNode& operator<<(JSONNode &json, const JSON_PARAM ¶m) +{ + json.push_back(JSONNode(param.szName, param.node)); + return json; +} + +JSONNode& operator<<(JSONNode &json, const INT_PARAM ¶m) +{ + json.push_back(JSONNode(param.szName, param.iValue)); + return json; +} + +JSONNode& operator<<(JSONNode &json, const BOOL_PARAM ¶m) +{ + json.push_back(JSONNode(param.szName, param.bValue)); + return json; +} + +JSONNode& operator<<(JSONNode &json, const CHAR_PARAM ¶m) +{ + json.push_back(JSONNode(param.szName, param.szValue)); + return json; +} + +JSONNode& operator<<(JSONNode &json, const WCHAR_PARAM ¶m) +{ + json.push_back(JSONNode(param.szName, ptrA(mir_utf8encodeW(param.wszValue)).get())); + return json; +} + +///////////////////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/protocols/FacebookRM/src/json.h b/protocols/FacebookRM/src/json.h index d62666a66d..27dbbf1710 100644 --- a/protocols/FacebookRM/src/json.h +++ b/protocols/FacebookRM/src/json.h @@ -47,3 +47,63 @@ public: this->proto = proto; } }; + +struct PARAM +{ + LPCSTR szName; + __forceinline PARAM(LPCSTR _name) : szName(_name) + {} +}; + +struct NULL_PARAM : public PARAM +{ + __forceinline NULL_PARAM(LPCSTR _name) : PARAM(_name) + {} +}; + +struct JSON_PARAM : public PARAM +{ + JSONNode node; + __forceinline JSON_PARAM(LPCSTR _name, JSONNode _node) : + PARAM(_name), node(_node) + {} +}; + +struct BOOL_PARAM : public PARAM +{ + bool bValue; + __forceinline BOOL_PARAM(LPCSTR _name, bool _value) : + PARAM(_name), bValue(_value) + {} +}; + +struct INT_PARAM : public PARAM +{ + int iValue; + __forceinline INT_PARAM(LPCSTR _name, int _value) : + PARAM(_name), iValue(_value) + {} +}; + +struct CHAR_PARAM : public PARAM +{ + LPCSTR szValue; + __forceinline CHAR_PARAM(LPCSTR _name, LPCSTR _value) : + PARAM(_name), szValue(_value) + {} +}; + +struct WCHAR_PARAM : public PARAM +{ + LPCWSTR wszValue; + __forceinline WCHAR_PARAM(LPCSTR _name, LPCWSTR _value) : + PARAM(_name), wszValue(_value) + {} +}; + +JSONNode& operator<<(JSONNode &json, const NULL_PARAM ¶m); +JSONNode& operator<<(JSONNode &json, const JSON_PARAM ¶m); +JSONNode& operator<<(JSONNode &json, const INT_PARAM ¶m); +JSONNode& operator<<(JSONNode &json, const BOOL_PARAM ¶m); +JSONNode& operator<<(JSONNode &json, const CHAR_PARAM ¶m); +JSONNode& operator<<(JSONNode &json, const WCHAR_PARAM ¶m); diff --git a/protocols/FacebookRM/src/requests/contacts.h b/protocols/FacebookRM/src/requests/contacts.h index 8fa60fced8..960fb269b3 100644 --- a/protocols/FacebookRM/src/requests/contacts.h +++ b/protocols/FacebookRM/src/requests/contacts.h @@ -36,7 +36,7 @@ public: // getting info about particular friend -// revised 17.8.2016 +// revised 3.12.2017 class UserInfoRequest : public HttpRequest { public: @@ -60,7 +60,11 @@ public: << CHAR_VALUE("__rev", fc->__rev()) << "__a=1" << "__pc=PHASED:DEFAULT" - << "__be=-1"; + << "__be=1" + << "jazoest=" + << "__spin_r=" + << "__spin_b=" + << "__spin_t="; } }; diff --git a/protocols/FacebookRM/src/requests/history.h b/protocols/FacebookRM/src/requests/history.h index 9ac3d52168..88890a0f8e 100644 --- a/protocols/FacebookRM/src/requests/history.h +++ b/protocols/FacebookRM/src/requests/history.h @@ -24,20 +24,20 @@ along with this program. If not, see . #define _FACEBOOK_REQUEST_HISTORY_H_ // getting thread info and messages -// revised 17.8.2016 +// revised 3.12.2017 class ThreadInfoRequest : public HttpRequest { public: // Request only messages history ThreadInfoRequest(facebook_client *fc, bool isChat, const char *id, int offset, const char *timestamp, int limit) : - HttpRequest(REQUEST_POST, FACEBOOK_SERVER_REGULAR "/ajax/mercury/thread_info.php") + HttpRequest(REQUEST_POST, FACEBOOK_SERVER_REGULAR "/api/graphqlbatch/") { - Url - << "dpr=1"; - setCommonBody(fc); - const char *type = isChat ? "thread_fbids" : "user_ids"; + // FIXME: FB removed /ajax/mercury/thread_info requests and now all messaging stuff does through /api/graphqlbatch/ - all loading of threads, (unread) messages, list of contacts in groupchat, etc. + // All these request must be rewritten to the new request. Preparation is below but unfinished. + + //const char *type = isChat ? "thread_fbids" : "user_ids"; std::string id_ = id; // FIXME: Rewrite this without std::string... if (isChat) { // NOTE: Remove "id." prefix as here we need to give threadFbId and not threadId @@ -46,6 +46,38 @@ public: } ptrA idEncoded(mir_urlEncode(id_.c_str())); + + JSONNode root, o0, query_params; + + int before = -1; + + query_params + << CHAR_PARAM("id", id_) // TODO: Do I have to encode the id? And remove that first "id." at the begin as we do above? + << INT_PARAM("message_limit", limit) + << INT_PARAM("load_messages", 1) + << BOOL_PARAM("load_read_receipts", false); + + if (before != -1) { + query_params << INT_PARAM("before", before); + } + else { + query_params << NULL_PARAM("before"); + } + + o0 + << CHAR_PARAM("doc_id", id) + << JSON_PARAM("query_params", query_params); + + root << JSON_PARAM("o0", o0); + + Body + << "batch_name=MessengerGraphQLThreadFetcherRe" + << CHAR_VALUE("queries", root.write().c_str()); + + // example request data we need to send: { "o0":{"doc_id":"456789456123","query_params" : {"id":"123456789","message_limit" : 20,"load_messages" : 1,"load_read_receipts" : false,"before" : null}} } + + + /* //if (loadMessages) { // Grrr, offset doesn't work at all, we need to use timestamps to get back in history... // And we don't know, what's timestamp of first message, so we need to get from latest to oldest @@ -55,7 +87,7 @@ public: << CMStringA(::FORMAT, "%s[offset]=%i", begin.c_str(), offset).c_str() << CMStringA(::FORMAT, "%s[timestamp]=%s", begin.c_str(), timestamp).c_str() << CMStringA(::FORMAT, "%s[limit]=%i", begin.c_str(), limit).c_str(); - //} + //}*/ /*if (loadThreadInfo) { data += "&threads[" + type + "][0]=" + idEncoded; @@ -64,11 +96,8 @@ public: // Request only thread info // TODO: Make it array of ids ThreadInfoRequest(facebook_client *fc, bool isChat, const char *id) : - HttpRequest(REQUEST_POST, FACEBOOK_SERVER_REGULAR "/ajax/mercury/thread_info.php") + HttpRequest(REQUEST_POST, FACEBOOK_SERVER_REGULAR "/api/graphqlbatch/") { - Url - << "dpr=1"; - setCommonBody(fc); const char *type = isChat ? "thread_fbids" : "user_ids"; @@ -86,11 +115,8 @@ public: // Request both thread info and messages for single contact/chat ThreadInfoRequest(facebook_client *fc, bool isChat, const char *id, int limit) : - HttpRequest(REQUEST_POST, FACEBOOK_SERVER_REGULAR "/ajax/mercury/thread_info.php") + HttpRequest(REQUEST_POST, FACEBOOK_SERVER_REGULAR "/api/graphqlbatch/") { - Url - << "dpr=1"; - setCommonBody(fc); const char *type = isChat ? "thread_fbids" : "user_ids"; @@ -116,11 +142,8 @@ public: // Request both thread info and messages for more threads ThreadInfoRequest(facebook_client *fc, const LIST &ids, int offset, int limit) : - HttpRequest(REQUEST_POST, FACEBOOK_SERVER_REGULAR "/ajax/mercury/thread_info.php") + HttpRequest(REQUEST_POST, FACEBOOK_SERVER_REGULAR "/api/graphqlbatch/") { - Url - << "dpr=1"; - setCommonBody(fc); for (int i = 0; i < ids.getCount(); i++) { @@ -146,7 +169,6 @@ private: void setCommonBody(facebook_client *fc) { Body - << "client=mercury" << CHAR_VALUE("__user", fc->self_.user_id.c_str()) << CHAR_VALUE("__dyn", fc->__dyn()) << CHAR_VALUE("__req", fc->__req()) @@ -155,7 +177,11 @@ private: << CHAR_VALUE("ttstamp", fc->ttstamp_.c_str()) << "__a=1" << "__pc=PHASED:DEFAULT" - << "__be=-1"; + << "__be=1" + << "jazoest=" + << "__spin_r=" + << "__spin_b=" + << "__spin_t="; } }; @@ -183,6 +209,8 @@ public: << "__a=1" << "__pc=PHASED:DEFAULT" << "__be=-1"; + + //queries={"o0":{"doc_id":"2003371749678240","query_params":{"limit":99,"before":null,"tags":["PENDING","unread"],"includeDeliveryReceipts":true,"includeSeqID":false}}} } }; -- cgit v1.2.3