From 0b2f5dc1d8da227609af4eb737bf5dbe81b88349 Mon Sep 17 00:00:00 2001 From: Kristofer Berggren Date: Sun, 24 Sep 2023 22:17:27 +0800 Subject: [PATCH] add whatsapp support for editing messages --- lib/common/src/protocol.h | 3 ++- lib/common/src/version.h | 2 +- lib/tgchat/src/tgchat.cpp | 2 +- lib/wmchat/go/cgowm.go | 4 ++-- lib/wmchat/go/gowm.go | 39 ++++++++++++++++++++++++++------------- lib/wmchat/src/wmchat.cpp | 39 +++++++++++++++++++++++++++++++++++++-- src/nchat.1 | 2 +- src/uimodel.cpp | 20 +++++++++++++++++--- 8 files changed, 87 insertions(+), 24 deletions(-) diff --git a/lib/common/src/protocol.h b/lib/common/src/protocol.h index 57ce6ba4..0b13e7a3 100644 --- a/lib/common/src/protocol.h +++ b/lib/common/src/protocol.h @@ -21,7 +21,8 @@ enum ProtocolFeature FeatureNone = 0, FeatureAutoGetChatsOnLogin = (1 << 0), FeatureTypingTimeout = (1 << 1), - FeatureEditMessages = (1 << 2), + FeatureEditMessagesWithinTwoDays = (1 << 2), + FeatureEditMessagesWithinFifteenMins = (1 << 3), }; class Protocol diff --git a/lib/common/src/version.h b/lib/common/src/version.h index 953de1c8..69b5e048 100644 --- a/lib/common/src/version.h +++ b/lib/common/src/version.h @@ -7,4 +7,4 @@ #pragma once -#define NCHAT_VERSION "3.72" +#define NCHAT_VERSION "3.73" diff --git a/lib/tgchat/src/tgchat.cpp b/lib/tgchat/src/tgchat.cpp index 9aa464a0..a7766c32 100644 --- a/lib/tgchat/src/tgchat.cpp +++ b/lib/tgchat/src/tgchat.cpp @@ -257,7 +257,7 @@ std::string TgChat::Impl::GetProfileId() const bool TgChat::Impl::HasFeature(ProtocolFeature p_ProtocolFeature) const { - static int customFeatures = FeatureTypingTimeout | FeatureEditMessages; + static int customFeatures = FeatureTypingTimeout | FeatureEditMessagesWithinTwoDays; return (p_ProtocolFeature & customFeatures); } diff --git a/lib/wmchat/go/cgowm.go b/lib/wmchat/go/cgowm.go index d5c59776..87c5d2b4 100644 --- a/lib/wmchat/go/cgowm.go +++ b/lib/wmchat/go/cgowm.go @@ -55,8 +55,8 @@ func CWmGetMessages(connId int, chatId *C.char, limit int, fromMsgId *C.char, ow } //export CWmSendMessage -func CWmSendMessage(connId int, chatId *C.char, text *C.char, quotedId *C.char, quotedText *C.char, quotedSender *C.char, filePath *C.char, fileType *C.char) int { - return WmSendMessage(connId, C.GoString(chatId), C.GoString(text), C.GoString(quotedId), C.GoString(quotedText), C.GoString(quotedSender), C.GoString(filePath), C.GoString(fileType)) +func CWmSendMessage(connId int, chatId *C.char, text *C.char, quotedId *C.char, quotedText *C.char, quotedSender *C.char, filePath *C.char, fileType *C.char, editMsgId *C.char, editMsgSent int) int { + return WmSendMessage(connId, C.GoString(chatId), C.GoString(text), C.GoString(quotedId), C.GoString(quotedText), C.GoString(quotedSender), C.GoString(filePath), C.GoString(fileType), C.GoString(editMsgId), editMsgSent) } //export CWmGetStatus diff --git a/lib/wmchat/go/gowm.go b/lib/wmchat/go/gowm.go index 65ce9245..89d81938 100644 --- a/lib/wmchat/go/gowm.go +++ b/lib/wmchat/go/gowm.go @@ -1559,7 +1559,7 @@ func WmGetMessages(connId int, chatId string, limit int, fromMsgId string, owner return -1 } -func WmSendMessage(connId int, chatId string, text string, quotedId string, quotedText string, quotedSender string, filePath string, fileType string) int { +func WmSendMessage(connId int, chatId string, text string, quotedId string, quotedText string, quotedSender string, filePath string, fileType string, editMsgId string, editMsgSent int) int { LOG_TRACE("send message " + strconv.Itoa(connId) + ", " + chatId + ", " + text) @@ -1575,7 +1575,6 @@ func WmSendMessage(connId int, chatId string, text string, quotedId string, quot // local vars var sendErr error var message waProto.Message - var timeStamp time.Time var sendResponse whatsmeow.SendResponse // recipient @@ -1585,6 +1584,8 @@ func WmSendMessage(connId int, chatId string, text string, quotedId string, quot return -1 } + isSend := false + // check message type if len(filePath) == 0 { @@ -1620,9 +1621,7 @@ func WmSendMessage(connId int, chatId string, text string, quotedId string, quot message.Conversation = &text } - // send message - sendResponse, sendErr = client.SendMessage(context.Background(), chatJid, &message) - + isSend = true } else { mimeType := strings.Split(fileType, "/")[0] // image, text, application, etc. @@ -1655,9 +1654,7 @@ func WmSendMessage(connId int, chatId string, text string, quotedId string, quot message.ImageMessage = &imageMessage - // send message - sendResponse, sendErr = client.SendMessage(context.Background(), chatJid, &message) - + isSend = true } else { LOG_TRACE("send document " + fileType) @@ -1689,8 +1686,21 @@ func WmSendMessage(connId int, chatId string, text string, quotedId string, quot message.DocumentMessage = &documentMessage + isSend = true + } + } + + if isSend { + + if len(editMsgId) > 0 { + // edit message + sendResponse, sendErr = + client.SendMessage(context.Background(), chatJid, client.BuildEdit(chatJid, editMsgId, &message)) + + } else { // send message sendResponse, sendErr = client.SendMessage(context.Background(), chatJid, &message) + } } @@ -1701,16 +1711,19 @@ func WmSendMessage(connId int, chatId string, text string, quotedId string, quot } else { LOG_TRACE(fmt.Sprintf("send message ok")) - timeStamp = sendResponse.Timestamp - msgId := sendResponse.ID - // messageInfo var messageInfo types.MessageInfo messageInfo.Chat = chatJid - messageInfo.ID = msgId messageInfo.IsFromMe = true messageInfo.Sender = *client.Store.ID - messageInfo.Timestamp = timeStamp + + if len(editMsgId) > 0 { + messageInfo.ID = editMsgId + messageInfo.Timestamp = time.Unix(int64(editMsgSent), 0) + } else { + messageInfo.ID = sendResponse.ID + messageInfo.Timestamp = sendResponse.Timestamp + } handler := GetHandler(connId) handler.HandleMessage(messageInfo, &message, false) diff --git a/lib/wmchat/src/wmchat.cpp b/lib/wmchat/src/wmchat.cpp index 18218fa5..db8c022a 100644 --- a/lib/wmchat/src/wmchat.cpp +++ b/lib/wmchat/src/wmchat.cpp @@ -43,7 +43,7 @@ std::string WmChat::GetProfileId() const bool WmChat::HasFeature(ProtocolFeature p_ProtocolFeature) const { - ProtocolFeature customFeatures = FeatureNone; + ProtocolFeature customFeatures = FeatureEditMessagesWithinFifteenMins; return (p_ProtocolFeature & customFeatures); } @@ -278,12 +278,14 @@ void WmChat::PerformRequest(std::shared_ptr p_RequestMessage) std::shared_ptr sendMessageRequest = std::static_pointer_cast(p_RequestMessage); std::string chatId = sendMessageRequest->chatId; + std::string editMsgId = ""; std::string text = sendMessageRequest->chatMessage.text; std::string quotedId = sendMessageRequest->chatMessage.quotedId; std::string quotedText = sendMessageRequest->chatMessage.quotedText; std::string quotedSender = sendMessageRequest->chatMessage.quotedSender; std::string filePath; std::string fileType; + int editMsgSent = 0; if (!sendMessageRequest->chatMessage.fileInfo.empty()) { FileInfo fileInfo = @@ -296,7 +298,8 @@ void WmChat::PerformRequest(std::shared_ptr p_RequestMessage) CWmSendMessage(m_ConnId, const_cast(chatId.c_str()), const_cast(text.c_str()), const_cast(quotedId.c_str()), const_cast(quotedText.c_str()), const_cast(quotedSender.c_str()), const_cast(filePath.c_str()), - const_cast(fileType.c_str())); + const_cast(fileType.c_str()), const_cast(editMsgId.c_str()), + editMsgSent); Status::Clear(Status::FlagSending); std::shared_ptr sendMessageNotify = std::make_shared(m_ProfileId); @@ -307,6 +310,38 @@ void WmChat::PerformRequest(std::shared_ptr p_RequestMessage) } break; + case EditMessageRequestType: + { + LOG_DEBUG("edit message"); + Status::Set(Status::FlagSending); + std::shared_ptr editMessageRequest = + std::static_pointer_cast(p_RequestMessage); + std::string chatId = editMessageRequest->chatId; + std::string editMsgId = editMessageRequest->msgId; + std::string text = editMessageRequest->chatMessage.text; + std::string quotedId = editMessageRequest->chatMessage.quotedId; + std::string quotedText = editMessageRequest->chatMessage.quotedText; + std::string quotedSender = editMessageRequest->chatMessage.quotedSender; + std::string filePath; + std::string fileType; + int editMsgSent = editMessageRequest->chatMessage.timeSent / 1000; + if (!editMessageRequest->chatMessage.fileInfo.empty()) + { + FileInfo fileInfo = + ProtocolUtil::FileInfoFromHex(editMessageRequest->chatMessage.fileInfo); + filePath = fileInfo.filePath; + fileType = fileInfo.fileType; + } + + CWmSendMessage(m_ConnId, const_cast(chatId.c_str()), const_cast(text.c_str()), + const_cast(quotedId.c_str()), const_cast(quotedText.c_str()), + const_cast(quotedSender.c_str()), const_cast(filePath.c_str()), + const_cast(fileType.c_str()), const_cast(editMsgId.c_str()), + editMsgSent); + Status::Clear(Status::FlagSending); + } + break; + case MarkMessageReadRequestType: { LOG_DEBUG("mark message read"); diff --git a/src/nchat.1 b/src/nchat.1 index df843dbb..30f5a28b 100644 --- a/src/nchat.1 +++ b/src/nchat.1 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man. -.TH NCHAT "1" "September 2023" "nchat v3.72" "User Commands" +.TH NCHAT "1" "September 2023" "nchat v3.73" "User Commands" .SH NAME nchat \- ncurses chat .SH SYNOPSIS diff --git a/src/uimodel.cpp b/src/uimodel.cpp index 253a0f08..58a0b7fd 100644 --- a/src/uimodel.cpp +++ b/src/uimodel.cpp @@ -2677,7 +2677,8 @@ void UiModel::EditMessage() if (!GetSelectMessageActive() || GetEditMessageActive()) return; std::string profileId = m_CurrentChat.first; - if (!m_Protocols[profileId]->HasFeature(FeatureEditMessages)) + if (!m_Protocols[profileId]->HasFeature(FeatureEditMessagesWithinTwoDays) && + !m_Protocols[profileId]->HasFeature(FeatureEditMessagesWithinFifteenMins)) { MessageDialog("Warning", "Protocol does not support editing.", 0.7, 5); return; @@ -2701,12 +2702,22 @@ void UiModel::EditMessage() const time_t timeNow = time(NULL); const time_t timeSent = (time_t)(chatMessage.timeSent / 1000); const time_t messageAgeSec = timeNow - timeSent; - static const time_t maxEditAgeSec = 48 * 3600; - if (messageAgeSec >= maxEditAgeSec) + static const time_t twoDaysSec = 48 * 3600; + static const time_t fifteenMinsSec = 15 * 60; + + if (m_Protocols[profileId]->HasFeature(FeatureEditMessagesWithinTwoDays) && + (messageAgeSec >= twoDaysSec)) { MessageDialog("Warning", "Messages older than 48 hours cannot be edited.", 0.8, 5); return; } + else if (m_Protocols[profileId]->HasFeature(FeatureEditMessagesWithinFifteenMins) && + (messageAgeSec >= fifteenMinsSec)) + + { + MessageDialog("Warning", "Messages older than 15 minutes cannot be edited.", 0.8, 5); + return; + } m_EditMessageId = messageId; SetEditMessageActive(true); @@ -2727,6 +2738,8 @@ void UiModel::SaveEditMessage() std::string profileId = m_CurrentChat.first; std::string chatId = m_CurrentChat.second; std::wstring& entryStr = m_EntryStr[profileId][chatId]; + const std::unordered_map& messages = m_Messages[profileId][chatId]; + const ChatMessage& chatMessage = messages.at(m_EditMessageId); if (entryStr.empty()) return; @@ -2735,6 +2748,7 @@ void UiModel::SaveEditMessage() editMessageRequest->chatId = chatId; editMessageRequest->msgId = m_EditMessageId; editMessageRequest->chatMessage.text = EntryStrToSendStr(entryStr); + editMessageRequest->chatMessage.timeSent = chatMessage.timeSent; m_Protocols[profileId]->SendRequest(editMessageRequest); SetEditMessageActive(false);