From 0bfc7cda142437e55909073f0654de060e3e1614 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Fri, 10 May 2024 15:10:49 +0300 Subject: Discord: reply support --- protocols/Discord/src/dispatch.cpp | 12 ++++++++---- protocols/Discord/src/groupchat.cpp | 30 +++++++++++++----------------- protocols/Discord/src/proto.cpp | 16 ++++++++++++++-- 3 files changed, 35 insertions(+), 23 deletions(-) (limited to 'protocols/Discord/src') diff --git a/protocols/Discord/src/dispatch.cpp b/protocols/Discord/src/dispatch.cpp index e2dcb9d30d..a2a5cd8a57 100644 --- a/protocols/Discord/src/dispatch.cpp +++ b/protocols/Discord/src/dispatch.cpp @@ -463,12 +463,12 @@ void CDiscordProto::OnCommandMessage(const JSONNode &pRoot, bool bIsNew) if (lastId < msgId) setId(pUser->hContact, DB_KEY_LASTMSGID, msgId); - char szMsgId[100]; + char szMsgId[100], szReplyId[100]; _i64toa_s(msgId, szMsgId, _countof(szMsgId), 10); COwnMessage ownMsg(::getId(pRoot["nonce"]), 0); COwnMessage *p = arOwnMessages.find(&ownMsg); - if (p != nullptr) { // own message? skip it + if (p != nullptr && !Contact::IsGroupChat(pUser->hContact)) { // own message? skip it ProtoBroadcastAck(pUser->hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE)p->reqId, (LPARAM)szMsgId); debugLogA("skipping own message with nonce=%lld, id=%lld", ownMsg.nonce, msgId); } @@ -497,12 +497,16 @@ void CDiscordProto::OnCommandMessage(const JSONNode &pRoot, bool bIsNew) wszText.Insert(0, wszOldText); } + if (auto &nReply = pRoot["message_reference"]) { + _i64toa(::getId(nReply["message_id"]), szReplyId, 10); + dbei.szReplyId = szReplyId; + } + debugLogA("store a message from private user %lld, channel id %lld", pUser->id, pUser->channelId); - ptrA buf(mir_utf8encodeW(wszText)); dbei.timestamp = (uint32_t)StringToDate(pRoot["timestamp"].as_mstring()); - dbei.pBlob = buf; dbei.szId = szMsgId; + replaceStr(dbei.pBlob, mir_utf8encodeW(wszText)); if (!pUser->bIsPrivate || pUser->bIsGroup) { dbei.szUserId = szUserId; diff --git a/protocols/Discord/src/groupchat.cpp b/protocols/Discord/src/groupchat.cpp index b65bc0dffd..4a9d5bb457 100644 --- a/protocols/Discord/src/groupchat.cpp +++ b/protocols/Discord/src/groupchat.cpp @@ -333,7 +333,8 @@ int CDiscordProto::GroupchatEventHook(WPARAM, LPARAM lParam) if (gch == nullptr) return 0; - if (mir_strcmpi(gch->si->pszModule, m_szModuleName)) + auto *si = gch->si; + if (mir_strcmpi(si->pszModule, m_szModuleName)) return 0; switch (gch->iType) { @@ -346,27 +347,22 @@ int CDiscordProto::GroupchatEventHook(WPARAM, LPARAM lParam) if (pos != -1) { auto wszWord = wszText.Left(pos); wszWord.Trim(); - if (auto *si = Chat_Find(gch->si->ptszID, gch->si->pszModule)) { - USERINFO *pUser = nullptr; - - for (auto &U : si->getUserList()) - if (wszWord == U->pszNick) { - pUser = U; - break; - } - - if (pUser) { - wszText.Delete(0, pos); - wszText.Insert(0, L"<@" + CMStringW(pUser->pszUID) + L">"); + + USERINFO *pUser = nullptr; + for (auto &U : si->getUserList()) + if (wszWord == U->pszNick) { + pUser = U; + break; } + + if (pUser) { + wszText.Delete(0, pos); + wszText.Insert(0, L"<@" + CMStringW(pUser->pszUID) + L">"); } } Chat_UnescapeTags(wszText.GetBuffer()); - - JSONNode body; body << WCHAR_PARAM("content", wszText); - CMStringA szUrl(FORMAT, "/channels/%S/messages", gch->si->ptszID); - Push(new AsyncHttpRequest(this, REQUEST_POST, szUrl, nullptr, &body)); + SendMsg(si->hContact, (si->pDlg) ? si->pDlg->m_hQuoteEvent : 0, T2Utf(wszText)); } break; diff --git a/protocols/Discord/src/proto.cpp b/protocols/Discord/src/proto.cpp index 4c129de23b..48141312f5 100644 --- a/protocols/Discord/src/proto.cpp +++ b/protocols/Discord/src/proto.cpp @@ -227,7 +227,7 @@ INT_PTR CDiscordProto::GetCaps(int type, MCONTACT) return PF2_ONLINE | PF2_SHORTAWAY | PF2_HEAVYDND | PF2_INVISIBLE; case PFLAGNUM_4: return PF4_FORCEAUTH | PF4_NOCUSTOMAUTH | PF4_NOAUTHDENYREASON | PF4_SUPPORTTYPING | PF4_SUPPORTIDLE | PF4_AVATARS | - PF4_IMSENDOFFLINE | PF4_SERVERMSGID | PF4_OFFLINEFILES | PF4_GROUPCHATFILES; + PF4_IMSENDOFFLINE | PF4_SERVERMSGID | PF4_OFFLINEFILES | PF4_GROUPCHATFILES | PF4_REPLY; case PFLAG_UNIQUEIDTEXT: return (INT_PTR)TranslateT("User ID"); } @@ -484,7 +484,7 @@ void CDiscordProto::OnSendMsg(MHttpResponse *pReply, AsyncHttpRequest *pReq) } } -int CDiscordProto::SendMsg(MCONTACT hContact, MEVENT, const char *pszSrc) +int CDiscordProto::SendMsg(MCONTACT hContact, MEVENT hReplyEvent, const char *pszSrc) { if (!m_bOnline) return -1; @@ -516,6 +516,18 @@ int CDiscordProto::SendMsg(MCONTACT hContact, MEVENT, const char *pszSrc) SnowFlake nonce; Utils_GetRandom(&nonce, sizeof(nonce)); nonce = abs(nonce); JSONNode body; body << WCHAR_PARAM("content", wszText) << SINT64_PARAM("nonce", nonce); + if (hReplyEvent) { + SnowFlake iReplyId = 0; + DB::EventInfo dbei(hReplyEvent, false); + if (dbei && dbei.szId) { + iReplyId = _atoi64(dbei.szId); + + JSONNode reply; reply.set_name("message_reference"); + reply << INT64_PARAM("channel_id", pUser->channelId) << INT64_PARAM("message_id", iReplyId); + body << reply; + } + } + CMStringA szUrl(FORMAT, "/channels/%lld/messages", pUser->channelId); AsyncHttpRequest *pReq = new AsyncHttpRequest(this, REQUEST_POST, szUrl, &CDiscordProto::OnSendMsg, &body); pReq->hContact = hContact; -- cgit v1.2.3