Ejemplo n.º 1
0
    def build_bot_request(self, event: Dict[str, Any]) -> Optional[Any]:
        # Because we don't have a place for the recipient of an
        # outgoing webhook to indicate whether it wants the raw
        # Markdown or the rendered HTML, we leave both the content and
        # rendered_content fields in the message payload.
        MessageDict.finalize_payload(event['message'], False, False,
                                     keep_rendered_content=True)

        request_data = {"data": event['command'],
                        "message": event['message'],
                        "bot_email": self.user_profile.email,
                        "token": self.token,
                        "trigger": event['trigger']}
        return json.dumps(request_data)
Ejemplo n.º 2
0
    def get_client_payload(apply_markdown: bool, client_gravatar: bool) -> Dict[str, Any]:
        dct = copy.deepcopy(wide_dict)

        # Temporary transitional code: Zulip servers that have message
        # events in their event queues and upgrade to the new version
        # that expects sender_delivery_email in these events will
        # throw errors processing events.  We can remove this block
        # once we don't expect anyone to be directly upgrading from
        # 2.0.x to the latest Zulip.
        if 'sender_delivery_email' not in dct:  # nocoverage
            dct['sender_delivery_email'] = dct['sender_email']

        MessageDict.finalize_payload(dct, apply_markdown, client_gravatar)
        return dct
Ejemplo n.º 3
0
 def get_client_payload(apply_markdown: bool,
                        client_gravatar: bool) -> Dict[str, Any]:
     return MessageDict.finalize_payload(
         wide_dict,
         apply_markdown=apply_markdown,
         client_gravatar=client_gravatar,
     )
Ejemplo n.º 4
0
    def make_request(self, base_url: str,
                     event: Dict[str, Any]) -> Optional[Response]:
        """
        We send a simple version of the message to outgoing
        webhooks, since most of them really only need
        `content` and a few other fields.  We may eventually
        allow certain bots to get more information, but
        that's not a high priority.  We do send the gravatar
        info to the clients (so they don't have to compute
        it themselves).
        """
        message_dict = MessageDict.finalize_payload(
            event["message"],
            apply_markdown=False,
            client_gravatar=False,
            keep_rendered_content=True,
        )

        request_data = {
            "data": event["command"],
            "message": message_dict,
            "bot_email": self.user_profile.email,
            "bot_full_name": self.user_profile.full_name,
            "token": self.token,
            "trigger": event["trigger"],
        }

        return self.session.post(base_url, json=request_data)
Ejemplo n.º 5
0
    def build_bot_request(self, event: Dict[str, Any]) -> Optional[Any]:
        '''
        We send a simple version of the message to outgoing
        webhooks, since most of them really only need
        `content` and a few other fields.  We may eventually
        allow certain bots to get more information, but
        that's not a high priority.  We do send the gravatar
        info to the clients (so they don't have to compute
        it themselves).
        '''
        message_dict = MessageDict.finalize_payload(
            event['message'],
            apply_markdown=False,
            client_gravatar=False,
            keep_rendered_content=True,
        )

        request_data = {
            "data": event['command'],
            "message": message_dict,
            "bot_email": self.user_profile.email,
            "token": self.token,
            "trigger": event['trigger']
        }
        return json.dumps(request_data)
Ejemplo n.º 6
0
        def get_send_message_payload(msg_id: int, apply_markdown: bool,
                                     client_gravatar: bool) -> Dict[str, Any]:
            msg = reload_message(msg_id)
            wide_dict = MessageDict.wide_dict(msg)

            narrow_dict = MessageDict.finalize_payload(
                wide_dict,
                apply_markdown=apply_markdown,
                client_gravatar=client_gravatar,
            )
            return narrow_dict
Ejemplo n.º 7
0
 def get_client_payload(apply_markdown: bool, client_gravatar: bool) -> Dict[str, Any]:
     dct = copy.deepcopy(wide_dict)
     MessageDict.finalize_payload(dct, apply_markdown, client_gravatar)
     return dct
Ejemplo n.º 8
0
def process_message_event(event_template, users):
    # type: (Mapping[str, Any], Iterable[Mapping[str, Any]]) -> None
    send_to_clients = get_client_info_for_message_event(event_template, users)

    presence_idle_user_ids = set(
        event_template.get('presence_idle_user_ids', []))
    message_dict = event_template['message_dict']  # type: Dict[str, Any]

    sender_id = message_dict['sender_id']  # type: int
    message_id = message_dict['id']  # type: int
    message_type = message_dict['type']  # type: str
    sending_client = message_dict['client']  # type: Text

    message_dict_html = copy.deepcopy(message_dict)
    MessageDict.finalize_payload(message_dict_html, apply_markdown=True)

    message_dict_text = copy.deepcopy(message_dict)
    MessageDict.finalize_payload(message_dict_text, apply_markdown=False)

    # Extra user-specific data to include
    extra_user_data = {}  # type: Dict[int, Any]

    for user_data in users:
        user_profile_id = user_data['id']  # type: int
        flags = user_data.get('flags', [])  # type: Iterable[str]

        # If the recipient was offline and the message was a single or group PM to them
        # or they were @-notified potentially notify more immediately
        private_message = message_type == "private" and user_profile_id != sender_id
        mentioned = 'mentioned' in flags and 'read' not in flags
        stream_push_notify = user_data.get('stream_push_notify', False)

        # We first check if a message is potentially mentionable,
        # since receiver_is_off_zulip is somewhat expensive.
        if private_message or mentioned or stream_push_notify:
            idle = receiver_is_off_zulip(user_profile_id) or (
                user_profile_id in presence_idle_user_ids)
            always_push_notify = user_data.get('always_push_notify', False)
            stream_name = event_template.get('stream_name')
            result = maybe_enqueue_notifications(user_profile_id, message_id,
                                                 private_message, mentioned,
                                                 stream_push_notify,
                                                 stream_name,
                                                 always_push_notify, idle, {})
            result['stream_push_notify'] = stream_push_notify
            extra_user_data[user_profile_id] = result

    for client_data in send_to_clients.values():
        client = client_data['client']
        flags = client_data['flags']
        is_sender = client_data.get('is_sender', False)  # type: bool
        extra_data = extra_user_data.get(
            client.user_profile_id, None)  # type: Optional[Mapping[str, bool]]

        if not client.accepts_messages():
            # The actual check is the accepts_event() check below;
            # this line is just an optimization to avoid copying
            # message data unnecessarily
            continue

        if client.apply_markdown:
            message_dict = message_dict_html
        else:
            message_dict = message_dict_text

        # Make sure Zephyr mirroring bots know whether stream is invite-only
        if "mirror" in client.client_type_name and event_template.get(
                "invite_only"):
            message_dict = message_dict.copy()
            message_dict["invite_only_stream"] = True

        user_event = dict(type='message', message=message_dict,
                          flags=flags)  # type: Dict[str, Any]
        if extra_data is not None:
            user_event.update(extra_data)

        if is_sender:
            local_message_id = event_template.get('local_id', None)
            if local_message_id is not None:
                user_event["local_message_id"] = local_message_id

        if not client.accepts_event(user_event):
            continue

        # The below prevents (Zephyr) mirroring loops.
        if ('mirror' in sending_client
                and sending_client.lower() == client.client_type_name.lower()):
            continue
        client.add_event(user_event)
Ejemplo n.º 9
0
 def get_client_payload(apply_markdown: bool, client_gravatar: bool) -> Dict[str, Any]:
     dct = copy.deepcopy(wide_dict)
     MessageDict.finalize_payload(dct, apply_markdown, client_gravatar)
     return dct
Ejemplo n.º 10
0
def process_message_event(event_template, users):
    # type: (Mapping[str, Any], Iterable[Mapping[str, Any]]) -> None
    send_to_clients = get_client_info_for_message_event(event_template, users)

    presence_idle_user_ids = set(event_template.get('presence_idle_user_ids', []))
    message_dict = event_template['message_dict']  # type: Dict[str, Any]

    sender_id = message_dict['sender_id']  # type: int
    message_id = message_dict['id']  # type: int
    message_type = message_dict['type']  # type: str
    sending_client = message_dict['client']  # type: Text

    message_dict_html = copy.deepcopy(message_dict)
    MessageDict.finalize_payload(message_dict_html, apply_markdown=True)

    message_dict_text = copy.deepcopy(message_dict)
    MessageDict.finalize_payload(message_dict_text, apply_markdown=False)

    # Extra user-specific data to include
    extra_user_data = {}  # type: Dict[int, Any]

    for user_data in users:
        user_profile_id = user_data['id']  # type: int
        flags = user_data.get('flags', [])  # type: Iterable[str]

        # If the recipient was offline and the message was a single or group PM to them
        # or they were @-notified potentially notify more immediately
        private_message = message_type == "private" and user_profile_id != sender_id
        mentioned = 'mentioned' in flags and 'read' not in flags
        stream_push_notify = user_data.get('stream_push_notify', False)

        # We first check if a message is potentially mentionable,
        # since receiver_is_off_zulip is somewhat expensive.
        if private_message or mentioned or stream_push_notify:
            idle = receiver_is_off_zulip(user_profile_id) or (user_profile_id in presence_idle_user_ids)
            always_push_notify = user_data.get('always_push_notify', False)
            stream_name = event_template.get('stream_name')
            result = maybe_enqueue_notifications(user_profile_id, message_id, private_message,
                                                 mentioned, stream_push_notify, stream_name,
                                                 always_push_notify, idle, {})
            result['stream_push_notify'] = stream_push_notify
            extra_user_data[user_profile_id] = result

    for client_data in send_to_clients.values():
        client = client_data['client']
        flags = client_data['flags']
        is_sender = client_data.get('is_sender', False)  # type: bool
        extra_data = extra_user_data.get(client.user_profile_id, None)  # type: Optional[Mapping[str, bool]]

        if not client.accepts_messages():
            # The actual check is the accepts_event() check below;
            # this line is just an optimization to avoid copying
            # message data unnecessarily
            continue

        if client.apply_markdown:
            message_dict = message_dict_html
        else:
            message_dict = message_dict_text

        # Make sure Zephyr mirroring bots know whether stream is invite-only
        if "mirror" in client.client_type_name and event_template.get("invite_only"):
            message_dict = message_dict.copy()
            message_dict["invite_only_stream"] = True

        user_event = dict(type='message', message=message_dict, flags=flags)  # type: Dict[str, Any]
        if extra_data is not None:
            user_event.update(extra_data)

        if is_sender:
            local_message_id = event_template.get('local_id', None)
            if local_message_id is not None:
                user_event["local_message_id"] = local_message_id

        if not client.accepts_event(user_event):
            continue

        # The below prevents (Zephyr) mirroring loops.
        if ('mirror' in sending_client and
                sending_client.lower() == client.client_type_name.lower()):
            continue
        client.add_event(user_event)
Ejemplo n.º 11
0
 def get_client_payload(apply_markdown, client_gravatar):
     # type: (bool, bool) -> Mapping[str, Any]
     dct = copy.deepcopy(wide_dict)
     MessageDict.finalize_payload(dct, apply_markdown, client_gravatar)
     return dct