Пример #1
0
    async def _send_text(self,
                         request: Request,
                         stack: Stack,
                         parse_mode: Optional[Text] = None):
        """
        Base function for sending text
        """

        parts = []
        chat_id = request.message.get_chat_id()

        for layer in stack.layers:
            if isinstance(layer, (lyr.Text, lyr.RawText, lyr.Markdown)):
                text = await render(layer.text, request)
                parts.append(text)

        for part in parts[:-1]:
            await self.call(
                'sendMessage',
                text=part,
                chat_id=chat_id,
            )

        msg = {
            'text': parts[-1],
            'chat_id': chat_id,
        }

        if parse_mode is not None:
            msg['parse_mode'] = parse_mode

        await set_reply_markup(msg, request, stack)

        if stack.has_layer(Reply):
            reply = stack.get_layer(Reply)
            if reply.message:
                msg['reply_to_message_id'] = reply.message['message_id']

        if stack.has_layer(Update):
            update = stack.get_layer(Update)

            if update.inline_message_id:
                msg['inline_message_id'] = update.inline_message_id
                del msg['chat_id']
            else:
                msg['message_id'] = update.message_id

            await self.call('editMessageText',
                            {'Bad Request: message is not modified'}, **msg)
        else:
            await self.call('sendMessage', **msg)
Пример #2
0
class Request(object):
    """
    The request object is generated after each message. Its goal is to provide
    a comprehensive access to the received message and its context to be used
    by the transitions and the handlers.
    """
    def __init__(self, message: BaseMessage, register: Register):
        self.message = message
        self.platform = message.get_platform()
        self.conversation = message.get_conversation()
        self.user = message.get_user()
        self.stack = Stack(message.get_layers())
        self.register = register
        self.custom_content = {}

    async def transform(self):
        await self.stack.transform(self)

    def get_trans_reg(self, name: Text, default: Any = None) -> Any:
        """
        Convenience function to access the transition register of a specific
        kind.

        :param name: Name of the register you want to see
        :param default: What to return by default
        """

        tr = self.register.get(Register.TRANSITION, {})
        return tr.get(name, default)

    def has_layer(self, class_: Type[L], became: bool = True) -> bool:
        """
        Proxy to stack
        """
        return self.stack.has_layer(class_, became)

    def get_layer(self, class_: Type[L], became: bool = True) -> L:
        """
        Proxy to stack
        """
        return self.stack.get_layer(class_, became)

    def get_layers(self, class_: Type[L], became: bool = True) -> List[L]:
        """
        Proxy to stack
        """
        return self.stack.get_layers(class_, became)
Пример #3
0
    async def _send(self, request: Request, content: Dict[Text, Any],
                    stack: Stack):
        """
        Actually proceed to sending the message to the Facebook API.
        """

        msg = {
            'recipient': {
                'id': request.conversation.fbid,
            },
            'message': content,
        }

        if stack and stack.has_layer(MessagingType):
            mt = stack.get_layer(MessagingType)
        else:
            mt = MessagingType(response=True)

        msg.update(mt.serialize())
        msg_json = ujson.dumps(msg)

        headers = {
            'content-type': 'application/json',
        }

        params = {
            'access_token': self._access_token(request),
        }

        post = self.session.post(
            MESSAGES_ENDPOINT,
            params=params,
            data=msg_json,
            headers=headers,
        )

        logger.debug('Sending: %s', msg_json)

        async with post as r:
            await self._handle_fb_response(r)
Пример #4
0
class Request(object):
    """
    The request object is generated after each message. Its goal is to provide
    a comprehensive access to the received message and its context to be used
    by the transitions and the handlers.
    """

    QUERY = 'query'
    HASH = 'hash'

    def __init__(self, message: BaseMessage, register: Register):
        self.message = message
        self.platform = message.get_platform()
        self.conversation = message.get_conversation()
        self.user = message.get_user()
        self.stack = Stack(message.get_layers())
        self.register = register
        self.custom_content = {}

        self._locale_override = None

    async def transform(self):
        await self.stack.transform(self)

    def get_trans_reg(self, name: Text, default: Any = None) -> Any:
        """
        Convenience function to access the transition register of a specific
        kind.

        :param name: Name of the register you want to see
        :param default: What to return by default
        """

        tr = self.register.get(Register.TRANSITION, {})
        return tr.get(name, default)

    def has_layer(self, class_: Type[L], became: bool = True) -> bool:
        """
        Proxy to stack
        """
        return self.stack.has_layer(class_, became)

    def get_layer(self, class_: Type[L], became: bool = True) -> L:
        """
        Proxy to stack
        """
        return self.stack.get_layer(class_, became)

    def get_layers(self, class_: Type[L], became: bool = True) -> List[L]:
        """
        Proxy to stack
        """
        return self.stack.get_layers(class_, became)

    def set_locale_override(self, locale: Text) -> None:
        """
        This allows to override manually the locale that will be used in
        replies.

        :param locale: Name of the locale (format 'fr' or 'fr_FR')
        """

        self._locale_override = locale

    async def get_locale(self) -> Text:
        """
        Get the locale to use for this request. It's either the overridden
        locale or the locale provided by the platform.

        :return: Locale to use for this request
        """

        if self._locale_override:
            return self._locale_override
        else:
            return await self.user.get_locale()

    async def get_trans_flags(self) -> 'Flags':
        """
        Gives a chance to middlewares to make the translation flags
        """

        from bernard.middleware import MiddlewareManager

        async def make_flags(request: Request) -> 'Flags':
            return {}

        mf = MiddlewareManager.instance().get('make_trans_flags', make_flags)
        return await mf(self)

    async def get_token(self) -> Text:
        """
        Returns the auth token from the message
        """

        return await self.message.get_token()

    async def sign_url(self, url, method=HASH):
        """
        Sign an URL with this request's auth token
        """

        token = await self.get_token()

        if method == self.QUERY:
            return patch_qs(url, {
                settings.WEBVIEW_TOKEN_KEY: token,
            })
        elif method == self.HASH:
            hash_id = 5
            p = list(urlparse(url))
            p[hash_id] = quote(token)
            return urlunparse(p)
        else:
            raise ValueError(f'Invalid signing method "{method}"')