summaryrefslogtreecommitdiff
path: root/protocols/FacebookRM
diff options
context:
space:
mode:
authorRobert Pösel <robyer@seznam.cz>2016-04-17 15:08:48 +0000
committerRobert Pösel <robyer@seznam.cz>2016-04-17 15:08:48 +0000
commitac8ae1407f91cfb4a440e55e8a62b3365aec9ad2 (patch)
treeb7bd8204a73ef3423b591aa900e4bb4e9fc11157 /protocols/FacebookRM
parent7eecd876c15dfdb9ea6fad13c203e5afbab8af17 (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')
-rw-r--r--protocols/FacebookRM/src/client.h4
-rw-r--r--protocols/FacebookRM/src/communication.cpp33
-rw-r--r--protocols/FacebookRM/src/json.cpp85
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"];