Description: Add deleted_messages update type for regular chats
 Dispatches a deleted_messages update to bots when messages are
 permanently deleted (not cache evictions). Opt-in via
 allowed_updates, disabled by default.
Forwarded: no
Last-Update: 2026-06-01

--- telegram-bot-api-10.0+tdlib1.8.64.orig/telegram-bot-api/Client.cpp
+++ telegram-bot-api-10.0+tdlib1.8.64/telegram-bot-api/Client.cpp
@@ -5573,6 +5573,23 @@ class Client::JsonBusinessMessagesDelete
   const Client *client_;
 };
 
+class Client::JsonDeletedMessages final : public td::Jsonable {
+ public:
+  JsonDeletedMessages(int64 chat_id, const td::vector<int64> &message_ids, const Client *client)
+      : chat_id_(chat_id), message_ids_(message_ids), client_(client) {
+  }
+  void store(td::JsonValueScope *scope) const {
+    auto object = scope->enter_object();
+    object("chat", JsonChat(chat_id_, client_));
+    object("message_ids", td::json_array(message_ids_, as_client_message_id));
+  }
+
+ private:
+  int64 chat_id_;
+  const td::vector<int64> &message_ids_;
+  const Client *client_;
+};
+
 class Client::JsonReceivedGift final : public td::Jsonable {
  public:
   JsonReceivedGift(const td_api::receivedGift *received_gift, bool can_be_managed, const Client *client)
@@ -8886,6 +8903,11 @@ void Client::on_update(object_ptr<td_api
     }
     case td_api::updateDeleteMessages::ID: {
       auto update = move_object_as<td_api::updateDeleteMessages>(result);
+      if (update->is_permanent_ && !update->from_cache_) {
+        add_update(UpdateType::DeletedMessages,
+                   JsonDeletedMessages(update->chat_id_, update->message_ids_, this), 86400,
+                   update->chat_id_ + (static_cast<int64>(11) << 33));
+      }
       td::vector<td::unique_ptr<MessageInfo>> deleted_messages;
       for (auto message_id : update->message_ids_) {
         auto deleted_message = delete_message(update->chat_id_, message_id, update->from_cache_);
@@ -16880,6 +16902,8 @@ td::Slice Client::get_update_type_name(U
       return td::Slice("managed_bot");
     case UpdateType::GuestMessage:
       return td::Slice("guest_message");
+    case UpdateType::DeletedMessages:
+      return td::Slice("deleted_messages");
     default:
       UNREACHABLE();
       return td::Slice();
--- telegram-bot-api-10.0+tdlib1.8.64.orig/telegram-bot-api/Client.h
+++ telegram-bot-api-10.0+tdlib1.8.64/telegram-bot-api/Client.h
@@ -1421,6 +1421,7 @@ class Client final : public WebhookActor
     PurchasedPaidMedia,
     ManagedBot,
     GuestMessage,
+    DeletedMessages,
     Size
   };
 
@@ -1452,11 +1453,12 @@ class Client final : public WebhookActor
 
   bool have_message_access(int64 chat_id) const;
 
-  // by default ChatMember, MessageReaction, and MessageReactionCount updates are disabled
+  // by default ChatMember, MessageReaction, MessageReactionCount, and DeletedMessages updates are disabled
   static constexpr td::uint32 DEFAULT_ALLOWED_UPDATE_TYPES =
       (1 << static_cast<int32>(UpdateType::Size)) - 1 - (1 << static_cast<int32>(UpdateType::ChatMember)) -
       (1 << static_cast<int32>(UpdateType::MessageReaction)) -
-      (1 << static_cast<int32>(UpdateType::MessageReactionCount));
+      (1 << static_cast<int32>(UpdateType::MessageReactionCount)) -
+      (1 << static_cast<int32>(UpdateType::DeletedMessages));
 
   object_ptr<td_api::AuthorizationState> authorization_state_;
   bool was_authorized_ = false;
