class SeatState(BaseState): choices = tuple(range(1, 5)) _intro_message = BotMessage(_('How many seats?'), buttons=[ [{ 'text': str(x), 'data': str(x), } for x in choices], [BACK] ]) async def get_back_state(self): if self.data.get('seat'): return 'purchase' return 'show' async def process(self): try: seat_number = int(self.value) except ValueError: self.message_was_not_recognized = True return if seat_number not in self.choices: self.message_was_not_recognized = True return self.set_state('purchase')
class PhoneState(BaseState): _intro_message = BotMessage( text=_('Tap the button below to share your phone number or enter it.'), buttons=[ [{ 'text': _('Share phone number'), 'type': 'phone', }], [_('⬅ Back')] ], is_tg_text_buttons=True ) async def get_back_state(self): return 'purchase' if self.user.phone else 'show' async def process(self): if self.text and self.text.startswith('⬅'): self.set_state(await self.get_back_state()) return phone = (self.contact and self.contact.phone) or validate_phone(self.text) if phone is None: self.message_was_not_recognized = True return self.user.phone = phone self.set_state('purchase')
def get_intro_message(self): trip_service = TripService.get_service(self.data['show']) stations = trip_service.get_stations() if stations.count() == 0: raise ValueError(f'There are no stations available in db for ' f'provider {trip_service.provider_name()}' f'and direction {trip_service.direction_name()}') buttons = [[{'text': x.name, 'data': str(x.id)}] for x in stations] viber_limit_with_back = VIBER_ROWS_LIMIT - 1 viber_limit_with_back_and_navigate = viber_limit_with_back - 1 if len(buttons) > viber_limit_with_back: if self.data.get('station__last'): buttons = buttons[viber_limit_with_back_and_navigate:] buttons.insert(0, [{ 'text': _('...previous'), 'data': 'first', }]) else: buttons = buttons[:viber_limit_with_back_and_navigate] buttons.append([{ 'text': _('more...'), 'data': 'last', }]) buttons.append([BACK]) return BotMessage(_('Choose start station:'), buttons=buttons)
def to_telegram_message(message: BotMessage, chat_id): formatted = { 'text': message.text, 'method': TelegramMethod.SEND_MESSAGE, 'chat_id': chat_id, } if message.parse_mode: formatted['parse_mode'] = message.parse_mode buttons = message.get_tg_buttons() if buttons: if message.is_tg_text_buttons: formatted['reply_markup'] = { 'keyboard': TextButtonFormatter.format_list(buttons), 'resize_keyboard': True, 'one_time_keyboard': True, } else: formatted['reply_markup'] = { 'inline_keyboard': InlineButtonFormatter.format_list(buttons), } return formatted
def get_intro_message(self): db = get_db() trip = db.query(Trip).get(self.data['show']) return BotMessage( text=self.get_text(trip), buttons=self.get_buttons() )
class NotesState(BaseState): back = 'purchase' _intro_message = BotMessage(_('Add some notes:'), buttons=[[BACK]], is_text_input=True) async def process(self): notes = (self.text or '').strip() self.data[self.get_name()] = notes self.set_state('purchase')
def get_intro_message(self): purchases = tuple(UserService(self.user).future_purchases()) if not purchases: return BotMessage(_('You have no pending trips'), buttons=[[BACK]]) buttons = [] for purchase in purchases: buttons.append([{ 'text': self.build_purchase_label(purchase), 'data': 'show_{}'.format(purchase.id), }, { 'text': b'\xE2\x9D\x8C'.decode('utf-8'), 'data': 'cancel_{}'.format(purchase.id), }]) buttons.append([BACK]) text = _('Your purchases') if len(purchases) > 1 else _( 'Your purchase') return BotMessage(text, buttons)
def to_viber_message(bot_message: BotMessage, receiver) -> dict: viber_message = build_basic_message(bot_message) buttons = bot_message.get_viber_buttons() if buttons: add_keyboard_into_message(viber_message, buttons, hide_input=not bot_message.is_text_input) viber_message['receiver'] = receiver.id return viber_message
def get_intro_message(self): if self.is_wrong_sms(): text = _('Wrong SMS code.') buttons = [[BACK, { 'text': _('Send again'), 'data': 'resend', }]] else: text = _('SMS was sent to +%s. Enter it.') % self.user.phone buttons = [[BACK]] return BotMessage( text=text, buttons=buttons, is_text_input=True, )
def get_intro_message(self): trip_id_list = self.data['trip_id_list'] show_shorten = (len(trip_id_list) > 4) and not self.data.get(FULL_TRIPS_SWITCH) if show_shorten: trip_id_list = trip_id_list[:3] trips = TripService.id_list(trip_id_list).order_by(Trip.start_datetime) buttons = [trip_to_line(trip) for trip in trips] if show_shorten: buttons.append([{ 'text': _('More'), 'data': 'full', }]) buttons.append([BACK]) return BotMessage(text=_('Choose trip:'), buttons=buttons)
class FirstNameState(BaseState): async def get_back_state(self): if self.user.first_name: return 'purchase' return 'show' _intro_message = BotMessage(text=_("What's your name?"), buttons=[[BACK]], is_text_input=True) async def process(self): if self.text: self.text = self.text.strip() if not self.text: self.message_was_not_recognized = True return self.user.first_name = self.text self.set_state('purchase')
def test_get_viber_buttons__none(self): tested = BotMessage('Hello') assert tested.get_viber_buttons() is None
def test_get_viber_buttons(self): tested = BotMessage(buttons=[ [ { 'text': '1.1', 'data': '1.1', }, { 'text': '1.2', 'data': '1.2', }, { 'text': '1.3', 'data': '1.3', }, ], [ { 'text': '2.1', 'data': '2.1', }, { 'text': '2.2', 'data': '2.2', }, ], [ { 'text': '3.1', 'data': '3.1', }, ], ]) assert tested.get_viber_buttons() == [ { 'text': '1.1', 'data': '1.1', 'viber': { 'Columns': 2, }, }, { 'text': '1.2', 'data': '1.2', 'viber': { 'Columns': 2, }, }, { 'text': '1.3', 'data': '1.3', 'viber': { 'Columns': 2, }, }, { 'text': '2.1', 'data': '2.1', 'viber': { 'Columns': 3, }, }, { 'text': '2.2', 'data': '2.2', 'viber': { 'Columns': 3, }, }, { 'text': '3.1', 'data': '3.1', 'viber': { 'Columns': 6, }, }, ]
def get_intro_message(self): return BotMessage( text=_('SMS was sent to +%s. Enter it.') % self.user.phone, buttons=[[BACK]], is_text_input=True, )
class WhereState(BaseState): """ Store where we are going and ask WHEN? """ with_trips_intro_message = BotMessage(text=_('Where are we going?'), buttons=[[{ 'text': _('To Mogilev'), 'data': Trip.MINSK_MOG_DIRECTION, }, { 'text': _('To Minsk'), 'data': Trip.MOG_MINSK_DIRECTION, }], [{ 'text': _('My trips'), 'data': 'purchase_list' }], [{ 'text': _('Feedback'), 'data': 'feedback', }]]) no_trips_intro_message = BotMessage(text=_('Where are we going?'), buttons=[[{ 'text': _('To Mogilev'), 'data': Trip.MINSK_MOG_DIRECTION, }, { 'text': _('To Minsk'), 'data': Trip.MOG_MINSK_DIRECTION, }], [{ 'text': _('Feedback'), 'data': 'feedback', }]]) def get_intro_message(self): if not UserService(self.user).future_purchases().count(): return self.no_trips_intro_message return self.with_trips_intro_message async def process(self): if self.value in (Trip.MOG_MINSK_DIRECTION, Trip.MINSK_MOG_DIRECTION): self.set_state('date') return if self.value == 'purchase_list': self.set_state('purchaselist') return if self.value == 'feedback': self.set_state('feedback') return self.message_was_not_recognized = True
class FeedbackState(BaseState): back = 'where' greeting_intro_message = BotMessage( _('Send me some feedback. ' 'What would you improve, ' 'what went wrong while using the bot?\n' 'It will help me become better.'), buttons=[[BACK]], is_text_input=True ) continue_intro_message = BotMessage( _('Add anything or press "Back" to return to booking trips.'), buttons=[[BACK]], is_text_input=True ) def get_intro_message(self): if self.data.pop('feedback__continue', False): return self.continue_intro_message return self.greeting_intro_message async def process(self): bot = self.get_bot() logger.warning( 'Got %s feedback!\n---\n%s\n---\n' 'User: first_name - %s; phone - %s\n' 'Context: %s', bot, self.text, self.user.first_name, self.user.phone, self.data, extra={ 'tags': { 'event': 'feedback', 'bot': bot, }, }, ) if not self.text: if bot == TELEGRAM_BOT: contact = TG_CONTACT else: contact = VIBER_CONTACT self.add_message(_( "Excuse me, I can't recognize your message :( " "Please, contact me directly at %s to tell what you wanted." ) % contact) else: ConversationService.add_user_message( self.user, self.text, self.data, bot ) self.data['feedback__continue'] = True
def get_intro_message(self): return BotMessage(self.TEXT, [self.buttons, [BACK]])