diff options
author | George Hazan <george.hazan@gmail.com> | 2023-06-02 22:13:31 +0300 |
---|---|---|
committer | George Hazan <george.hazan@gmail.com> | 2023-06-02 22:13:31 +0300 |
commit | fe8e65a6696f1a4623111125ad10019caf3141dd (patch) | |
tree | f6a642e331766f8debe327e174b2d7392e7627dc /protocols/Telegram/src | |
parent | c944dd795207f196ce64be39904506a58c9eac70 (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.cpp | 84 | ||||
-rw-r--r-- | protocols/Telegram/src/proto.h | 10 | ||||
-rw-r--r-- | protocols/Telegram/src/server.cpp | 43 | ||||
-rw-r--r-- | protocols/Telegram/src/utils.cpp | 25 | ||||
-rw-r--r-- | protocols/Telegram/src/utils.h | 2 |
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);
|