Edit message media.
GitOrigin-RevId: eba2f32f4e033720ea1143463a9f3d1eae54880d
This commit is contained in:
parent
744df9f511
commit
4d5197d31c
@ -2498,32 +2498,40 @@ deleteMessages chat_id:int53 message_ids:vector<int53> revoke:Bool = Ok;
|
|||||||
deleteChatMessagesFromUser chat_id:int53 user_id:int32 = Ok;
|
deleteChatMessagesFromUser chat_id:int53 user_id:int32 = Ok;
|
||||||
|
|
||||||
|
|
||||||
//@description Edits the text of a message (or a text of a game message). Non-bot users can edit messages for a limited period of time. Returns the edited message after the edit is completed on the server side
|
//@description Edits the text of a message (or a text of a game message). Returns the edited message after the edit is completed on the server side
|
||||||
//@chat_id The chat the message belongs to @message_id Identifier of the message @reply_markup The new message reply markup; for bots only @input_message_content New text content of the message. Should be of type InputMessageText
|
//@chat_id The chat the message belongs to @message_id Identifier of the message @reply_markup The new message reply markup; for bots only @input_message_content New text content of the message. Should be of type InputMessageText
|
||||||
editMessageText chat_id:int53 message_id:int53 reply_markup:ReplyMarkup input_message_content:InputMessageContent = Message;
|
editMessageText chat_id:int53 message_id:int53 reply_markup:ReplyMarkup input_message_content:InputMessageContent = Message;
|
||||||
|
|
||||||
//@description Edits the message content of a live location. Messages can be edited for a limited period of time specified in the live location. Returns the edited message after the edit is completed server-side
|
//@description Edits the message content of a live location. Messages can be edited for a limited period of time specified in the live location. Returns the edited message after the edit is completed server-side
|
||||||
//@chat_id The chat the message belongs to @message_id Identifier of the message @reply_markup Tew message reply markup; for bots only @location New location content of the message; may be null. Pass null to stop sharing the live location
|
//@chat_id The chat the message belongs to @message_id Identifier of the message @reply_markup The new message reply markup; for bots only @location New location content of the message; may be null. Pass null to stop sharing the live location
|
||||||
editMessageLiveLocation chat_id:int53 message_id:int53 reply_markup:ReplyMarkup location:location = Message;
|
editMessageLiveLocation chat_id:int53 message_id:int53 reply_markup:ReplyMarkup location:location = Message;
|
||||||
|
|
||||||
//@description Edits the message content caption. Non-bots can edit messages for a limited period of time. Returns the edited message after the edit is completed server-side
|
//@description Edits the message content of an animation, an audio, a document, a photo or a video. A message media can't be edited if the message is self-destructed or to self-destructed message. A message in a message album can be edited only to a photo or a video. Returns the edited message after the edit is completed server-side
|
||||||
|
//@chat_id The chat the message belongs to @message_id Identifier of the message @reply_markup The new message reply markup; for bots only @input_message_content New content of the message. Must be one of the following types: InputMessageAnimation, InputMessageAudio, InputMessageDocument, InputMessagePhoto or InputMessageVideo
|
||||||
|
editMessageMedia chat_id:int53 message_id:int53 reply_markup:ReplyMarkup input_message_content:InputMessageContent = Message;
|
||||||
|
|
||||||
|
//@description Edits the message content caption. Returns the edited message after the edit is completed server-side
|
||||||
//@chat_id The chat the message belongs to @message_id Identifier of the message @reply_markup The new message reply markup; for bots only @caption New message content caption; 0-200 characters
|
//@chat_id The chat the message belongs to @message_id Identifier of the message @reply_markup The new message reply markup; for bots only @caption New message content caption; 0-200 characters
|
||||||
editMessageCaption chat_id:int53 message_id:int53 reply_markup:ReplyMarkup caption:formattedText = Message;
|
editMessageCaption chat_id:int53 message_id:int53 reply_markup:ReplyMarkup caption:formattedText = Message;
|
||||||
|
|
||||||
//@description Edits the message reply markup; for bots only. Returns the edited message after the edit is completed server-side
|
//@description Edits the message reply markup; for bots only. Returns the edited message after the edit is completed server-side
|
||||||
//@chat_id The chat the message belongs to @message_id Identifier of the message @reply_markup New message reply markup
|
//@chat_id The chat the message belongs to @message_id Identifier of the message @reply_markup The new message reply markup
|
||||||
editMessageReplyMarkup chat_id:int53 message_id:int53 reply_markup:ReplyMarkup = Message;
|
editMessageReplyMarkup chat_id:int53 message_id:int53 reply_markup:ReplyMarkup = Message;
|
||||||
|
|
||||||
//@description Edits the text of an inline text or game message sent via a bot; for bots only @inline_message_id Inline message identifier @reply_markup New message reply markup @input_message_content New text content of the message. Should be of type InputMessageText
|
//@description Edits the text of an inline text or game message sent via a bot; for bots only @inline_message_id Inline message identifier @reply_markup The new message reply markup @input_message_content New text content of the message. Should be of type InputMessageText
|
||||||
editInlineMessageText inline_message_id:string reply_markup:ReplyMarkup input_message_content:InputMessageContent = Ok;
|
editInlineMessageText inline_message_id:string reply_markup:ReplyMarkup input_message_content:InputMessageContent = Ok;
|
||||||
|
|
||||||
//@description Edits the content of a live location in an inline message sent via a bot; for bots only @inline_message_id Inline message identifier @reply_markup New message reply markup @location New location content of the message; may be null. Pass null to stop sharing the live location
|
//@description Edits the content of a live location in an inline message sent via a bot; for bots only @inline_message_id Inline message identifier @reply_markup The new message reply markup @location New location content of the message; may be null. Pass null to stop sharing the live location
|
||||||
editInlineMessageLiveLocation inline_message_id:string reply_markup:ReplyMarkup location:location = Ok;
|
editInlineMessageLiveLocation inline_message_id:string reply_markup:ReplyMarkup location:location = Ok;
|
||||||
|
|
||||||
//@description Edits the caption of an inline message sent via a bot; for bots only @inline_message_id Inline message identifier @reply_markup New message reply markup @caption New message content caption; 0-200 characters
|
//@description Edits the message content of an animation, an audio, a document, a photo or a video in an inline message sent via a bot; for bots only @inline_message_id Inline message identifier
|
||||||
|
//@reply_markup The new message reply markup; for bots only @input_message_content New content of the message. Must be one of the following types: InputMessageAnimation, InputMessageAudio, InputMessageDocument, InputMessagePhoto or InputMessageVideo
|
||||||
|
editInlineMessageMedia inline_message_id:string reply_markup:ReplyMarkup input_message_content:InputMessageContent = Ok;
|
||||||
|
|
||||||
|
//@description Edits the caption of an inline message sent via a bot; for bots only @inline_message_id Inline message identifier @reply_markup The new message reply markup @caption New message content caption; 0-200 characters
|
||||||
editInlineMessageCaption inline_message_id:string reply_markup:ReplyMarkup caption:formattedText = Ok;
|
editInlineMessageCaption inline_message_id:string reply_markup:ReplyMarkup caption:formattedText = Ok;
|
||||||
|
|
||||||
//@description Edits the reply markup of an inline message sent via a bot; for bots only @inline_message_id Inline message identifier @reply_markup New message reply markup
|
//@description Edits the reply markup of an inline message sent via a bot; for bots only @inline_message_id Inline message identifier @reply_markup The new message reply markup
|
||||||
editInlineMessageReplyMarkup inline_message_id:string reply_markup:ReplyMarkup = Ok;
|
editInlineMessageReplyMarkup inline_message_id:string reply_markup:ReplyMarkup = Ok;
|
||||||
|
|
||||||
|
|
||||||
|
Binary file not shown.
@ -1834,6 +1834,7 @@ class SendSecretMessageActor : public NetActor {
|
|||||||
int64 random_id) {
|
int64 random_id) {
|
||||||
if (false && !media.empty()) {
|
if (false && !media.empty()) {
|
||||||
td->messages_manager_->on_send_secret_message_error(random_id, Status::Error(400, "FILE_PART_1_MISSING"), Auto());
|
td->messages_manager_->on_send_secret_message_error(random_id, Status::Error(400, "FILE_PART_1_MISSING"), Auto());
|
||||||
|
stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1886,6 +1887,7 @@ class SendMessageActor : public NetActorOnce {
|
|||||||
auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Write);
|
auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Write);
|
||||||
if (input_peer == nullptr) {
|
if (input_peer == nullptr) {
|
||||||
on_error(0, Status::Error(400, "Have no write access to the chat"));
|
on_error(0, Status::Error(400, "Have no write access to the chat"));
|
||||||
|
stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2061,6 +2063,7 @@ class SendMultiMediaActor : public NetActorOnce {
|
|||||||
auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Write);
|
auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Write);
|
||||||
if (input_peer == nullptr) {
|
if (input_peer == nullptr) {
|
||||||
on_error(0, Status::Error(400, "Have no write access to the chat"));
|
on_error(0, Status::Error(400, "Have no write access to the chat"));
|
||||||
|
stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2160,6 +2163,7 @@ class SendMediaActor : public NetActorOnce {
|
|||||||
auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Write);
|
auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Write);
|
||||||
if (input_peer == nullptr) {
|
if (input_peer == nullptr) {
|
||||||
on_error(0, Status::Error(400, "Have no write access to the chat"));
|
on_error(0, Status::Error(400, "Have no write access to the chat"));
|
||||||
|
stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!entities.empty()) {
|
if (!entities.empty()) {
|
||||||
@ -2210,6 +2214,10 @@ class SendMediaActor : public NetActorOnce {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
td->messages_manager_->on_get_dialog_error(dialog_id_, status, "SendMediaActor");
|
td->messages_manager_->on_get_dialog_error(dialog_id_, status, "SendMediaActor");
|
||||||
|
if (thumbnail_file_id_.is_valid()) {
|
||||||
|
// always delete partial remote location for the thumbnail, because it can't be reused anyway
|
||||||
|
td->file_manager_->delete_partial_remote_location(thumbnail_file_id_);
|
||||||
|
}
|
||||||
if (file_id_.is_valid()) {
|
if (file_id_.is_valid()) {
|
||||||
if (begins_with(status.message(), "FILE_PART_") && ends_with(status.message(), "_MISSING")) {
|
if (begins_with(status.message(), "FILE_PART_") && ends_with(status.message(), "_MISSING")) {
|
||||||
td->messages_manager_->on_send_message_file_part_missing(random_id_,
|
td->messages_manager_->on_send_message_file_part_missing(random_id_,
|
||||||
@ -2221,10 +2229,6 @@ class SendMediaActor : public NetActorOnce {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (thumbnail_file_id_.is_valid()) {
|
|
||||||
// always delete partial remote location for the thumbnail, because it can't be reused anyway
|
|
||||||
td->file_manager_->delete_partial_remote_location(thumbnail_file_id_);
|
|
||||||
}
|
|
||||||
td->messages_manager_->on_send_message_fail(random_id_, std::move(status));
|
td->messages_manager_->on_send_message_fail(random_id_, std::move(status));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -2260,6 +2264,11 @@ class UploadMediaQuery : public Td::ResultHandler {
|
|||||||
return on_error(id, result_ptr.move_as_error());
|
return on_error(id, result_ptr.move_as_error());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (thumbnail_file_id_.is_valid()) {
|
||||||
|
// always delete partial remote location for the thumbnail, because it can't be reused anyway
|
||||||
|
td->file_manager_->delete_partial_remote_location(thumbnail_file_id_);
|
||||||
|
}
|
||||||
|
|
||||||
auto ptr = result_ptr.move_as_ok();
|
auto ptr = result_ptr.move_as_ok();
|
||||||
LOG(INFO) << "Receive result for uploadMedia: " << to_string(ptr);
|
LOG(INFO) << "Receive result for uploadMedia: " << to_string(ptr);
|
||||||
td->messages_manager_->on_upload_message_media_success(dialog_id_, message_id_, std::move(ptr));
|
td->messages_manager_->on_upload_message_media_success(dialog_id_, message_id_, std::move(ptr));
|
||||||
@ -2272,6 +2281,10 @@ class UploadMediaQuery : public Td::ResultHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
td->messages_manager_->on_get_dialog_error(dialog_id_, status, "UploadMediaQuery");
|
td->messages_manager_->on_get_dialog_error(dialog_id_, status, "UploadMediaQuery");
|
||||||
|
if (thumbnail_file_id_.is_valid()) {
|
||||||
|
// always delete partial remote location for the thumbnail, because it can't be reused anyway
|
||||||
|
td->file_manager_->delete_partial_remote_location(thumbnail_file_id_);
|
||||||
|
}
|
||||||
if (file_id_.is_valid()) {
|
if (file_id_.is_valid()) {
|
||||||
if (begins_with(status.message(), "FILE_PART_") && ends_with(status.message(), "_MISSING")) {
|
if (begins_with(status.message(), "FILE_PART_") && ends_with(status.message(), "_MISSING")) {
|
||||||
td->messages_manager_->on_upload_message_media_file_part_missing(
|
td->messages_manager_->on_upload_message_media_file_part_missing(
|
||||||
@ -2297,13 +2310,21 @@ class EditMessageActor : public NetActorOnce {
|
|||||||
|
|
||||||
void send(int32 flags, DialogId dialog_id, MessageId message_id, const string &message,
|
void send(int32 flags, DialogId dialog_id, MessageId message_id, const string &message,
|
||||||
vector<tl_object_ptr<telegram_api::MessageEntity>> &&entities,
|
vector<tl_object_ptr<telegram_api::MessageEntity>> &&entities,
|
||||||
|
tl_object_ptr<telegram_api::InputMedia> &&input_media,
|
||||||
tl_object_ptr<telegram_api::InputGeoPoint> &&input_geo_point,
|
tl_object_ptr<telegram_api::InputGeoPoint> &&input_geo_point,
|
||||||
tl_object_ptr<telegram_api::ReplyMarkup> &&reply_markup, uint64 sequence_dispatcher_id) {
|
tl_object_ptr<telegram_api::ReplyMarkup> &&reply_markup, uint64 sequence_dispatcher_id) {
|
||||||
|
if (false && input_media != nullptr) {
|
||||||
|
on_error(0, Status::Error(400, "FILE_PART_1_MISSING"));
|
||||||
|
stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
dialog_id_ = dialog_id;
|
dialog_id_ = dialog_id;
|
||||||
|
|
||||||
auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Edit);
|
auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Edit);
|
||||||
if (input_peer == nullptr) {
|
if (input_peer == nullptr) {
|
||||||
on_error(0, Status::Error(400, "Can't access the chat"));
|
on_error(0, Status::Error(400, "Can't access the chat"));
|
||||||
|
stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2316,6 +2337,9 @@ class EditMessageActor : public NetActorOnce {
|
|||||||
if (!message.empty()) {
|
if (!message.empty()) {
|
||||||
flags |= MessagesManager::SEND_MESSAGE_FLAG_HAS_MESSAGE;
|
flags |= MessagesManager::SEND_MESSAGE_FLAG_HAS_MESSAGE;
|
||||||
}
|
}
|
||||||
|
if (input_media != nullptr) {
|
||||||
|
flags |= telegram_api::messages_editMessage::MEDIA_MASK;
|
||||||
|
}
|
||||||
if (input_geo_point != nullptr) {
|
if (input_geo_point != nullptr) {
|
||||||
flags |= telegram_api::messages_editMessage::GEO_POINT_MASK;
|
flags |= telegram_api::messages_editMessage::GEO_POINT_MASK;
|
||||||
}
|
}
|
||||||
@ -2323,7 +2347,7 @@ class EditMessageActor : public NetActorOnce {
|
|||||||
|
|
||||||
auto query = G()->net_query_creator().create(create_storer(telegram_api::messages_editMessage(
|
auto query = G()->net_query_creator().create(create_storer(telegram_api::messages_editMessage(
|
||||||
flags, false /*ignored*/, false /*ignored*/, std::move(input_peer), message_id.get_server_message_id().get(),
|
flags, false /*ignored*/, false /*ignored*/, std::move(input_peer), message_id.get_server_message_id().get(),
|
||||||
message, nullptr, std::move(reply_markup), std::move(entities), std::move(input_geo_point))));
|
message, std::move(input_media), std::move(reply_markup), std::move(entities), std::move(input_geo_point))));
|
||||||
|
|
||||||
query->debug("send to MessagesManager::MultiSequenceDispatcher");
|
query->debug("send to MessagesManager::MultiSequenceDispatcher");
|
||||||
send_closure(td->messages_manager_->sequence_dispatcher_, &MultiSequenceDispatcher::send_with_callback,
|
send_closure(td->messages_manager_->sequence_dispatcher_, &MultiSequenceDispatcher::send_with_callback,
|
||||||
@ -2367,6 +2391,7 @@ class EditInlineMessageQuery : public Td::ResultHandler {
|
|||||||
|
|
||||||
void send(int32 flags, tl_object_ptr<telegram_api::inputBotInlineMessageID> input_bot_inline_message_id,
|
void send(int32 flags, tl_object_ptr<telegram_api::inputBotInlineMessageID> input_bot_inline_message_id,
|
||||||
const string &message, vector<tl_object_ptr<telegram_api::MessageEntity>> &&entities,
|
const string &message, vector<tl_object_ptr<telegram_api::MessageEntity>> &&entities,
|
||||||
|
tl_object_ptr<telegram_api::InputMedia> &&input_media,
|
||||||
tl_object_ptr<telegram_api::InputGeoPoint> &&input_geo_point,
|
tl_object_ptr<telegram_api::InputGeoPoint> &&input_geo_point,
|
||||||
tl_object_ptr<telegram_api::ReplyMarkup> &&reply_markup) {
|
tl_object_ptr<telegram_api::ReplyMarkup> &&reply_markup) {
|
||||||
CHECK(input_bot_inline_message_id != nullptr);
|
CHECK(input_bot_inline_message_id != nullptr);
|
||||||
@ -2383,13 +2408,16 @@ class EditInlineMessageQuery : public Td::ResultHandler {
|
|||||||
if (input_geo_point != nullptr) {
|
if (input_geo_point != nullptr) {
|
||||||
flags |= telegram_api::messages_editInlineBotMessage::GEO_POINT_MASK;
|
flags |= telegram_api::messages_editInlineBotMessage::GEO_POINT_MASK;
|
||||||
}
|
}
|
||||||
|
if (input_media != nullptr) {
|
||||||
|
flags |= telegram_api::messages_editInlineBotMessage::MEDIA_MASK;
|
||||||
|
}
|
||||||
LOG(DEBUG) << "Edit inline message with flags " << flags;
|
LOG(DEBUG) << "Edit inline message with flags " << flags;
|
||||||
|
|
||||||
auto dc_id = DcId::internal(input_bot_inline_message_id->dc_id_);
|
auto dc_id = DcId::internal(input_bot_inline_message_id->dc_id_);
|
||||||
send_query(G()->net_query_creator().create(
|
send_query(G()->net_query_creator().create(
|
||||||
create_storer(telegram_api::messages_editInlineBotMessage(
|
create_storer(telegram_api::messages_editInlineBotMessage(
|
||||||
flags, false /*ignored*/, false /*ignored*/, std::move(input_bot_inline_message_id), message, nullptr,
|
flags, false /*ignored*/, false /*ignored*/, std::move(input_bot_inline_message_id), message,
|
||||||
std::move(reply_markup), std::move(entities), std::move(input_geo_point))),
|
std::move(input_media), std::move(reply_markup), std::move(entities), std::move(input_geo_point))),
|
||||||
dc_id));
|
dc_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2433,6 +2461,7 @@ class SetGameScoreActor : public NetActorOnce {
|
|||||||
auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Edit);
|
auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Edit);
|
||||||
if (input_peer == nullptr) {
|
if (input_peer == nullptr) {
|
||||||
on_error(0, Status::Error(400, "Can't access the chat"));
|
on_error(0, Status::Error(400, "Can't access the chat"));
|
||||||
|
stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2611,12 +2640,14 @@ class ForwardMessagesActor : public NetActorOnce {
|
|||||||
auto to_input_peer = td->messages_manager_->get_input_peer(to_dialog_id, AccessRights::Write);
|
auto to_input_peer = td->messages_manager_->get_input_peer(to_dialog_id, AccessRights::Write);
|
||||||
if (to_input_peer == nullptr) {
|
if (to_input_peer == nullptr) {
|
||||||
on_error(0, Status::Error(400, "Have no write access to the chat"));
|
on_error(0, Status::Error(400, "Have no write access to the chat"));
|
||||||
|
stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto from_input_peer = td->messages_manager_->get_input_peer(from_dialog_id, AccessRights::Read);
|
auto from_input_peer = td->messages_manager_->get_input_peer(from_dialog_id, AccessRights::Read);
|
||||||
if (from_input_peer == nullptr) {
|
if (from_input_peer == nullptr) {
|
||||||
on_error(0, Status::Error(400, "Can't access the chat to forward messages from"));
|
on_error(0, Status::Error(400, "Can't access the chat to forward messages from"));
|
||||||
|
stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6749,15 +6780,16 @@ void MessagesManager::on_upload_media(FileId file_id, tl_object_ptr<telegram_api
|
|||||||
|
|
||||||
Message *m = get_message(full_message_id);
|
Message *m = get_message(full_message_id);
|
||||||
if (m == nullptr) {
|
if (m == nullptr) {
|
||||||
// message has already been deleted by the user or sent to inaccessible channel, do not need to send it
|
// message has already been deleted by the user or sent to inaccessible channel, do not need to send or edit it
|
||||||
// file upload should be already cancelled in cancel_send_message_query, it shouldn't happen
|
// file upload should be already cancelled in cancel_send_message_query, it shouldn't happen
|
||||||
LOG(ERROR) << "Message with a media has already been deleted";
|
LOG(ERROR) << "Message with a media has already been deleted";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_edit = m->message_id.is_server();
|
||||||
auto dialog_id = full_message_id.get_dialog_id();
|
auto dialog_id = full_message_id.get_dialog_id();
|
||||||
auto can_send_status = can_send_message(dialog_id);
|
auto can_send_status = can_send_message(dialog_id);
|
||||||
if (can_send_status.is_error()) {
|
if (!is_edit && can_send_status.is_error()) {
|
||||||
// user has left the chat during upload of the file or lost his privileges
|
// user has left the chat during upload of the file or lost his privileges
|
||||||
LOG(INFO) << "Can't send a message to " << dialog_id << ": " << can_send_status.error();
|
LOG(INFO) << "Can't send a message to " << dialog_id << ": " << can_send_status.error();
|
||||||
|
|
||||||
@ -6806,8 +6838,20 @@ void MessagesManager::do_send_media(DialogId dialog_id, Message *m, FileId file_
|
|||||||
thumbnail_file_id = FileId();
|
thumbnail_file_id = FileId();
|
||||||
}
|
}
|
||||||
CHECK(m != nullptr);
|
CHECK(m != nullptr);
|
||||||
on_message_media_uploaded(
|
|
||||||
dialog_id, m, get_input_media(m->content.get(), std::move(input_file), std::move(input_thumbnail), m->ttl),
|
MessageContent *content = nullptr;
|
||||||
|
if (m->message_id.is_server()) {
|
||||||
|
content = m->edited_content.get();
|
||||||
|
if (content == nullptr) {
|
||||||
|
LOG(ERROR) << "Message has no edited content";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
content = m->content.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
on_message_media_uploaded(dialog_id, m,
|
||||||
|
get_input_media(content, std::move(input_file), std::move(input_thumbnail), m->ttl),
|
||||||
file_id, thumbnail_file_id);
|
file_id, thumbnail_file_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6821,6 +6865,7 @@ void MessagesManager::do_send_secret_media(DialogId dialog_id, Message *m, FileI
|
|||||||
|
|
||||||
CHECK(dialog_id.get_type() == DialogType::SecretChat);
|
CHECK(dialog_id.get_type() == DialogType::SecretChat);
|
||||||
CHECK(m != nullptr);
|
CHECK(m != nullptr);
|
||||||
|
CHECK(m->message_id.is_yet_unsent());
|
||||||
auto layer = td_->contacts_manager_->get_secret_chat_layer(dialog_id.get_secret_chat_id());
|
auto layer = td_->contacts_manager_->get_secret_chat_layer(dialog_id.get_secret_chat_id());
|
||||||
on_secret_message_media_uploaded(
|
on_secret_message_media_uploaded(
|
||||||
dialog_id, m,
|
dialog_id, m,
|
||||||
@ -6847,8 +6892,13 @@ void MessagesManager::on_upload_media_error(FileId file_id, Status status) {
|
|||||||
|
|
||||||
being_uploaded_files_.erase(it);
|
being_uploaded_files_.erase(it);
|
||||||
|
|
||||||
|
bool is_edit = full_message_id.get_message_id().is_server();
|
||||||
|
if (is_edit) {
|
||||||
|
fail_edit_message_media(full_message_id, Status::Error(status.code() > 0 ? status.code() : 500, status.message()));
|
||||||
|
} else {
|
||||||
fail_send_message(full_message_id, status.code() > 0 ? status.code() : 500,
|
fail_send_message(full_message_id, status.code() > 0 ? status.code() : 500,
|
||||||
status.message().str()); // TODO CHECK that status has always a code
|
status.message().str()); // TODO CHECK that status has always a code
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesManager::on_load_secret_thumbnail(FileId thumbnail_file_id, BufferSlice thumbnail) {
|
void MessagesManager::on_load_secret_thumbnail(FileId thumbnail_file_id, BufferSlice thumbnail) {
|
||||||
@ -6879,6 +6929,7 @@ void MessagesManager::on_load_secret_thumbnail(FileId thumbnail_file_id, BufferS
|
|||||||
LOG(INFO) << "Message with a media has already been deleted";
|
LOG(INFO) << "Message with a media has already been deleted";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
CHECK(m->message_id.is_yet_unsent());
|
||||||
|
|
||||||
if (thumbnail.empty()) {
|
if (thumbnail.empty()) {
|
||||||
delete_message_content_thumbnail(m->content.get());
|
delete_message_content_thumbnail(m->content.get());
|
||||||
@ -6921,19 +6972,21 @@ void MessagesManager::on_upload_thumbnail(FileId thumbnail_file_id,
|
|||||||
|
|
||||||
Message *m = get_message(full_message_id);
|
Message *m = get_message(full_message_id);
|
||||||
if (m == nullptr) {
|
if (m == nullptr) {
|
||||||
// message has already been deleted by the user or sent to inaccessible channel, do not need to send it
|
// message has already been deleted by the user or sent to inaccessible channel, do not need to send or edit it
|
||||||
// thumbnail file upload should be already cancelled in cancel_send_message_query
|
// thumbnail file upload should be already cancelled in cancel_send_message_query
|
||||||
LOG(ERROR) << "Message with a media has already been deleted";
|
LOG(ERROR) << "Message with a media has already been deleted";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_edit = m->message_id.is_server();
|
||||||
|
|
||||||
if (thumbnail_input_file == nullptr) {
|
if (thumbnail_input_file == nullptr) {
|
||||||
delete_message_content_thumbnail(m->content.get());
|
delete_message_content_thumbnail(is_edit ? m->edited_content.get() : m->content.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto dialog_id = full_message_id.get_dialog_id();
|
auto dialog_id = full_message_id.get_dialog_id();
|
||||||
auto can_send_status = can_send_message(dialog_id);
|
auto can_send_status = can_send_message(dialog_id);
|
||||||
if (can_send_status.is_error()) {
|
if (!is_edit && can_send_status.is_error()) {
|
||||||
// user has left the chat during upload of the thumbnail or lost his privileges
|
// user has left the chat during upload of the thumbnail or lost his privileges
|
||||||
LOG(INFO) << "Can't send a message to " << dialog_id << ": " << can_send_status.error();
|
LOG(INFO) << "Can't send a message to " << dialog_id << ": " << can_send_status.error();
|
||||||
|
|
||||||
@ -11211,11 +11264,11 @@ bool MessagesManager::can_unload_message(const Dialog *d, const Message *m) cons
|
|||||||
// don't want to unload messages from opened dialogs
|
// don't want to unload messages from opened dialogs
|
||||||
// don't want to unload messages to which there are replies in yet unsent messages
|
// don't want to unload messages to which there are replies in yet unsent messages
|
||||||
// don't want to unload messages with pending web pages
|
// don't want to unload messages with pending web pages
|
||||||
// can't unload from memory last dialog, last database messages, yet unsent messages and active live locations
|
// can't unload from memory last dialog, last database messages, yet unsent messages, being edited media messages and active live locations
|
||||||
FullMessageId full_message_id{d->dialog_id, m->message_id};
|
FullMessageId full_message_id{d->dialog_id, m->message_id};
|
||||||
return !d->is_opened && m->message_id != d->last_message_id && m->message_id != d->last_database_message_id &&
|
return !d->is_opened && m->message_id != d->last_message_id && m->message_id != d->last_database_message_id &&
|
||||||
!m->message_id.is_yet_unsent() && active_live_location_full_message_ids_.count(full_message_id) == 0 &&
|
!m->message_id.is_yet_unsent() && active_live_location_full_message_ids_.count(full_message_id) == 0 &&
|
||||||
replied_by_yet_unsent_messages_.count(full_message_id) == 0 &&
|
replied_by_yet_unsent_messages_.count(full_message_id) == 0 && m->edited_content == nullptr &&
|
||||||
waiting_for_web_page_messages_.count(full_message_id) == 0;
|
waiting_for_web_page_messages_.count(full_message_id) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -11406,6 +11459,8 @@ unique_ptr<MessagesManager::Message> MessagesManager::do_delete_message(Dialog *
|
|||||||
if (!only_from_memory) {
|
if (!only_from_memory) {
|
||||||
if (message_id.is_yet_unsent()) {
|
if (message_id.is_yet_unsent()) {
|
||||||
cancel_send_message_query(d->dialog_id, result);
|
cancel_send_message_query(d->dialog_id, result);
|
||||||
|
} else {
|
||||||
|
cancel_edit_message_media(d->dialog_id, result.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (need_get_history && !td_->auth_manager_->is_bot() && have_input_peer(d->dialog_id, AccessRights::Read)) {
|
if (need_get_history && !td_->auth_manager_->is_bot() && have_input_peer(d->dialog_id, AccessRights::Read)) {
|
||||||
@ -11492,6 +11547,8 @@ void MessagesManager::do_delete_all_dialog_messages(Dialog *d, unique_ptr<Messag
|
|||||||
|
|
||||||
if (message_id.is_yet_unsent()) {
|
if (message_id.is_yet_unsent()) {
|
||||||
cancel_send_message_query(d->dialog_id, m);
|
cancel_send_message_query(d->dialog_id, m);
|
||||||
|
} else {
|
||||||
|
cancel_edit_message_media(d->dialog_id, m.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (d->dialog_id.get_type()) {
|
switch (d->dialog_id.get_type()) {
|
||||||
@ -15505,6 +15562,7 @@ MessagesManager::Message *MessagesManager::get_message_to_send(Dialog *d, Messag
|
|||||||
int64 MessagesManager::begin_send_message(DialogId dialog_id, const Message *m) {
|
int64 MessagesManager::begin_send_message(DialogId dialog_id, const Message *m) {
|
||||||
LOG(INFO) << "Begin to send " << FullMessageId(dialog_id, m->message_id) << " with random_id = " << m->random_id;
|
LOG(INFO) << "Begin to send " << FullMessageId(dialog_id, m->message_id) << " with random_id = " << m->random_id;
|
||||||
CHECK(m->random_id != 0 && being_sent_messages_.find(m->random_id) == being_sent_messages_.end());
|
CHECK(m->random_id != 0 && being_sent_messages_.find(m->random_id) == being_sent_messages_.end());
|
||||||
|
CHECK(m->message_id.is_yet_unsent());
|
||||||
being_sent_messages_[m->random_id] = FullMessageId(dialog_id, m->message_id);
|
being_sent_messages_[m->random_id] = FullMessageId(dialog_id, m->message_id);
|
||||||
debug_being_sent_messages_[m->random_id] = dialog_id;
|
debug_being_sent_messages_[m->random_id] = dialog_id;
|
||||||
return m->random_id;
|
return m->random_id;
|
||||||
@ -15945,6 +16003,8 @@ void MessagesManager::cancel_send_message_query(DialogId dialog_id, unique_ptr<M
|
|||||||
|
|
||||||
cancel_upload_message_content_files(m->content.get());
|
cancel_upload_message_content_files(m->content.get());
|
||||||
|
|
||||||
|
CHECK(m->edited_content == nullptr);
|
||||||
|
|
||||||
if (!m->send_query_ref.empty()) {
|
if (!m->send_query_ref.empty()) {
|
||||||
LOG(INFO) << "Cancel send query for " << m->message_id;
|
LOG(INFO) << "Cancel send query for " << m->message_id;
|
||||||
cancel_query(m->send_query_ref);
|
cancel_query(m->send_query_ref);
|
||||||
@ -16424,7 +16484,7 @@ Result<MessagesManager::InputMessageContent> MessagesManager::process_input_mess
|
|||||||
clear_draft = input_message_text.clear_draft;
|
clear_draft = input_message_text.clear_draft;
|
||||||
|
|
||||||
WebPageId web_page_id;
|
WebPageId web_page_id;
|
||||||
if (!disable_web_page_preview &&
|
if (!td_->auth_manager_->is_bot() && !disable_web_page_preview &&
|
||||||
(dialog_id.get_type() != DialogType::Channel ||
|
(dialog_id.get_type() != DialogType::Channel ||
|
||||||
td_->contacts_manager_->get_channel_status(dialog_id.get_channel_id()).can_add_web_page_previews())) {
|
td_->contacts_manager_->get_channel_status(dialog_id.get_channel_id()).can_add_web_page_previews())) {
|
||||||
web_page_id = td_->web_pages_manager_->get_web_page_by_url(
|
web_page_id = td_->web_pages_manager_->get_web_page_by_url(
|
||||||
@ -16703,7 +16763,9 @@ Result<MessagesManager::InputMessageContent> MessagesManager::process_input_mess
|
|||||||
return Status::Error(10, "Message TTL can be specified only in private chats");
|
return Status::Error(10, "Message TTL can be specified only in private chats");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dialog_id != DialogId()) {
|
||||||
TRY_STATUS(can_send_message_content(dialog_id, content.get(), false));
|
TRY_STATUS(can_send_message_content(dialog_id, content.get(), false));
|
||||||
|
}
|
||||||
|
|
||||||
return InputMessageContent{std::move(content), disable_web_page_preview, clear_draft, ttl, via_bot_user_id};
|
return InputMessageContent{std::move(content), disable_web_page_preview, clear_draft, ttl, via_bot_user_id};
|
||||||
}
|
}
|
||||||
@ -16788,10 +16850,11 @@ void MessagesManager::save_send_message_logevent(DialogId dialog_id, Message *m)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MessagesManager::do_send_message(DialogId dialog_id, Message *m, vector<int> bad_parts) {
|
void MessagesManager::do_send_message(DialogId dialog_id, Message *m, vector<int> bad_parts) {
|
||||||
LOG(INFO) << "Do send " << FullMessageId(dialog_id, m->message_id);
|
bool is_edit = m->message_id.is_server();
|
||||||
|
LOG(INFO) << "Do " << (is_edit ? "edit" : "send") << ' ' << FullMessageId(dialog_id, m->message_id);
|
||||||
bool is_secret = dialog_id.get_type() == DialogType::SecretChat;
|
bool is_secret = dialog_id.get_type() == DialogType::SecretChat;
|
||||||
|
|
||||||
if (m->media_album_id != 0 && bad_parts.empty() && !is_secret) {
|
if (m->media_album_id != 0 && bad_parts.empty() && !is_secret && !is_edit) {
|
||||||
auto &request = pending_message_group_sends_[m->media_album_id];
|
auto &request = pending_message_group_sends_[m->media_album_id];
|
||||||
request.dialog_id = dialog_id;
|
request.dialog_id = dialog_id;
|
||||||
request.message_ids.push_back(m->message_id);
|
request.message_ids.push_back(m->message_id);
|
||||||
@ -16800,7 +16863,8 @@ void MessagesManager::do_send_message(DialogId dialog_id, Message *m, vector<int
|
|||||||
request.results.push_back(Status::OK());
|
request.results.push_back(Status::OK());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto content = m->content.get();
|
auto content = is_edit ? m->edited_content.get() : m->content.get();
|
||||||
|
CHECK(content != nullptr);
|
||||||
auto content_type = content->get_id();
|
auto content_type = content->get_id();
|
||||||
if (content_type == MessageText::ID) {
|
if (content_type == MessageText::ID) {
|
||||||
auto message_text = static_cast<const MessageText *>(content);
|
auto message_text = static_cast<const MessageText *>(content);
|
||||||
@ -16862,9 +16926,29 @@ void MessagesManager::on_message_media_uploaded(DialogId dialog_id, Message *m,
|
|||||||
FileId thumbnail_file_id) {
|
FileId thumbnail_file_id) {
|
||||||
CHECK(m != nullptr);
|
CHECK(m != nullptr);
|
||||||
CHECK(input_media != nullptr);
|
CHECK(input_media != nullptr);
|
||||||
|
|
||||||
|
auto message_id = m->message_id;
|
||||||
|
if (message_id.is_server()) {
|
||||||
|
auto caption = get_message_content_caption(m->edited_content.get());
|
||||||
|
auto input_reply_markup = get_input_reply_markup(m->edited_reply_markup);
|
||||||
|
|
||||||
|
LOG(INFO) << "Edit media from " << message_id << " in " << dialog_id;
|
||||||
|
auto promise = PromiseCreator::lambda([actor_id = actor_id(this), dialog_id, message_id, file_id, thumbnail_file_id,
|
||||||
|
generation = m->edit_generation](Result<Unit> result) {
|
||||||
|
send_closure(actor_id, &MessagesManager::on_message_media_edited, dialog_id, message_id, file_id,
|
||||||
|
thumbnail_file_id, generation, std::move(result));
|
||||||
|
});
|
||||||
|
send_closure(td_->create_net_actor<EditMessageActor>(std::move(promise)), &EditMessageActor::send, 1 << 11,
|
||||||
|
dialog_id, message_id, caption.text,
|
||||||
|
get_input_message_entities(td_->contacts_manager_.get(), caption.entities, "edit_message_media"),
|
||||||
|
std::move(input_media), nullptr, std::move(input_reply_markup),
|
||||||
|
get_sequence_dispatcher_id(dialog_id, -1));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (m->media_album_id == 0) {
|
if (m->media_album_id == 0) {
|
||||||
on_media_message_ready_to_send(
|
on_media_message_ready_to_send(
|
||||||
dialog_id, m->message_id,
|
dialog_id, message_id,
|
||||||
PromiseCreator::lambda([this, dialog_id, input_media = std::move(input_media), file_id,
|
PromiseCreator::lambda([this, dialog_id, input_media = std::move(input_media), file_id,
|
||||||
thumbnail_file_id](Result<Message *> result) mutable {
|
thumbnail_file_id](Result<Message *> result) mutable {
|
||||||
if (result.is_error() || G()->close_flag()) {
|
if (result.is_error() || G()->close_flag()) {
|
||||||
@ -16896,19 +16980,19 @@ void MessagesManager::on_message_media_uploaded(DialogId dialog_id, Message *m,
|
|||||||
case telegram_api::inputMediaUploadedPhoto::ID:
|
case telegram_api::inputMediaUploadedPhoto::ID:
|
||||||
case telegram_api::inputMediaDocumentExternal::ID:
|
case telegram_api::inputMediaDocumentExternal::ID:
|
||||||
case telegram_api::inputMediaPhotoExternal::ID:
|
case telegram_api::inputMediaPhotoExternal::ID:
|
||||||
LOG(INFO) << "Upload media from " << m->message_id << " in " << dialog_id;
|
LOG(INFO) << "Upload media from " << message_id << " in " << dialog_id;
|
||||||
td_->create_handler<UploadMediaQuery>()->send(dialog_id, m->message_id, file_id, thumbnail_file_id,
|
td_->create_handler<UploadMediaQuery>()->send(dialog_id, message_id, file_id, thumbnail_file_id,
|
||||||
std::move(input_media));
|
std::move(input_media));
|
||||||
break;
|
break;
|
||||||
case telegram_api::inputMediaDocument::ID:
|
case telegram_api::inputMediaDocument::ID:
|
||||||
case telegram_api::inputMediaPhoto::ID:
|
case telegram_api::inputMediaPhoto::ID:
|
||||||
send_closure_later(actor_id(this), &MessagesManager::on_upload_message_media_finished, m->media_album_id,
|
send_closure_later(actor_id(this), &MessagesManager::on_upload_message_media_finished, m->media_album_id,
|
||||||
dialog_id, m->message_id, Status::OK());
|
dialog_id, message_id, Status::OK());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG(ERROR) << "Have wrong input media " << to_string(input_media);
|
LOG(ERROR) << "Have wrong input media " << to_string(input_media);
|
||||||
send_closure_later(actor_id(this), &MessagesManager::on_upload_message_media_finished, m->media_album_id,
|
send_closure_later(actor_id(this), &MessagesManager::on_upload_message_media_finished, m->media_album_id,
|
||||||
dialog_id, m->message_id, Status::Error(400, "Wrong input media"));
|
dialog_id, message_id, Status::Error(400, "Wrong input media"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -16933,7 +17017,7 @@ void MessagesManager::on_secret_message_media_uploaded(DialogId dialog_id, Messa
|
|||||||
return send_closure_later(actor_id(this), &MessagesManager::on_upload_message_media_finished, m->media_album_id,
|
return send_closure_later(actor_id(this), &MessagesManager::on_upload_message_media_finished, m->media_album_id,
|
||||||
dialog_id, m->message_id, Status::Error(400, "Wrong input media"));
|
dialog_id, m->message_id, Status::Error(400, "Wrong input media"));
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
// TODO use file_id, thumbnail_file_id, invalidate partial remote location for file_id in case of failed upload
|
// TODO use file_id, thumbnail_file_id, invalidate partial remote location for file_id in case of failed upload
|
||||||
// even message has already been deleted
|
// even message has already been deleted
|
||||||
on_media_message_ready_to_send(
|
on_media_message_ready_to_send(
|
||||||
@ -17712,7 +17796,7 @@ void MessagesManager::edit_message_text(FullMessageId full_message_id,
|
|||||||
td_->create_net_actor<EditMessageActor>(std::move(promise)), &EditMessageActor::send, flags, dialog_id,
|
td_->create_net_actor<EditMessageActor>(std::move(promise)), &EditMessageActor::send, flags, dialog_id,
|
||||||
message_id, input_message_text.text.text,
|
message_id, input_message_text.text.text,
|
||||||
get_input_message_entities(td_->contacts_manager_.get(), input_message_text.text.entities, "edit_message_text"),
|
get_input_message_entities(td_->contacts_manager_.get(), input_message_text.text.entities, "edit_message_text"),
|
||||||
nullptr, std::move(input_reply_markup), get_sequence_dispatcher_id(dialog_id, -1));
|
nullptr, nullptr, std::move(input_reply_markup), get_sequence_dispatcher_id(dialog_id, -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesManager::edit_message_live_location(FullMessageId full_message_id,
|
void MessagesManager::edit_message_live_location(FullMessageId full_message_id,
|
||||||
@ -17762,11 +17846,146 @@ void MessagesManager::edit_message_live_location(FullMessageId full_message_id,
|
|||||||
flags |= telegram_api::messages_editMessage::STOP_GEO_LIVE_MASK;
|
flags |= telegram_api::messages_editMessage::STOP_GEO_LIVE_MASK;
|
||||||
}
|
}
|
||||||
send_closure(td_->create_net_actor<EditMessageActor>(std::move(promise)), &EditMessageActor::send, flags, dialog_id,
|
send_closure(td_->create_net_actor<EditMessageActor>(std::move(promise)), &EditMessageActor::send, flags, dialog_id,
|
||||||
message_id, string(), vector<tl_object_ptr<telegram_api::MessageEntity>>(),
|
message_id, string(), vector<tl_object_ptr<telegram_api::MessageEntity>>(), nullptr,
|
||||||
location.empty() ? nullptr : location.get_input_geo_point(), std::move(input_reply_markup),
|
location.empty() ? nullptr : location.get_input_geo_point(), std::move(input_reply_markup),
|
||||||
get_sequence_dispatcher_id(dialog_id, -1));
|
get_sequence_dispatcher_id(dialog_id, -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MessagesManager::cancel_edit_message_media(DialogId dialog_id, Message *m) {
|
||||||
|
if (m->edited_content == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cancel_upload_message_content_files(m->edited_content.get());
|
||||||
|
|
||||||
|
m->edited_content = nullptr;
|
||||||
|
m->edited_reply_markup = nullptr;
|
||||||
|
m->edit_generation = 0;
|
||||||
|
m->edit_promise.set_error(Status::Error(400, "Cancelled"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessagesManager::on_message_media_edited(DialogId dialog_id, MessageId message_id, FileId file_id,
|
||||||
|
FileId thumbnail_file_id, uint64 generation, Result<Unit> &&result) {
|
||||||
|
CHECK(message_id.is_server());
|
||||||
|
auto m = get_message({dialog_id, message_id});
|
||||||
|
if (m == nullptr || m->edit_generation != generation) {
|
||||||
|
// message is already deleted or was edited again
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK(m->edited_content != nullptr);
|
||||||
|
if (result.is_ok()) {
|
||||||
|
std::swap(m->content, m->edited_content);
|
||||||
|
update_message_content(dialog_id, m, std::move(m->edited_content),
|
||||||
|
m->edited_content->get_id() == MessagePhoto::ID && m->content->get_id() == MessagePhoto::ID,
|
||||||
|
true);
|
||||||
|
} else {
|
||||||
|
auto error_message = result.error().message();
|
||||||
|
if (thumbnail_file_id.is_valid()) {
|
||||||
|
// always delete partial remote location for the thumbnail, because it can't be reused anyway
|
||||||
|
td_->file_manager_->delete_partial_remote_location(thumbnail_file_id);
|
||||||
|
}
|
||||||
|
if (file_id.is_valid()) {
|
||||||
|
if (begins_with(error_message, "FILE_PART_") && ends_with(error_message, "_MISSING")) {
|
||||||
|
do_send_message(dialog_id, m, {to_integer<int32>(error_message.substr(10))});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.error().code() != 429 && result.error().code() < 500 && !G()->close_flag()) {
|
||||||
|
td_->file_manager_->delete_partial_remote_location(file_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cancel_upload_message_content_files(m->edited_content.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
m->edited_content = nullptr;
|
||||||
|
m->edited_reply_markup = nullptr;
|
||||||
|
m->edit_generation = 0;
|
||||||
|
if (result.is_ok()) {
|
||||||
|
m->edit_promise.set_value(Unit());
|
||||||
|
} else {
|
||||||
|
m->edit_promise.set_error(result.move_as_error());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessagesManager::edit_message_media(FullMessageId full_message_id,
|
||||||
|
tl_object_ptr<td_api::ReplyMarkup> &&reply_markup,
|
||||||
|
tl_object_ptr<td_api::InputMessageContent> &&input_message_content,
|
||||||
|
Promise<Unit> &&promise) {
|
||||||
|
if (input_message_content == nullptr) {
|
||||||
|
return promise.set_error(Status::Error(5, "Can't edit message without new content"));
|
||||||
|
}
|
||||||
|
int32 new_message_content_type = input_message_content->get_id();
|
||||||
|
if (new_message_content_type != td_api::inputMessageAnimation::ID &&
|
||||||
|
new_message_content_type != td_api::inputMessageAudio::ID &&
|
||||||
|
new_message_content_type != td_api::inputMessageDocument::ID &&
|
||||||
|
new_message_content_type != td_api::inputMessagePhoto::ID &&
|
||||||
|
new_message_content_type != td_api::inputMessageVideo::ID) {
|
||||||
|
return promise.set_error(Status::Error(5, "Unsupported input message content type"));
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG(INFO) << "Begin to edit media of " << full_message_id;
|
||||||
|
auto dialog_id = full_message_id.get_dialog_id();
|
||||||
|
Dialog *d = get_dialog_force(dialog_id);
|
||||||
|
if (d == nullptr) {
|
||||||
|
return promise.set_error(Status::Error(5, "Chat not found"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!have_input_peer(dialog_id, AccessRights::Edit)) {
|
||||||
|
return promise.set_error(Status::Error(5, "Can't access the chat"));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto message_id = full_message_id.get_message_id();
|
||||||
|
Message *m = get_message_force(d, message_id);
|
||||||
|
if (m == nullptr) {
|
||||||
|
return promise.set_error(Status::Error(5, "Message not found"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!can_edit_message(dialog_id, m, true)) {
|
||||||
|
return promise.set_error(Status::Error(5, "Message can't be edited"));
|
||||||
|
}
|
||||||
|
CHECK(message_id.is_server());
|
||||||
|
|
||||||
|
int32 old_message_content_type = m->content->get_id();
|
||||||
|
if (old_message_content_type != MessageAnimation::ID && old_message_content_type != MessageAudio::ID &&
|
||||||
|
old_message_content_type != MessageDocument::ID && old_message_content_type != MessagePhoto::ID &&
|
||||||
|
old_message_content_type != MessageVideo::ID) {
|
||||||
|
return promise.set_error(Status::Error(5, "There is no media in the message to edit"));
|
||||||
|
}
|
||||||
|
if (m->media_album_id != 0 && new_message_content_type != td_api::inputMessagePhoto::ID &&
|
||||||
|
new_message_content_type != td_api::inputMessageVideo::ID) {
|
||||||
|
return promise.set_error(Status::Error(5, "Message can be edit only to Photo or Video"));
|
||||||
|
}
|
||||||
|
if (m->ttl > 0) {
|
||||||
|
return promise.set_error(Status::Error(5, "Can't edit media in self-destructing message"));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto r_input_message_content = process_input_message_content(dialog_id, std::move(input_message_content));
|
||||||
|
if (r_input_message_content.is_error()) {
|
||||||
|
return promise.set_error(r_input_message_content.move_as_error());
|
||||||
|
}
|
||||||
|
InputMessageContent content = r_input_message_content.move_as_ok();
|
||||||
|
if (content.ttl > 0) {
|
||||||
|
return promise.set_error(Status::Error(5, "Can't enable self-destruction for media"));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto r_new_reply_markup = get_reply_markup(std::move(reply_markup), td_->auth_manager_->is_bot(), true, false,
|
||||||
|
!is_broadcast_channel(dialog_id));
|
||||||
|
if (r_new_reply_markup.is_error()) {
|
||||||
|
return promise.set_error(r_new_reply_markup.move_as_error());
|
||||||
|
}
|
||||||
|
|
||||||
|
cancel_edit_message_media(dialog_id, m);
|
||||||
|
|
||||||
|
m->edited_content = dup_message_content(dialog_id, content.content.get(), false);
|
||||||
|
m->edited_reply_markup = r_new_reply_markup.move_as_ok();
|
||||||
|
m->edit_generation = ++current_message_edit_generation_;
|
||||||
|
m->edit_promise = std::move(promise);
|
||||||
|
|
||||||
|
do_send_message(dialog_id, m);
|
||||||
|
}
|
||||||
|
|
||||||
void MessagesManager::edit_message_caption(FullMessageId full_message_id,
|
void MessagesManager::edit_message_caption(FullMessageId full_message_id,
|
||||||
tl_object_ptr<td_api::ReplyMarkup> &&reply_markup,
|
tl_object_ptr<td_api::ReplyMarkup> &&reply_markup,
|
||||||
tl_object_ptr<td_api::formattedText> &&input_caption,
|
tl_object_ptr<td_api::formattedText> &&input_caption,
|
||||||
@ -17813,7 +18032,7 @@ void MessagesManager::edit_message_caption(FullMessageId full_message_id,
|
|||||||
send_closure(td_->create_net_actor<EditMessageActor>(std::move(promise)), &EditMessageActor::send, 1 << 11, dialog_id,
|
send_closure(td_->create_net_actor<EditMessageActor>(std::move(promise)), &EditMessageActor::send, 1 << 11, dialog_id,
|
||||||
message_id, caption.text,
|
message_id, caption.text,
|
||||||
get_input_message_entities(td_->contacts_manager_.get(), caption.entities, "edit_message_caption"),
|
get_input_message_entities(td_->contacts_manager_.get(), caption.entities, "edit_message_caption"),
|
||||||
nullptr, std::move(input_reply_markup), get_sequence_dispatcher_id(dialog_id, -1));
|
nullptr, nullptr, std::move(input_reply_markup), get_sequence_dispatcher_id(dialog_id, -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesManager::edit_message_reply_markup(FullMessageId full_message_id,
|
void MessagesManager::edit_message_reply_markup(FullMessageId full_message_id,
|
||||||
@ -17851,7 +18070,7 @@ void MessagesManager::edit_message_reply_markup(FullMessageId full_message_id,
|
|||||||
}
|
}
|
||||||
auto input_reply_markup = get_input_reply_markup(r_new_reply_markup.ok());
|
auto input_reply_markup = get_input_reply_markup(r_new_reply_markup.ok());
|
||||||
send_closure(td_->create_net_actor<EditMessageActor>(std::move(promise)), &EditMessageActor::send, 0, dialog_id,
|
send_closure(td_->create_net_actor<EditMessageActor>(std::move(promise)), &EditMessageActor::send, 0, dialog_id,
|
||||||
message_id, string(), vector<tl_object_ptr<telegram_api::MessageEntity>>(), nullptr,
|
message_id, string(), vector<tl_object_ptr<telegram_api::MessageEntity>>(), nullptr, nullptr,
|
||||||
std::move(input_reply_markup), get_sequence_dispatcher_id(dialog_id, -1));
|
std::move(input_reply_markup), get_sequence_dispatcher_id(dialog_id, -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -17896,7 +18115,7 @@ void MessagesManager::edit_inline_message_text(const string &inline_message_id,
|
|||||||
->send(flags, std::move(input_bot_inline_message_id), input_message_text.text.text,
|
->send(flags, std::move(input_bot_inline_message_id), input_message_text.text.text,
|
||||||
get_input_message_entities(td_->contacts_manager_.get(), input_message_text.text.entities,
|
get_input_message_entities(td_->contacts_manager_.get(), input_message_text.text.entities,
|
||||||
"edit_inline_message_text"),
|
"edit_inline_message_text"),
|
||||||
nullptr, get_input_reply_markup(r_new_reply_markup.ok()));
|
nullptr, nullptr, get_input_reply_markup(r_new_reply_markup.ok()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesManager::edit_inline_message_live_location(const string &inline_message_id,
|
void MessagesManager::edit_inline_message_live_location(const string &inline_message_id,
|
||||||
@ -17928,10 +18147,62 @@ void MessagesManager::edit_inline_message_live_location(const string &inline_mes
|
|||||||
}
|
}
|
||||||
td_->create_handler<EditInlineMessageQuery>(std::move(promise))
|
td_->create_handler<EditInlineMessageQuery>(std::move(promise))
|
||||||
->send(flags, std::move(input_bot_inline_message_id), "", vector<tl_object_ptr<telegram_api::MessageEntity>>(),
|
->send(flags, std::move(input_bot_inline_message_id), "", vector<tl_object_ptr<telegram_api::MessageEntity>>(),
|
||||||
location.empty() ? nullptr : location.get_input_geo_point(),
|
nullptr, location.empty() ? nullptr : location.get_input_geo_point(),
|
||||||
get_input_reply_markup(r_new_reply_markup.ok()));
|
get_input_reply_markup(r_new_reply_markup.ok()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MessagesManager::edit_inline_message_media(const string &inline_message_id,
|
||||||
|
tl_object_ptr<td_api::ReplyMarkup> &&reply_markup,
|
||||||
|
tl_object_ptr<td_api::InputMessageContent> &&input_message_content,
|
||||||
|
Promise<Unit> &&promise) {
|
||||||
|
if (!td_->auth_manager_->is_bot()) {
|
||||||
|
return promise.set_error(Status::Error(3, "Method is available only for bots"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input_message_content == nullptr) {
|
||||||
|
return promise.set_error(Status::Error(5, "Can't edit message without new content"));
|
||||||
|
}
|
||||||
|
int32 new_message_content_type = input_message_content->get_id();
|
||||||
|
if (new_message_content_type != td_api::inputMessageAnimation::ID &&
|
||||||
|
new_message_content_type != td_api::inputMessageAudio::ID &&
|
||||||
|
new_message_content_type != td_api::inputMessageDocument::ID &&
|
||||||
|
new_message_content_type != td_api::inputMessagePhoto::ID &&
|
||||||
|
new_message_content_type != td_api::inputMessageVideo::ID) {
|
||||||
|
return promise.set_error(Status::Error(5, "Unsupported input message content type"));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto r_input_message_content = process_input_message_content(DialogId(), std::move(input_message_content));
|
||||||
|
if (r_input_message_content.is_error()) {
|
||||||
|
return promise.set_error(r_input_message_content.move_as_error());
|
||||||
|
}
|
||||||
|
InputMessageContent content = r_input_message_content.move_as_ok();
|
||||||
|
if (content.ttl > 0) {
|
||||||
|
LOG(ERROR) << "Have message content with ttl " << content.ttl;
|
||||||
|
return promise.set_error(Status::Error(5, "Can't enable self-destruction for media"));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto r_new_reply_markup = get_reply_markup(std::move(reply_markup), td_->auth_manager_->is_bot(), true, false, true);
|
||||||
|
if (r_new_reply_markup.is_error()) {
|
||||||
|
return promise.set_error(r_new_reply_markup.move_as_error());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto input_bot_inline_message_id = td_->inline_queries_manager_->get_input_bot_inline_message_id(inline_message_id);
|
||||||
|
if (input_bot_inline_message_id == nullptr) {
|
||||||
|
return promise.set_error(Status::Error(400, "Wrong inline message identifier specified"));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto input_media = get_input_media(content.content.get(), nullptr, nullptr, 0);
|
||||||
|
if (input_media == nullptr) {
|
||||||
|
return promise.set_error(Status::Error(400, "Wrong message content specified"));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto caption = get_message_content_caption(content.content.get());
|
||||||
|
td_->create_handler<EditInlineMessageQuery>(std::move(promise))
|
||||||
|
->send(1 << 11, std::move(input_bot_inline_message_id), caption.text,
|
||||||
|
get_input_message_entities(td_->contacts_manager_.get(), caption.entities, "edit_inline_message_media"),
|
||||||
|
std::move(input_media), nullptr, get_input_reply_markup(r_new_reply_markup.ok()));
|
||||||
|
}
|
||||||
|
|
||||||
void MessagesManager::edit_inline_message_caption(const string &inline_message_id,
|
void MessagesManager::edit_inline_message_caption(const string &inline_message_id,
|
||||||
tl_object_ptr<td_api::ReplyMarkup> &&reply_markup,
|
tl_object_ptr<td_api::ReplyMarkup> &&reply_markup,
|
||||||
tl_object_ptr<td_api::formattedText> &&input_caption,
|
tl_object_ptr<td_api::formattedText> &&input_caption,
|
||||||
@ -17959,7 +18230,7 @@ void MessagesManager::edit_inline_message_caption(const string &inline_message_i
|
|||||||
td_->create_handler<EditInlineMessageQuery>(std::move(promise))
|
td_->create_handler<EditInlineMessageQuery>(std::move(promise))
|
||||||
->send(1 << 11, std::move(input_bot_inline_message_id), caption.text,
|
->send(1 << 11, std::move(input_bot_inline_message_id), caption.text,
|
||||||
get_input_message_entities(td_->contacts_manager_.get(), caption.entities, "edit_inline_message_caption"),
|
get_input_message_entities(td_->contacts_manager_.get(), caption.entities, "edit_inline_message_caption"),
|
||||||
nullptr, get_input_reply_markup(r_new_reply_markup.ok()));
|
nullptr, nullptr, get_input_reply_markup(r_new_reply_markup.ok()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesManager::edit_inline_message_reply_markup(const string &inline_message_id,
|
void MessagesManager::edit_inline_message_reply_markup(const string &inline_message_id,
|
||||||
@ -17981,7 +18252,7 @@ void MessagesManager::edit_inline_message_reply_markup(const string &inline_mess
|
|||||||
|
|
||||||
td_->create_handler<EditInlineMessageQuery>(std::move(promise))
|
td_->create_handler<EditInlineMessageQuery>(std::move(promise))
|
||||||
->send(0, std::move(input_bot_inline_message_id), string(), vector<tl_object_ptr<telegram_api::MessageEntity>>(),
|
->send(0, std::move(input_bot_inline_message_id), string(), vector<tl_object_ptr<telegram_api::MessageEntity>>(),
|
||||||
nullptr, get_input_reply_markup(r_new_reply_markup.ok()));
|
nullptr, nullptr, get_input_reply_markup(r_new_reply_markup.ok()));
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 MessagesManager::get_message_flags(const Message *m) {
|
int32 MessagesManager::get_message_flags(const Message *m) {
|
||||||
@ -19737,6 +20008,23 @@ void MessagesManager::fail_send_message(FullMessageId full_message_id, int error
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MessagesManager::fail_edit_message_media(FullMessageId full_message_id, Status &&error) {
|
||||||
|
auto dialog_id = full_message_id.get_dialog_id();
|
||||||
|
Dialog *d = get_dialog(dialog_id);
|
||||||
|
CHECK(d != nullptr);
|
||||||
|
MessageId message_id = full_message_id.get_message_id();
|
||||||
|
CHECK(message_id.is_server());
|
||||||
|
|
||||||
|
auto m = get_message(d, message_id);
|
||||||
|
if (m == nullptr) {
|
||||||
|
// message has already been deleted by the user or sent to inaccessible channel
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
CHECK(m->edited_content != nullptr);
|
||||||
|
m->edit_promise.set_error(std::move(error));
|
||||||
|
cancel_edit_message_media(dialog_id, m);
|
||||||
|
}
|
||||||
|
|
||||||
void MessagesManager::on_update_dialog_draft_message(DialogId dialog_id,
|
void MessagesManager::on_update_dialog_draft_message(DialogId dialog_id,
|
||||||
tl_object_ptr<telegram_api::DraftMessage> &&draft_message) {
|
tl_object_ptr<telegram_api::DraftMessage> &&draft_message) {
|
||||||
if (!dialog_id.is_valid()) {
|
if (!dialog_id.is_valid()) {
|
||||||
@ -23380,7 +23668,7 @@ bool MessagesManager::update_message_content(DialogId dialog_id, Message *old_me
|
|||||||
const bool can_delete_old_document = old_message->message_id.is_yet_unsent() && false;
|
const bool can_delete_old_document = old_message->message_id.is_yet_unsent() && false;
|
||||||
|
|
||||||
auto old_file_id = get_message_content_file_id(old_content.get());
|
auto old_file_id = get_message_content_file_id(old_content.get());
|
||||||
bool need_finish_upload = old_file_id.is_valid() && old_message->message_id.is_yet_unsent();
|
bool need_finish_upload = old_file_id.is_valid() && need_merge_files;
|
||||||
if (old_content_type != new_content_type) {
|
if (old_content_type != new_content_type) {
|
||||||
need_update = true;
|
need_update = true;
|
||||||
LOG(INFO) << "Message content has changed its type from " << old_content_type << " to " << new_content_type;
|
LOG(INFO) << "Message content has changed its type from " << old_content_type << " to " << new_content_type;
|
||||||
|
@ -1109,6 +1109,9 @@ class MessagesManager : public Actor {
|
|||||||
void edit_message_live_location(FullMessageId full_message_id, tl_object_ptr<td_api::ReplyMarkup> &&reply_markup,
|
void edit_message_live_location(FullMessageId full_message_id, tl_object_ptr<td_api::ReplyMarkup> &&reply_markup,
|
||||||
tl_object_ptr<td_api::location> &&input_location, Promise<Unit> &&promise);
|
tl_object_ptr<td_api::location> &&input_location, Promise<Unit> &&promise);
|
||||||
|
|
||||||
|
void edit_message_media(FullMessageId full_message_id, tl_object_ptr<td_api::ReplyMarkup> &&reply_markup,
|
||||||
|
tl_object_ptr<td_api::InputMessageContent> &&input_message_content, Promise<Unit> &&promise);
|
||||||
|
|
||||||
void edit_message_caption(FullMessageId full_message_id, tl_object_ptr<td_api::ReplyMarkup> &&reply_markup,
|
void edit_message_caption(FullMessageId full_message_id, tl_object_ptr<td_api::ReplyMarkup> &&reply_markup,
|
||||||
tl_object_ptr<td_api::formattedText> &&input_caption, Promise<Unit> &&promise);
|
tl_object_ptr<td_api::formattedText> &&input_caption, Promise<Unit> &&promise);
|
||||||
|
|
||||||
@ -1123,6 +1126,10 @@ class MessagesManager : public Actor {
|
|||||||
tl_object_ptr<td_api::ReplyMarkup> &&reply_markup,
|
tl_object_ptr<td_api::ReplyMarkup> &&reply_markup,
|
||||||
tl_object_ptr<td_api::location> &&input_location, Promise<Unit> &&promise);
|
tl_object_ptr<td_api::location> &&input_location, Promise<Unit> &&promise);
|
||||||
|
|
||||||
|
void edit_inline_message_media(const string &inline_message_id, tl_object_ptr<td_api::ReplyMarkup> &&reply_markup,
|
||||||
|
tl_object_ptr<td_api::InputMessageContent> &&input_message_content,
|
||||||
|
Promise<Unit> &&promise);
|
||||||
|
|
||||||
void edit_inline_message_caption(const string &inline_message_id, tl_object_ptr<td_api::ReplyMarkup> &&reply_markup,
|
void edit_inline_message_caption(const string &inline_message_id, tl_object_ptr<td_api::ReplyMarkup> &&reply_markup,
|
||||||
tl_object_ptr<td_api::formattedText> &&input_caption, Promise<Unit> &&promise);
|
tl_object_ptr<td_api::formattedText> &&input_caption, Promise<Unit> &&promise);
|
||||||
|
|
||||||
@ -1541,6 +1548,11 @@ class MessagesManager : public Actor {
|
|||||||
|
|
||||||
unique_ptr<ReplyMarkup> reply_markup;
|
unique_ptr<ReplyMarkup> reply_markup;
|
||||||
|
|
||||||
|
unique_ptr<MessageContent> edited_content;
|
||||||
|
unique_ptr<ReplyMarkup> edited_reply_markup;
|
||||||
|
uint64 edit_generation = 0;
|
||||||
|
Promise<Unit> edit_promise;
|
||||||
|
|
||||||
unique_ptr<Message> left;
|
unique_ptr<Message> left;
|
||||||
unique_ptr<Message> right;
|
unique_ptr<Message> right;
|
||||||
|
|
||||||
@ -1942,6 +1954,11 @@ class MessagesManager : public Actor {
|
|||||||
|
|
||||||
bool can_report_dialog(DialogId dialog_id) const;
|
bool can_report_dialog(DialogId dialog_id) const;
|
||||||
|
|
||||||
|
void cancel_edit_message_media(DialogId dialog_id, Message *m);
|
||||||
|
|
||||||
|
void on_message_media_edited(DialogId dialog_id, MessageId message_id, FileId file_id, FileId thumbnail_file_id,
|
||||||
|
uint64 generation, Result<Unit> &&result);
|
||||||
|
|
||||||
MessageId get_persistent_message_id(const Dialog *d, MessageId message_id) const;
|
MessageId get_persistent_message_id(const Dialog *d, MessageId message_id) const;
|
||||||
|
|
||||||
static MessageId get_replied_message_id(const Message *m);
|
static MessageId get_replied_message_id(const Message *m);
|
||||||
@ -2146,6 +2163,8 @@ class MessagesManager : public Actor {
|
|||||||
|
|
||||||
void fail_send_message(FullMessageId full_message_id, int error_code, const string &error_message);
|
void fail_send_message(FullMessageId full_message_id, int error_code, const string &error_message);
|
||||||
|
|
||||||
|
void fail_edit_message_media(FullMessageId full_message_id, Status &&error);
|
||||||
|
|
||||||
void on_dialog_updated(DialogId dialog_id, const char *source);
|
void on_dialog_updated(DialogId dialog_id, const char *source);
|
||||||
|
|
||||||
BufferSlice get_dialog_database_value(const Dialog *d);
|
BufferSlice get_dialog_database_value(const Dialog *d);
|
||||||
@ -2839,6 +2858,8 @@ class MessagesManager : public Actor {
|
|||||||
|
|
||||||
int64 current_pinned_dialog_order_ = DEFAULT_ORDER;
|
int64 current_pinned_dialog_order_ = DEFAULT_ORDER;
|
||||||
|
|
||||||
|
uint64 current_message_edit_generation_ = 0;
|
||||||
|
|
||||||
std::set<DialogDate> ordered_dialogs_;
|
std::set<DialogDate> ordered_dialogs_;
|
||||||
std::set<DialogDate> ordered_server_dialogs_;
|
std::set<DialogDate> ordered_server_dialogs_;
|
||||||
|
|
||||||
|
@ -1282,6 +1282,31 @@ class EditMessageLiveLocationRequest : public RequestOnceActor {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class EditMessageMediaRequest : public RequestOnceActor {
|
||||||
|
FullMessageId full_message_id_;
|
||||||
|
tl_object_ptr<td_api::ReplyMarkup> reply_markup_;
|
||||||
|
tl_object_ptr<td_api::InputMessageContent> input_message_content_;
|
||||||
|
|
||||||
|
void do_run(Promise<Unit> &&promise) override {
|
||||||
|
td->messages_manager_->edit_message_media(full_message_id_, std::move(reply_markup_),
|
||||||
|
std::move(input_message_content_), std::move(promise));
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_send_result() override {
|
||||||
|
send_result(td->messages_manager_->get_message_object(full_message_id_));
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
EditMessageMediaRequest(ActorShared<Td> td, uint64 request_id, int64 dialog_id, int64 message_id,
|
||||||
|
tl_object_ptr<td_api::ReplyMarkup> reply_markup,
|
||||||
|
tl_object_ptr<td_api::InputMessageContent> input_message_content)
|
||||||
|
: RequestOnceActor(std::move(td), request_id)
|
||||||
|
, full_message_id_(DialogId(dialog_id), MessageId(message_id))
|
||||||
|
, reply_markup_(std::move(reply_markup))
|
||||||
|
, input_message_content_(std::move(input_message_content)) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class EditMessageCaptionRequest : public RequestOnceActor {
|
class EditMessageCaptionRequest : public RequestOnceActor {
|
||||||
FullMessageId full_message_id_;
|
FullMessageId full_message_id_;
|
||||||
tl_object_ptr<td_api::ReplyMarkup> reply_markup_;
|
tl_object_ptr<td_api::ReplyMarkup> reply_markup_;
|
||||||
@ -1370,6 +1395,27 @@ class EditInlineMessageLiveLocationRequest : public RequestOnceActor {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class EditInlineMessageMediaRequest : public RequestOnceActor {
|
||||||
|
string inline_message_id_;
|
||||||
|
tl_object_ptr<td_api::ReplyMarkup> reply_markup_;
|
||||||
|
tl_object_ptr<td_api::InputMessageContent> input_message_content_;
|
||||||
|
|
||||||
|
void do_run(Promise<Unit> &&promise) override {
|
||||||
|
td->messages_manager_->edit_inline_message_media(inline_message_id_, std::move(reply_markup_),
|
||||||
|
std::move(input_message_content_), std::move(promise));
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
EditInlineMessageMediaRequest(ActorShared<Td> td, uint64 request_id, string inline_message_id,
|
||||||
|
tl_object_ptr<td_api::ReplyMarkup> reply_markup,
|
||||||
|
tl_object_ptr<td_api::InputMessageContent> input_message_content)
|
||||||
|
: RequestOnceActor(std::move(td), request_id)
|
||||||
|
, inline_message_id_(std::move(inline_message_id))
|
||||||
|
, reply_markup_(std::move(reply_markup))
|
||||||
|
, input_message_content_(std::move(input_message_content)) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class EditInlineMessageCaptionRequest : public RequestOnceActor {
|
class EditInlineMessageCaptionRequest : public RequestOnceActor {
|
||||||
string inline_message_id_;
|
string inline_message_id_;
|
||||||
tl_object_ptr<td_api::ReplyMarkup> reply_markup_;
|
tl_object_ptr<td_api::ReplyMarkup> reply_markup_;
|
||||||
@ -5823,6 +5869,11 @@ void Td::on_request(uint64 id, td_api::editMessageLiveLocation &request) {
|
|||||||
std::move(request.reply_markup_), std::move(request.location_));
|
std::move(request.reply_markup_), std::move(request.location_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Td::on_request(uint64 id, td_api::editMessageMedia &request) {
|
||||||
|
CREATE_REQUEST(EditMessageMediaRequest, request.chat_id_, request.message_id_, std::move(request.reply_markup_),
|
||||||
|
std::move(request.input_message_content_));
|
||||||
|
}
|
||||||
|
|
||||||
void Td::on_request(uint64 id, td_api::editMessageCaption &request) {
|
void Td::on_request(uint64 id, td_api::editMessageCaption &request) {
|
||||||
CREATE_REQUEST(EditMessageCaptionRequest, request.chat_id_, request.message_id_, std::move(request.reply_markup_),
|
CREATE_REQUEST(EditMessageCaptionRequest, request.chat_id_, request.message_id_, std::move(request.reply_markup_),
|
||||||
std::move(request.caption_));
|
std::move(request.caption_));
|
||||||
@ -5848,6 +5899,13 @@ void Td::on_request(uint64 id, td_api::editInlineMessageLiveLocation &request) {
|
|||||||
std::move(request.reply_markup_), std::move(request.location_));
|
std::move(request.reply_markup_), std::move(request.location_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Td::on_request(uint64 id, td_api::editInlineMessageMedia &request) {
|
||||||
|
CHECK_IS_BOT();
|
||||||
|
CLEAN_INPUT_STRING(request.inline_message_id_);
|
||||||
|
CREATE_REQUEST(EditInlineMessageMediaRequest, std::move(request.inline_message_id_), std::move(request.reply_markup_),
|
||||||
|
std::move(request.input_message_content_));
|
||||||
|
}
|
||||||
|
|
||||||
void Td::on_request(uint64 id, td_api::editInlineMessageCaption &request) {
|
void Td::on_request(uint64 id, td_api::editInlineMessageCaption &request) {
|
||||||
CHECK_IS_BOT();
|
CHECK_IS_BOT();
|
||||||
CLEAN_INPUT_STRING(request.inline_message_id_);
|
CLEAN_INPUT_STRING(request.inline_message_id_);
|
||||||
|
@ -503,6 +503,8 @@ class Td final : public NetQueryCallback {
|
|||||||
|
|
||||||
void on_request(uint64 id, td_api::editMessageLiveLocation &request);
|
void on_request(uint64 id, td_api::editMessageLiveLocation &request);
|
||||||
|
|
||||||
|
void on_request(uint64 id, td_api::editMessageMedia &request);
|
||||||
|
|
||||||
void on_request(uint64 id, td_api::editMessageCaption &request);
|
void on_request(uint64 id, td_api::editMessageCaption &request);
|
||||||
|
|
||||||
void on_request(uint64 id, td_api::editMessageReplyMarkup &request);
|
void on_request(uint64 id, td_api::editMessageReplyMarkup &request);
|
||||||
@ -511,6 +513,8 @@ class Td final : public NetQueryCallback {
|
|||||||
|
|
||||||
void on_request(uint64 id, td_api::editInlineMessageLiveLocation &request);
|
void on_request(uint64 id, td_api::editInlineMessageLiveLocation &request);
|
||||||
|
|
||||||
|
void on_request(uint64 id, td_api::editInlineMessageMedia &request);
|
||||||
|
|
||||||
void on_request(uint64 id, td_api::editInlineMessageCaption &request);
|
void on_request(uint64 id, td_api::editInlineMessageCaption &request);
|
||||||
|
|
||||||
void on_request(uint64 id, td_api::editInlineMessageReplyMarkup &request);
|
void on_request(uint64 id, td_api::editInlineMessageReplyMarkup &request);
|
||||||
|
@ -830,16 +830,21 @@ class CliClient final : public Actor {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static tl_object_ptr<td_api::formattedText> as_formatted_text(
|
||||||
|
string text, vector<td_api::object_ptr<td_api::textEntity>> entities = {}) {
|
||||||
|
if (entities.empty()) {
|
||||||
|
auto parsed_text =
|
||||||
|
execute(make_tl_object<td_api::parseTextEntities>(text, make_tl_object<td_api::textParseModeMarkdown>()));
|
||||||
|
if (parsed_text->get_id() == td_api::formattedText::ID) {
|
||||||
|
return td_api::move_object_as<td_api::formattedText>(parsed_text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return make_tl_object<td_api::formattedText>(text, std::move(entities));
|
||||||
|
}
|
||||||
|
|
||||||
static tl_object_ptr<td_api::formattedText> as_caption(string caption,
|
static tl_object_ptr<td_api::formattedText> as_caption(string caption,
|
||||||
vector<td_api::object_ptr<td_api::textEntity>> entities = {}) {
|
vector<td_api::object_ptr<td_api::textEntity>> entities = {}) {
|
||||||
if (entities.empty()) {
|
return as_formatted_text(caption, std::move(entities));
|
||||||
auto parsed_caption =
|
|
||||||
execute(make_tl_object<td_api::parseTextEntities>(caption, make_tl_object<td_api::textParseModeMarkdown>()));
|
|
||||||
if (parsed_caption->get_id() == td_api::formattedText::ID) {
|
|
||||||
return td_api::move_object_as<td_api::formattedText>(parsed_caption);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return make_tl_object<td_api::formattedText>(caption, std::move(entities));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tl_object_ptr<td_api::NotificationSettingsScope> get_notification_settings_scope(Slice scope) const {
|
tl_object_ptr<td_api::NotificationSettingsScope> get_notification_settings_scope(Slice scope) const {
|
||||||
@ -2243,8 +2248,7 @@ class CliClient final : public Actor {
|
|||||||
|
|
||||||
draft_message = make_tl_object<td_api::draftMessage>(
|
draft_message = make_tl_object<td_api::draftMessage>(
|
||||||
as_message_id(reply_to_message_id),
|
as_message_id(reply_to_message_id),
|
||||||
make_tl_object<td_api::inputMessageText>(
|
make_tl_object<td_api::inputMessageText>(as_formatted_text(message, std::move(entities)), true, false));
|
||||||
make_tl_object<td_api::formattedText>(message, std::move(entities)), true, false));
|
|
||||||
}
|
}
|
||||||
send_request(make_tl_object<td_api::setChatDraftMessage>(as_chat_id(chat_id), std::move(draft_message)));
|
send_request(make_tl_object<td_api::setChatDraftMessage>(as_chat_id(chat_id), std::move(draft_message)));
|
||||||
} else if (op == "tcip") {
|
} else if (op == "tcip") {
|
||||||
@ -2281,10 +2285,7 @@ class CliClient final : public Actor {
|
|||||||
send_message(chat_id, make_tl_object<td_api::inputMessagePhoto>(as_local_file("rgb.jpg"), nullptr, Auto(), 0,
|
send_message(chat_id, make_tl_object<td_api::inputMessagePhoto>(as_local_file("rgb.jpg"), nullptr, Auto(), 0,
|
||||||
0, as_caption(message), 0));
|
0, as_caption(message), 0));
|
||||||
} else {
|
} else {
|
||||||
send_message(chat_id,
|
send_message(chat_id, make_tl_object<td_api::inputMessageText>(as_formatted_text(message), false, true));
|
||||||
make_tl_object<td_api::inputMessageText>(
|
|
||||||
make_tl_object<td_api::formattedText>(message, vector<tl_object_ptr<td_api::textEntity>>()),
|
|
||||||
false, true));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (op == "ssm") {
|
} else if (op == "ssm") {
|
||||||
@ -2315,15 +2316,7 @@ class CliClient final : public Actor {
|
|||||||
message = string(5097, 'a');
|
message = string(5097, 'a');
|
||||||
}
|
}
|
||||||
|
|
||||||
auto parsed_text =
|
send_message(chat_id, make_tl_object<td_api::inputMessageText>(as_formatted_text(message), false, true),
|
||||||
execute(make_tl_object<td_api::parseTextEntities>(message, make_tl_object<td_api::textParseModeMarkdown>()));
|
|
||||||
if (parsed_text->get_id() == td_api::error::ID) {
|
|
||||||
parsed_text = make_tl_object<td_api::formattedText>(message, vector<tl_object_ptr<td_api::textEntity>>());
|
|
||||||
}
|
|
||||||
|
|
||||||
send_message(
|
|
||||||
chat_id,
|
|
||||||
make_tl_object<td_api::inputMessageText>(move_tl_object_as<td_api::formattedText>(parsed_text), false, true),
|
|
||||||
op == "sms", false, as_message_id(reply_to_message_id));
|
op == "sms", false, as_message_id(reply_to_message_id));
|
||||||
} else if (op == "alm" || op == "almr") {
|
} else if (op == "alm" || op == "almr") {
|
||||||
string chat_id;
|
string chat_id;
|
||||||
@ -2337,16 +2330,9 @@ class CliClient final : public Actor {
|
|||||||
std::tie(reply_to_message_id, message) = split(message);
|
std::tie(reply_to_message_id, message) = split(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto parsed_text =
|
|
||||||
execute(make_tl_object<td_api::parseTextEntities>(message, make_tl_object<td_api::textParseModeMarkdown>()));
|
|
||||||
if (parsed_text->get_id() == td_api::error::ID) {
|
|
||||||
parsed_text = make_tl_object<td_api::formattedText>(message, vector<tl_object_ptr<td_api::textEntity>>());
|
|
||||||
}
|
|
||||||
|
|
||||||
send_request(make_tl_object<td_api::addLocalMessage>(
|
send_request(make_tl_object<td_api::addLocalMessage>(
|
||||||
as_chat_id(chat_id), as_user_id(user_id), as_message_id(reply_to_message_id), false,
|
as_chat_id(chat_id), as_user_id(user_id), as_message_id(reply_to_message_id), false,
|
||||||
make_tl_object<td_api::inputMessageText>(move_tl_object_as<td_api::formattedText>(parsed_text), false,
|
make_tl_object<td_api::inputMessageText>(as_formatted_text(message), false, true)));
|
||||||
true)));
|
|
||||||
} else if (op == "smap" || op == "smapr") {
|
} else if (op == "smap" || op == "smapr") {
|
||||||
string chat_id;
|
string chat_id;
|
||||||
string reply_to_message_id;
|
string reply_to_message_id;
|
||||||
@ -2373,9 +2359,66 @@ class CliClient final : public Actor {
|
|||||||
std::tie(message_id, message) = split(args);
|
std::tie(message_id, message) = split(args);
|
||||||
send_request(make_tl_object<td_api::editMessageText>(
|
send_request(make_tl_object<td_api::editMessageText>(
|
||||||
as_chat_id(chat_id), as_message_id(message_id), nullptr,
|
as_chat_id(chat_id), as_message_id(message_id), nullptr,
|
||||||
make_tl_object<td_api::inputMessageText>(
|
make_tl_object<td_api::inputMessageText>(as_formatted_text(message), true, true)));
|
||||||
make_tl_object<td_api::formattedText>(message, vector<tl_object_ptr<td_api::textEntity>>()), true,
|
} else if (op == "eman") {
|
||||||
true)));
|
string chat_id;
|
||||||
|
string message_id;
|
||||||
|
string animation;
|
||||||
|
std::tie(chat_id, args) = split(args);
|
||||||
|
std::tie(message_id, animation) = split(args);
|
||||||
|
send_request(make_tl_object<td_api::editMessageMedia>(
|
||||||
|
as_chat_id(chat_id), as_message_id(message_id), nullptr,
|
||||||
|
make_tl_object<td_api::inputMessageAnimation>(as_input_file(animation), nullptr, 0, 0, 0,
|
||||||
|
as_caption("animation"))));
|
||||||
|
} else if (op == "emc") {
|
||||||
|
string chat_id;
|
||||||
|
string message_id;
|
||||||
|
string caption;
|
||||||
|
std::tie(chat_id, args) = split(args);
|
||||||
|
std::tie(message_id, caption) = split(args);
|
||||||
|
send_request(make_tl_object<td_api::editMessageCaption>(as_chat_id(chat_id), as_message_id(message_id), nullptr,
|
||||||
|
as_caption(caption)));
|
||||||
|
} else if (op == "emd") {
|
||||||
|
string chat_id;
|
||||||
|
string message_id;
|
||||||
|
string document;
|
||||||
|
std::tie(chat_id, args) = split(args);
|
||||||
|
std::tie(message_id, document) = split(args);
|
||||||
|
send_request(make_tl_object<td_api::editMessageMedia>(
|
||||||
|
as_chat_id(chat_id), as_message_id(message_id), nullptr,
|
||||||
|
make_tl_object<td_api::inputMessageDocument>(as_input_file(document), nullptr, as_caption(""))));
|
||||||
|
} else if (op == "emp") {
|
||||||
|
string chat_id;
|
||||||
|
string message_id;
|
||||||
|
string photo;
|
||||||
|
std::tie(chat_id, args) = split(args);
|
||||||
|
std::tie(message_id, photo) = split(args);
|
||||||
|
send_request(make_tl_object<td_api::editMessageMedia>(
|
||||||
|
as_chat_id(chat_id), as_message_id(message_id), nullptr,
|
||||||
|
make_tl_object<td_api::inputMessagePhoto>(as_input_file(photo), as_input_thumbnail(as_input_file(photo)),
|
||||||
|
Auto(), 0, 0, as_caption(""), 0)));
|
||||||
|
} else if (op == "empttl") {
|
||||||
|
string chat_id;
|
||||||
|
string message_id;
|
||||||
|
string photo;
|
||||||
|
std::tie(chat_id, args) = split(args);
|
||||||
|
std::tie(message_id, photo) = split(args);
|
||||||
|
send_request(make_tl_object<td_api::editMessageMedia>(
|
||||||
|
as_chat_id(chat_id), as_message_id(message_id), nullptr,
|
||||||
|
make_tl_object<td_api::inputMessagePhoto>(as_input_file(photo), as_input_thumbnail(as_input_file(photo)),
|
||||||
|
Auto(), 0, 0, as_caption(""), 10)));
|
||||||
|
} else if (op == "emvt") {
|
||||||
|
string chat_id;
|
||||||
|
string message_id;
|
||||||
|
string video;
|
||||||
|
string thumbnail;
|
||||||
|
std::tie(chat_id, args) = split(args);
|
||||||
|
std::tie(message_id, args) = split(args);
|
||||||
|
std::tie(video, thumbnail) = split(args);
|
||||||
|
send_request(make_tl_object<td_api::editMessageMedia>(
|
||||||
|
as_chat_id(chat_id), as_message_id(message_id), nullptr,
|
||||||
|
make_tl_object<td_api::inputMessageVideo>(as_input_file(video), as_input_thumbnail(as_input_file(thumbnail)),
|
||||||
|
Auto(), 1, 2, 3, true, as_caption(""), 0)));
|
||||||
} else if (op == "emll") {
|
} else if (op == "emll") {
|
||||||
string chat_id;
|
string chat_id;
|
||||||
string message_id;
|
string message_id;
|
||||||
@ -3163,6 +3206,10 @@ class CliClient final : public Actor {
|
|||||||
fd.truncate_to_current_position(size).ignore();
|
fd.truncate_to_current_position(size).ignore();
|
||||||
} else if (op == "SetVerbosity" || op == "SV") {
|
} else if (op == "SetVerbosity" || op == "SV") {
|
||||||
td::Log::set_verbosity_level(to_integer<int>(args));
|
td::Log::set_verbosity_level(to_integer<int>(args));
|
||||||
|
} else if (op[0] == 'v' && op[1] == 'v') {
|
||||||
|
td::Log::set_verbosity_level(static_cast<int>(op.size()));
|
||||||
|
} else if (op[0] == 'v' && ('0' <= op[1] && op[1] <= '9')) {
|
||||||
|
td::Log::set_verbosity_level(to_integer<int>(op.substr(1)));
|
||||||
} else if (op == "q" || op == "Quit") {
|
} else if (op == "q" || op == "Quit") {
|
||||||
quit();
|
quit();
|
||||||
} else if (op == "dnq" || op == "DumpNetQueries") {
|
} else if (op == "dnq" || op == "DumpNetQueries") {
|
||||||
|
Loading…
Reference in New Issue
Block a user