diff options
author | Robert Pösel <robyer@seznam.cz> | 2016-04-17 15:08:48 +0000 |
---|---|---|
committer | Robert Pösel <robyer@seznam.cz> | 2016-04-17 15:08:48 +0000 |
commit | ac8ae1407f91cfb4a440e55e8a62b3365aec9ad2 (patch) | |
tree | b7bd8204a73ef3423b591aa900e4bb4e9fc11157 /protocols/FacebookRM/src | |
parent | 7eecd876c15dfdb9ea6fad13c203e5afbab8af17 (diff) |
Facebook: Rework read receipts for multi chats
git-svn-id: http://svn.miranda-ng.org/main/trunk@16691 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols/FacebookRM/src')
-rw-r--r-- | protocols/FacebookRM/src/client.h | 4 | ||||
-rw-r--r-- | protocols/FacebookRM/src/communication.cpp | 33 | ||||
-rw-r--r-- | protocols/FacebookRM/src/json.cpp | 85 |
3 files changed, 67 insertions, 55 deletions
diff --git a/protocols/FacebookRM/src/client.h b/protocols/FacebookRM/src/client.h index 3aedecceac..a6b0ddd4ac 100644 --- a/protocols/FacebookRM/src/client.h +++ b/protocols/FacebookRM/src/client.h @@ -125,7 +125,7 @@ public: void clear_notifications();
void clear_chatrooms();
void clear_readers();
- void insert_reader(MCONTACT, time_t, const std::tstring &reader = _T(""));
+ void insert_reader(MCONTACT, time_t, const std::string &readerId = "");
void erase_reader(MCONTACT);
////////////////////////////////////////////////////////////
@@ -158,7 +158,7 @@ public: }
std::string __inline __rev() {
- return "2177663"; // FIXME: Some version of communication protocol? This version is from 12.2.2015
+ return "2288795"; // FIXME: Some version of communication protocol? This version is from 17.4.2016
}
////////////////////////////////////////////////////////////
diff --git a/protocols/FacebookRM/src/communication.cpp b/protocols/FacebookRM/src/communication.cpp index 95deab843d..b1a0f23691 100644 --- a/protocols/FacebookRM/src/communication.cpp +++ b/protocols/FacebookRM/src/communication.cpp @@ -694,9 +694,36 @@ void facebook_client::clear_readers() /** * Inserts info to readers list, db and writes to statusbar */ -void facebook_client::insert_reader(MCONTACT hContact, time_t timestamp, const std::tstring &reader) +void facebook_client::insert_reader(MCONTACT hContact, time_t timestamp, const std::string &readerId) { + if (!hContact) + return; + if (parent->isChatRoom(hContact)) { + std::string tid = ptrA(parent->getStringA(hContact, "ChatRoomID")); + + std::string name = readerId; + + // get name of this participant from chatroom's participants list + auto itRoom = chat_rooms.find(tid); + if (itRoom != chat_rooms.end()) { + facebook_chatroom *chatroom = itRoom->second; + std::map<std::string, std::string> participants = chatroom->participants; + + // try to get name of this participant + auto participant = participants.find(readerId); + if (participant != participants.end()) { + name = participant->second; + } + else { + // FIXME: This probably shouldn't be here, but chatroom should have all it's participants loaded itself already + // add this missing participant, just in case + participants.insert(std::make_pair(readerId, name)); + parent->AddChatContact(tid.c_str(), readerId.c_str(), name.c_str()); + } + } + + std::tstring treaderName = _A2T(name.c_str(), CP_UTF8); std::tstring treaders; // Load old readers @@ -705,7 +732,7 @@ void facebook_client::insert_reader(MCONTACT hContact, time_t timestamp, const s treaders = std::tstring(told) + _T(", "); // Append new reader name and remember them - treaders += utils::text::prepare_name(reader, true); + treaders += utils::text::prepare_name(treaderName, true); parent->setTString(hContact, FACEBOOK_KEY_MESSAGE_READERS, treaders.c_str()); } @@ -1396,7 +1423,7 @@ int facebook_client::send_message(int seqid, MCONTACT hContact, const std::strin data += "&message_batch[0][message_id]"; data += "&message_batch[0][ephemeral_ttl_mode]=0"; data += "&message_batch[0][manual_retry_cnt]=0"; - data += "&client=mercury&__a=1&__pc=EXP1:DEFAULT"; + data += "&client=mercury&__a=1&__be=0&__pc=EXP1:DEFAULT"; data += "&fb_dtsg=" + this->dtsg_; data += "&__user=" + this->self_.user_id; data += "&ttstamp=" + ttstamp_; diff --git a/protocols/FacebookRM/src/json.cpp b/protocols/FacebookRM/src/json.cpp index 1d7ab875d4..97bd85e610 100644 --- a/protocols/FacebookRM/src/json.cpp +++ b/protocols/FacebookRM/src/json.cpp @@ -598,17 +598,45 @@ int facebook_json_parser::parse_messages(std::string *pData, std::vector< facebo } else if (cls == "ReadReceipt") { // user read message - const JSONNode &reader_ = delta_["threadKey"]["otherUserFbId"]; // who read the message - const JSONNode &time_ = delta_["actionTimestampMs"]; // when read - if (!reader_ || !time_) + // when read + const JSONNode &time_ = delta_["actionTimestampMs"]; + if (!time_) continue; - + time_t timestamp = utils::time::from_string(time_.as_string()); - MCONTACT hContact = proto->ContactIDToHContact(reader_.as_string()); - if (hContact) + // for multi chats (not available for single) + const JSONNode &actor_ = delta_["actorFbId"]; // who read the message + const JSONNode &thread_ = delta_["threadKey"]["threadFbId"]; // chat thread + + // for single chats (not available for multi) + const JSONNode &reader_ = delta_["threadKey"]["otherUserFbId"]; // who read the message + + if (actor_ && thread_) { + // multi chat + + // ignore if disabled + if (!proto->m_enableChat) + continue; + + std::string readerId = actor_.as_string(); + std::string tid = "id." + thread_.as_string(); // NOTE: threadFbId means just numeric id of thread, without "id." prefix. We add it here to have it consistent with other methods (where threadId is used) + + MCONTACT hContact = proto->ChatIDToHContact(tid); + proto->facy.insert_reader(hContact, timestamp, readerId); + } + else if (reader_) { + // single chat + std::string userId = reader_.as_string(); + + MCONTACT hContact = proto->ContactIDToHContact(userId); proto->facy.insert_reader(hContact, timestamp); + } + } + else if (cls == "NoOp") { + // contains numNoOps=1 (or probably other number) in delta element, but I don't know what is it for + continue; } else { proto->debugLogA("json::parse_messages - Unknown class '%s'", cls.c_str()); @@ -622,50 +650,7 @@ int facebook_json_parser::parse_messages(std::string *pData, std::vector< facebo continue; std::string ev = ev_.as_string(); - if (ev == "read") { - // user read chat message - if (!proto->m_enableChat) - continue; - - const JSONNode &reader_ = (*it)["realtime_viewer_fbid"]; - const JSONNode &time_ = (*it)["timestamp"]; - if (!reader_ || !time_) - continue; - - std::string readerId = reader_.as_string(); - time_t timestamp = utils::time::from_string(time_.as_string()); - std::string tid = ""; - - const JSONNode &tids = (*it)["tids"]; - for (auto it2 = tids.begin(); it2 != tids.end(); ++it2) { - tid = (*it2).as_string(); - break; - } - - auto itRoom = proto->facy.chat_rooms.find(tid); - if (itRoom != proto->facy.chat_rooms.end()) { - facebook_chatroom *chatroom = itRoom->second; - std::map<std::string, std::string> participants = chatroom->participants; - - auto participant = participants.find(readerId); - if (participant == participants.end()) { - // TODO: load name of this participant - std::string name = readerId; - participants.insert(std::make_pair(readerId, name)); - proto->AddChatContact(tid.c_str(), readerId.c_str(), name.c_str()); - } - - participant = participants.find(readerId); - if (participant != participants.end()) { - // TODO: remember just reader ids to avoid eventual duplication of names - std::tstring reader = _A2T(participant->second.c_str(), CP_UTF8); - - MCONTACT hContact = proto->ChatIDToHContact(tid); - proto->facy.insert_reader(hContact, timestamp, reader); - } - } - } - else if (ev == "deliver") { + if (ev == "deliver") { // inbox message (multiuser or direct) const JSONNode &msg = (*it)["message"]; |