summaryrefslogtreecommitdiff
path: root/protocols/Telegram/src
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2023-06-02 22:13:31 +0300
committerGeorge Hazan <george.hazan@gmail.com>2023-06-02 22:13:31 +0300
commitfe8e65a6696f1a4623111125ad10019caf3141dd (patch)
treef6a642e331766f8debe327e174b2d7392e7627dc /protocols/Telegram/src
parentc944dd795207f196ce64be39904506a58c9eac70 (diff)
fixes #3392 ([Telegram] Add support for file transfers (images etc) both incoming and outgoing)
Diffstat (limited to 'protocols/Telegram/src')
-rw-r--r--protocols/Telegram/src/proto.cpp84
-rw-r--r--protocols/Telegram/src/proto.h10
-rw-r--r--protocols/Telegram/src/server.cpp43
-rw-r--r--protocols/Telegram/src/utils.cpp25
-rw-r--r--protocols/Telegram/src/utils.h2
5 files changed, 158 insertions, 6 deletions
diff --git a/protocols/Telegram/src/proto.cpp b/protocols/Telegram/src/proto.cpp
index c7da8568ec..a7fe012792 100644
--- a/protocols/Telegram/src/proto.cpp
+++ b/protocols/Telegram/src/proto.cpp
@@ -331,6 +331,90 @@ HANDLE CTelegramProto::SearchByName(const wchar_t *nick, const wchar_t *firstNam
/////////////////////////////////////////////////////////////////////////////////////////
+HANDLE CTelegramProto::SendFile(MCONTACT hContact, const wchar_t *szDescription, wchar_t **ppszFiles)
+{
+ auto *pUser = FindUser(GetId(hContact));
+ if (pUser == nullptr) {
+ debugLogA("request from unknown contact %d, ignored", hContact);
+ return nullptr;
+ }
+
+ TG_FILE_REQUEST *pTransfer = nullptr;
+
+ for (int i = 0; ppszFiles[i] != 0; i++) {
+ struct _stat statbuf;
+ if (_wstat(ppszFiles[0], &statbuf)) {
+ debugLogW(L"'%s' is an invalid filename", ppszFiles[i]);
+ continue;
+ }
+
+ pTransfer = new TG_FILE_REQUEST(TG_FILE_REQUEST::FILE, 0, "");
+ pTransfer->m_fileName = ppszFiles[i];
+ if (m_bCompressFiles)
+ pTransfer->AutoDetectType();
+
+ pTransfer->m_hContact = hContact;
+ pTransfer->m_fileSize = statbuf.st_size;
+ if (mir_wstrlen(szDescription))
+ pTransfer->m_wszDescr = szDescription;
+
+ // create a message with embedded file
+ auto *pMessage = new TD::sendMessage();
+ pMessage->chat_id_ = pUser->chatId;
+ auto caption = TD::make_object<TD::formattedText>();
+ caption->text_ = T2Utf(szDescription).get();
+
+ if (pTransfer->m_type == TG_FILE_REQUEST::FILE) {
+ auto pContent = TD::make_object<TD::inputMessageDocument>();
+ pContent->document_= makeFile(pTransfer->m_fileName);
+ pContent->caption_ = std::move(caption);
+ pContent->thumbnail_ = 0;
+ pMessage->input_message_content_ = std::move(pContent);
+ }
+ else if (pTransfer->m_type == TG_FILE_REQUEST::PICTURE) {
+ auto pContent = TD::make_object<TD::inputMessagePhoto>();
+ pContent->photo_ = makeFile(pTransfer->m_fileName);
+ pContent->thumbnail_ = 0;
+ pContent->caption_ = std::move(caption);
+ pContent->ttl_ = 0;
+ pContent->height_ = 0;
+ pContent->width_ = 0;
+ pMessage->input_message_content_ = std::move(pContent);
+ }
+ else if (pTransfer->m_type == TG_FILE_REQUEST::VOICE) {
+ auto pContent = TD::make_object<TD::inputMessageVoiceNote>();
+ pContent->voice_note_ = makeFile(pTransfer->m_fileName);
+ pContent->caption_ = std::move(caption);
+ pContent->duration_ = 0;
+ pMessage->input_message_content_ = std::move(pContent);
+ }
+ else if (pTransfer->m_type == TG_FILE_REQUEST::VIDEO) {
+ auto pContent = TD::make_object<TD::inputMessageVideo>();
+ pContent->video_ = makeFile(pTransfer->m_fileName);
+ pContent->caption_ = std::move(caption);
+ pContent->duration_ = 0;
+ pContent->height_ = 0;
+ pContent->width_ = 0;
+ pContent->ttl_ = 0;
+ pMessage->input_message_content_ = std::move(pContent);
+ }
+ else return nullptr;
+
+ SendQuery(pMessage, &CTelegramProto::OnSendFile, pTransfer);
+ }
+
+ return pTransfer;
+}
+
+void CTelegramProto::OnSendFile(td::ClientManager::Response &, void *pUserInfo)
+{
+ auto *ft = (TG_FILE_REQUEST *)pUserInfo;
+ ProtoBroadcastAck(ft->m_hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft);
+ delete ft;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
int CTelegramProto::SendMsg(MCONTACT hContact, int, const char *pszMessage)
{
ptrA szId(getStringA(hContact, DBKEY_ID));
diff --git a/protocols/Telegram/src/proto.h b/protocols/Telegram/src/proto.h
index eaeb187795..e03405560a 100644
--- a/protocols/Telegram/src/proto.h
+++ b/protocols/Telegram/src/proto.h
@@ -70,12 +70,15 @@ struct TG_FILE_REQUEST : public MZeroedObject
m_uniqueId(_3)
{}
+ void AutoDetectType();
+
Type m_type;
bool m_bOpen = false;
MEVENT m_hEvent = 0;
+ MCONTACT m_hContact = 0;
TD::int53 m_fileId, m_fileSize = 0;
CMStringA m_uniqueId;
- CMStringW m_destPath, m_fileName;
+ CMStringW m_destPath, m_fileName, m_wszDescr;
};
struct TG_USER : public MZeroedObject
@@ -196,6 +199,7 @@ class CTelegramProto : public PROTO<CTelegramProto>
void OnGetFileInfo(td::ClientManager::Response &response, void *pUserInfo);
void OnGetHistory(td::ClientManager::Response &response, void *pUserInfo);
void OnSearchResults(td::ClientManager::Response &response);
+ void OnSendFile(td::ClientManager::Response &response, void *pUserInfo);
void OnSendMessage(td::ClientManager::Response &response, void *pUserInfo);
void OnUpdateAuth(td::ClientManager::Response &response);
@@ -221,7 +225,8 @@ class CTelegramProto : public PROTO<CTelegramProto>
void ProcessFile(TD::updateFile *pObj);
void ProcessGroups(TD::updateChatFilters *pObj);
void ProcessMarkRead(TD::updateChatReadInbox *pObj);
- void ProcessMessage(TD::updateNewMessage *pObj);
+ void ProcessMessage(const TD::message *pMsg);
+ void ProcessMessageContent(TD::updateMessageContent *pObj);
void ProcessOption(TD::updateOption *pObj);
void ProcessStatus(TD::updateUserStatus *pObj);
void ProcessSuperGroup(TD::updateSupergroup *pObj);
@@ -303,6 +308,7 @@ public:
INT_PTR GetCaps(int type, MCONTACT hContact = NULL) override;
+ HANDLE SendFile(MCONTACT hContact, const wchar_t *szDescription, wchar_t **ppszFiles) override;
MEVENT RecvFile(MCONTACT hContact, PROTORECVFILE *pre) override;
HANDLE SearchByName(const wchar_t *nick, const wchar_t *firstName, const wchar_t *lastName) override;
diff --git a/protocols/Telegram/src/server.cpp b/protocols/Telegram/src/server.cpp
index 2b83443ec8..3b8ddda8ca 100644
--- a/protocols/Telegram/src/server.cpp
+++ b/protocols/Telegram/src/server.cpp
@@ -176,12 +176,20 @@ void CTelegramProto::ProcessResponse(td::ClientManager::Response response)
ProcessFile((TD::updateFile *)response.object.get());
break;
+ case TD::updateMessageContent::ID:
+ ProcessMessageContent((TD::updateMessageContent *)response.object.get());
+ break;
+
+ case TD::updateMessageSendSucceeded::ID:
+ ProcessMessage(((TD::updateMessageSendSucceeded *)response.object.get())->message_.get());
+ break;
+
case TD::updateNewChat::ID:
ProcessChat((TD::updateNewChat *)response.object.get());
break;
case TD::updateNewMessage::ID:
- ProcessMessage((TD::updateNewMessage *)response.object.get());
+ ProcessMessage(((TD::updateNewMessage *)response.object.get())->message_.get());
break;
case TD::updateOption::ID:
@@ -588,16 +596,18 @@ void CTelegramProto::ProcessMarkRead(TD::updateChatReadInbox *pObj)
}
}
-void CTelegramProto::ProcessMessage(TD::updateNewMessage *pObj)
+void CTelegramProto::ProcessMessage(const TD::message *pMessage)
{
- auto *pMessage = pObj->message_.get();
-
auto *pUser = FindChat(pMessage->chat_id_);
if (pUser == nullptr) {
debugLogA("message from unknown chat/user, ignored");
return;
}
+ if (pMessage->sending_state_)
+ if (pMessage->sending_state_->get_id() == TD::messageSendingStatePending::ID)
+ return;
+
CMStringA szText(GetMessageText(pUser, pMessage));
if (szText.IsEmpty()) {
debugLogA("this message was not processed, ignored");
@@ -629,6 +639,31 @@ void CTelegramProto::ProcessMessage(TD::updateNewMessage *pObj)
ProtoChainRecvMsg((pUser->hContact) ? pUser->hContact : m_iSavedMessages, &pre);
}
+void CTelegramProto::ProcessMessageContent(TD::updateMessageContent *pObj)
+{
+ auto *pUser = FindChat(pObj->chat_id_);
+ if (pUser == nullptr) {
+ debugLogA("message from unknown chat/user, ignored");
+ return;
+ }
+
+ char szMsgId[100];
+ _i64toa(pObj->message_id_, szMsgId, 10);
+
+ MEVENT hDbEvent = db_event_getById(m_szModuleName, szMsgId);
+ if (hDbEvent == 0) {
+ debugLogA("Unknown message with id=%lld (chat id %lld, ignored", pObj->message_id_, pObj->chat_id_);
+ return;
+ }
+
+ /*
+ CMStringA szText(GetMessageText(pUser, pObj->new_content_.get()));
+ if (szText.IsEmpty()) {
+ debugLogA("this message was not processed, ignored");
+ return;
+ }*/
+}
+
void CTelegramProto::ProcessOption(TD::updateOption *pObj)
{
TD::int53 iValue = 0;
diff --git a/protocols/Telegram/src/utils.cpp b/protocols/Telegram/src/utils.cpp
index 5fabcb2c61..cc8aff096e 100644
--- a/protocols/Telegram/src/utils.cpp
+++ b/protocols/Telegram/src/utils.cpp
@@ -22,6 +22,31 @@ const char *getName(const TD::usernames *pName)
return (pName == nullptr) ? TranslateU("none") : pName->editable_username_.c_str();
}
+TD::object_ptr<TD::inputFileLocal> makeFile(const CMStringW &wszFile)
+{
+ std::string szPath = T2Utf(wszFile);
+ return TD::make_object<TD::inputFileLocal>(std::move(szPath));
+}
+
+void TG_FILE_REQUEST::AutoDetectType()
+{
+ if (ProtoGetAvatarFileFormat(m_fileName) != PA_FORMAT_UNKNOWN) {
+ m_type = this->PICTURE;
+ return;
+ }
+
+ int idx = m_fileName.ReverseFind('.');
+ if (idx == -1 || m_fileName.Find('\\', idx) != -1)
+ return;
+
+ auto wszExt = m_fileName.Right(m_fileName.GetLength() - idx);
+ wszExt.MakeLower();
+ if (wszExt == L"mp4" || wszExt == L"webm")
+ m_type = this->VIDEO;
+ else if (wszExt == L"mp3" || wszExt == "ogg" || wszExt == "oga" || wszExt == "wav")
+ m_type = this->VOICE;
+}
+
CMStringW TG_USER::getDisplayName() const
{
if (!wszFirstName.IsEmpty())
diff --git a/protocols/Telegram/src/utils.h b/protocols/Telegram/src/utils.h
index 7f98ecbcf6..ad42a3e425 100644
--- a/protocols/Telegram/src/utils.h
+++ b/protocols/Telegram/src/utils.h
@@ -1,3 +1,5 @@
#pragma once
const char *getName(const TD::usernames *pName);
+
+TD::object_ptr<TD::inputFileLocal> makeFile(const CMStringW &wszFile);