summaryrefslogtreecommitdiff
path: root/protocols
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2019-12-27 22:51:52 +0300
committerGeorge Hazan <ghazan@miranda.im>2019-12-27 22:51:52 +0300
commit8bc24cb41ad6db6fc56731c9dffcb765cbd9a79f (patch)
tree6403195285ecb7beae3a8547d65932257803cdc9 /protocols
parent42b48e4121e22cea97a9d4fc4c671b59004c77b9 (diff)
Facebook: sending messages
Diffstat (limited to 'protocols')
-rw-r--r--protocols/Discord/src/proto.cpp2
-rw-r--r--protocols/Facebook/src/proto.cpp38
-rw-r--r--protocols/Facebook/src/proto.h25
-rw-r--r--protocols/Facebook/src/server.cpp28
-rw-r--r--protocols/Facebook/src/version.h2
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>