Add information about failed to send messages.

GitOrigin-RevId: a4cb3669b5cf478a2e2f5ca1ecf2ea9c5f3ef5cc
This commit is contained in:
levlam 2019-08-11 00:14:35 +03:00
parent 5a032743e6
commit c045fce56a
6 changed files with 77 additions and 33 deletions

View File

@ -516,8 +516,9 @@ messageForwardInfo origin:MessageForwardOrigin date:int32 from_chat_id:int53 fro
//@description The message is being sent now, but has not yet been delivered to the server //@description The message is being sent now, but has not yet been delivered to the server
messageSendingStatePending = MessageSendingState; messageSendingStatePending = MessageSendingState;
//@description The message failed to be sent //@description The message failed to be sent @error_code An error code; 0 if unknown @error_message Error message
messageSendingStateFailed = MessageSendingState; //@can_retry True, if the message can be re-sent @retry_after Time left before the message can be re-sent, in seconds. No update is sent when this field changes
messageSendingStateFailed error_code:int32 error_message:string can_retry:Bool retry_after:double = MessageSendingState;
//@description Describes a message //@description Describes a message
@ -747,8 +748,8 @@ richTextMarked text:RichText = RichText;
richTextPhoneNumber text:RichText phone_number:string = RichText; richTextPhoneNumber text:RichText phone_number:string = RichText;
//@description A small image inside the text @document The image represented as a document. The image can be in GIF, JPEG or PNG format //@description A small image inside the text @document The image represented as a document. The image can be in GIF, JPEG or PNG format
//@width Width of a bounding box in which the image should be shown, 0 if unknown //@width Width of a bounding box in which the image should be shown; 0 if unknown
//@height Height of a bounding box in which the image should be shown, 0 if unknown //@height Height of a bounding box in which the image should be shown; 0 if unknown
richTextIcon document:document width:int32 height:int32 = RichText; richTextIcon document:document width:int32 height:int32 = RichText;
//@description A rich text anchor @text Text @name Anchor name //@description A rich text anchor @text Text @name Anchor name
@ -855,7 +856,7 @@ pageBlockVideo video:video caption:pageBlockCaption need_autoplay:Bool is_looped
//@description A page cover @cover Cover //@description A page cover @cover Cover
pageBlockCover cover:PageBlock = PageBlock; pageBlockCover cover:PageBlock = PageBlock;
//@description An embedded web page @url Web page URL, if available @html HTML-markup of the embedded page @poster_photo Poster photo, if available; may be null @width Block width, 0 if unknown @height Block height, 0 if unknown @caption Block caption @is_full_width True, if the block should be full width @allow_scrolling True, if scrolling should be allowed //@description An embedded web page @url Web page URL, if available @html HTML-markup of the embedded page @poster_photo Poster photo, if available; may be null @width Block width; 0 if unknown @height Block height; 0 if unknown @caption Block caption @is_full_width True, if the block should be full width @allow_scrolling True, if scrolling should be allowed
pageBlockEmbedded url:string html:string poster_photo:photo width:int32 height:int32 caption:pageBlockCaption is_full_width:Bool allow_scrolling:Bool = PageBlock; pageBlockEmbedded url:string html:string poster_photo:photo width:int32 height:int32 caption:pageBlockCaption is_full_width:Bool allow_scrolling:Bool = PageBlock;
//@description An embedded post @url Web page URL @author Post author @author_photo Post author photo; may be null @date Point in time (Unix timestamp) when the post was created; 0 if unknown @page_blocks Post content @caption Post caption //@description An embedded post @url Web page URL @author Post author @author_photo Post author photo; may be null @date Point in time (Unix timestamp) when the post was created; 0 if unknown @page_blocks Post content @caption Post caption

Binary file not shown.

View File

@ -4846,11 +4846,6 @@ void update_expired_message_content(unique_ptr<MessageContent> &content) {
void update_failed_to_send_message_content(Td *td, unique_ptr<MessageContent> &content) { void update_failed_to_send_message_content(Td *td, unique_ptr<MessageContent> &content) {
// do not forget about failed to send message forwards // do not forget about failed to send message forwards
switch (content->get_type()) { switch (content->get_type()) {
case MessageContentType::LiveLocation: {
MessageLiveLocation *message_live_location = static_cast<MessageLiveLocation *>(content.get());
message_live_location->period = 1;
break;
}
case MessageContentType::Poll: { case MessageContentType::Poll: {
const MessagePoll *message_poll = static_cast<const MessagePoll *>(content.get()); const MessagePoll *message_poll = static_cast<const MessagePoll *>(content.get());
if (PollManager::is_local_poll_id(message_poll->poll_id)) { if (PollManager::is_local_poll_id(message_poll->poll_id)) {

View File

@ -3570,6 +3570,7 @@ void MessagesManager::Message::store(StorerT &storer) const {
bool has_flags2 = true; bool has_flags2 = true;
bool has_notification_id = notification_id.is_valid(); bool has_notification_id = notification_id.is_valid();
bool has_forward_sender_name = is_forwarded && !forward_info->sender_name.empty(); bool has_forward_sender_name = is_forwarded && !forward_info->sender_name.empty();
bool has_send_error_code = send_error_code != 0;
BEGIN_STORE_FLAGS(); BEGIN_STORE_FLAGS();
STORE_FLAG(is_channel_post); STORE_FLAG(is_channel_post);
STORE_FLAG(is_outgoing); STORE_FLAG(is_outgoing);
@ -3608,6 +3609,7 @@ void MessagesManager::Message::store(StorerT &storer) const {
STORE_FLAG(is_mention_notification_disabled); STORE_FLAG(is_mention_notification_disabled);
STORE_FLAG(had_forward_info); STORE_FLAG(had_forward_info);
STORE_FLAG(has_forward_sender_name); STORE_FLAG(has_forward_sender_name);
STORE_FLAG(has_send_error_code);
END_STORE_FLAGS(); END_STORE_FLAGS();
} }
@ -3655,13 +3657,13 @@ void MessagesManager::Message::store(StorerT &storer) const {
} }
if (has_ttl) { if (has_ttl) {
store(ttl, storer); store(ttl, storer);
double server_time = storer.context()->server_time(); store_time(ttl_expires_at, storer);
if (ttl_expires_at == 0) { }
store(-1.0, storer); if (has_send_error_code) {
} else { store(send_error_code, storer);
double ttl_left = max(ttl_expires_at - Time::now_cached(), 0.0); store(send_error_message, storer);
store(ttl_left, storer); if (send_error_code == 429) {
store(server_time, storer); store_time(try_resend_at, storer);
} }
} }
if (has_author_signature) { if (has_author_signature) {
@ -3701,6 +3703,7 @@ void MessagesManager::Message::parse(ParserT &parser) {
bool has_flags2; bool has_flags2;
bool has_notification_id = false; bool has_notification_id = false;
bool has_forward_sender_name = false; bool has_forward_sender_name = false;
bool has_send_error_code = false;
BEGIN_PARSE_FLAGS(); BEGIN_PARSE_FLAGS();
PARSE_FLAG(is_channel_post); PARSE_FLAG(is_channel_post);
PARSE_FLAG(is_outgoing); PARSE_FLAG(is_outgoing);
@ -3739,6 +3742,7 @@ void MessagesManager::Message::parse(ParserT &parser) {
PARSE_FLAG(is_mention_notification_disabled); PARSE_FLAG(is_mention_notification_disabled);
PARSE_FLAG(had_forward_info); PARSE_FLAG(had_forward_info);
PARSE_FLAG(has_forward_sender_name); PARSE_FLAG(has_forward_sender_name);
PARSE_FLAG(has_send_error_code);
END_PARSE_FLAGS(); END_PARSE_FLAGS();
} }
@ -3791,16 +3795,13 @@ void MessagesManager::Message::parse(ParserT &parser) {
} }
if (has_ttl) { if (has_ttl) {
parse(ttl, parser); parse(ttl, parser);
double ttl_left; parse_time(ttl_expires_at, parser);
parse(ttl_left, parser); }
if (ttl_left < -0.1) { if (has_send_error_code) {
ttl_expires_at = 0; parse(send_error_code, parser);
} else { parse(send_error_message, parser);
double old_server_time; if (send_error_code == 429) {
parse(old_server_time, parser); parse_time(try_resend_at, parser);
double passed_server_time = max(parser.context()->server_time() - old_server_time, 0.0);
ttl_left = max(ttl_left - passed_server_time, 0.0);
ttl_expires_at = Time::now_cached() + ttl_left;
} }
} }
if (has_author_signature) { if (has_author_signature) {
@ -5192,7 +5193,8 @@ void MessagesManager::on_update_message_content(FullMessageId full_message_id) {
CHECK(d != nullptr); CHECK(d != nullptr);
const Message *m = get_message(d, full_message_id.get_message_id()); const Message *m = get_message(d, full_message_id.get_message_id());
CHECK(m != nullptr); CHECK(m != nullptr);
send_update_message_content(full_message_id.get_dialog_id(), m->message_id, m->content.get(), m->date, auto live_location_date = m->is_failed_to_send ? 0 : m->date;
send_update_message_content(full_message_id.get_dialog_id(), m->message_id, m->content.get(), live_location_date,
m->is_content_secret, "on_update_message_content"); m->is_content_secret, "on_update_message_content");
on_message_changed(d, m, true, "on_update_message_content"); on_message_changed(d, m, true, "on_update_message_content");
} }
@ -14579,6 +14581,10 @@ vector<FullMessageId> MessagesManager::get_active_live_location_messages(Promise
CHECK(m != nullptr); CHECK(m != nullptr);
CHECK(m->content->get_type() == MessageContentType::LiveLocation); CHECK(m->content->get_type() == MessageContentType::LiveLocation);
if (m->is_failed_to_send) {
continue;
}
auto live_period = get_message_content_live_location_period(m->content.get()); auto live_period = get_message_content_live_location_period(m->content.get());
if (live_period <= G()->unix_time() - m->date) { // bool is_expired flag? if (live_period <= G()->unix_time() - m->date) { // bool is_expired flag?
// live location is expired // live location is expired
@ -14635,7 +14641,7 @@ void MessagesManager::on_load_active_live_location_messages_finished() {
void MessagesManager::try_add_active_live_location(DialogId dialog_id, const Message *m) { void MessagesManager::try_add_active_live_location(DialogId dialog_id, const Message *m) {
CHECK(m != nullptr); CHECK(m != nullptr);
if (m->content->get_type() != MessageContentType::LiveLocation) { if (m->content->get_type() != MessageContentType::LiveLocation || m->is_failed_to_send) {
return; return;
} }
@ -15531,7 +15537,8 @@ tl_object_ptr<td_api::message> MessagesManager::get_message_object(DialogId dial
// TODO get_message_sending_state_object // TODO get_message_sending_state_object
tl_object_ptr<td_api::MessageSendingState> sending_state; tl_object_ptr<td_api::MessageSendingState> sending_state;
if (m->is_failed_to_send) { if (m->is_failed_to_send) {
sending_state = make_tl_object<td_api::messageSendingStateFailed>(); sending_state = make_tl_object<td_api::messageSendingStateFailed>(
m->send_error_code, m->send_error_message, m->send_error_code == 429, max(m->try_resend_at - Time::now(), 0.0));
} else if (m->message_id.is_yet_unsent()) { } else if (m->message_id.is_yet_unsent()) {
sending_state = make_tl_object<td_api::messageSendingStatePending>(); sending_state = make_tl_object<td_api::messageSendingStatePending>();
} }
@ -15599,13 +15606,14 @@ tl_object_ptr<td_api::message> MessagesManager::get_message_object(DialogId dial
auto media_album_id = for_event_log ? static_cast<int64>(0) : m->media_album_id; auto media_album_id = for_event_log ? static_cast<int64>(0) : m->media_album_id;
auto reply_to_message_id = for_event_log ? static_cast<int64>(0) : m->reply_to_message_id.get(); auto reply_to_message_id = for_event_log ? static_cast<int64>(0) : m->reply_to_message_id.get();
bool contains_unread_mention = for_event_log ? false : m->contains_unread_mention; bool contains_unread_mention = for_event_log ? false : m->contains_unread_mention;
auto live_location_date = m->is_failed_to_send ? 0 : m->date;
return make_tl_object<td_api::message>( return make_tl_object<td_api::message>(
m->message_id.get(), td_->contacts_manager_->get_user_id_object(m->sender_user_id, "sender_user_id"), m->message_id.get(), td_->contacts_manager_->get_user_id_object(m->sender_user_id, "sender_user_id"),
dialog_id.get(), std::move(sending_state), is_outgoing, can_be_edited, can_be_forwarded, can_delete_for_self, dialog_id.get(), std::move(sending_state), is_outgoing, can_be_edited, can_be_forwarded, can_delete_for_self,
can_delete_for_all_users, m->is_channel_post, contains_unread_mention, m->date, m->edit_date, can_delete_for_all_users, m->is_channel_post, contains_unread_mention, m->date, m->edit_date,
get_message_forward_info_object(m->forward_info), reply_to_message_id, ttl, ttl_expires_in, get_message_forward_info_object(m->forward_info), reply_to_message_id, ttl, ttl_expires_in,
td_->contacts_manager_->get_user_id_object(m->via_bot_user_id, "via_bot_user_id"), m->author_signature, m->views, td_->contacts_manager_->get_user_id_object(m->via_bot_user_id, "via_bot_user_id"), m->author_signature, m->views,
media_album_id, get_message_content_object(m->content.get(), td_, m->date, m->is_content_secret), media_album_id, get_message_content_object(m->content.get(), td_, live_location_date, m->is_content_secret),
get_reply_markup_object(m->reply_markup)); get_reply_markup_object(m->reply_markup));
} }
@ -20851,7 +20859,16 @@ void MessagesManager::fail_send_message(FullMessageId full_message_id, int error
CHECK(message->message_id.is_valid()); CHECK(message->message_id.is_valid());
message->random_y = get_random_y(message->message_id); message->random_y = get_random_y(message->message_id);
message->is_failed_to_send = true; message->is_failed_to_send = true;
message->send_error_code = error_code;
message->send_error_message = error_message;
message->try_resend_at = 0.0;
Slice retry_after_prefix("Too Many Requests: retry after ");
if (error_code == 429 && begins_with(error_message, retry_after_prefix)) {
auto r_retry_after = to_integer_safe<int32>(error_message.substr(retry_after_prefix.size()));
if (r_retry_after.is_ok() && r_retry_after.ok() > 0) {
message->try_resend_at = Time::now() + r_retry_after.ok();
}
}
update_failed_to_send_message_content(td_, message->content); update_failed_to_send_message_content(td_, message->content);
message->have_previous = true; message->have_previous = true;

View File

@ -868,7 +868,7 @@ class MessagesManager : public Actor {
bool is_channel_post = false; bool is_channel_post = false;
bool is_outgoing = false; bool is_outgoing = false;
bool is_failed_to_send = false; // TODO replace with error_code bool is_failed_to_send = false;
bool disable_notification = false; bool disable_notification = false;
bool contains_mention = false; bool contains_mention = false;
bool contains_unread_mention = false; bool contains_unread_mention = false;
@ -891,6 +891,10 @@ class MessagesManager : public Actor {
int32 views = 0; int32 views = 0;
int32 send_error_code = 0;
string send_error_message;
double try_resend_at = 0;
int32 ttl = 0; int32 ttl = 0;
double ttl_expires_at = 0; double ttl_expires_at = 0;

View File

@ -35,4 +35,31 @@ inline Promise<Unit> get_erase_logevent_promise_impl(const char *file, int32 lin
}); });
} }
template <class StorerT>
void store_time(double time_at, StorerT &storer) {
double server_time = storer.context()->server_time();
if (time_at == 0) {
store(-1.0, storer);
} else {
double time_left = max(time_at - Time::now(), 0.0);
store(time_left, storer);
store(server_time, storer);
}
}
template <class ParserT>
void parse_time(double &time_at, ParserT &parser) {
double time_left;
parse(time_left, parser);
if (time_left < -0.1) {
time_at = 0;
} else {
double old_server_time;
parse(old_server_time, parser);
double passed_server_time = max(parser.context()->server_time() - old_server_time, 0.0);
time_left = max(time_left - passed_server_time, 0.0);
time_at = Time::now_cached() + time_left;
}
}
} // namespace td } // namespace td