diff options
author | George Hazan <ghazan@miranda.im> | 2019-12-27 22:51:52 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2019-12-27 22:51:52 +0300 |
commit | 8bc24cb41ad6db6fc56731c9dffcb765cbd9a79f (patch) | |
tree | 6403195285ecb7beae3a8547d65932257803cdc9 /protocols | |
parent | 42b48e4121e22cea97a9d4fc4c671b59004c77b9 (diff) |
Facebook: sending messages
Diffstat (limited to 'protocols')
-rw-r--r-- | protocols/Discord/src/proto.cpp | 2 | ||||
-rw-r--r-- | protocols/Facebook/src/proto.cpp | 38 | ||||
-rw-r--r-- | protocols/Facebook/src/proto.h | 25 | ||||
-rw-r--r-- | protocols/Facebook/src/server.cpp | 28 | ||||
-rw-r--r-- | protocols/Facebook/src/version.h | 2 |
5 files changed, 90 insertions, 5 deletions
diff --git a/protocols/Discord/src/proto.cpp b/protocols/Discord/src/proto.cpp index c6ffdba35e..dc13c2fccc 100644 --- a/protocols/Discord/src/proto.cpp +++ b/protocols/Discord/src/proto.cpp @@ -407,7 +407,7 @@ int CDiscordProto::SendMsg(MCONTACT hContact, int /*flags*/, const char *pszSrc) // we generate a random 64-bit integer and pass it to the server // to distinguish our own messages from these generated by another clients SnowFlake nonce; Utils_GetRandom(&nonce, sizeof(nonce)); - JSONNode body; body << WCHAR_PARAM("content", wszText) << INT64_PARAM("nonce", nonce); + JSONNode body; body << WCHAR_PARAM("content", wszText) << INT64_PARAM("nonce", abs(nonce)); CMStringA szUrl(FORMAT, "/channels/%lld/messages", pUser->channelId); AsyncHttpRequest *pReq = new AsyncHttpRequest(this, REQUEST_POST, szUrl, nullptr, &body); diff --git a/protocols/Facebook/src/proto.cpp b/protocols/Facebook/src/proto.cpp index 381547bf10..567f2bc94f 100644 --- a/protocols/Facebook/src/proto.cpp +++ b/protocols/Facebook/src/proto.cpp @@ -28,9 +28,18 @@ static int CompareUsers(const FacebookUser *p1, const FacebookUser *p2) return (p1->id < p2->id) ? -1 : 1; } +static int CompareMessages(const COwnMessage *p1, const COwnMessage *p2) +{ + if (p1->msgId == p2->msgId) + return 0; + + return (p1->msgId < p2->msgId) ? -1 : 1; +} + FacebookProto::FacebookProto(const char *proto_name, const wchar_t *username) : PROTO<FacebookProto>(proto_name, username), m_users(50, CompareUsers), + arOwnMessages(1, CompareMessages), m_bUseBigAvatars(this, "UseBigAvatars", true), m_wszDefaultGroup(this, "DefaultGroup", L"Facebook") { @@ -152,6 +161,35 @@ INT_PTR FacebookProto::GetCaps(int type, MCONTACT) ///////////////////////////////////////////////////////////////////////////////////////// +void __cdecl FacebookProto::SendMessageAckThread(void *param) +{ + Sleep(100); + ProtoBroadcastAck((UINT_PTR)param, ACKTYPE_MESSAGE, ACKRESULT_FAILED, (HANDLE)1, (LPARAM)TranslateT("Protocol is offline or user isn't authorized yet")); +} + +int FacebookProto::SendMsg(MCONTACT hContact, int, const char *pszSrc) +{ + if (!m_bOnline) { + ForkThread(&FacebookProto::SendMessageAckThread, (void *)hContact); + return 1; + } + + CMStringA userId(getMStringA(hContact, DBKEY_ID)); + + __int64 msgId; + Utils_GetRandom(&msgId, sizeof(msgId)); + msgId = abs(msgId); + + JSONNode root; + root << CHAR_PARAM("body", pszSrc) << INT64_PARAM("msgid", msgId) << INT64_PARAM("sender_fbid", m_uid) << CHAR_PARAM("to", userId); + MqttPublish("/send_message2", root.write().c_str()); + + arOwnMessages.insert(new COwnMessage(msgId, m_mid)); + return m_mid; +} + +///////////////////////////////////////////////////////////////////////////////////////// + int FacebookProto::SetStatus(int iNewStatus) { if (iNewStatus != ID_STATUS_OFFLINE && IsStatusConnecting(m_iStatus)) { diff --git a/protocols/Facebook/src/proto.h b/protocols/Facebook/src/proto.h index 6a91ca9fbd..be40348793 100644 --- a/protocols/Facebook/src/proto.h +++ b/protocols/Facebook/src/proto.h @@ -304,6 +304,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. class FacebookProto; +///////////////////////////////////////////////////////////////////////////////////////// + struct AsyncHttpRequest : public MTHttpRequest<FacebookProto> { struct Param @@ -337,6 +339,8 @@ public: __forceinline int error() const { return m_errorCode; } }; +///////////////////////////////////////////////////////////////////////////////////////// + struct FacebookUser { FacebookUser(__int64 _p1, MCONTACT _p2) : @@ -348,6 +352,20 @@ struct FacebookUser MCONTACT hContact; }; +///////////////////////////////////////////////////////////////////////////////////////// + +struct COwnMessage +{ + __int64 msgId; + int reqId; + + COwnMessage(__int64 _id, int _reqId) : + msgId(_id), + reqId(_reqId) + { + } +}; + class FacebookProto : public PROTO<FacebookProto> { uint8_t *doZip(size_t cbData, const void *pData, size_t &cbRes); @@ -398,6 +416,8 @@ class FacebookProto : public PROTO<FacebookProto> CMStringA m_szAuthToken; // calculated + OBJLIST<COwnMessage> arOwnMessages; + OBJLIST<FacebookUser> m_users; FacebookUser *FindUser(__int64 id) { @@ -410,7 +430,8 @@ class FacebookProto : public PROTO<FacebookProto> bool RefreshToken(); bool RefreshContacts(); - void __cdecl ServerThread(void *); + void __cdecl SendMessageAckThread(void *); + void __cdecl ServerThread(void *); public: FacebookProto(const char *proto_name, const wchar_t *username); @@ -421,6 +442,7 @@ public: } void OnPublishPrivateMessage(const JSONNode &json); + void OnPublishSentMessage(const JSONNode &json); ////////////////////////////////////////////////////////////////////////////////////// // options @@ -435,6 +457,7 @@ public: void OnShutdown() override; INT_PTR GetCaps(int type, MCONTACT hContact) override; + int SendMsg(MCONTACT hContact, int flags, const char *pszSrc); int SetStatus(int iNewStatus) override; int UserIsTyping(MCONTACT hContact, int type) override; diff --git a/protocols/Facebook/src/server.cpp b/protocols/Facebook/src/server.cpp index b87ba413ef..000e15684a 100644 --- a/protocols/Facebook/src/server.cpp +++ b/protocols/Facebook/src/server.cpp @@ -367,7 +367,8 @@ struct } static MsgHandlers[] = { - { "deltaNewMessage", &FacebookProto::OnPublishPrivateMessage } + { "deltaNewMessage", &FacebookProto::OnPublishPrivateMessage }, + { "deltaSentMessage", &FacebookProto::OnPublishSentMessage } }; void FacebookProto::OnPublishMessage(FbThriftReader &rdr) @@ -408,7 +409,7 @@ void FacebookProto::OnPublishPrivateMessage(const JSONNode &root) { auto &metadata = root["messageMetadata"]; __int64 offlineId = _wtoi64(metadata["offlineThreadingId"].as_mstring()); - if (offlineId) { + if (!offlineId) { debugLogA("We care about messages only, event skipped"); return; } @@ -429,3 +430,26 @@ void FacebookProto::OnPublishPrivateMessage(const JSONNode &root) pre.szMsgId = (char *)szId.c_str(); ProtoChainRecvMsg(pUser->hContact, &pre); } + +// my own message was sent +void FacebookProto::OnPublishSentMessage(const JSONNode &root) +{ + auto &metadata = root["messageMetadata"]; + + __int64 offlineId = _wtoi64(metadata["offlineThreadingId"].as_mstring()); + std::string szId(metadata["messageId"].as_string()); + + CMStringA wszUserId(metadata["threadKey"]["otherUserFbId"].as_mstring()); + auto *pUser = FindUser(_atoi64(wszUserId)); + if (pUser == nullptr) { + debugLogA("Message from unknown contact %s, ignored", wszUserId.c_str()); + return; + } + + for (auto &it : arOwnMessages) + if (it->msgId == offlineId) { + ProtoBroadcastAck(pUser->hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE)it->reqId, (LPARAM)szId.c_str()); + arOwnMessages.remove(arOwnMessages.indexOf(&it)); + break; + } +} diff --git a/protocols/Facebook/src/version.h b/protocols/Facebook/src/version.h index a1141f5a00..5d8a50c107 100644 --- a/protocols/Facebook/src/version.h +++ b/protocols/Facebook/src/version.h @@ -1,7 +1,7 @@ #define __MAJOR_VERSION 0 #define __MINOR_VERSION 0 #define __RELEASE_NUM 1 -#define __BUILD_NUM 0 +#define __BUILD_NUM 1 #include <stdver.h> |