Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 36 additions & 28 deletions zulip/zulip/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -61,35 +70,54 @@ 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... ",
message_data["to"],
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)

Expand Down Expand Up @@ -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")
Expand Down Expand Up @@ -154,36 +177,21 @@ 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."""
response = client.mark_all_as_read()
log_exit(response)


# Streams API


@cli.command()
def get_subscriptions() -> None:
"""Get all streams that the user is subscribed to."""
Expand All @@ -192,4 +200,4 @@ def get_subscriptions() -> None:


if __name__ == "__main__":
cli()
cli()
Loading