diff options
author | Robert Pösel <robyer@seznam.cz> | 2013-12-13 09:27:00 +0000 |
---|---|---|
committer | Robert Pösel <robyer@seznam.cz> | 2013-12-13 09:27:00 +0000 |
commit | a915fe3a7ff1f0512d91c1d4e2fe603b08458e6f (patch) | |
tree | 09203d632ef425fc11e567cc6e5d0b5b08d35f02 /protocols | |
parent | 112bcc323d1532c8dac92f5af9b37f767879417f (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
Diffstat (limited to 'protocols')
-rw-r--r-- | protocols/FacebookRM/src/contacts.cpp | 44 | ||||
-rw-r--r-- | protocols/FacebookRM/src/json.cpp | 61 | ||||
-rw-r--r-- | protocols/FacebookRM/src/json.h | 1 | ||||
-rw-r--r-- | protocols/FacebookRM/src/process.cpp | 73 | ||||
-rw-r--r-- | protocols/FacebookRM/src/proto.h | 1 |
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);
|