diff --git a/compiler/docs/compiler.py b/compiler/docs/compiler.py
index 24eeb19f..f737c821 100644
--- a/compiler/docs/compiler.py
+++ b/compiler/docs/compiler.py
@@ -165,6 +165,7 @@ def pyrogram_api():
""",
messages="""
Messages
+ add_task_to_todo
send_message
forward_media_group
forward_messages
@@ -174,6 +175,7 @@ def pyrogram_api():
send_audio
send_document
send_sticker
+ send_todo
send_video
send_animation
send_voice
@@ -185,6 +187,7 @@ def pyrogram_api():
send_contact
send_cached_media
send_reaction
+ set_todo_tasks_completion
edit_message_text
edit_message_caption
edit_message_media
@@ -535,6 +538,11 @@ def pyrogram_api():
MessageOrigin
Photo
Thumbnail
+ TodoList
+ TodoTask
+ TodoTasksAdded
+ TodoTasksCompleted
+ TodoTasksIncompleted
Audio
AvailableEffect
Document
@@ -734,6 +742,7 @@ def pyrogram_api():
InputVenueMessageContent
InputContactMessageContent
InputInvoiceMessageContent
+ InputTodoTask
""",
authorization="""
Authorization
diff --git a/pyrogram/enums/message_media_type.py b/pyrogram/enums/message_media_type.py
index c9e3fa44..067c2f96 100644
--- a/pyrogram/enums/message_media_type.py
+++ b/pyrogram/enums/message_media_type.py
@@ -84,3 +84,6 @@ class MessageMediaType(AutoName):
PAID_MEDIA = auto()
"Paid media"
+
+ TODO = auto()
+ "To-Do list media"
diff --git a/pyrogram/enums/message_service_type.py b/pyrogram/enums/message_service_type.py
index 5f25dd6b..cd631b61 100644
--- a/pyrogram/enums/message_service_type.py
+++ b/pyrogram/enums/message_service_type.py
@@ -135,3 +135,9 @@ class MessageServiceType(AutoName):
PAID_MESSAGE_PRICE_CHANGED = auto()
"Paid message price changed"
+
+ TODO_TASKS_ADDED = auto()
+ "To-Do tasks added"
+
+ TODO_TASKS_COMPLETION = auto()
+ "To-Do tasks completion/incompletion"
diff --git a/pyrogram/methods/messages/__init__.py b/pyrogram/methods/messages/__init__.py
index d239cb49..8a720a87 100644
--- a/pyrogram/methods/messages/__init__.py
+++ b/pyrogram/methods/messages/__init__.py
@@ -17,6 +17,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrofork. If not, see .
+from .add_task_to_todo import AddTaskToTodo
from .copy_media_group import CopyMediaGroup
from .copy_message import CopyMessage
from .delete_chat_history import DeleteChatHistory
@@ -52,6 +53,7 @@ from .search_global_hashtag_messages import SearchGlobalHashtagMessages
from .search_global_hashtag_messages_count import SearchGlobalHashtagMessagesCount
from .search_messages import SearchMessages
from .search_messages_count import SearchMessagesCount
+from .set_todo_tasks_completion import SetTodoTasksCompletion
from .send_animation import SendAnimation
from .send_audio import SendAudio
from .send_cached_media import SendCachedMedia
@@ -66,6 +68,7 @@ from .send_photo import SendPhoto
from .send_poll import SendPoll
from .send_reaction import SendReaction
from .send_sticker import SendSticker
+from .send_todo import SendTodo
from .send_venue import SendVenue
from .send_video import SendVideo
from .send_video_note import SendVideoNote
@@ -79,6 +82,7 @@ from .transcribe_audio import TranscribeAudio
from .translate_text import TranslateText
class Messages(
+ AddTaskToTodo,
DeleteChatHistory,
DeleteMessages,
DeleteScheduledMessages,
@@ -93,6 +97,7 @@ class Messages(
GetMessages,
GetMessageReadParticipants,
GetScheduledMessages,
+ SetTodoTasksCompletion,
SendAudio,
SendChatAction,
SendContact,
@@ -103,6 +108,7 @@ class Messages(
SendMessage,
SendPhoto,
SendSticker,
+ SendTodo,
SendVenue,
SendVideo,
SendVideoNote,
diff --git a/pyrogram/methods/messages/add_task_to_todo.py b/pyrogram/methods/messages/add_task_to_todo.py
new file mode 100644
index 00000000..a8203785
--- /dev/null
+++ b/pyrogram/methods/messages/add_task_to_todo.py
@@ -0,0 +1,82 @@
+# Pyrofork - Telegram MTProto API Client Library for Python
+# Copyright (C) 2022-present Mayuri-Chan
+#
+# This file is part of Pyrofork.
+#
+# Pyrofork is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Pyrofork is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Pyrofork. If not, see .
+
+import pyrogram
+
+from pyrogram import raw, types, utils
+from typing import Union, List
+
+
+class AddTaskToTodo:
+ async def add_task_to_todo(
+ self: "pyrogram.Client",
+ chat_id: Union[int, str],
+ message_id: Union[int, str],
+ tasks: List["types.InputTodoTask"],
+ parse_mode: str = None
+ ) -> "types.Message":
+ """Add tasks to a todo list.
+
+ Parameters:
+ chat_id (``int`` | ``str``):
+ Unique identifier for the target chat or username of the target channel.
+
+ message_id (``int`` | ``str``):
+ Unique identifier for the target message or username of the target channel.
+
+ tasks (List of :obj:`~pyrogram.types.InputTodoTask`):
+ List of tasks to be added to the todo list.
+
+ parse_mode (``str``, *optional*):
+ The parse mode to use for formatting the text.
+
+ entities (List of :obj:`~pyrogram.types.MessageEntity`, *optional*):
+ Entities in the title of the todo list.
+ """
+ tasks_list = []
+ get_message = await self.get_messages(chat_id, message_id)
+ if not isinstance(get_message, types.Message):
+ raise ValueError("The message must be a valid Message object.")
+ todo_list = get_message.todo
+ last_task_id = max((task.id for task in todo_list.tasks), default=0)
+ for i, task in enumerate(tasks):
+ task_title, task_entities = (await utils.parse_text_entities(self, task.title, parse_mode, task.entities)).values()
+ tasks_list.append(
+ raw.types.TodoItem(
+ id=last_task_id + i + 1,
+ title=raw.types.TextWithEntities(
+ text=task_title,
+ entities=task_entities or []
+ )
+ )
+ )
+
+ r = await self.invoke(
+ raw.functions.messages.AppendTodoList(
+ peer=await self.resolve_peer(chat_id),
+ msg_id=message_id,
+ list=tasks_list
+ )
+ )
+
+ for update in r.updates:
+ if isinstance(update, (raw.types.UpdateNewMessage,
+ raw.types.UpdateNewChannelMessage,
+ raw.types.UpdateNewScheduledMessage,
+ raw.types.UpdateBotNewBusinessMessage)):
+ return types.Message._parse(self, update.message, update, r.users, r.chats)
diff --git a/pyrogram/methods/messages/send_todo.py b/pyrogram/methods/messages/send_todo.py
new file mode 100644
index 00000000..8e671085
--- /dev/null
+++ b/pyrogram/methods/messages/send_todo.py
@@ -0,0 +1,99 @@
+# Pyrofork - Telegram MTProto API Client Library for Python
+# Copyright (C) 2022-present Mayuri-Chan
+#
+# This file is part of Pyrofork.
+#
+# Pyrofork is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Pyrofork is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Pyrofork. If not, see .
+
+import pyrogram
+
+from pyrogram import raw, types, utils
+from typing import Union, List
+
+
+class SendTodo:
+ async def send_todo(
+ self: "pyrogram.Client",
+ chat_id: Union[int, str],
+ title: str,
+ tasks: List["types.InputTodoTask"],
+ entities: List["types.MessageEntity"] = None,
+ can_append: bool = False,
+ can_complete: bool = False,
+ parse_mode: Union[str, None] = None
+ ):
+ """Send a todo list to a chat.
+
+ Parameters:
+ chat_id (``int`` | ``str``):
+ Unique identifier for the target chat or username of the target channel.
+
+ title (``str``):
+ Title of the todo list.
+
+ tasks (List of :obj:`~pyrogram.types.TodoTask`):
+ List of tasks in the todo list.
+
+ entities (List of :obj:`~pyrogram.types.MessageEntity`, *optional*):
+ Entities in the title of the todo list.
+
+ can_append (``bool``, *optional*):
+ True, if other users can append tasks to this todo list.
+
+ can_complete (``bool``, *optional*):
+ True, if other users can complete tasks in this todo list.
+ """
+ title, entities = (await utils.parse_text_entities(self, title, parse_mode, entities)).values()
+ tasks_list = []
+ for i, task in enumerate(tasks):
+ task_title, task_entities = (await utils.parse_text_entities(self, task.title, parse_mode, task.entities)).values()
+ tasks_list.append(
+ raw.types.TodoItem(
+ id=i + 1,
+ title=raw.types.TextWithEntities(
+ text=task_title,
+ entities=task_entities or []
+ )
+ )
+ )
+
+ r = await self.invoke(
+ raw.functions.messages.SendMedia(
+ peer=await self.resolve_peer(chat_id),
+ message="",
+ random_id=self.rnd_id(),
+ media=raw.types.InputMediaTodo(
+ todo=raw.types.TodoList(
+ title=raw.types.TextWithEntities(
+ text=title,
+ entities=entities or []
+ ),
+ list=tasks_list,
+ others_can_append=can_append,
+ others_can_complete=can_complete
+ )
+ )
+ )
+ )
+ for i in r.updates:
+ if isinstance(i, (raw.types.UpdateNewMessage,
+ raw.types.UpdateNewChannelMessage,
+ raw.types.UpdateNewScheduledMessage,
+ raw.types.UpdateBotNewBusinessMessage)):
+ return await types.Message._parse(
+ self, i.message,
+ {i.id: i for i in r.users},
+ {i.id: i for i in r.chats},
+ is_scheduled=isinstance(i, raw.types.UpdateNewScheduledMessage)
+ )
diff --git a/pyrogram/methods/messages/set_todo_tasks_completion.py b/pyrogram/methods/messages/set_todo_tasks_completion.py
new file mode 100644
index 00000000..2bb0420b
--- /dev/null
+++ b/pyrogram/methods/messages/set_todo_tasks_completion.py
@@ -0,0 +1,76 @@
+# Pyrofork - Telegram MTProto API Client Library for Python
+# Copyright (C) 2022-present Mayuri-Chan
+#
+# This file is part of Pyrofork.
+#
+# Pyrofork is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Pyrofork is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Pyrofork. If not, see .
+
+from typing import List, Union
+from pyrogram import raw, types
+
+
+class SetTodoTasksCompletion:
+ async def set_todo_tasks_completion(
+ self,
+ chat_id: int | str,
+ message_id: int,
+ completed_ids: Union[int, List[int]] = None,
+ incompleted_ids: Union[int, List[int]] = None
+ ) -> "types.Message":
+ """Set the completion status of one or more todo tasks.
+
+ Parameters:
+ chat_id (``int`` | ``str``):
+ Unique identifier (int) or username (str) of the target chat.
+
+ message_id (``int``):
+ Unique identifier of the message containing the todo list.
+
+ completed_ids (``int`` | List of ``int``, *optional*):
+ Unique identifier of the todo tasks to be marked as completed.
+ If a list is provided, all tasks in the list will be marked as completed.
+
+ incompleted_ids (``int`` | List of ``int``, *optional*):
+ Unique identifier of the todo tasks to be marked as incomplete.
+ If a list is provided, all tasks in the list will be marked as incomplete.
+ """
+ is_complete_iterable = None
+ is_incomplete_iterable = None
+ if completed_ids:
+ is_complete_iterable = not isinstance(completed_ids, int)
+ if incompleted_ids:
+ is_incomplete_iterable = not isinstance(incompleted_ids, int)
+ if not is_complete_iterable and not is_incomplete_iterable:
+ raise ValueError("At least one of completed_ids or incompleted_ids must be provided.")
+
+ r = await self.invoke(
+ raw.functions.messages.ToggleTodoCompleted(
+ peer=await self.resolve_peer(chat_id),
+ msg_id=message_id,
+ completed=(completed_ids if is_complete_iterable else [completed_ids]) if completed_ids else [],
+ incompleted=(incompleted_ids if is_incomplete_iterable else [incompleted_ids]) if incompleted_ids else []
+ )
+ )
+
+ for i in r.updates:
+ if isinstance(i, (raw.types.UpdateNewMessage,
+ raw.types.UpdateNewChannelMessage,
+ raw.types.UpdateNewScheduledMessage,
+ raw.types.UpdateBotNewBusinessMessage)):
+ return await types.Message._parse(
+ self, i.message,
+ {i.id: i for i in r.users},
+ {i.id: i for i in r.chats},
+ is_scheduled=isinstance(i, raw.types.UpdateNewScheduledMessage)
+ )
diff --git a/pyrogram/types/input_message_content/__init__.py b/pyrogram/types/input_message_content/__init__.py
index ae897b0d..5b2b15a0 100644
--- a/pyrogram/types/input_message_content/__init__.py
+++ b/pyrogram/types/input_message_content/__init__.py
@@ -26,6 +26,7 @@ from .input_location_message_content import InputLocationMessageContent
from .input_venue_message_content import InputVenueMessageContent
from .input_contact_message_content import InputContactMessageContent
from .input_invoice_message_content import InputInvoiceMessageContent
+from .input_todo_task import InputTodoTask
__all__ = [
"InputMessageContent",
@@ -36,5 +37,6 @@ __all__ = [
"InputLocationMessageContent",
"InputVenueMessageContent",
"InputContactMessageContent",
- "InputInvoiceMessageContent"
+ "InputInvoiceMessageContent",
+ "InputTodoTask"
]
diff --git a/pyrogram/types/input_message_content/input_todo_task.py b/pyrogram/types/input_message_content/input_todo_task.py
new file mode 100644
index 00000000..2e4d6ab0
--- /dev/null
+++ b/pyrogram/types/input_message_content/input_todo_task.py
@@ -0,0 +1,37 @@
+# Pyrofork - Telegram MTProto API Client Library for Python
+# Copyright (C) 2022-present Mayuri-Chan
+#
+# This file is part of Pyrofork.
+#
+# Pyrofork is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Pyrofork is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Pyrofork. If not, see .
+
+from ..object import Object
+
+
+class InputTodoTask(Object):
+ """Contains information about a todo task.
+
+ Parameters:
+ title (``str``):
+ Title of the task.
+
+ entities (List of :obj:`~pyrogram.types.MessageEntity`):
+ Entities in the title of the task.
+ """
+
+ def __init__(self, *, title: str, entities: list = None):
+ super().__init__()
+
+ self.title = title
+ self.entities = entities
diff --git a/pyrogram/types/messages_and_media/__init__.py b/pyrogram/types/messages_and_media/__init__.py
index 7cb8837f..778ad9d9 100644
--- a/pyrogram/types/messages_and_media/__init__.py
+++ b/pyrogram/types/messages_and_media/__init__.py
@@ -55,6 +55,11 @@ from .stickerset import StickerSet
from .stories_privacy_rules import StoriesPrivacyRules
from .stripped_thumbnail import StrippedThumbnail
from .thumbnail import Thumbnail
+from .todo_list import TodoList
+from .todo_task import TodoTask
+from .todo_tasks_added import TodoTasksAdded
+from .todo_tasks_completed import TodoTasksCompleted
+from .todo_tasks_incompleted import TodoTasksIncompleted
from .venue import Venue
from .video import Video
from .video_note import VideoNote
@@ -142,5 +147,10 @@ __all__ = [
"WallpaperSettings",
"TranscribedAudio",
"TranslatedText",
- "TextQuote"
+ "TextQuote",
+ "TodoList",
+ "TodoTask",
+ "TodoTasksAdded",
+ "TodoTasksCompleted",
+ "TodoTasksIncompleted"
]
diff --git a/pyrogram/types/messages_and_media/message.py b/pyrogram/types/messages_and_media/message.py
index bb6007c2..bf53a774 100644
--- a/pyrogram/types/messages_and_media/message.py
+++ b/pyrogram/types/messages_and_media/message.py
@@ -194,6 +194,9 @@ class Message(Object, Update):
paid_media (:obj:`~pyrogram.types.PaidMedia`, *optional*):
Message is a paid media, information about the paid media.
+ todo (:obj:`~pyrogram.types.Todo`, *optional*):
+ Message is a todo list, information about the todo list.
+
sticker (:obj:`~pyrogram.types.Sticker`, *optional*):
Message is a sticker, information about the sticker.
@@ -404,6 +407,21 @@ class Message(Object, Update):
gifted_premium (:obj:`~pyrogram.types.GiftedPremium`, *optional*):
Info about a gifted Telegram Premium subscription
+ screenshot_taken (:obj:`~pyrogram.types.ScreenshotTaken`, *optional*):
+ Service message: screenshot taken.
+
+ paid_message_price_changed (:obj:`~pyrogram.types.PaidMessagePriceChanged`, *optional*):
+ Service message: paid message price changed.
+
+ todo_tasks_added (:obj:`~pyrogram.types.TodoTasksAdded`, *optional*):
+ Service message: todo tasks added.
+
+ todo_tasks_completed (:obj:`~pyrogram.types.TodoTasksCompleted`, *optional*):
+ Service message: todo tasks completed.
+
+ todo_tasks_incompleted (:obj:`~pyrogram.types.TodoTasksIncompleted`, *optional*):
+ Service message: todo tasks incompleted.
+
link (``str``, *property*):
Generate a link to this message, only for groups and channels.
@@ -468,6 +486,7 @@ class Message(Object, Update):
document: "types.Document" = None,
photo: "types.Photo" = None,
paid_media: "types.PaidMedia" = None,
+ todo: "types.Todo" = None,
sticker: "types.Sticker" = None,
animation: "types.Animation" = None,
game: "types.Game" = None,
@@ -481,6 +500,9 @@ class Message(Object, Update):
gift: "types.Gift" = None,
screenshot_taken: "types.ScreenshotTaken" = None,
paid_message_price_changed: "types.PaidMessagePriceChanged" = None,
+ todo_tasks_added: "types.TodoTasksAdded" = None,
+ todo_tasks_completed: "types.TodoTasksCompleted" = None,
+ todo_tasks_incompleted: "types.TodoTasksIncompleted" = None,
invoice: "types.Invoice" = None,
story: Union["types.MessageStory", "types.Story"] = None,
alternative_videos: List["types.AlternativeVideo"] = None,
@@ -584,6 +606,7 @@ class Message(Object, Update):
self.document = document
self.photo = photo
self.paid_media = paid_media
+ self.todo = todo
self.sticker = sticker
self.animation = animation
self.game = game
@@ -598,6 +621,9 @@ class Message(Object, Update):
self.gift = gift
self.screenshot_taken = screenshot_taken
self.paid_message_price_changed = paid_message_price_changed
+ self.todo_tasks_added = todo_tasks_added
+ self.todo_tasks_completed = todo_tasks_completed
+ self.todo_tasks_incompleted = todo_tasks_incompleted
self.invoice = invoice
self.story = story
self.video = video
@@ -763,6 +789,9 @@ class Message(Object, Update):
gift = None
screenshot_taken = None
paid_message_price_changed = None
+ todo_tasks_added = None
+ todo_tasks_completed = None
+ todo_tasks_incompleted = None
service_type = None
chat_join_type = None
@@ -888,6 +917,7 @@ class Message(Object, Update):
paid_message_price_changed = types.PaidMessagePriceChanged._parse(action)
service_type = enums.MessageServiceType.PAID_MESSAGE_PRICE_CHANGED
+
parsed_message = Message(
id=message.id,
message_thread_id=message_thread_id,
@@ -967,6 +997,34 @@ class Message(Object, Update):
parsed_message.service = enums.MessageServiceType.GAME_HIGH_SCORE
except MessageIdsEmpty:
pass
+ if isinstance(action, raw.types.MessageActionTodoCompletions):
+ if action.completed:
+ parsed_message.todo_tasks_completed = types.TodoTasksCompleted._parse(action)
+ if action.incompleted:
+ parsed_message.todo_tasks_incompleted = types.TodoTasksIncompleted._parse(action)
+ parsed_message.service_type = enums.MessageServiceType.TODO_TASKS_COMPLETION
+ try:
+ parsed_message.reply_to_message = await client.get_messages(
+ parsed_message.chat.id,
+ reply_to_message_ids=message.id,
+ replies=0
+ )
+ except MessageIdsEmpty:
+ pass
+ parsed_message.reply_to_message_id = message.reply_to.reply_to_msg_id
+
+ if isinstance(action, raw.types.MessageActionTodoAppendTasks):
+ parsed_message.todo_tasks_added = types.TodoTasksAdded._parse(client, action)
+ parsed_message.service = enums.MessageServiceType.TODO_TASKS_ADDED
+ try:
+ parsed_message.reply_to_message = await client.get_messages(
+ parsed_message.chat.id,
+ reply_to_message_ids=message.id,
+ replies=0
+ )
+ except MessageIdsEmpty:
+ pass
+ parsed_message.reply_to_message_id = message.reply_to.reply_to_msg_id
client.message_cache[(parsed_message.chat.id, parsed_message.id)] = parsed_message
@@ -1004,6 +1062,7 @@ class Message(Object, Update):
photo = None
paid_media = None
+ todo = None
location = None
contact = None
venue = None
@@ -1130,6 +1189,9 @@ class Message(Object, Update):
elif isinstance(media, raw.types.MessageMediaPaidMedia):
paid_media = types.PaidMedia._parse(client, media)
media_type = enums.MessageMediaType.PAID_MEDIA
+ elif isinstance(media, raw.types.MessageMediaToDo):
+ todo = types.TodoList._parse(client, media, users)
+ media_type = enums.MessageMediaType.TODO
else:
media = None
@@ -1199,6 +1261,7 @@ class Message(Object, Update):
invert_media=message.invert_media,
photo=photo,
paid_media=paid_media,
+ todo=todo,
location=location,
contact=contact,
venue=venue,
diff --git a/pyrogram/types/messages_and_media/todo_list.py b/pyrogram/types/messages_and_media/todo_list.py
new file mode 100644
index 00000000..5c30a4f0
--- /dev/null
+++ b/pyrogram/types/messages_and_media/todo_list.py
@@ -0,0 +1,83 @@
+# Pyrofork - Telegram MTProto API Client Library for Python
+# Copyright (C) 2022-present Mayuri-Chan
+#
+# This file is part of Pyrofork.
+#
+# Pyrofork is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Pyrofork is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Pyrofork. If not, see .
+
+
+from typing import List, Dict
+
+import pyrogram
+from pyrogram import raw, types
+from ..object import Object
+
+
+class TodoList(Object):
+ """A list of tasks.
+
+ Parameters:
+ title (``str``):
+ Title of the todo list.
+
+ entities (List of :obj:`~pyrogram.types.MessageEntity`):
+ Entities in the title of the todo list.
+
+ tasks (List of :obj:`~pyrogram.types.TodoTask`):
+ List of tasks in the todo list.
+
+ can_append (``bool``, optional):
+ True, if other users can append tasks to this todo list.
+
+ can_complete (``bool``, optional):
+ True, if other users can complete tasks in this todo list.
+ """
+
+ def __init__(
+ self,
+ title: str,
+ entities: List["types.MessageEntity"],
+ tasks: List["types.TodoTask"] = None,
+ can_append: bool = False,
+ can_complete: bool = False
+ ):
+ super().__init__()
+
+ self.title = title
+ self.entities = entities
+ self.tasks = tasks
+ self.can_append = can_append
+ self.can_complete = can_complete
+
+ @staticmethod
+ def _parse(
+ client: "pyrogram.Client",
+ todo: "raw.types.TodoList",
+ users: Dict
+ ) -> "TodoList":
+ todo_list = todo.todo
+ completions = todo.completions
+ entities = [types.MessageEntity._parse(client, entity, None) for entity in todo_list.title.entities]
+ entities = types.List(filter(lambda x: x is not None, entities))
+ tasks = [
+ types.TodoTask._parse(client, task, users, completions)
+ for task in todo_list.list
+ ] if todo_list.list else []
+ return TodoList(
+ title=todo_list.title.text,
+ entities=entities,
+ tasks=tasks,
+ can_append=todo_list.others_can_append,
+ can_complete=todo_list.others_can_complete
+ )
diff --git a/pyrogram/types/messages_and_media/todo_task.py b/pyrogram/types/messages_and_media/todo_task.py
new file mode 100644
index 00000000..01a7c97d
--- /dev/null
+++ b/pyrogram/types/messages_and_media/todo_task.py
@@ -0,0 +1,85 @@
+# Pyrofork - Telegram MTProto API Client Library for Python
+# Copyright (C) 2022-present Mayuri-Chan
+#
+# This file is part of Pyrofork.
+#
+# Pyrofork is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Pyrofork is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Pyrofork. If not, see .
+
+
+from typing import List, Dict
+
+import pyrogram
+from pyrogram import raw, types, utils
+from ..object import Object
+
+
+class TodoTask(Object):
+ """A task in a todo list.
+
+ Parameters:
+ title (``str``):
+ Title of the task.
+
+ entities (List of :obj:`~pyrogram.types.MessageEntity`):
+ Entities in the title of the task.
+
+ is_completed (``bool``):
+ True, if the task is completed.
+
+ completed_by (:obj:`~pyrogram.types.User`, *optional*):
+ User who completed the task.
+
+ complete_date (:obj:`~datetime.datetime`, *optional*):
+ Date when the task was completed.
+ """
+
+ def __init__(
+ self,
+ id: int,
+ title: str,
+ entities: List["types.MessageEntity"],
+ is_completed: bool,
+ completed_by: "types.User" = None,
+ complete_date: "pyrogram.types.datetime" = None
+ ):
+ super().__init__()
+
+ self.id = id
+ self.title = title
+ self.entities = entities
+ self.is_completed = is_completed
+ self.completed_by = completed_by
+ self.complete_date = complete_date
+
+ @staticmethod
+ def _parse(
+ client: "pyrogram.Client",
+ todo_task: "raw.types.TodoTask",
+ users: Dict,
+ completions: List["raw.types.TodoTaskCompletion"] = None
+ ) -> "TodoTask":
+ entities = [types.MessageEntity._parse(client, entity, None) for entity in todo_task.title.entities]
+ entities = types.List(filter(lambda x: x is not None, entities))
+ complete = {i.id: i for i in completions} if completions else {}
+ todo_completion = complete.get(todo_task.id)
+ completed_by = types.User._parse(client, users.get(todo_completion.completed_by, None)) if todo_completion else None
+ complete_date = utils.timestamp_to_datetime(todo_completion.date) if todo_completion else None
+ return TodoTask(
+ id=todo_task.id,
+ title=todo_task.title.text,
+ entities=entities,
+ is_completed=True if todo_completion else False,
+ completed_by=completed_by,
+ complete_date=complete_date
+ )
diff --git a/pyrogram/types/messages_and_media/todo_tasks_added.py b/pyrogram/types/messages_and_media/todo_tasks_added.py
new file mode 100644
index 00000000..70da3bdd
--- /dev/null
+++ b/pyrogram/types/messages_and_media/todo_tasks_added.py
@@ -0,0 +1,45 @@
+# Pyrofork - Telegram MTProto API Client Library for Python
+# Copyright (C) 2022-present Mayuri-Chan
+#
+# This file is part of Pyrofork.
+#
+# Pyrofork is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Pyrofork is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Pyrofork. If not, see .
+
+import pyrogram
+
+from pyrogram import raw, types
+from ..object import Object
+
+
+class TodoTasksAdded(Object):
+ """A todo task added to a todo list.
+
+ Parameters:
+ task (:obj:`~pyrogram.types.TodoTask`):
+ The added todo task.
+ """
+
+ def __init__(self, tasks: "types.TodoTask"):
+ super().__init__()
+
+ self.tasks = tasks
+
+ @staticmethod
+ def _parse(
+ client: "pyrogram.Client",
+ todo_task_added: "raw.types.MessageActionTodoAppendTasks"
+ ) -> "TodoTasksAdded":
+ return TodoTasksAdded(
+ tasks=[types.TodoTask._parse(client, task, {}, {}) for task in todo_task_added.list]
+ )
diff --git a/pyrogram/types/messages_and_media/todo_tasks_completed.py b/pyrogram/types/messages_and_media/todo_tasks_completed.py
new file mode 100644
index 00000000..4b0fdcb3
--- /dev/null
+++ b/pyrogram/types/messages_and_media/todo_tasks_completed.py
@@ -0,0 +1,44 @@
+# Pyrofork - Telegram MTProto API Client Library for Python
+# Copyright (C) 2022-present Mayuri-Chan
+#
+# This file is part of Pyrofork.
+#
+# Pyrofork is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Pyrofork is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Pyrofork. If not, see .
+
+
+from typing import List
+
+from pyrogram import raw
+from ..object import Object
+
+
+class TodoTasksCompleted(Object):
+ """One or more todo task/s has been flag as complete.
+
+ Parameters:
+ ids (List of ``int``):
+ List of Unique identifier of the todo tasks.
+ """
+
+ def __init__(self, ids: List[int]):
+ super().__init__()
+
+ self.ids = ids
+
+ @staticmethod
+ def _parse(todo_completion: "raw.types.TodoCompletion") -> "TodoTasksCompleted":
+ ids = [id for id in todo_completion.completed]
+ return TodoTasksCompleted(
+ ids=ids,
+ )
diff --git a/pyrogram/types/messages_and_media/todo_tasks_incompleted.py b/pyrogram/types/messages_and_media/todo_tasks_incompleted.py
new file mode 100644
index 00000000..e0a33762
--- /dev/null
+++ b/pyrogram/types/messages_and_media/todo_tasks_incompleted.py
@@ -0,0 +1,44 @@
+# Pyrofork - Telegram MTProto API Client Library for Python
+# Copyright (C) 2022-present Mayuri-Chan
+#
+# This file is part of Pyrofork.
+#
+# Pyrofork is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Pyrofork is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Pyrofork. If not, see .
+
+
+from typing import List
+
+from pyrogram import raw
+from ..object import Object
+
+
+class TodoTasksIncompleted(Object):
+ """One or more todo task/s has been flag as incomplete.
+
+ Parameters:
+ ids (List of ``int``):
+ List of Unique identifier of the todo tasks.
+ """
+
+ def __init__(self, ids: List[int]):
+ super().__init__()
+
+ self.ids = ids
+
+ @staticmethod
+ def _parse(todo_completion: "raw.types.TodoCompletion") -> "TodoTasksIncompleted":
+ ids = [id for id in todo_completion.incompleted]
+ return TodoTasksIncompleted(
+ ids=ids,
+ )