From 11f5a643fa4cac574d097aba9efc5c48a9b491a9 Mon Sep 17 00:00:00 2001 From: sujanyd Date: Sun, 9 Nov 2025 11:16:23 +0530 Subject: [PATCH] Support using 'direct' as the message type for private messages --- zulip/zulip/cli.py | 64 ++++++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/zulip/zulip/cli.py b/zulip/zulip/cli.py index 16d4f9587..4e0a50296 100755 --- a/zulip/zulip/cli.py +++ b/zulip/zulip/cli.py @@ -51,7 +51,16 @@ def log_exit(response: Dict[str, Any]) -> None: help="Allows the user to specify a subject for the message.", ) @click.option("--message", "-m", required=True) -def send_message(recipients: List[str], stream: str, subject: str, message: str) -> None: +@click.option( + "--type", + "-t", + "message_type", + default="private", + help="Message type: 'stream', 'private', or 'direct'.", +) +def send_message( + recipients: List[str], stream: str, subject: str, message: str, message_type: str +) -> None: """Sends a message and optionally prints status about the same.""" # Sanity check user data @@ -61,27 +70,45 @@ def send_message(recipients: List[str], stream: str, subject: str, message: str) click.echo("You cannot specify both a username and a stream/subject.") raise SystemExit(1) if len(recipients) == 0 and has_stream != has_subject: - click.echo("Stream messages must have a subject") + click.echo("Stream messages must have a subject.") raise SystemExit(1) if len(recipients) == 0 and not has_stream: click.echo("You must specify a stream/subject or at least one recipient.") raise SystemExit(1) - message_data: Dict[str, Any] + # Normalize message type + if message_type not in ("stream", "private", "direct"): + click.echo("Invalid message type. Use 'stream', 'private', or 'direct'.") + raise SystemExit(1) + + # Determine type if has_stream: - message_data = { + message_data: Dict[str, Any] = { "type": "stream", "content": message, "subject": subject, "to": stream, } else: + # Default to "direct" if explicitly given, else private message_data = { - "type": "private", + "type": "direct" if message_type == "direct" else "private", "content": message, "to": recipients, } + # Backward compatibility: convert "direct" → "private" if server doesn’t support feature level 174+ + if message_data["type"] == "direct": + try: + if client.server_feature_level() < 174: + log.info( + "Server does not support 'direct' message type; falling back to 'private'." + ) + message_data["type"] = "private" + except Exception: + # Fallback: assume older server + message_data["type"] = "private" + if message_data["type"] == "stream": log.info( "Sending message to stream %r, subject %r... ", @@ -89,7 +116,8 @@ def send_message(recipients: List[str], stream: str, subject: str, message: str) message_data["subject"], ) else: - log.info("Sending message to %s... ", message_data["to"]) + log.info("Sending %r message to %s... ", message_data["type"], message_data["to"]) + response = client.send_message(message_data) log_exit(response) @@ -121,11 +149,6 @@ def delete_message(message_id: int) -> None: log_exit(response) -# TODO -# https://zulip.com/api/get-messages -# https://zulip.com/api/construct-narrow - - @cli.command() @click.argument("message_id", type=int) @click.argument("emoji_name") @@ -154,26 +177,14 @@ def remove_reaction(message_id: int, emoji_name: str) -> None: log_exit(response) -# TODO -# https://zulip.com/api/render-message -# https://zulip.com/api/get-raw-message -# https://zulip.com/api/check-narrow-matches - - @cli.command() @click.argument("message_id", type=int) def get_message_history(message_id: int) -> None: - """Fetch the message edit history of a previously edited message. - Note that edit history may be disabled in some organizations; see https://zulip.com/help/view-a-messages-edit-history. - """ + """Fetch the message edit history of a previously edited message.""" response = client.get_message_history(message_id) log_exit(response) -# TODO -# https://zulip.com/api/update-message-flags - - @cli.command() def mark_all_as_read() -> None: """Marks all of the current user's unread messages as read.""" @@ -181,9 +192,6 @@ def mark_all_as_read() -> None: log_exit(response) -# Streams API - - @cli.command() def get_subscriptions() -> None: """Get all streams that the user is subscribed to.""" @@ -192,4 +200,4 @@ def get_subscriptions() -> None: if __name__ == "__main__": - cli() + cli() \ No newline at end of file