Skip to content
Merged
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Possible use-cases:
| :white_check_mark: | User Notifications |
| :white_check_mark: | User |
| :x: | Creator Store |
| :x: | Luau Execution |
| :white_check_mark: | Luau Execution |

- :white_check_mark: = Supported
- :x: = Not yet supported
Expand Down
54 changes: 54 additions & 0 deletions docs/cli/cli-luau-execution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Luau Execution API

# Execute Task
Executes Luau code on Roblox.
```
Usage: rbxcloud luau execute [OPTIONS] --universe-id <UNIVERSE_ID> --place-id <PLACE_ID> --api-key <API_KEY>

Options:
-u, --universe-id <UNIVERSE_ID> Universe ID of the experience
-i, --place-id <PLACE_ID> Place ID of the experience
-r, --version-id <VERSION_ID> Version ID of the experience
-s, --script <SCRIPT> Script source code
-f, --filepath <FILEPATH> Script source code file
-t, --timeout <TIMEOUT> Execution timeout
-p, --pretty Pretty-print the JSON response
-a, --api-key <API_KEY> Roblox Open Cloud API Key [env: RBXCLOUD_API_KEY=]
-h, --help Print help
```

## Get Task Information
Gets information on a previously executed task.

```
Usage: rbxcloud luau get-task [OPTIONS] --universe-id <UNIVERSE_ID> --place-id <PLACE_ID> --session-id <SESSION_ID> --task-id <TASK_ID> --api-key <API_KEY>

Options:
-u, --universe-id <UNIVERSE_ID> Universe ID of the experience
-i, --place-id <PLACE_ID> Place ID of the experience
-r, --version-id <VERSION_ID> Version ID of the experience
-s, --session-id <SESSION_ID> Luau execution session ID
-t, --task-id <TASK_ID> Luau execution task ID
-p, --pretty Pretty-print the JSON response
-a, --api-key <API_KEY> Roblox Open Cloud API Key [env: RBXCLOUD_API_KEY=]
-h, --help Print help
```

## Get Task Logs
Retrieves logs on a previously executed task.
```
Usage: rbxcloud.exe luau get-logs [OPTIONS] --universe-id <UNIVERSE_ID> --place-id <PLACE_ID> --session-id <SESSION_ID> --task-id <TASK_ID> --api-key <API_KEY>

Options:
-u, --universe-id <UNIVERSE_ID> Universe ID of the experience
-i, --place-id <PLACE_ID> Place ID of the experience
-r, --version-id <VERSION_ID> Version ID of the experience
-s, --session-id <SESSION_ID> Luau execution session ID
-t, --task-id <TASK_ID> Luau execution task ID
-m, --max-page-size <MAX_PAGE_SIZE> Max page size
-n, --page-token <PAGE_TOKEN> Next page token
-w, --view <VIEW> Log view type [possible values: flat, structured]
-p, --pretty Pretty-print the JSON response
-a, --api-key <API_KEY> Roblox Open Cloud API Key [env: RBXCLOUD_API_KEY=]
-h, --help Print help
```
11 changes: 6 additions & 5 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@ nav:
- Home: index.md
- CLI:
- Install: cli/cli-install.md
- Assets: cli/cli-assets.md
- API Key: cli/cli-api-key.md
- Experience: cli/cli-experience.md
- Messaging: cli/cli-messaging.md
- Assets: cli/cli-assets.md
- DataStore: cli/cli-datastore.md
- OrderedDataStore: cli/cli-ordered-datastore.md
- Experience: cli/cli-experience.md
- Group: cli/cli-group.md
- Subscription: cli/cli-subscription.md
- Luau Execution: cli/cli-luau-execution.md
- Messaging: cli/cli-messaging.md
- Notification: cli/cli-notification.md
- OrderedDataStore: cli/cli-ordered-datastore.md
- Place: cli/cli-place.md
- Subscription: cli/cli-subscription.md
- Universe: cli/cli-universe.md
- User: cli/cli-user.md
- Rust Lib:
Expand Down
237 changes: 237 additions & 0 deletions src/cli/luau_execution_cli.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
use clap::{Args, Subcommand};
use rbxcloud::rbx::{
types::{PlaceId, UniverseId},
v2::{luau_execution::LuauExecutionTaskLogView, Client},
};
use tokio::fs;

#[derive(Debug, Subcommand)]
pub enum LuauExecutionCommands {
/// Executes Luau code on Roblox
Execute {
/// Universe ID of the experience
#[clap(short, long, value_parser)]
universe_id: u64,

/// Place ID of the experience
#[clap(short = 'i', long, value_parser)]
place_id: u64,

/// Version ID of the experience
#[clap(short = 'r', long, value_parser)]
version_id: Option<String>,

/// Script source code
#[clap(short, long, value_parser)]
script: Option<String>,

/// Script source code file
#[clap(short, long, value_parser)]
filepath: Option<String>,

/// Execution timeout
#[clap(short, long, value_parser)]
timeout: Option<String>,

/// Pretty-print the JSON response
#[clap(short, long, value_parser, default_value_t = false)]
pretty: bool,

/// Roblox Open Cloud API Key
#[clap(short, long, value_parser, env = "RBXCLOUD_API_KEY")]
api_key: String,
},

/// Gets information on a previously executed task
GetTask {
/// Universe ID of the experience
#[clap(short, long, value_parser)]
universe_id: u64,

/// Place ID of the experience
#[clap(short = 'i', long, value_parser)]
place_id: u64,

/// Version ID of the experience
#[clap(short = 'r', long, value_parser)]
version_id: Option<String>,

/// Luau execution session ID
#[clap(short, long, value_parser)]
session_id: String,

/// Luau execution task ID
#[clap(short, long, value_parser)]
task_id: String,

/// Pretty-print the JSON response
#[clap(short, long, value_parser, default_value_t = false)]
pretty: bool,

/// Roblox Open Cloud API Key
#[clap(short, long, value_parser, env = "RBXCLOUD_API_KEY")]
api_key: String,
},

/// Retrieves logs on a previously executed task
GetLogs {
/// Universe ID of the experience
#[clap(short, long, value_parser)]
universe_id: u64,

/// Place ID of the experience
#[clap(short = 'i', long, value_parser)]
place_id: u64,

/// Version ID of the experience
#[clap(short = 'r', long, value_parser)]
version_id: Option<String>,

/// Luau execution session ID
#[clap(short, long, value_parser)]
session_id: String,

/// Luau execution task ID
#[clap(short, long, value_parser)]
task_id: String,

/// Max page size
#[clap(short, long, value_parser)]
max_page_size: Option<u32>,

/// Next page token
#[clap(short = 'n', long, value_parser)]
page_token: Option<String>,

/// Log view type
#[clap(short = 'w', long, value_enum)]
view: Option<LuauExecutionTaskLogView>,

/// Pretty-print the JSON response
#[clap(short, long, value_parser, default_value_t = false)]
pretty: bool,

/// Roblox Open Cloud API Key
#[clap(short, long, value_parser, env = "RBXCLOUD_API_KEY")]
api_key: String,
},
}

#[derive(Debug, Args)]
pub struct Luau {
#[clap(subcommand)]
command: LuauExecutionCommands,
}

impl Luau {
pub async fn run(self) -> anyhow::Result<Option<String>> {
match self.command {
LuauExecutionCommands::Execute {
universe_id,
place_id,
version_id,
script,
filepath,
timeout,
pretty,
api_key,
} => {
let client = Client::new(&api_key);

let luau = client.luau(UniverseId(universe_id), PlaceId(place_id), version_id);

let mut script_source: Option<String> = None;
if script.is_some() {
script_source = script;
}

if script_source.is_none() {
if let Some(path) = filepath {
let src_bytes = fs::read(path).await?;
script_source = Some(String::from_utf8(src_bytes)?);
}
}

let src = script_source.expect("script or filepath must be set");

let res = luau.create_task(src, timeout).await;
match res {
Ok(data) => {
let r = if pretty {
serde_json::to_string_pretty(&data)?
} else {
serde_json::to_string(&data)?
};
Ok(Some(r))
}
Err(err) => Err(anyhow::anyhow!(err)),
}
}

LuauExecutionCommands::GetTask {
universe_id,
place_id,
version_id,
session_id,
task_id,
pretty,
api_key,
} => {
let client = Client::new(&api_key);

let luau = client.luau(UniverseId(universe_id), PlaceId(place_id), version_id);

let res = luau.get_task(session_id, task_id).await;
match res {
Ok(data) => {
let r = if pretty {
serde_json::to_string_pretty(&data)?
} else {
serde_json::to_string(&data)?
};
Ok(Some(r))
}
Err(err) => Err(anyhow::anyhow!(err)),
}
}

LuauExecutionCommands::GetLogs {
universe_id,
place_id,
version_id,
session_id,
task_id,
max_page_size,
page_token,
view,
pretty,
api_key,
} => {
let client = Client::new(&api_key);

let luau = client.luau(UniverseId(universe_id), PlaceId(place_id), version_id);

let res = luau
.get_logs(
session_id,
task_id,
view.unwrap_or(LuauExecutionTaskLogView::Flat),
max_page_size,
page_token,
)
.await;
match res {
Ok(data) => {
let r = if pretty {
serde_json::to_string_pretty(&data)?
} else {
serde_json::to_string(&data)?
};
Ok(Some(r))
}
Err(err) => Err(anyhow::anyhow!(err)),
}
}
}
}
}
5 changes: 5 additions & 0 deletions src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ mod assets_cli;
mod datastore_cli;
mod experience_cli;
mod group_cli;
mod luau_execution_cli;
mod messaging_cli;
mod notification_cli;
mod ordered_datastore_cli;
Expand All @@ -11,6 +12,7 @@ mod universe_cli;
mod user_cli;

use clap::{Parser, Subcommand};
use luau_execution_cli::Luau;
use universe_cli::Universe;
use user_cli::User;

Expand Down Expand Up @@ -47,6 +49,8 @@ pub enum Command {
/// Access the Roblox Group API
Group(Group),

Luau(Luau),

/// Access the Roblox Subscription API
Subscription(Subscription),

Expand All @@ -72,6 +76,7 @@ impl Cli {
Command::Datastore(command) => command.run().await,
Command::OrderedDatastore(command) => command.run().await,
Command::Group(command) => command.run().await,
Command::Luau(command) => command.run().await,
Command::Subscription(command) => command.run().await,
Command::Notification(command) => command.run().await,
Command::Place(command) => command.run().await,
Expand Down
6 changes: 4 additions & 2 deletions src/rbx/types.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use serde::{Deserialize, Serialize};

/// Represents the UniverseId of a Roblox experience.
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct UniverseId(pub u64);

/// Represents the PlaceId of a specific place within a Roblox experience.
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct PlaceId(pub u64);

// Number of items to return.
Expand Down
Loading