aboutsummaryrefslogtreecommitdiff
path: root/bot.py
diff options
context:
space:
mode:
Diffstat (limited to 'bot.py')
-rw-r--r--bot.py108
1 files changed, 67 insertions, 41 deletions
diff --git a/bot.py b/bot.py
index a0a00b3..5c90144 100644
--- a/bot.py
+++ b/bot.py
@@ -18,20 +18,20 @@ if __version_info__ < (20, 0, 0, "alpha", 1):
18 f"{TG_VER} version of this example, " 18 f"{TG_VER} version of this example, "
19 f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html" 19 f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
20 ) 20 )
21from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update, ReplyKeyboardRemove 21from telegram import InlineKeyboardButton, InlineKeyboardMarkup
22from telegram.ext import Application, CallbackQueryHandler, \ 22from telegram.ext import Application, CallbackQueryHandler, \
23 CommandHandler, ContextTypes, MessageHandler, filters, ConversationHandler, CallbackContext, JobQueue 23 CommandHandler, ContextTypes, MessageHandler, filters, ConversationHandler, CallbackContext
24from config import BOT_TOKEN 24from config import BOT_TOKEN
25from foursquare.poi import query_poi 25from foursquare.poi import query_poi
26from dbstore.dbm_store import get_loc 26from dbstore.dbm_store import get_loc
27from toot import mastodon_client 27from toot import mastodon_client
28from typing import TypedDict, List, cast 28from typing import TypedDict, List, cast
29from telegram import Update, InputMediaVideo, InputMediaPhoto 29from telegram import Update, ReplyKeyboardMarkup, KeyboardButton
30 30
31scheduler = None 31scheduler = None
32PRIVACY, TOOT = map(chr, range(8, 10)) 32PRIVACY, TOOT = map(chr, range(8, 10))
33 33
34WAIT_LOC, LOCATION, PHOTO, PROCESS_PHOTO, FINAL = range(5) 34WAIT_LOC, LOCATION, PHOTO, PROCESS_PHOTO, FINAL, SETTING = range(6)
35 35
36# Enable logging 36# Enable logging
37logging.basicConfig( 37logging.basicConfig(
@@ -39,6 +39,20 @@ logging.basicConfig(
39) 39)
40logger = logging.getLogger(__name__) 40logger = logging.getLogger(__name__)
41 41
42MAIN_MENU = ReplyKeyboardMarkup([
43 [telegram.KeyboardButton(text="/check in", request_location=True)],
44 [telegram.KeyboardButton(text="/cancel")],
45 [telegram.KeyboardButton(text="/setting")]
46])
47
48SKIP_MENU = ReplyKeyboardMarkup([[telegram.KeyboardButton(text="/skip")]])
49SETTING_MENU = ReplyKeyboardMarkup(
50 [
51 [KeyboardButton(text="/tos")],
52 [telegram.KeyboardButton(text="/back")],
53 ]
54)
55
42 56
43async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: 57async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
44 hello = "Hello, this is `checkin.bot`. \n\n" \ 58 hello = "Hello, this is `checkin.bot`. \n\n" \
@@ -49,10 +63,7 @@ async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
49 "Start using this bot by sharing your location using Telegram context menu to it." 63 "Start using this bot by sharing your location using Telegram context menu to it."
50 64
51 await update.message.reply_text(hello, parse_mode=telegram.constants.ParseMode.MARKDOWN) 65 await update.message.reply_text(hello, parse_mode=telegram.constants.ParseMode.MARKDOWN)
52 await update.message.reply_text("Please choose", 66 await update.message.reply_text("Use bot keyboard to choose an action", reply_markup=MAIN_MENU)
53 reply_markup=telegram.ReplyKeyboardMarkup([
54 [telegram.KeyboardButton(text="Check in", request_location=True)],
55 [telegram.KeyboardButton(text="Setting")]]))
56 67
57 return LOCATION 68 return LOCATION
58 69
@@ -66,7 +77,7 @@ async def checkin(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
66 ]) 77 ])
67 78
68 reply_markup = InlineKeyboardMarkup(keyboard) 79 reply_markup = InlineKeyboardMarkup(keyboard)
69 await update.message.reply_text("Select a place", reply_markup=reply_markup) 80 await update.message.reply_text("Where are you?", reply_markup=reply_markup)
70 81
71 return WAIT_LOC 82 return WAIT_LOC
72 83
@@ -94,32 +105,25 @@ async def process_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -
94 await query.message.reply_text( 105 await query.message.reply_text(
95 text=f"Selected place: {poi['name']}, `{query.data}`\nPosted to Mastodon: {status['url']}", 106 text=f"Selected place: {poi['name']}, `{query.data}`\nPosted to Mastodon: {status['url']}",
96 parse_mode=telegram.constants.ParseMode.MARKDOWN, 107 parse_mode=telegram.constants.ParseMode.MARKDOWN,
97 reply_markup=telegram.ReplyKeyboardMarkup([ 108 reply_markup=MAIN_MENU
98 [telegram.KeyboardButton(text="Check in", request_location=True)],
99 [telegram.KeyboardButton(text="Setting")]])
100 ) 109 )
101 110
102 await query.message.reply_text("You can continue attaching photos, or press skip to continue", 111 await query.message.reply_text("You can continue attaching photos, or press skip to finish", reply_markup=SKIP_MENU)
103 reply_markup=telegram.ReplyKeyboardMarkup([
104 [telegram.KeyboardButton(text="/skip")]]))
105 return PHOTO 112 return PHOTO
106 113
107 114
108async def action(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: 115async def tos(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
109 if update.message.text == "Check in": 116 await update.message.reply_text("TOS", reply_markup=MAIN_MENU)
110 await update.message.reply_text("Please share your location",
111 reply_markup=telegram.ReplyKeyboardRemove())
112 elif update.message.text == "Setting":
113 await update.message.reply_text("Setting")
114 117
115 118
116async def setting(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: 119async def setting(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
117 keyboard = [[ 120 await update.message.reply_text("Setting", reply_markup=SETTING_MENU)
118 InlineKeyboardButton("Privacy", callback_data=PRIVACY), 121 return SETTING
119 ]]
120 122
121 reply_markup = InlineKeyboardMarkup(keyboard) 123
122 await update.message.reply_text("Setting", reply_markup=reply_markup) 124async def setting_process_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
125 await update.message.reply_text("Setting Process Callback", reply_markup=SETTING_MENU)
126 return ConversationHandler.END
123 127
124 128
125async def process_location(update: Update, context: ContextTypes.DEFAULT_TYPE): 129async def process_location(update: Update, context: ContextTypes.DEFAULT_TYPE):
@@ -154,12 +158,27 @@ async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> No
154 await update.message.reply_text("Use /start to test this bot.") 158 await update.message.reply_text("Use /start to test this bot.")
155 159
156 160
161async def setting_cancel(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
162 """Cancels and ends the conversation."""
163 user = update.message.from_user
164 logger.info("User %s canceled the conversation.", user.first_name)
165 await update.message.reply_text(
166 text="Setting canceled.",
167 # "Bye! I hope we can talk again some day.",
168 reply_markup=MAIN_MENU
169 )
170
171 return ConversationHandler.END
172
173
157async def cancel(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: 174async def cancel(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
158 """Cancels and ends the conversation.""" 175 """Cancels and ends the conversation."""
159 user = update.message.from_user 176 user = update.message.from_user
160 logger.info("User %s canceled the conversation.", user.first_name) 177 logger.info("User %s canceled the conversation.", user.first_name)
161 await update.message.reply_text( 178 await update.message.reply_text(
162 "Bye! I hope we can talk again some day.", reply_markup=ReplyKeyboardRemove() 179 text="Canceled.",
180 # "Bye! I hope we can talk again some day.",
181 reply_markup=MAIN_MENU
163 ) 182 )
164 183
165 return ConversationHandler.END 184 return ConversationHandler.END
@@ -197,9 +216,8 @@ async def media_group_sender(context: CallbackContext):
197 media_ids=media_id) 216 media_ids=media_id)
198 217
199 await context.bot.send_message(chat_id=chat_id, text="Done", 218 await context.bot.send_message(chat_id=chat_id, text="Done",
200 reply_markup=telegram.ReplyKeyboardMarkup([ 219 reply_markup=MAIN_MENU
201 [telegram.KeyboardButton(text="Check in", request_location=True)], 220 )
202 [telegram.KeyboardButton(text="Setting")]]))
203 221
204 222
205async def photo(update: Update, context: CallbackContext): 223async def photo(update: Update, context: CallbackContext):
@@ -225,9 +243,6 @@ async def photo(update: Update, context: CallbackContext):
225 if jobs: 243 if jobs:
226 jobs[0].data.append(msg_dict) 244 jobs[0].data.append(msg_dict)
227 else: 245 else:
228 # TODO
229 # media_group_sender won't end the callback context
230 # should add a job event listener
231 context.job_queue.run_once(callback=media_group_sender, when=5, data=[msg_dict], 246 context.job_queue.run_once(callback=media_group_sender, when=5, data=[msg_dict],
232 name=str(message.media_group_id)) 247 name=str(message.media_group_id))
233 else: 248 else:
@@ -243,17 +258,14 @@ async def photo(update: Update, context: CallbackContext):
243 media_ids=media["id"]) 258 media_ids=media["id"])
244 259
245 await update.message.reply_text(text="Done", 260 await update.message.reply_text(text="Done",
246 reply_markup=telegram.ReplyKeyboardMarkup([ 261 reply_markup=MAIN_MENU
247 [telegram.KeyboardButton(text="Check in", request_location=True)], 262 )
248 [telegram.KeyboardButton(text="Setting")]]))
249 263
250 264
251async def skip_photo(update: Update, context: ContextTypes.DEFAULT_TYPE): 265async def skip_photo(update: Update, context: ContextTypes.DEFAULT_TYPE):
252 print(context.user_data) 266 print(context.user_data)
253 await update.message.reply_text( 267 await update.message.reply_text(
254 text="Done.", reply_markup=telegram.ReplyKeyboardMarkup([ 268 text="Done.", reply_markup=MAIN_MENU
255 [telegram.KeyboardButton(text="Check in", request_location=True)],
256 [telegram.KeyboardButton(text="Setting")]])
257 ) 269 )
258 return ConversationHandler.END 270 return ConversationHandler.END
259 271
@@ -261,7 +273,7 @@ async def skip_photo(update: Update, context: ContextTypes.DEFAULT_TYPE):
261def main() -> None: 273def main() -> None:
262 application = Application.builder().token(BOT_TOKEN).build() 274 application = Application.builder().token(BOT_TOKEN).build()
263 275
264 conv_handler = ConversationHandler( 276 checkin_handler = ConversationHandler(
265 entry_points=[ 277 entry_points=[
266 CommandHandler("start", start), 278 CommandHandler("start", start),
267 MessageHandler(filters.LOCATION, checkin), 279 MessageHandler(filters.LOCATION, checkin),
@@ -279,7 +291,21 @@ def main() -> None:
279 allow_reentry=True, 291 allow_reentry=True,
280 ) 292 )
281 293
282 application.add_handler(conv_handler) 294 setting_conv_handler = ConversationHandler(
295 entry_points=[CommandHandler("setting", setting)],
296 states={
297 SETTING: [
298 CallbackQueryHandler(setting_process_callback),
299 ],
300 },
301 fallbacks=[CommandHandler("back", setting_cancel)],
302 per_message=False,
303 allow_reentry=True,
304 )
305
306 application.add_handler(CommandHandler("tos", tos))
307 application.add_handler(setting_conv_handler, 2)
308 application.add_handler(checkin_handler, 1)
283 309
284 # Run the bot until the user presses Ctrl-C 310 # Run the bot until the user presses Ctrl-C
285 application.run_polling() 311 application.run_polling()
Powered by cgit v1.2.3 (git 2.41.0)