summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Pösel <robyer@seznam.cz>2013-12-13 09:27:00 +0000
committerRobert Pösel <robyer@seznam.cz>2013-12-13 09:27:00 +0000
commita915fe3a7ff1f0512d91c1d4e2fe603b08458e6f (patch)
tree09203d632ef425fc11e567cc6e5d0b5b08d35f02
parent112bcc323d1532c8dac92f5af9b37f767879417f (diff)
Facebook: Fixed loading sent messages (from other connected devices)
git-svn-id: http://svn.miranda-ng.org/main/trunk@7170 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
-rw-r--r--protocols/FacebookRM/src/contacts.cpp44
-rw-r--r--protocols/FacebookRM/src/json.cpp61
-rw-r--r--protocols/FacebookRM/src/json.h1
-rw-r--r--protocols/FacebookRM/src/process.cpp73
-rw-r--r--protocols/FacebookRM/src/proto.h1
5 files changed, 137 insertions, 43 deletions
diff --git a/protocols/FacebookRM/src/contacts.cpp b/protocols/FacebookRM/src/contacts.cpp
index c7487cd71d..f225c5b8c7 100644
--- a/protocols/FacebookRM/src/contacts.cpp
+++ b/protocols/FacebookRM/src/contacts.cpp
@@ -94,6 +94,50 @@ HANDLE FacebookProto::ContactIDToHContact(std::string user_id)
return 0;
}
+std::string FacebookProto::ThreadIDToContactID(std::string thread_id)
+{
+ std::string user_id;
+
+ for (HANDLE hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) {
+ if (!IsMyContact(hContact))
+ continue;
+
+ ptrA tid(getStringA(hContact, FACEBOOK_KEY_TID));
+ if (tid && !strcmp(tid, thread_id.c_str())) {
+ user_id = ptrA( getStringA(hContact, FACEBOOK_KEY_ID));
+ return user_id;
+ }
+ }
+
+ // We don't have any contact with thish thread_id cached, we must ask server
+
+ std::string data = "client=mercury";
+ data += "&__user=" + facy.self_.user_id;
+ data += "&fb_dtsg=" + (facy.dtsg_.length() ? facy.dtsg_ : "0");
+ data += "&__a=1&__dyn=&__req=&ttstamp=0";
+ data += "&threads[thread_ids][0]=" + utils::url::encode(thread_id);
+
+ http::response resp = facy.flap(REQUEST_THREAD_INFO, &data);
+
+ if (resp.code == HTTP_CODE_OK) {
+ CODE_BLOCK_TRY
+
+ facebook_json_parser* p = new facebook_json_parser(this);
+ p->parse_thread_info(&resp.data, &user_id);
+ delete p;
+
+ debugLogA("***** Thread info processed");
+
+ CODE_BLOCK_CATCH
+
+ debugLogA("***** Error processing thread info: %s", e.what());
+
+ CODE_BLOCK_END
+ }
+
+ return user_id;
+}
+
HANDLE FacebookProto::AddToContactList(facebook_user* fbu, ContactType type, bool dont_check)
{
HANDLE hContact;
diff --git a/protocols/FacebookRM/src/json.cpp b/protocols/FacebookRM/src/json.cpp
index cbb18c66e1..9abb95c088 100644
--- a/protocols/FacebookRM/src/json.cpp
+++ b/protocols/FacebookRM/src/json.cpp
@@ -372,7 +372,7 @@ int facebook_json_parser::parse_messages(void* data, std::vector< facebook_messa
std::string t = json_as_pstring(type);
if (t == "messaging") {
- // we use this only for incomming messages (and getting seen info)
+ // various messaging stuff (received and sent messages, getting seen info)
JSONNODE *type = json_get(it, "event");
if (type == NULL)
@@ -470,10 +470,6 @@ int facebook_json_parser::parse_messages(void* data, std::vector< facebook_messa
// Process attachements and stickers
parseAttachments(proto, &message_text, msg);
- // Ignore messages from myself, as there is no id of recipient
- if (id == proto->facy.self_.user_id)
- continue;
-
// Ignore duplicits or messages sent from miranda
if (body == NULL || ignore_duplicits(proto, message_id, message_text))
continue;
@@ -524,9 +520,9 @@ int facebook_json_parser::parse_messages(void* data, std::vector< facebook_messa
// RM TODO: better use check if chatroom exists/is in db/is online... no?
/// e.g. HANDLE hChatContact = proto->ChatIDToHContact(thread_id); ?
if (proto->GetChatUsers(thread_id.c_str()) == NULL) {
- // Set thread id (TID) for later.
proto->AddChat(thread_id.c_str(), name.c_str());
hChatContact = proto->ChatIDToHContact(thread_id);
+ // Set thread id (TID) for later
proto->setTString(hChatContact, FACEBOOK_KEY_TID, thread_id.c_str());
}
@@ -551,21 +547,25 @@ int facebook_json_parser::parse_messages(void* data, std::vector< facebook_messa
senderName = senderName.substr(0, pos);
}*/
- // Last fall-back for adding this sender (Incase was not in the participants) - Is this even needed?
+ // Last fall-back for adding this sender (in case he was not in the participants) - is this even needed?
if (!proto->IsChatContact(thread_id.c_str(), id.c_str())) {
proto->AddChatContact(thread_id.c_str(), id.c_str(), senderName.c_str());
}
- // Update chat with message.
+ // Update chat with message
+ // TODO: support also system messages (rename chat, user quit, etc.)! (here? or it is somewhere else?)
proto->UpdateChat(thread_id.c_str(), id.c_str(), senderName.c_str(), message_text.c_str(), utils::time::fix_timestamp(json_as_float(timestamp)));
proto->setString(hChatContact, FACEBOOK_KEY_MESSAGE_ID, message_id.c_str());
proto->ForkThread(&FacebookProto::ReadMessageWorker, hChatContact);
} else {
facebook_message* message = new facebook_message();
+
+ message->isIncoming = (id != proto->facy.self_.user_id);
message->message_text = message_text;
message->sender_name = utils::text::special_expressions_decode(utils::text::slashu_to_utf8(json_as_pstring(sender_name)));
message->time = utils::time::fix_timestamp(json_as_float(timestamp));
- message->user_id = id; // TODO: Check if we have contact with this ID in friendlist and otherwise do something different?
+ message->thread_id = json_as_pstring(tid);
+ message->user_id = message->isIncoming ? id : proto->ThreadIDToContactID(message->thread_id); // TODO: Check if we have contact with this user_id in friendlist and otherwise do something different?
message->message_id = message_id;
messages->push_back(message);
@@ -867,6 +867,7 @@ int facebook_json_parser::parse_thread_messages(void* data, std::vector< faceboo
if (author_email != NULL)
message->sender_name = json_as_pstring(author_email);
message->time = utils::time::fix_timestamp(json_as_float(timestamp));
+ message->thread_id = thread_id;
message->message_id = message_id;
message->isIncoming = (author_id != proto->facy.self_.user_id);
@@ -875,7 +876,6 @@ int facebook_json_parser::parse_thread_messages(void* data, std::vector< faceboo
// this is chatroom message
message->isChat = true;
message->user_id = author_id;
- message->thread_id = thread_id;
} else {
// this is standard message
@@ -899,3 +899,44 @@ int facebook_json_parser::parse_thread_messages(void* data, std::vector< faceboo
json_delete(root);
return EXIT_SUCCESS;
}
+
+int facebook_json_parser::parse_thread_info(void* data, std::string* user_id)
+{
+ std::string jsonData = static_cast< std::string* >(data)->substr(9);
+
+ JSONNODE *root = json_parse(jsonData.c_str());
+ if (root == NULL)
+ return EXIT_FAILURE;
+
+ JSONNODE *payload = json_get(root, "payload");
+ if (payload == NULL) {
+ json_delete(root);
+ return EXIT_FAILURE;
+ }
+
+ JSONNODE *threads = json_get(payload, "threads");
+ if (threads == NULL) {
+ json_delete(root);
+ return EXIT_FAILURE;
+ }
+
+ std::map<std::string, std::string> thread_ids;
+ for (unsigned int i = 0; i < json_size(threads); i++) {
+ JSONNODE *it = json_at(threads, i);
+ JSONNODE *canonical = json_get(it, "canonical_fbid");
+ JSONNODE *thread_id = json_get(it, "thread_id");
+ JSONNODE *message_count = json_get(it, "message_count"); // TODO: this could be useful for loading history from server
+
+ if (canonical == NULL || thread_id == NULL)
+ continue;
+
+ std::string id = json_as_pstring(canonical);
+ if (id == "null")
+ continue;
+
+ *user_id = id;
+ }
+
+ json_delete(root);
+ return EXIT_SUCCESS;
+}
diff --git a/protocols/FacebookRM/src/json.h b/protocols/FacebookRM/src/json.h
index 9e06e8b042..d506f0f50c 100644
--- a/protocols/FacebookRM/src/json.h
+++ b/protocols/FacebookRM/src/json.h
@@ -36,6 +36,7 @@ public:
int parse_messages(void*, std::vector< facebook_message* >*, std::vector< facebook_notification* >*);
int parse_unread_threads(void*, std::vector< std::string >*);
int parse_thread_messages(void*, std::vector< facebook_message* >*, std::map< std::string, facebook_chatroom* >*, bool unreadOnly, int limit);
+ int parse_thread_info(void* data, std::string* user_id);
facebook_json_parser(FacebookProto* proto)
{
diff --git a/protocols/FacebookRM/src/process.cpp b/protocols/FacebookRM/src/process.cpp
index 584d1bebcb..866bc8cf00 100644
--- a/protocols/FacebookRM/src/process.cpp
+++ b/protocols/FacebookRM/src/process.cpp
@@ -359,9 +359,9 @@ void FacebookProto::ProcessUnreadMessage(void *p)
facebook_chatroom *room = it->second;
HANDLE hChatContact;
if (GetChatUsers(room->thread_id.c_str()) == NULL) {
- // Set thread id (TID) for later.
AddChat(room->thread_id.c_str(), room->chat_name.c_str());
hChatContact = ChatIDToHContact(room->thread_id);
+ // Set thread id (TID) for later
setTString(hChatContact, FACEBOOK_KEY_TID, room->thread_id.c_str());
for (std::map<std::string, std::string>::iterator jt = room->participants.begin(); jt != room->participants.end(); ) {
@@ -395,6 +395,11 @@ void FacebookProto::ProcessUnreadMessage(void *p)
// TODO: optimize this?
HANDLE hContact = AddToContactList(&fbu, CONTACT_NONE);
setString(hContact, FACEBOOK_KEY_MESSAGE_ID, messages[i]->message_id.c_str());
+
+ // Save TID if not exists already
+ ptrA tid( getStringA(hContact, FACEBOOK_KEY_TID));
+ if (!tid || strcmp(tid, messages[i]->thread_id.c_str()))
+ setString(hContact, FACEBOOK_KEY_TID, messages[i]->thread_id.c_str());
// TODO: if contact is newly added, get his user info
// TODO: maybe create new "receiveMsg" function and use it for offline and channel messages?
@@ -469,38 +474,40 @@ void FacebookProto::ProcessMessages(void* data)
for(std::vector<facebook_message*>::size_type i=0; i<messages.size(); i++)
{
- if (messages[i]->user_id != facy.self_.user_id)
- {
- debugLogA(" Got message: %s", messages[i]->message_text.c_str());
- facebook_user fbu;
- fbu.user_id = messages[i]->user_id;
- fbu.real_name = messages[i]->sender_name;
-
- HANDLE hContact = AddToContactList(&fbu, CONTACT_NONE);
- setString(hContact, FACEBOOK_KEY_MESSAGE_ID, messages[i]->message_id.c_str());
-
- // TODO: if contact is newly added, get his user info
- // TODO: maybe create new "receiveMsg" function and use it for offline and channel messages?
-
- ParseSmileys(messages[i]->message_text, hContact);
-
- if (messages[i]->isIncoming) {
- PROTORECVEVENT recv = {0};
- recv.flags = PREF_UTF;
- recv.szMessage = const_cast<char*>(messages[i]->message_text.c_str());
- recv.timestamp = local_timestamp || !messages[i]->time ? ::time(NULL) : messages[i]->time;
- ProtoChainRecvMsg(hContact, &recv);
- } else {
- DBEVENTINFO dbei = {0};
- dbei.cbSize = sizeof(dbei);
- dbei.eventType = EVENTTYPE_MESSAGE;
- dbei.flags = DBEF_SENT | DBEF_UTF;
- dbei.szModule = m_szModuleName;
- dbei.timestamp = local_timestamp || !messages[i]->time ? ::time(NULL) : messages[i]->time;
- dbei.cbBlob = (DWORD)messages[i]->message_text.length() + 1;
- dbei.pBlob = (PBYTE)messages[i]->message_text.c_str();
- db_event_add(hContact, &dbei);
- }
+ debugLogA(" Got message: %s", messages[i]->message_text.c_str());
+ facebook_user fbu;
+ fbu.user_id = messages[i]->user_id;
+ fbu.real_name = messages[i]->sender_name;
+
+ HANDLE hContact = AddToContactList(&fbu, CONTACT_NONE);
+ setString(hContact, FACEBOOK_KEY_MESSAGE_ID, messages[i]->message_id.c_str());
+
+ // Save TID if not exists already
+ ptrA tid(getStringA(hContact, FACEBOOK_KEY_TID));
+ if (!tid || strcmp(tid, messages[i]->thread_id.c_str()))
+ setString(hContact, FACEBOOK_KEY_TID, messages[i]->thread_id.c_str());
+
+ // TODO: if contact is newly added, get his user info
+ // TODO: maybe create new "receiveMsg" function and use it for offline and channel messages?
+
+ ParseSmileys(messages[i]->message_text, hContact);
+
+ if (messages[i]->isIncoming) {
+ PROTORECVEVENT recv = {0};
+ recv.flags = PREF_UTF;
+ recv.szMessage = const_cast<char*>(messages[i]->message_text.c_str());
+ recv.timestamp = local_timestamp || !messages[i]->time ? ::time(NULL) : messages[i]->time;
+ ProtoChainRecvMsg(hContact, &recv);
+ } else {
+ DBEVENTINFO dbei = {0};
+ dbei.cbSize = sizeof(dbei);
+ dbei.eventType = EVENTTYPE_MESSAGE;
+ dbei.flags = DBEF_SENT | DBEF_UTF;
+ dbei.szModule = m_szModuleName;
+ dbei.timestamp = local_timestamp || !messages[i]->time ? ::time(NULL) : messages[i]->time;
+ dbei.cbBlob = (DWORD)messages[i]->message_text.length() + 1;
+ dbei.pBlob = (PBYTE)messages[i]->message_text.c_str();
+ db_event_add(hContact, &dbei);
}
delete messages[i];
}
diff --git a/protocols/FacebookRM/src/proto.h b/protocols/FacebookRM/src/proto.h
index 000afba6ec..3d056a92c4 100644
--- a/protocols/FacebookRM/src/proto.h
+++ b/protocols/FacebookRM/src/proto.h
@@ -188,6 +188,7 @@ public:
bool IsMyContact(HANDLE, bool include_chat = false);
HANDLE ContactIDToHContact(std::string);
HANDLE ChatIDToHContact(std::tstring);
+ std::string ThreadIDToContactID(std::string thread_id);
HANDLE AddToContactList(facebook_user*, ContactType type, bool dont_check = false);
void SetAllContactStatuses(int status);
HANDLE HContactFromAuthEvent(HANDLE hEvent);