-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path11 pollbot.py
156 lines (130 loc) · 6.22 KB
/
11 pollbot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#!/usr/bin/env python
# pylint: disable=unused-argument
# This program is dedicated to the public domain under the CC0 license.
"""
Basic example for a bot that works with polls. Only 3 people are allowed to interact with each
poll/quiz the bot generates. The preview command generates a closed poll/quiz, exactly like the
one the user sends the bot
"""
import logging
from telegram import (KeyboardButton,KeyboardButtonPollType,Poll,ReplyKeyboardMarkup,ReplyKeyboardRemove,Update)
from telegram.ext import (Application,CommandHandler,ContextTypes,MessageHandler,PollAnswerHandler,PollHandler,filters)
from telegram.constants import ParseMode
logging.basicConfig(format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO)
logging.getLogger("httpx").setLevel(logging.WARNING)
logger = logging.getLogger(__name__)
TOTAL_VOTER_COUNT = 3
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""Inform user about what this bot can do"""
await update.message.reply_text(
"Please select /poll to get a Poll, /quiz to get a Quiz or /preview"
" to generate a preview for your poll"
)
async def poll(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""Sends a predefined poll"""
questions = ["Good", "Really good", "Fantastic", "Great"]
message = await context.bot.send_poll(
update.effective_chat.id,
"How are you?",
questions,
is_anonymous=False,
allows_multiple_answers=True,
)
# Save some info about the poll the bot_data for later use in receive_poll_answer
payload = {
message.poll.id: {
"questions": questions,
"message_id": message.message_id,
"chat_id": update.effective_chat.id,
"answers": 0,
}
}
context.bot_data.update(payload)
async def receive_poll_answer(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""Summarize a users poll vote"""
answer = update.poll_answer
answered_poll = context.bot_data[answer.poll_id]
try:
questions = answered_poll["questions"]
# this means this poll answer update is from an old poll, we can't do our answering then
except KeyError:
return
selected_options = answer.option_ids
answer_string = ""
for question_id in selected_options:
if question_id != selected_options[-1]:
answer_string += questions[question_id] + " and "
else:
answer_string += questions[question_id]
await context.bot.send_message(
answered_poll["chat_id"],
f"{update.effective_user.mention_html()} feels {answer_string}!",
parse_mode=ParseMode.HTML,
)
answered_poll["answers"] += 1
# Close poll after three participants voted
if answered_poll["answers"] == TOTAL_VOTER_COUNT:
await context.bot.stop_poll(answered_poll["chat_id"], answered_poll["message_id"])
async def quiz(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""Send a predefined poll"""
questions = ["1", "2", "4", "20"]
message = await update.effective_message.reply_poll(
"How many eggs do you need for a cake?", questions, type=Poll.QUIZ, correct_option_id=2
)
# Save some info about the poll the bot_data for later use in receive_quiz_answer
payload = {
message.poll.id: {"chat_id": update.effective_chat.id, "message_id": message.message_id}
}
context.bot_data.update(payload)
async def receive_quiz_answer(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""Close quiz after three participants took it"""
# the bot can receive closed poll updates we don't care about
if update.poll.is_closed:
return
if update.poll.total_voter_count == TOTAL_VOTER_COUNT:
try:
quiz_data = context.bot_data[update.poll.id]
# this means this poll answer update is from an old poll, we can't stop it then
except KeyError:
return
await context.bot.stop_poll(quiz_data["chat_id"], quiz_data["message_id"])
async def preview(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""Ask user to create a poll and display a preview of it"""
# using this without a type lets the user chooses what he wants (quiz or poll)
button = [[KeyboardButton("Press me!", request_poll=KeyboardButtonPollType())]]
message = "Press the button to let the bot generate a preview for your poll"
# using one_time_keyboard to hide the keyboard
await update.effective_message.reply_text(
message, reply_markup=ReplyKeyboardMarkup(button, one_time_keyboard=True)
)
async def receive_poll(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""On receiving polls, reply to it by a closed poll copying the received poll"""
actual_poll = update.effective_message.poll
# Only need to set the question and options, since all other parameters don't matter for
# a closed poll
await update.effective_message.reply_poll(
question=actual_poll.question,
options=[o.text for o in actual_poll.options],
# with is_closed true, the poll/quiz is immediately closed
is_closed=True,
reply_markup=ReplyKeyboardRemove(),
)
async def help_handler(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""Display a help message"""
await update.message.reply_text("Use /quiz, /poll or /preview to test this bot.")
def main() -> None:
"""Run bot."""
# Create the Application and pass it your bot's token.
application = Application.builder().token("6780033449:AAFKWBuWlPcBHLm303owSEvDriPZjCxs9ZU").build()
application.add_handler(CommandHandler("start", start))
application.add_handler(CommandHandler("poll", poll))
application.add_handler(CommandHandler("quiz", quiz))
application.add_handler(CommandHandler("preview", preview))
application.add_handler(CommandHandler("help", help_handler))
application.add_handler(MessageHandler(filters.POLL, receive_poll))
application.add_handler(PollAnswerHandler(receive_poll_answer))
application.add_handler(PollHandler(receive_quiz_answer))
# Run the bot until the user presses Ctrl-C
application.run_polling(allowed_updates=Update.ALL_TYPES)
if __name__ == "__main__":
main()