-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpolina.py
122 lines (95 loc) · 3.4 KB
/
polina.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
import json
import aiogram.utils.markdown as md
from aiogram import Bot, Dispatcher, types
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters import Text
from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.types import ParseMode, BotCommand, BotCommandScopeDefault
from aiogram.utils import executor
settings = json.load(open('settings.json', encoding='utf-8'))
bot = Bot(settings['token'])
storage = MemoryStorage() # todo redis storage for persistent sessions
dp = Dispatcher(bot, storage=storage)
campuses = json.load(open('campuses.json', encoding='utf-8'))
# Defining available states
class Form(StatesGroup):
campus = State()
destination = State()
@dp.message_handler(commands='start')
async def cmd_start(message: types.Message):
"""
Conversation's entry point
"""
commands = [
BotCommand('start', 'Begin dialog'),
BotCommand('navigate', 'Begin navigation'),
BotCommand('cancel', 'Cancel navigation at any point')
]
await dp.bot.set_my_commands(commands, BotCommandScopeDefault()) # todo ensure every user getting actual commands
await message.answer("Hello, I'm PolyNa, Polytech University Navagaion Bot!")
@dp.message_handler(commands='navigate')
async def cmd_navigate(message: types.Message):
"""
Navigation entry point
"""
# Configure ReplyKeyboardMarkup for campuses
markup = types.ReplyKeyboardMarkup(resize_keyboard=True, selective=True)
for campus in campuses:
markup.add(campus)
await Form.campus.set()
await message.answer("Please choose your campus for destination", reply_markup=markup)
# You can use state '*' if you need to handle all states
@dp.message_handler(state='*', commands='cancel')
@dp.message_handler(Text(equals='cancel', ignore_case=True), state='*')
async def cancel_handler(message: types.Message, state: FSMContext):
"""
Allow user to cancel any state
"""
current_state = await state.get_state()
if current_state is None:
return
await state.finish()
await message.answer('Dialog reset!', reply_markup=types.ReplyKeyboardRemove())
@dp.message_handler(state=Form.campus)
async def process_campus(message: types.Message, state: FSMContext):
"""
Process campus
"""
async with state.proxy() as data:
data['campus'] = message.text
await Form.destination.set()
# Remove keyboard
markup = types.ReplyKeyboardRemove()
await message.answer('Enter destination room', reply_markup=markup)
@dp.message_handler(lambda message: message.text not in campuses, state=Form.campus)
async def process_campus_invalid(message: types.Message):
"""
Campus has to be one of predefined
"""
return await message.answer('Bad campus. Choose your campus from the keyboard!')
@dp.message_handler(state=Form.destination)
async def process_destination(message: types.Message, state: FSMContext):
"""
Process destination room or point
"""
async with state.proxy() as data:
data['destination'] = message.text
# Remove keyboard
markup = types.ReplyKeyboardRemove()
# And send message
await bot.send_message(
message.chat.id,
md.text(
md.text('Hi! Nice to navigate you to'),
md.text('Campus: ', md.bold(data['campus'])),
md.text('Room: ', md.bold(data['destination'])),
sep='\n',
),
reply_markup=markup,
parse_mode=ParseMode.MARKDOWN,
)
# Finish nav session
await state.finish()
if __name__ == '__main__':
executor.start_polling(dp, skip_updates=True)