def zulip_server_error(report: Dict[str, Any]) -> None: email_subject = '%(node)s: %(message)s' % dict(report) logger_str = logger_repr(report) user_info = user_info_str(report) deployment = deployment_repr(report) if report['has_request']: request_repr = ("Request info:\n~~~~\n" "- path: %(path)s\n" "- %(method)s: %(data)s\n") % dict(report) for field in ["REMOTE_ADDR", "QUERY_STRING", "SERVER_NAME"]: val = report.get(field.lower()) if field == "QUERY_STRING": val = clean_data_from_query_parameters(str(val)) request_repr += "- %s: \"%s\"\n" % (field, val) request_repr += "~~~~" else: request_repr = "Request info: none" message = ("%s\nError generated by %s\n\n~~~~ pytb\n%s\n\n~~~~\n%s\n%s" % (logger_str, user_info, report['stack_trace'], deployment, request_repr)) error_bot = get_system_bot(settings.ERROR_BOT) realm = error_bot.realm errors_stream = get_stream('errors', realm) internal_send_stream_message(realm, error_bot, errors_stream, format_email_subject(email_subject), message)
def send_message(self, message: Dict[str, Any]) -> None: if not self._rate_limit.is_legal(): self._rate_limit.show_error_and_exit() if message['type'] == 'stream': internal_send_stream_message(self.user_profile.realm, self.user_profile, message['to'], message['topic'], message['content']) return assert message['type'] == 'private' # Ensure that it's a comma-separated list, even though the # usual 'to' field could be either a List[str] or a str. recipients = ','.join(message['to']).split(',') if len(message['to']) == 0: raise EmbeddedBotEmptyRecipientsList( _('Message must have recipients!')) elif len(message['to']) == 1: recipient_user = get_active_user(recipients[0], self.user_profile.realm) internal_send_private_message(self.user_profile.realm, self.user_profile, recipient_user, message['content']) else: internal_send_huddle_message(self.user_profile.realm, self.user_profile, recipients, message['content'])
def consume_batch(self, slow_query_events: List[Dict[str, Any]]) -> None: for event in slow_query_events: logging.info("Slow query: %s" % (event["query"],)) if settings.SLOW_QUERY_LOGS_STREAM is None: return if settings.ERROR_BOT is None: return if len(slow_query_events) > 0: topic = "%s: slow queries" % (settings.EXTERNAL_HOST,) content = "" for event in slow_query_events: content += " %s\n" % (event["query"],) error_bot = get_system_bot(settings.ERROR_BOT) realm = error_bot.realm errors_stream = get_stream( settings.SLOW_QUERY_LOGS_STREAM, realm ) internal_send_stream_message( realm, error_bot, errors_stream, topic, content )
def send_zulip(sender: UserProfile, stream: Stream, topic: str, content: str) -> None: internal_send_stream_message(stream.realm, sender, stream, truncate_topic(topic), truncate_body(content), email_gateway=True)
def process_missed_message(to: str, message: EmailMessage) -> None: mm_address = get_usable_missed_message_address(to) mm_address.increment_times_used() user_profile = mm_address.user_profile topic = mm_address.message.topic_name() if mm_address.message.recipient.type == Recipient.PERSONAL: # We need to reply to the sender so look up their personal recipient_id recipient = mm_address.message.sender.recipient else: recipient = mm_address.message.recipient if not is_user_active(user_profile): logger.warning( "Sending user is not active. Ignoring this missed message email.") return body = construct_zulip_body(message, user_profile.realm) if recipient.type == Recipient.STREAM: stream = get_stream_by_id_in_realm(recipient.type_id, user_profile.realm) internal_send_stream_message( user_profile.realm, user_profile, stream, topic, body, ) recipient_str = stream.name elif recipient.type == Recipient.PERSONAL: display_recipient = get_display_recipient(recipient) assert not isinstance(display_recipient, str) recipient_str = display_recipient[0]["email"] recipient_user = get_user(recipient_str, user_profile.realm) internal_send_private_message(user_profile.realm, user_profile, recipient_user, body) elif recipient.type == Recipient.HUDDLE: display_recipient = get_display_recipient(recipient) assert not isinstance(display_recipient, str) emails = [user_dict["email"] for user_dict in display_recipient] recipient_str = ", ".join(emails) internal_send_huddle_message(user_profile.realm, user_profile, emails, body) else: raise AssertionError("Invalid recipient type!") logger.info( "Successfully processed email from user %s to %s", user_profile.id, recipient_str, )
def zulip_browser_error(report: Dict[str, Any]) -> None: email_subject = "JS error: %s" % (report['user_email'], ) user_info = user_info_str(report) body = "User: %s\n" % (user_info, ) body += ("Message: %(message)s\n" % dict(report)) error_bot = get_system_bot(settings.ERROR_BOT) realm = error_bot.realm errors_stream = get_stream('errors', realm) internal_send_stream_message(realm, error_bot, errors_stream, format_email_subject(email_subject), body)
def zulip_server_error(report: Dict[str, Any]) -> None: email_subject = "{node}: {message}".format(**report) logger_str = logger_repr(report) user_info = user_info_str(report) deployment = deployment_repr(report) if report["has_request"]: request_repr = """\ Request info: ~~~~ - path: {path} - {method}: {data} """.format( **report ) for field in ["REMOTE_ADDR", "QUERY_STRING", "SERVER_NAME"]: val = report.get(field.lower()) if field == "QUERY_STRING": val = clean_data_from_query_parameters(str(val)) request_repr += f'- {field}: "{val}"\n' request_repr += "~~~~" else: request_repr = "Request info: none" message = f"""{logger_str} Error generated by {user_info} ~~~~ pytb {report['stack_trace']} ~~~~ {deployment} {request_repr}""" error_bot = get_system_bot(settings.ERROR_BOT) realm = error_bot.realm errors_stream = get_stream("errors", realm) internal_send_stream_message( error_bot, errors_stream, format_email_subject(email_subject), message, )
def zulip_browser_error(report: Dict[str, Any]) -> None: email_subject = "JS error: {user_email}".format(**report) user_info = user_info_str(report) body = f"User: {user_info}\n" body += "Message: {message}\n".format(**report) error_bot = get_system_bot(settings.ERROR_BOT) realm = error_bot.realm errors_stream = get_stream("errors", realm) internal_send_stream_message( error_bot, errors_stream, format_email_subject(email_subject), body, )
def send_to_missed_message_address(address: str, message: message.Message) -> None: token = get_missed_message_token_from_address(address) key = missed_message_redis_key(token) result = redis_client.hmget(key, 'user_profile_id', 'recipient_id', 'subject') if not all(val is not None for val in result): raise ZulipEmailForwardError('Missing missed message address data') user_profile_id, recipient_id, subject_b = result # type: (bytes, bytes, bytes) user_profile = get_user_profile_by_id(user_profile_id) if not is_user_active(user_profile): logger.warning( "Sending user is not active. Ignoring this missed message email.") return recipient = Recipient.objects.get(id=recipient_id) body = construct_zulip_body(message, user_profile.realm) if recipient.type == Recipient.STREAM: stream = get_stream_by_id_in_realm(recipient.type_id, user_profile.realm) internal_send_stream_message(user_profile.realm, user_profile, stream, subject_b.decode('utf-8'), body) recipient_str = stream.name elif recipient.type == Recipient.PERSONAL: display_recipient = get_display_recipient(recipient) assert not isinstance(display_recipient, str) recipient_str = display_recipient[0]['email'] recipient_user = get_user(recipient_str, user_profile.realm) internal_send_private_message(user_profile.realm, user_profile, recipient_user, body) elif recipient.type == Recipient.HUDDLE: display_recipient = get_display_recipient(recipient) assert not isinstance(display_recipient, str) emails = [user_dict['email'] for user_dict in display_recipient] recipient_str = ', '.join(emails) internal_send_huddle_message(user_profile.realm, user_profile, emails, body) else: raise AssertionError("Invalid recipient type!") logger.info("Successfully processed email from user %s to %s" % (user_profile.id, recipient_str))
def send_message(self, message: Dict[str, Any]) -> None: if not self._rate_limit.is_legal(): self._rate_limit.show_error_and_exit() if message['type'] == 'stream': internal_send_stream_message(self.user_profile.realm, self.user_profile, message['to'], message['topic'], message['content']) return assert message['type'] == 'private' # Ensure that it's a comma-separated list, even though the # usual 'to' field could be either a List[str] or a str. recipients = ','.join(message['to']).split(',') if len(message['to']) == 1: recipient_user = get_active_user(recipients[0], self.user_profile.realm) internal_send_private_message(self.user_profile.realm, self.user_profile, recipient_user, message['content']) else: internal_send_huddle_message(self.user_profile.realm, self.user_profile, recipients, message['content'])
def send_to_missed_message_address(address: str, message: message.Message) -> None: token = get_missed_message_token_from_address(address) key = missed_message_redis_key(token) result = redis_client.hmget(key, 'user_profile_id', 'recipient_id', 'subject') if not all(val is not None for val in result): raise ZulipEmailForwardError('Missing missed message address data') user_profile_id, recipient_id, subject_b = result # type: (bytes, bytes, bytes) user_profile = get_user_profile_by_id(user_profile_id) recipient = Recipient.objects.get(id=recipient_id) body = construct_zulip_body(message, user_profile.realm) if recipient.type == Recipient.STREAM: stream = get_stream_by_id_in_realm(recipient.type_id, user_profile.realm) internal_send_stream_message( user_profile.realm, user_profile, stream, subject_b.decode('utf-8'), body ) recipient_str = stream.name elif recipient.type == Recipient.PERSONAL: display_recipient = get_display_recipient(recipient) assert not isinstance(display_recipient, str) recipient_str = display_recipient[0]['email'] recipient_user = get_user(recipient_str, user_profile.realm) internal_send_private_message(user_profile.realm, user_profile, recipient_user, body) elif recipient.type == Recipient.HUDDLE: display_recipient = get_display_recipient(recipient) assert not isinstance(display_recipient, str) emails = [user_dict['email'] for user_dict in display_recipient] recipient_str = ', '.join(emails) internal_send_huddle_message(user_profile.realm, user_profile, emails, body) else: raise AssertionError("Invalid recipient type!") logger.info("Successfully processed email from %s to %s" % ( user_profile.email, recipient_str))