async def option(payload, session=None, user=None, story=None): return await story.match_message( story_context.set_message_data( story_context.clean_message_data({ 'session': session, 'user': user, }), 'option', 'value', payload))
async def sticker(payload, session=None, user=None, story=None): return await story.match_message( story_context.set_message_data( story_context.clean_message_data({ 'session': session, 'user': user, }), 'sticker_id', payload['sticker_id']))
async def location(loc, session=None, user=None, story=None): return await story.match_message( story_context.set_message_data( story_context.clean_message_data({ 'session': session, 'user': user, }), 'location', loc))
async def pure_text(text, session=None, user=None, story=None): return await story.match_message( story_context.set_message_data( story_context.clean_message_data({ 'session': session, 'user': user, }), 'text', { 'raw': text, }))
async def ask(self, payload): if payload is None: return await self.story.match_message( story_context.set_message_data( story_context.clean_message_data({ 'session': self.session, 'user': self.user, }), {})) if 'sticker_id' in payload: return await self.wrap_user_talk(sticker)(payload) if isinstance(payload, str): return await self.pure_text(payload) raise NotImplementedError('put all other message types here')
def test_clean_message_data(): ctx = { 'session': { 'data': { 'message': { 'text': { 'raw': 'I\'m going to Mars', 'something': 'else', }, 'location': { 'lat': 12, 'lng': 21, } } } } } ctx = story_context.clean_message_data(ctx) assert ctx == {'session': {'data': {'message': {}}}}
async def handle(self, data): logger.debug('') logger.debug('> handle <') logger.debug('') logger.debug(' entry: {}'.format(data)) try: for e in data.get('entry', []): messaging = e.get('messaging', []) logger.debug(' messaging: {}'.format(messaging)) if len(messaging) == 0: logger.warning(' entry {} list lack of "messaging" field'.format(e)) for m in messaging: logger.debug(' m: {}'.format(m)) facebook_user_id = m['sender']['id'] logger.debug('before get user with facebook_user_id={}'.format(facebook_user_id)) user = await self.storage.get_user(facebook_user_id=facebook_user_id) if not user: logger.debug(' should create new user {}'.format(facebook_user_id)) try: messenger_profile_data = await self.request_profile(facebook_user_id) logger.debug('receive fb profile {}'.format(messenger_profile_data)) except commonhttp.errors.HttpRequestError as err: logger.debug('fail on request fb profile of {}. with {}'.format(facebook_user_id, err)) messenger_profile_data = { 'no_fb_profile': True, } logger.debug('before creating new user') user = await self.storage.new_user( facebook_user_id=facebook_user_id, no_fb_profile=messenger_profile_data.get('no_fb_profile', None), first_name=messenger_profile_data.get('first_name', None), last_name=messenger_profile_data.get('last_name', None), profile_pic=messenger_profile_data.get('profile_pic', None), locale=messenger_profile_data.get('locale', None), timezone=messenger_profile_data.get('timezone', None), gender=messenger_profile_data.get('gender', None), ) self.users.on_new_user_comes(user) session = await self.storage.get_session(facebook_user_id=facebook_user_id) if not session: logger.debug(' should create new session for user {}'.format(facebook_user_id)) session = await self.storage.new_session( facebook_user_id=facebook_user_id, stack=[], user=user, ) ctx = story_context.clean_message_data({ 'session': session, 'user': user, }) if 'message' in m: logger.debug('message notification') raw_message = m.get('message', {}) if 'is_echo' in raw_message: # TODO: should react somehow. # for example storing for debug purpose logger.debug('just echo message') else: text = raw_message.get('text', None) if text is not None: ctx = story_context.set_message_data(ctx, 'text', { 'raw': text, }) elif 'sticker_id' in raw_message: ctx = story_context.set_message_data(ctx, 'sticker_id', raw_message['sticker_id'], ) else: logger.warning(' entry {} "text"'.format(e)) quick_reply = raw_message.get('quick_reply', None) if quick_reply is not None: ctx = story_context.set_message_data(ctx, 'option', 'value', quick_reply['payload']) ctx = await self.story_processor.match_message(ctx) elif 'postback' in m: ctx = story_context.set_message_data(ctx, 'option', 'value', m['postback']['payload']) ctx = await self.story_processor.match_message(ctx) elif 'delivery' in m: logger.debug('delivery notification') elif 'read' in m: logger.debug('read notification') else: logger.warning('(!) unknown case {}'.format(e)) # after message were processed session and user information could change # so we should store it for the next usage await self.storage.set_session(ctx['session']) await self.storage.set_user(ctx['user']) except BaseException as err: logger.exception(err) return { 'status': 200, 'text': 'Ok!', }