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)
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)
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)
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}"')