diff --git a/README.md b/README.md index f31982a..94e4df4 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,7 @@ This MCP server exposes a huge suite of Telegram tools. **Every major Telegram/T - **get_history(chat_id, limit)**: Full chat history - **get_pinned_messages(chat_id)**: List pinned messages - **get_last_interaction(contact_id)**: Most recent message with a contact +- **create_poll(chat_id, question, options, multiple_choice, quiz_mode, public_votes, close_date)**: Create a poll ### Contact Management - **list_contacts()**: List all contacts diff --git a/main.py b/main.py index c184821..a484f4b 100644 --- a/main.py +++ b/main.py @@ -2623,6 +2623,79 @@ async def get_pinned_messages(chat_id: int) -> str: return log_and_format_error("get_pinned_messages", e, chat_id=chat_id) +@mcp.tool() +async def create_poll( + chat_id: int, + question: str, + options: list, + multiple_choice: bool = False, + quiz_mode: bool = False, + public_votes: bool = True, + close_date: str = None, +) -> str: + """ + Create a poll in a chat using Telegram's native poll feature. + + Args: + chat_id: The ID of the chat to send the poll to + question: The poll question + options: List of answer options (2-10 options) + multiple_choice: Whether users can select multiple answers + quiz_mode: Whether this is a quiz (has correct answer) + public_votes: Whether votes are public + close_date: Optional close date in ISO format (YYYY-MM-DD HH:MM:SS) + """ + try: + entity = await client.get_entity(chat_id) + + # Validate options + if len(options) < 2: + return "Error: Poll must have at least 2 options." + if len(options) > 10: + return "Error: Poll can have at most 10 options." + + # Parse close date if provided + close_date_obj = None + if close_date: + try: + close_date_obj = datetime.fromisoformat(close_date.replace("Z", "+00:00")) + except ValueError: + return f"Invalid close_date format. Use YYYY-MM-DD HH:MM:SS format." + + # Create the poll using InputMediaPoll with SendMediaRequest + from telethon.tl.types import InputMediaPoll, Poll, PollAnswer, TextWithEntities + import random + + poll = Poll( + id=random.randint(0, 2**63 - 1), + question=TextWithEntities(text=question, entities=[]), + answers=[ + PollAnswer(text=TextWithEntities(text=option, entities=[]), option=bytes([i])) + for i, option in enumerate(options) + ], + multiple_choice=multiple_choice, + quiz=quiz_mode, + public_voters=public_votes, + close_date=close_date_obj, + ) + + result = await client( + functions.messages.SendMediaRequest( + peer=entity, + media=InputMediaPoll(poll=poll), + message="", + random_id=random.randint(0, 2**63 - 1), + ) + ) + + return f"Poll created successfully in chat {chat_id}." + except Exception as e: + logger.exception(f"create_poll failed (chat_id={chat_id}, question='{question}')") + return log_and_format_error( + "create_poll", e, chat_id=chat_id, question=question, options=options + ) + + if __name__ == "__main__": nest_asyncio.apply()