Allow sending chat actions inside message thread.

GitOrigin-RevId: 6ad0b659f957013fa493386ad808eb6767399253
This commit is contained in:
levlam 2020-09-18 19:42:31 +03:00
parent b45ccc6d14
commit bda5a3c5bd
6 changed files with 42 additions and 17 deletions

View File

@ -3903,8 +3903,8 @@ getInlineGameHighScores inline_message_id:string user_id:int32 = GameHighScores;
deleteChatReplyMarkup chat_id:int53 message_id:int53 = Ok;
//@description Sends a notification about user activity in a chat @chat_id Chat identifier @action The action description
sendChatAction chat_id:int53 action:ChatAction = Ok;
//@description Sends a notification about user activity in a chat @chat_id Chat identifier @message_thread_id If not 0, a message thread identifier of the action @action The action description
sendChatAction chat_id:int53 message_thread_id:int53 action:ChatAction = Ok;
//@description Informs TDLib that the chat is opened by the user. Many useful activities depend on the chat being opened or closed (e.g., in supergroups and channels all updates are received only for opened chats) @chat_id Chat identifier

Binary file not shown.

View File

@ -3247,14 +3247,17 @@ class SetTypingQuery : public Td::ResultHandler {
explicit SetTypingQuery(Promise<Unit> &&promise) : promise_(std::move(promise)) {
}
NetQueryRef send(DialogId dialog_id, tl_object_ptr<telegram_api::SendMessageAction> &&action) {
NetQueryRef send(DialogId dialog_id, MessageId message_id, tl_object_ptr<telegram_api::SendMessageAction> &&action) {
dialog_id_ = dialog_id;
auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Write);
CHECK(input_peer != nullptr);
int32 flags = 0;
auto net_query = G()->net_query_creator().create(
telegram_api::messages_setTyping(flags, std::move(input_peer), 0, std::move(action)));
if (message_id.is_valid()) {
flags |= telegram_api::messages_setTyping::TOP_MSG_ID_MASK;
}
auto net_query = G()->net_query_creator().create(telegram_api::messages_setTyping(
flags, std::move(input_peer), message_id.get_server_message_id().get(), std::move(action)));
auto result = net_query.get_weak();
send_query(std::move(net_query));
return result;
@ -20952,6 +20955,12 @@ MessagesManager::Message *MessagesManager::get_message_to_send(
m->send_date = G()->unix_time();
m->date = is_scheduled ? options.schedule_date : m->send_date;
m->reply_to_message_id = reply_to_message_id;
if (reply_to_message_id.is_valid()) {
const Message *reply_m = get_message(d, reply_to_message_id);
if (reply_m != nullptr) {
m->top_reply_message_id = reply_m->top_reply_message_id;
}
}
m->is_channel_post = is_channel_post;
m->is_outgoing = is_scheduled || dialog_id != DialogId(my_id);
m->from_background = options.from_background;
@ -24483,6 +24492,12 @@ Result<MessageId> MessagesManager::add_local_message(
}
m->date = G()->unix_time();
m->reply_to_message_id = get_reply_to_message_id(d, reply_to_message_id);
if (m->reply_to_message_id.is_valid()) {
const Message *reply_m = get_message(d, m->reply_to_message_id);
if (reply_m != nullptr) {
m->top_reply_message_id = reply_m->top_reply_message_id;
}
}
m->is_channel_post = is_channel_post;
m->is_outgoing = dialog_id != DialogId(my_id) && sender_user_id == my_id;
m->disable_notification = disable_notification;
@ -27806,7 +27821,7 @@ bool MessagesManager::get_dialog_has_scheduled_messages(const Dialog *d) const {
return d->has_scheduled_server_messages || d->has_scheduled_database_messages || d->scheduled_messages != nullptr;
}
bool MessagesManager::is_dialog_action_unneded(DialogId dialog_id) const {
bool MessagesManager::is_dialog_action_unneeded(DialogId dialog_id) const {
if (is_anonymous_administrator(dialog_id)) {
return true;
}
@ -27827,8 +27842,8 @@ bool MessagesManager::is_dialog_action_unneded(DialogId dialog_id) const {
return false;
}
void MessagesManager::send_dialog_action(DialogId dialog_id, const tl_object_ptr<td_api::ChatAction> &action,
Promise<Unit> &&promise) {
void MessagesManager::send_dialog_action(DialogId dialog_id, MessageId top_thread_message_id,
const tl_object_ptr<td_api::ChatAction> &action, Promise<Unit> &&promise) {
if (action == nullptr) {
return promise.set_error(Status::Error(5, "Action must be non-empty"));
}
@ -27836,6 +27851,10 @@ void MessagesManager::send_dialog_action(DialogId dialog_id, const tl_object_ptr
if (!have_dialog_force(dialog_id)) {
return promise.set_error(Status::Error(5, "Chat not found"));
}
if (top_thread_message_id != MessageId() &&
(!top_thread_message_id.is_valid() || !top_thread_message_id.is_server())) {
return promise.set_error(Status::Error(5, "Invalid message thread specified"));
}
auto can_send_status = can_send_message(dialog_id);
if (can_send_status.is_error()) {
@ -27845,7 +27864,7 @@ void MessagesManager::send_dialog_action(DialogId dialog_id, const tl_object_ptr
return promise.set_value(Unit());
}
if (is_dialog_action_unneded(dialog_id)) {
if (is_dialog_action_unneeded(dialog_id)) {
return promise.set_value(Unit());
}
@ -27959,7 +27978,8 @@ void MessagesManager::send_dialog_action(DialogId dialog_id, const tl_object_ptr
LOG(INFO) << "Cancel previous set typing query";
cancel_query(query_ref);
}
query_ref = td_->create_handler<SetTypingQuery>(std::move(promise))->send(dialog_id, std::move(send_action));
query_ref = td_->create_handler<SetTypingQuery>(std::move(promise))
->send(dialog_id, top_thread_message_id, std::move(send_action));
}
void MessagesManager::on_send_dialog_action_timeout(DialogId dialog_id) {
@ -28035,7 +28055,7 @@ void MessagesManager::on_send_dialog_action_timeout(DialogId dialog_id) {
}
CHECK(action != nullptr);
LOG(INFO) << "Send action in " << dialog_id << ": " << to_string(action);
send_dialog_action(dialog_id, std::move(action), Auto());
send_dialog_action(dialog_id, m->top_reply_message_id, std::move(action), Auto());
}
void MessagesManager::on_active_dialog_action_timeout(DialogId dialog_id) {
@ -29828,7 +29848,7 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq
if (queue_id & 1) {
LOG(INFO) << "Add " << message_id << " from " << source << " to queue " << queue_id;
yet_unsent_media_queues_[queue_id][message_id.get()]; // reserve place for promise
if (!td_->auth_manager_->is_bot() && !is_dialog_action_unneded(dialog_id)) {
if (!td_->auth_manager_->is_bot() && !is_dialog_action_unneeded(dialog_id)) {
pending_send_dialog_action_timeout_.add_timeout_in(dialog_id.get(), 1.0);
}
}

View File

@ -472,7 +472,8 @@ class MessagesManager : public Actor {
tl_object_ptr<td_api::gameHighScores> get_game_high_scores_object(int64 random_id);
void send_dialog_action(DialogId dialog_id, const tl_object_ptr<td_api::ChatAction> &action, Promise<Unit> &&promise);
void send_dialog_action(DialogId dialog_id, MessageId top_thread_message_id,
const tl_object_ptr<td_api::ChatAction> &action, Promise<Unit> &&promise);
vector<DialogListId> get_dialog_lists_to_add_dialog(DialogId dialog_id);
@ -2283,7 +2284,7 @@ class MessagesManager : public Actor {
bool update_dialog_silent_send_message(Dialog *d, bool silent_send_message);
bool is_dialog_action_unneded(DialogId dialog_id) const;
bool is_dialog_action_unneeded(DialogId dialog_id) const;
void on_send_dialog_action_timeout(DialogId dialog_id);

View File

@ -5798,7 +5798,8 @@ void Td::on_request(uint64 id, const td_api::deleteChatReplyMarkup &request) {
void Td::on_request(uint64 id, td_api::sendChatAction &request) {
CREATE_OK_REQUEST_PROMISE();
messages_manager_->send_dialog_action(DialogId(request.chat_id_), std::move(request.action_), std::move(promise));
messages_manager_->send_dialog_action(DialogId(request.chat_id_), MessageId(request.message_thread_id_),
std::move(request.action_), std::move(promise));
}
void Td::on_request(uint64 id, td_api::sendChatScreenshotTakenNotification &request) {

View File

@ -2936,9 +2936,12 @@ class CliClient final : public Actor {
send_request(td_api::make_object<td_api::setPinnedChats>(as_chat_list(op), std::move(chat_ids)));
} else if (op == "sca") {
string chat_id;
string message_thread_id;
string action;
std::tie(chat_id, action) = split(args);
send_request(td_api::make_object<td_api::sendChatAction>(as_chat_id(chat_id), get_chat_action(action)));
std::tie(chat_id, args) = split(args);
std::tie(message_thread_id, action) = split(args);
send_request(td_api::make_object<td_api::sendChatAction>(
as_chat_id(chat_id), as_message_thread_id(message_thread_id), get_chat_action(action)));
} else if (op == "smt" || op == "smtp" || op == "smtf" || op == "smtpf") {
const string &chat_id = args;
for (int i = 1; i <= 200; i++) {