use std::path::PathBuf;
use clap::{ArgGroup, Args, Parser, Subcommand};
#[derive(Debug, Parser)]
#[command(name = "wechat-cli")]
#[command(about = "Command-line client for WeChat iLink bot APIs")]
#[command(version)]
pub struct Cli {
#[command(subcommand)]
pub command: Command,
}
#[derive(Debug, Subcommand)]
pub enum Command {
Login(LoginArgs),
Qrcode(QrcodeArgs),
QrcodeStatus(QrcodeStatusArgs),
Account(AccountArgs),
GetContextToken(GetContextTokenArgs),
Send(SendArgs),
}
#[derive(Debug, Args)]
pub struct LoginArgs {}
#[derive(Debug, Args)]
pub struct QrcodeArgs {}
#[derive(Debug, Args)]
pub struct QrcodeStatusArgs {
#[arg(long)]
pub qrcode_id: String,
}
#[derive(Debug, Args)]
pub struct AccountArgs {
#[command(subcommand)]
pub command: AccountCommand,
}
#[derive(Debug, Subcommand)]
pub enum AccountCommand {
List,
Add(AccountAddArgs),
Delete(AccountDeleteArgs),
}
#[derive(Debug, Args)]
pub struct AccountAddArgs {
#[arg(long)]
pub user_id: String,
#[arg(long)]
pub bot_token: String,
#[arg(long)]
pub route_tag: Option<String>,
}
#[derive(Debug, Args)]
pub struct AccountDeleteArgs {
#[arg(long)]
pub account: usize,
}
#[derive(Debug, Args)]
#[command(after_help = "Authentication Modes:
1. Saved Account Mode:
--account <index>
2. Explicit Credentials Mode:
--bot-token <token> --user-id <user_id> [--route-tag <tag>]
Usage Rules:
- You must use exactly one of the modes above.
- --account cannot be combined with --bot-token or --user-id.
- In Explicit mode, both --bot-token and --user-id are required.")]
pub struct GetContextTokenArgs {
#[arg(
long,
help = "Saved account index from `wechat-cli account list`. Required for Saved Account Mode."
)]
pub account: Option<usize>,
#[arg(long, help = "Target user ID. Required in Explicit Credentials Mode.")]
pub user_id: Option<String>,
#[arg(
long,
help = "Explicit bot token. Required in Explicit Credentials Mode."
)]
pub bot_token: Option<String>,
#[arg(
long,
help = "Optional route tag used only in Explicit Credentials Mode."
)]
pub route_tag: Option<String>,
}
#[derive(Debug, Args)]
#[command(group(
ArgGroup::new("message")
.args(["text", "file"])
.required(true)
.multiple(false)
))]
#[command(after_help = "Authentication Modes:
1. Saved Account Mode:
--account <index>
2. Explicit Credentials Mode:
--bot-token <token> --user-id <user_id> [--route-tag <tag>]
Usage Rules:
- You must use exactly one of the modes above.
- --account cannot be combined with --bot-token or --user-id.
- In Explicit mode, both --bot-token and --user-id are required.
- --context-token is always required for sending and must be provided explicitly.")]
pub struct SendArgs {
#[arg(
long,
help = "Saved account index from `wechat-cli account list`. Required for Saved Account Mode."
)]
pub account: Option<usize>,
#[arg(long, help = "Target user ID. Required in Explicit Credentials Mode.")]
pub user_id: Option<String>,
#[arg(
long,
help = "Explicit bot token. Required in Explicit Credentials Mode."
)]
pub bot_token: Option<String>,
#[arg(
long,
help = "Optional route tag used only in Explicit Credentials Mode."
)]
pub route_tag: Option<String>,
#[arg(
long,
help = "Context token from `get-context-token`. Always required."
)]
pub context_token: Option<String>,
#[arg(long, help = "Plain text message body")]
pub text: Option<String>,
#[arg(
long,
help = "File path to send. Images are detected and sent as image messages."
)]
pub file: Option<PathBuf>,
#[arg(long, requires = "file", help = "Optional caption for `--file`")]
pub caption: Option<String>,
}