Add missing command to json-rpc client

This commit is contained in:
AsamK 2024-01-30 18:52:43 +01:00
parent e13dcdc85a
commit 15c9d04703
3 changed files with 211 additions and 70 deletions

View file

@ -1,6 +1,7 @@
use clap::{crate_version, Parser, Subcommand, ValueEnum};
use std::{ffi::OsString, net::SocketAddr}; use std::{ffi::OsString, net::SocketAddr};
use clap::{crate_version, Parser, Subcommand, ValueEnum};
/// JSON-RPC client for signal-cli /// JSON-RPC client for signal-cli
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
#[command(rename_all = "kebab-case", version = crate_version!())] #[command(rename_all = "kebab-case", version = crate_version!())]
@ -21,9 +22,6 @@ pub struct Cli {
#[arg(long, conflicts_with = "json_rpc_socket")] #[arg(long, conflicts_with = "json_rpc_socket")]
pub json_rpc_http: Option<Option<String>>, pub json_rpc_http: Option<Option<String>>,
#[arg(value_enum, long, default_value_t = OutputTypes::Json)]
pub output: OutputTypes,
#[arg(long)] #[arg(long)]
pub verbose: bool, pub verbose: bool,
@ -31,13 +29,6 @@ pub struct Cli {
pub command: CliCommands, pub command: CliCommands,
} }
#[derive(ValueEnum, Clone, Debug)]
#[value(rename_all = "kebab-case")]
pub enum OutputTypes {
PlainText,
Json,
}
#[allow(clippy::large_enum_variant)] #[allow(clippy::large_enum_variant)]
#[derive(Subcommand, Debug)] #[derive(Subcommand, Debug)]
#[command(rename_all = "camelCase", version = crate_version!())] #[command(rename_all = "camelCase", version = crate_version!())]
@ -46,6 +37,10 @@ pub enum CliCommands {
#[arg(long)] #[arg(long)]
uri: String, uri: String,
}, },
AddStickerPack {
#[arg(long)]
uri: String,
},
#[command(rename_all = "kebab-case")] #[command(rename_all = "kebab-case")]
Block { Block {
recipient: Vec<String>, recipient: Vec<String>,
@ -57,6 +52,22 @@ pub enum CliCommands {
#[arg(long = "ignore-registered")] #[arg(long = "ignore-registered")]
ignore_registered: Option<bool>, ignore_registered: Option<bool>,
}, },
FinishChangeNumber {
number: String,
#[arg(short = 'v', long = "verification-code")]
verification_code: String,
#[arg(short = 'p', long)]
pin: Option<String>,
},
GetAttachment {
#[arg(long)]
id: String,
#[arg(long)]
recipient: Option<String>,
#[arg(short = 'g', long = "group-id")]
group_id: Option<String>,
},
GetUserStatus { GetUserStatus {
recipient: Vec<String>, recipient: Vec<String>,
}, },
@ -112,6 +123,8 @@ pub enum CliCommands {
recipient: String, recipient: String,
#[arg(long)] #[arg(long)]
forget: bool, forget: bool,
#[arg(long)]
hide: bool,
}, },
RemoveDevice { RemoveDevice {
#[arg(short = 'd', long = "device-id")] #[arg(short = 'd', long = "device-id")]
@ -152,6 +165,9 @@ pub enum CliCommands {
#[arg(long)] #[arg(long)]
mention: Vec<String>, mention: Vec<String>,
#[arg(long)]
text_style: Vec<String>,
#[arg(long)] #[arg(long)]
quote_timestamp: Option<u64>, quote_timestamp: Option<u64>,
@ -164,9 +180,24 @@ pub enum CliCommands {
#[arg(long)] #[arg(long)]
quote_mention: Vec<String>, quote_mention: Vec<String>,
#[arg(long)]
quote_text_style: Vec<String>,
#[arg(long)] #[arg(long)]
quote_attachment: Vec<String>, quote_attachment: Vec<String>,
#[arg(long)]
preview_url: Option<String>,
#[arg(long)]
preview_title: Option<String>,
#[arg(long)]
preview_description: Option<String>,
#[arg(long)]
preview_image: Option<String>,
#[arg(long)] #[arg(long)]
sticker: Option<String>, sticker: Option<String>,
@ -175,6 +206,9 @@ pub enum CliCommands {
#[arg(long)] #[arg(long)]
story_author: Option<String>, story_author: Option<String>,
#[arg(long)]
edit_timestamp: Option<u64>,
}, },
SendContacts, SendContacts,
SendPaymentNotification { SendPaymentNotification {
@ -232,6 +266,13 @@ pub enum CliCommands {
SetPin { SetPin {
pin: String, pin: String,
}, },
StartChangeNumber {
number: String,
#[arg(short = 'v', long)]
voice: bool,
#[arg(long)]
captcha: Option<String>,
},
SubmitRateLimitChallenge { SubmitRateLimitChallenge {
challenge: String, challenge: String,
captcha: String, captcha: String,
@ -259,6 +300,8 @@ pub enum CliCommands {
UpdateAccount { UpdateAccount {
#[arg(short = 'n', long = "device-name")] #[arg(short = 'n', long = "device-name")]
device_name: Option<String>, device_name: Option<String>,
#[arg(long = "unrestricted-unidentified-sender")]
unrestricted_unidentified_sender: Option<bool>,
}, },
UpdateConfiguration { UpdateConfiguration {
#[arg(long = "read-receipts")] #[arg(long = "read-receipts")]

View file

@ -18,6 +18,13 @@ pub trait Rpc {
uri: String, uri: String,
) -> Result<Value, ErrorObjectOwned>; ) -> Result<Value, ErrorObjectOwned>;
#[method(name = "addStickerPack", param_kind = map)]
async fn add_sticker_pack(
&self,
account: Option<String>,
uri: String,
) -> Result<Value, ErrorObjectOwned>;
#[method(name = "block", param_kind = map)] #[method(name = "block", param_kind = map)]
fn block( fn block(
&self, &self,
@ -33,6 +40,15 @@ pub trait Rpc {
#[allow(non_snake_case)] ignoreRegistered: Option<bool>, #[allow(non_snake_case)] ignoreRegistered: Option<bool>,
) -> Result<Value, ErrorObjectOwned>; ) -> Result<Value, ErrorObjectOwned>;
#[method(name = "getAttachment", param_kind = map)]
fn get_attachment(
&self,
account: Option<String>,
id: String,
recipient: Option<String>,
group_id: Option<String>,
) -> Result<Value, ErrorObjectOwned>;
#[method(name = "getUserStatus", param_kind = map)] #[method(name = "getUserStatus", param_kind = map)]
fn get_user_status( fn get_user_status(
&self, &self,
@ -43,6 +59,16 @@ pub trait Rpc {
#[method(name = "joinGroup", param_kind = map)] #[method(name = "joinGroup", param_kind = map)]
fn join_group(&self, account: Option<String>, uri: String) -> Result<Value, ErrorObjectOwned>; fn join_group(&self, account: Option<String>, uri: String) -> Result<Value, ErrorObjectOwned>;
#[allow(non_snake_case)]
#[method(name = "finishChangeNumber", param_kind = map)]
fn finish_change_number(
&self,
account: Option<String>,
number: String,
verificationCode: String,
pin: Option<String>,
) -> Result<Value, ErrorObjectOwned>;
#[method(name = "finishLink", param_kind = map)] #[method(name = "finishLink", param_kind = map)]
fn finish_link( fn finish_link(
&self, &self,
@ -106,6 +132,7 @@ pub trait Rpc {
account: Option<String>, account: Option<String>,
recipient: String, recipient: String,
forget: bool, forget: bool,
hide: bool,
) -> Result<Value, ErrorObjectOwned>; ) -> Result<Value, ErrorObjectOwned>;
#[method(name = "removeDevice", param_kind = map)] #[method(name = "removeDevice", param_kind = map)]
@ -128,25 +155,33 @@ pub trait Rpc {
#[allow(non_snake_case)] noteToSelf: bool, #[allow(non_snake_case)] noteToSelf: bool,
) -> Result<Value, ErrorObjectOwned>; ) -> Result<Value, ErrorObjectOwned>;
#[allow(non_snake_case)]
#[method(name = "send", param_kind = map)] #[method(name = "send", param_kind = map)]
fn send( fn send(
&self, &self,
account: Option<String>, account: Option<String>,
recipients: Vec<String>, recipients: Vec<String>,
#[allow(non_snake_case)] groupIds: Vec<String>, groupIds: Vec<String>,
#[allow(non_snake_case)] noteToSelf: bool, noteToSelf: bool,
#[allow(non_snake_case)] endSession: bool, endSession: bool,
message: String, message: String,
attachments: Vec<String>, attachments: Vec<String>,
mentions: Vec<String>, mentions: Vec<String>,
#[allow(non_snake_case)] quoteTimestamp: Option<u64>, textStyle: Vec<String>,
#[allow(non_snake_case)] quoteAuthor: Option<String>, quoteTimestamp: Option<u64>,
#[allow(non_snake_case)] quoteMessage: Option<String>, quoteAuthor: Option<String>,
#[allow(non_snake_case)] quoteMention: Vec<String>, quoteMessage: Option<String>,
#[allow(non_snake_case)] quoteAttachment: Vec<String>, quoteMention: Vec<String>,
quoteTextStyle: Vec<String>,
quoteAttachment: Vec<String>,
preview_url: Option<String>,
preview_title: Option<String>,
preview_description: Option<String>,
preview_image: Option<String>,
sticker: Option<String>, sticker: Option<String>,
#[allow(non_snake_case)] storyTimestamp: Option<u64>, storyTimestamp: Option<u64>,
#[allow(non_snake_case)] storyAuthor: Option<String>, storyAuthor: Option<String>,
editTimestamp: Option<u64>,
) -> Result<Value, ErrorObjectOwned>; ) -> Result<Value, ErrorObjectOwned>;
#[method(name = "sendContacts", param_kind = map)] #[method(name = "sendContacts", param_kind = map)]
@ -207,6 +242,15 @@ pub trait Rpc {
captcha: String, captcha: String,
) -> Result<Value, ErrorObjectOwned>; ) -> Result<Value, ErrorObjectOwned>;
#[method(name = "startChangeNumber", param_kind = map)]
fn start_change_number(
&self,
account: Option<String>,
number: String,
voice: bool,
captcha: Option<String>,
) -> Result<Value, ErrorObjectOwned>;
#[method(name = "startLink", param_kind = map)] #[method(name = "startLink", param_kind = map)]
fn start_link(&self, account: Option<String>) -> Result<JsonLink, ErrorObjectOwned>; fn start_link(&self, account: Option<String>) -> Result<JsonLink, ErrorObjectOwned>;
@ -234,18 +278,20 @@ pub trait Rpc {
#[allow(non_snake_case)] deleteAccount: bool, #[allow(non_snake_case)] deleteAccount: bool,
) -> Result<Value, ErrorObjectOwned>; ) -> Result<Value, ErrorObjectOwned>;
#[allow(non_snake_case)]
#[method(name = "updateAccount", param_kind = map)] #[method(name = "updateAccount", param_kind = map)]
fn update_account( fn update_account(
&self, &self,
account: Option<String>, account: Option<String>,
#[allow(non_snake_case)] deviceName: Option<String>, deviceName: Option<String>,
unrestrictedUnidentifiedSender: Option<bool>,
) -> Result<Value, ErrorObjectOwned>; ) -> Result<Value, ErrorObjectOwned>;
#[method(name = "updateConfiguration", param_kind = map)] #[method(name = "updateConfiguration", param_kind = map)]
fn update_configuration( fn update_configuration(
&self, &self,
account: Option<String>, account: Option<String>,
#[allow(non_snake_case)] readReceiptes: Option<bool>, #[allow(non_snake_case)] readReceipts: Option<bool>,
#[allow(non_snake_case)] unidentifiedDeliveryIndicators: Option<bool>, #[allow(non_snake_case)] unidentifiedDeliveryIndicators: Option<bool>,
#[allow(non_snake_case)] typingIndicators: Option<bool>, #[allow(non_snake_case)] typingIndicators: Option<bool>,
#[allow(non_snake_case)] linkPreviews: Option<bool>, #[allow(non_snake_case)] linkPreviews: Option<bool>,

View file

@ -1,13 +1,14 @@
use std::{path::PathBuf, time::Duration}; use std::{path::PathBuf, time::Duration};
use clap::Parser; use clap::Parser;
use cli::Cli;
use jsonrpsee::core::client::{Subscription, SubscriptionClientT}; use jsonrpsee::core::client::{Subscription, SubscriptionClientT};
use jsonrpsee::core::Error as RpcError; use jsonrpsee::core::Error as RpcError;
use serde_json::Value; use serde_json::Value;
use tokio::{select, time::sleep}; use tokio::{select, time::sleep};
use crate::cli::{GroupPermission, LinkState}; use cli::Cli;
use crate::cli::{CliCommands, GroupPermission, LinkState};
use crate::jsonrpc::RpcClient; use crate::jsonrpc::RpcClient;
mod cli; mod cli;
@ -38,7 +39,7 @@ async fn handle_command(
client: impl SubscriptionClientT + Sync, client: impl SubscriptionClientT + Sync,
) -> Result<Value, RpcError> { ) -> Result<Value, RpcError> {
match cli.command { match cli.command {
cli::CliCommands::Receive { timeout } => { CliCommands::Receive { timeout } => {
let mut stream = client.subscribe_receive(cli.account).await?; let mut stream = client.subscribe_receive(cli.account).await?;
{ {
@ -50,21 +51,21 @@ async fn handle_command(
stream.unsubscribe().await?; stream.unsubscribe().await?;
Ok(Value::Null) Ok(Value::Null)
} }
cli::CliCommands::AddDevice { uri } => client.add_device(cli.account, uri).await, CliCommands::AddDevice { uri } => client.add_device(cli.account, uri).await,
cli::CliCommands::Block { CliCommands::Block {
recipient, recipient,
group_id, group_id,
} => client.block(cli.account, recipient, group_id).await, } => client.block(cli.account, recipient, group_id).await,
cli::CliCommands::DeleteLocalAccountData { ignore_registered } => { CliCommands::DeleteLocalAccountData { ignore_registered } => {
client client
.delete_local_account_data(cli.account, ignore_registered) .delete_local_account_data(cli.account, ignore_registered)
.await .await
} }
cli::CliCommands::GetUserStatus { recipient } => { CliCommands::GetUserStatus { recipient } => {
client.get_user_status(cli.account, recipient).await client.get_user_status(cli.account, recipient).await
} }
cli::CliCommands::JoinGroup { uri } => client.join_group(cli.account, uri).await, CliCommands::JoinGroup { uri } => client.join_group(cli.account, uri).await,
cli::CliCommands::Link { name } => { CliCommands::Link { name } => {
let url = client let url = client
.start_link(cli.account) .start_link(cli.account)
.await .await
@ -73,8 +74,8 @@ async fn handle_command(
println!("{}", url); println!("{}", url);
client.finish_link(url, name).await client.finish_link(url, name).await
} }
cli::CliCommands::ListAccounts => client.list_accounts().await, CliCommands::ListAccounts => client.list_accounts().await,
cli::CliCommands::ListContacts { CliCommands::ListContacts {
recipient, recipient,
all_recipients, all_recipients,
blocked, blocked,
@ -84,16 +85,14 @@ async fn handle_command(
.list_contacts(cli.account, recipient, all_recipients, blocked, name) .list_contacts(cli.account, recipient, all_recipients, blocked, name)
.await .await
} }
cli::CliCommands::ListDevices => client.list_devices(cli.account).await, CliCommands::ListDevices => client.list_devices(cli.account).await,
cli::CliCommands::ListGroups { CliCommands::ListGroups {
detailed: _, detailed: _,
group_id, group_id,
} => client.list_groups(cli.account, group_id).await, } => client.list_groups(cli.account, group_id).await,
cli::CliCommands::ListIdentities { number } => { CliCommands::ListIdentities { number } => client.list_identities(cli.account, number).await,
client.list_identities(cli.account, number).await CliCommands::ListStickerPacks => client.list_sticker_packs(cli.account).await,
} CliCommands::QuitGroup {
cli::CliCommands::ListStickerPacks => client.list_sticker_packs(cli.account).await,
cli::CliCommands::QuitGroup {
group_id, group_id,
delete, delete,
admin, admin,
@ -102,17 +101,23 @@ async fn handle_command(
.quit_group(cli.account, group_id, delete, admin) .quit_group(cli.account, group_id, delete, admin)
.await .await
} }
cli::CliCommands::Register { voice, captcha } => { CliCommands::Register { voice, captcha } => {
client.register(cli.account, voice, captcha).await client.register(cli.account, voice, captcha).await
} }
cli::CliCommands::RemoveContact { recipient, forget } => { CliCommands::RemoveContact {
client.remove_contact(cli.account, recipient, forget).await recipient,
forget,
hide,
} => {
client
.remove_contact(cli.account, recipient, forget, hide)
.await
} }
cli::CliCommands::RemoveDevice { device_id } => { CliCommands::RemoveDevice { device_id } => {
client.remove_device(cli.account, device_id).await client.remove_device(cli.account, device_id).await
} }
cli::CliCommands::RemovePin => client.remove_pin(cli.account).await, CliCommands::RemovePin => client.remove_pin(cli.account).await,
cli::CliCommands::RemoteDelete { CliCommands::RemoteDelete {
target_timestamp, target_timestamp,
recipient, recipient,
group_id, group_id,
@ -128,7 +133,7 @@ async fn handle_command(
) )
.await .await
} }
cli::CliCommands::Send { CliCommands::Send {
recipient, recipient,
group_id, group_id,
note_to_self, note_to_self,
@ -136,14 +141,21 @@ async fn handle_command(
message, message,
attachment, attachment,
mention, mention,
text_style,
quote_timestamp, quote_timestamp,
quote_author, quote_author,
quote_message, quote_message,
quote_mention, quote_mention,
quote_text_style,
quote_attachment, quote_attachment,
preview_url,
preview_title,
preview_description,
preview_image,
sticker, sticker,
story_timestamp, story_timestamp,
story_author, story_author,
edit_timestamp,
} => { } => {
client client
.send( .send(
@ -155,19 +167,26 @@ async fn handle_command(
message.unwrap_or_default(), message.unwrap_or_default(),
attachment, attachment,
mention, mention,
text_style,
quote_timestamp, quote_timestamp,
quote_author, quote_author,
quote_message, quote_message,
quote_mention, quote_mention,
quote_text_style,
quote_attachment, quote_attachment,
preview_url,
preview_title,
preview_description,
preview_image,
sticker, sticker,
story_timestamp, story_timestamp,
story_author, story_author,
edit_timestamp,
) )
.await .await
} }
cli::CliCommands::SendContacts => client.send_contacts(cli.account).await, CliCommands::SendContacts => client.send_contacts(cli.account).await,
cli::CliCommands::SendPaymentNotification { CliCommands::SendPaymentNotification {
recipient, recipient,
receipt, receipt,
note, note,
@ -176,7 +195,7 @@ async fn handle_command(
.send_payment_notification(cli.account, recipient, receipt, note) .send_payment_notification(cli.account, recipient, receipt, note)
.await .await
} }
cli::CliCommands::SendReaction { CliCommands::SendReaction {
recipient, recipient,
group_id, group_id,
note_to_self, note_to_self,
@ -200,7 +219,7 @@ async fn handle_command(
) )
.await .await
} }
cli::CliCommands::SendReceipt { CliCommands::SendReceipt {
recipient, recipient,
target_timestamp, target_timestamp,
r#type, r#type,
@ -217,8 +236,8 @@ async fn handle_command(
) )
.await .await
} }
cli::CliCommands::SendSyncRequest => client.send_sync_request(cli.account).await, CliCommands::SendSyncRequest => client.send_sync_request(cli.account).await,
cli::CliCommands::SendTyping { CliCommands::SendTyping {
recipient, recipient,
group_id, group_id,
stop, stop,
@ -227,13 +246,13 @@ async fn handle_command(
.send_typing(cli.account, recipient, group_id, stop) .send_typing(cli.account, recipient, group_id, stop)
.await .await
} }
cli::CliCommands::SetPin { pin } => client.set_pin(cli.account, pin).await, CliCommands::SetPin { pin } => client.set_pin(cli.account, pin).await,
cli::CliCommands::SubmitRateLimitChallenge { challenge, captcha } => { CliCommands::SubmitRateLimitChallenge { challenge, captcha } => {
client client
.submit_rate_limit_challenge(cli.account, challenge, captcha) .submit_rate_limit_challenge(cli.account, challenge, captcha)
.await .await
} }
cli::CliCommands::Trust { CliCommands::Trust {
recipient, recipient,
trust_all_known_keys, trust_all_known_keys,
verified_safety_number, verified_safety_number,
@ -247,17 +266,22 @@ async fn handle_command(
) )
.await .await
} }
cli::CliCommands::Unblock { CliCommands::Unblock {
recipient, recipient,
group_id, group_id,
} => client.unblock(cli.account, recipient, group_id).await, } => client.unblock(cli.account, recipient, group_id).await,
cli::CliCommands::Unregister { delete_account } => { CliCommands::Unregister { delete_account } => {
client.unregister(cli.account, delete_account).await client.unregister(cli.account, delete_account).await
} }
cli::CliCommands::UpdateAccount { device_name } => { CliCommands::UpdateAccount {
client.update_account(cli.account, device_name).await device_name,
unrestricted_unidentified_sender,
} => {
client
.update_account(cli.account, device_name, unrestricted_unidentified_sender)
.await
} }
cli::CliCommands::UpdateConfiguration { CliCommands::UpdateConfiguration {
read_receipts, read_receipts,
unidentified_delivery_indicators, unidentified_delivery_indicators,
typing_indicators, typing_indicators,
@ -273,7 +297,7 @@ async fn handle_command(
) )
.await .await
} }
cli::CliCommands::UpdateContact { CliCommands::UpdateContact {
recipient, recipient,
expiration, expiration,
name, name,
@ -282,7 +306,7 @@ async fn handle_command(
.update_contact(cli.account, recipient, name, expiration) .update_contact(cli.account, recipient, name, expiration)
.await .await
} }
cli::CliCommands::UpdateGroup { CliCommands::UpdateGroup {
group_id, group_id,
name, name,
description, description,
@ -335,7 +359,7 @@ async fn handle_command(
) )
.await .await
} }
cli::CliCommands::UpdateProfile { CliCommands::UpdateProfile {
given_name, given_name,
family_name, family_name,
about, about,
@ -357,14 +381,42 @@ async fn handle_command(
) )
.await .await
} }
cli::CliCommands::UploadStickerPack { path } => { CliCommands::UploadStickerPack { path } => {
client.upload_sticker_pack(cli.account, path).await client.upload_sticker_pack(cli.account, path).await
} }
cli::CliCommands::Verify { CliCommands::Verify {
verification_code, verification_code,
pin, pin,
} => client.verify(cli.account, verification_code, pin).await, } => client.verify(cli.account, verification_code, pin).await,
cli::CliCommands::Version => client.version().await, CliCommands::Version => client.version().await,
CliCommands::AddStickerPack { uri } => client.add_sticker_pack(cli.account, uri).await,
CliCommands::FinishChangeNumber {
number,
verification_code,
pin,
} => {
client
.finish_change_number(cli.account, number, verification_code, pin)
.await
}
CliCommands::GetAttachment {
id,
recipient,
group_id,
} => {
client
.get_attachment(cli.account, id, recipient, group_id)
.await
}
CliCommands::StartChangeNumber {
number,
voice,
captcha,
} => {
client
.start_change_number(cli.account, number, voice, captcha)
.await
}
} }
} }