summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2022-12-25 21:02:38 +0300
committerGeorge Hazan <ghazan@miranda.im>2022-12-25 21:02:38 +0300
commit815d356584371b59545f5a2918a48cebd3a3b396 (patch)
treeda2ab9dfd087c5d39eb4b2224677e7c13dbef689
parent0c66b748a7b6b223d34374994e4d7d207e3d2c71 (diff)
Telegram: text message sending
-rw-r--r--protocols/Telegram/src/mt_proto.cpp19
-rw-r--r--protocols/Telegram/src/mt_proto.h55
-rw-r--r--protocols/Telegram/src/server.cpp51
3 files changed, 115 insertions, 10 deletions
diff --git a/protocols/Telegram/src/mt_proto.cpp b/protocols/Telegram/src/mt_proto.cpp
index 9e0cffd97c..e3dd7b6d29 100644
--- a/protocols/Telegram/src/mt_proto.cpp
+++ b/protocols/Telegram/src/mt_proto.cpp
@@ -1,5 +1,13 @@
#include "stdafx.h"
+static int CompareRequests(const TG_REQUEST_BASE *p1, const TG_REQUEST_BASE *p2)
+{
+ if (p1->requestId == p2->requestId)
+ return 0;
+
+ return (p1->requestId < p2->requestId) ? -1 : 1;
+}
+
static int CompareUsers(const TG_USER *p1, const TG_USER *p2)
{
if (p1->id == p2->id)
@@ -12,7 +20,7 @@ CMTProto::CMTProto(const char* protoName, const wchar_t* userName) :
PROTO<CMTProto>(protoName, userName),
m_pClientMmanager(std::make_unique<td::ClientManager>()),
m_arUsers(10, CompareUsers),
- m_arRequests(10, NumericKeySortT),
+ m_arRequests(10, CompareRequests),
m_szOwnPhone(this, "Phone"),
m_wszDefaultGroup(this, "DefaultGroup", L"Telegram"),
m_bUsePopups(this, "UsePopups", true),
@@ -90,6 +98,15 @@ INT_PTR CMTProto::GetCaps(int type, MCONTACT)
return 0;
}
+int CMTProto::SendMsg(MCONTACT hContact, int, const char *pszMessage)
+{
+ ptrA szId(getStringA(hContact, DBKEY_ID));
+ if (szId == nullptr)
+ return 0;
+
+ return SendTextMessage(_atoi64(szId), pszMessage);
+}
+
int CMTProto::SetStatus(int iNewStatus)
{
if (m_iDesiredStatus == iNewStatus)
diff --git a/protocols/Telegram/src/mt_proto.h b/protocols/Telegram/src/mt_proto.h
index 402dee432f..cc07eddd99 100644
--- a/protocols/Telegram/src/mt_proto.h
+++ b/protocols/Telegram/src/mt_proto.h
@@ -3,19 +3,57 @@
#define DBKEY_ID "id"
class CMTProto;
-typedef void (CMTProto::*TG_QUERY_HANDLER)(td::ClientManager::Response &response);
+typedef void (CMTProto:: *TG_QUERY_HANDLER)(td::ClientManager::Response &response);
+typedef void (CMTProto:: *TG_QUERY_HANDLER_FULL)(td::ClientManager::Response &response, void *pUserInfo);
-struct TG_REQUEST
+struct TG_REQUEST_BASE
+{
+ TG_REQUEST_BASE(td::ClientManager::RequestId _1) :
+ requestId(_1)
+ {}
+
+ virtual ~TG_REQUEST_BASE()
+ {}
+
+ td::ClientManager::RequestId requestId;
+
+ virtual void Execute(CMTProto *ppro, td::ClientManager::Response &response) = 0;
+};
+
+struct TG_REQUEST : public TG_REQUEST_BASE
{
TG_REQUEST(td::ClientManager::RequestId _1, TG_QUERY_HANDLER _2) :
- requestId(_1),
+ TG_REQUEST_BASE(_1),
pHandler(_2)
{}
- td::ClientManager::RequestId requestId;
TG_QUERY_HANDLER pHandler;
+
+ void Execute(CMTProto *ppro, td::ClientManager::Response &response) override
+ {
+ (ppro->*pHandler)(response);
+ }
+};
+
+struct TG_REQUEST_FULL : public TG_REQUEST_BASE
+{
+ TG_REQUEST_FULL(td::ClientManager::RequestId _1, TG_QUERY_HANDLER_FULL _2, void *_3) :
+ TG_REQUEST_BASE(_1),
+ pHandler(_2),
+ pUserInfo(_3)
+ {}
+
+ TG_QUERY_HANDLER_FULL pHandler;
+ void *pUserInfo;
+
+ void Execute(CMTProto *ppro, td::ClientManager::Response &response) override
+ {
+ (ppro->*pHandler)(response, pUserInfo);
+ }
};
+/////////////////////////////////////////////////////////////////////////////////////////
+
struct TG_USER
{
TG_USER(uint64_t _1, MCONTACT _2, bool _3 = false) :
@@ -35,10 +73,10 @@ class CMTProto : public PROTO<CMTProto>
TD::object_ptr<TD::AuthorizationState> pAuthState;
bool m_bAuthorized, m_bRunning = false, m_bTerminated;
- int32_t m_iClientId;
+ int32_t m_iClientId, m_iMsgId;
uint64_t m_iQueryId;
- OBJLIST<TG_REQUEST> m_arRequests;
+ OBJLIST<TG_REQUEST_BASE> m_arRequests;
static INT_PTR CALLBACK EnterPhoneCode(void *param);
static INT_PTR CALLBACK EnterPassword(void *param);
@@ -53,6 +91,7 @@ class CMTProto : public PROTO<CMTProto>
void OnLoggedIn(void);
void ProcessResponse(td::ClientManager::Response);
void SendQuery(TD::Function *pFunc, TG_QUERY_HANDLER pHandler = nullptr);
+ void SendQuery(TD::Function *pFunc, TG_QUERY_HANDLER_FULL pHandler, void *pUserInfo);
void ProcessAuth(TD::updateAuthorizationState *pObj);
void ProcessChat(TD::updateNewChat *pObj);
@@ -60,6 +99,9 @@ class CMTProto : public PROTO<CMTProto>
void ProcessMessage(TD::updateNewMessage *pObj);
void ProcessUser(TD::updateUser *pObj);
+ void OnSendMessage(td::ClientManager::Response &response, void *pUserInfo);
+ int SendTextMessage(uint64_t chatId, const char *pszMessage);
+
void UpdateString(MCONTACT hContact, const char *pszSetting, const std::string &str);
// Users
@@ -87,6 +129,7 @@ public:
INT_PTR GetCaps(int type, MCONTACT hContact = NULL) override;
+ int SendMsg(MCONTACT hContact, int flags, const char *pszMessage) override;
int SetStatus(int iNewStatus) override;
void OnModulesLoaded() override;
diff --git a/protocols/Telegram/src/server.cpp b/protocols/Telegram/src/server.cpp
index 89db787400..a94fe77e8f 100644
--- a/protocols/Telegram/src/server.cpp
+++ b/protocols/Telegram/src/server.cpp
@@ -68,9 +68,10 @@ void CMTProto::ProcessResponse(td::ClientManager::Response response)
debugLogA("ProcessResponse: id=%d (%s)", int(response.request_id), to_string(response.object).c_str());
if (response.request_id) {
- auto *p = m_arRequests.find((TG_REQUEST *)&response.request_id);
+ TG_REQUEST tmp(response.request_id, 0);
+ auto *p = m_arRequests.find(&tmp);
if (p) {
- (this->*p->pHandler)(response);
+ p->Execute(this, response);
m_arRequests.remove(p);
}
return;
@@ -99,6 +100,41 @@ void CMTProto::ProcessResponse(td::ClientManager::Response response)
}
}
+void CMTProto::OnSendMessage(td::ClientManager::Response &response, void *pUserInfo)
+{
+ if (!response.object)
+ return;
+
+ if (response.object->get_id() != TD::message::ID) {
+ debugLogA("Gotten class ID %d instead of %d, exiting", response.object->get_id(), TD::message::ID);
+ return;
+ }
+
+ auto *pMessage = ((TD::message *)response.object.get());
+ auto *pUser = FindUser(pMessage->chat_id_);
+ if (pUser) {
+ char szMsgId[100];
+ _i64toa(pMessage->id_, szMsgId, 10);
+ ProtoBroadcastAck(pUser->hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, pUserInfo, (LPARAM)szMsgId);
+ }
+}
+
+int CMTProto::SendTextMessage(uint64_t chatId, const char *pszMessage)
+{
+ int ret = m_iMsgId++;
+
+ auto pContent = TD::make_object<TD::inputMessageText>();
+ pContent->text_ = TD::make_object<TD::formattedText>();
+ pContent->text_->text_ = std::move(pszMessage);
+
+ auto *pMessage = new TD::sendMessage();
+ pMessage->chat_id_ = chatId;
+ pMessage->input_message_content_ = std::move(pContent);
+ SendQuery(pMessage, &CMTProto::OnSendMessage, (void*)ret);
+
+ return ret;
+}
+
void CMTProto::SendQuery(TD::Function *pFunc, TG_QUERY_HANDLER pHandler)
{
int queryId = ++m_iQueryId;
@@ -108,6 +144,15 @@ void CMTProto::SendQuery(TD::Function *pFunc, TG_QUERY_HANDLER pHandler)
m_arRequests.insert(new TG_REQUEST(queryId, pHandler));
}
+void CMTProto::SendQuery(TD::Function *pFunc, TG_QUERY_HANDLER_FULL pHandler, void *pUserInfo)
+{
+ int queryId = ++m_iQueryId;
+ m_pClientMmanager->send(m_iClientId, queryId, TD::object_ptr<TD::Function>(pFunc));
+
+ if (pHandler)
+ m_arRequests.insert(new TG_REQUEST_FULL(queryId, pHandler, pUserInfo));
+}
+
///////////////////////////////////////////////////////////////////////////////
void CMTProto::ProcessChat(TD::updateNewChat *pObj)
@@ -169,7 +214,7 @@ void CMTProto::ProcessMessage(TD::updateNewMessage *pObj)
}
char szId[100];
- _i64toa(pMessage->id_, szId, _countof(szId));
+ _i64toa(pMessage->id_, szId, 10);
PROTORECVEVENT pre = {};
pre.szMessage = szText.GetBuffer();