pub struct Packet {
pub opcode: Opcode,
pub payload: Value,
}Expand description
Represents a Discord IPC message packet.
Fields§
§opcode: Opcode§payload: ValueImplementations§
Source§impl Packet
impl Packet
Sourcepub fn new(opcode: Opcode, payload: impl Into<Value>) -> Self
pub fn new(opcode: Opcode, payload: impl Into<Value>) -> Self
Creates a new packet with the given opcode and payload.
§Arguments
opcode: The Opcode for the packet.payload: Data that can be converted into a JSONValue.
Examples found in repository?
examples/01_basics.rs (line 39)
7fn main() -> Result<(), Box<dyn std::error::Error>> {
8 // === Build a client ===
9
10 // Build your client instance (with your own application ID)
11 // You can create one in https://discord.com/developers/applications
12 let client = Client::new("<application_id>");
13
14 // Listen to "READY" event
15 // The "READY" event is triggered when the client has successfully connected to Discord
16 // and is ready to receive and send packets.
17 client.on("READY", |client, _packet| {
18 println!("Connected");
19 // You will receive as arguments a reference to the client instance you created and the incoming Discord packet.
20 // Once the client is connected, you can start interacting with Discord's IPC.
21
22 // === Build a packet ===
23 // A packet is built from an opcode and a payload.
24 // The opcode establishes the kind of operation to be performed
25 // The most common opcodes are Opcode::Frame (1) and Opcode::Ping (3).
26 // Frame is used for most operations, while Ping is only used to ping Discord.
27 let opcode = Opcode::Ping;
28 // The payload contains the command data in JSON format in addition to a
29 // unique nonce for identifying the packet exchange.
30 // The payload of a ping packet is optional; you can send an empty value if you prefer.
31 // You can listen to the opcode (4)Pong to handle the response
32 // or you can include a "nonce" field in the payload.
33 let nonce = Packet::generate_nonce();
34 let payload = json!({
35 "nonce": nonce,
36 "example_field": "ping"
37 });
38
39 let ping = Packet::new(opcode, payload);
40
41 // === Listen for a response ===
42 client.once(nonce, |_client, packet| {
43 // If you receive this, the ping was successful.
44 println!("Pong!");
45 // The received packet has the opcode (4)Pong and has the same payload as the one sent before.
46 println!("{}", packet);
47 });
48
49 // === Send the packet ===
50 // Once you set up the listener, you can now send your packet
51 if let Err(e) = client.send(ping) {
52 eprintln!("Couldn't send packet: {}", e)
53 };
54 // When a response is received, the listener will be triggered.
55 });
56
57 // Try to connect
58 client.connect()?;
59 std::io::stdin().read_line(&mut String::new()).unwrap();
60 client.disconnect()?;
61 println!("Disconnected");
62
63 Ok(())
64}Sourcepub fn new_activity(activity: Option<&Activity>, nonce: Option<&str>) -> Self
pub fn new_activity(activity: Option<&Activity>, nonce: Option<&str>) -> Self
Creates a new activity packet for Discord IPC.
§Arguments
activity: Optional Activity. PassNoneto clear.nonce: Optional nonce string.
Examples found in repository?
examples/00_simple.rs (line 32)
7fn main() -> Result<(), Box<dyn std::error::Error>> {
8 // Build your client instance (with your own application ID)
9 // You can create one in https://discord.com/developers/applications
10 let client = Client::new_simple("<application_id>");
11
12 // `connect_and_wait()` is a blocking method that sends a connection request,
13 // waits for a direct response, and returns the response packet.
14 let connection_response = client.connect_and_wait()?;
15
16 // You can use `filter()` in any packet to search for an error response.
17 match connection_response.filter() {
18 Ok(_packet) => println!("Connected"),
19 Err(e) => {
20 eprintln!("Couldn't connect to Discord: {}", e);
21 return Ok(());
22 }
23 }
24
25 // === Set an activity ===
26 let activity = Activity::new().details("Simple activity");
27
28 // Build an activity packet.
29 // Pass Some(&activity) to set an activity or None to clear it.
30 // The second argument is a nonce used to identify a packet exchange, but it's not needed here,
31 // since `send_and_wait()` already waits for a direct response.
32 let packet = Packet::new_activity(Some(&activity), None);
33
34 // You can use `filter()` in `send_and_wait()` as it returns a packet
35 match client.send_and_wait(packet)?.filter() {
36 Ok(_packet) => println!("Activity has been set!"),
37 Err(e) => eprintln!("Couldn't set activity: {}", e),
38 };
39
40 std::thread::sleep(std::time::Duration::from_secs(10));
41
42 // === Clear the activity ===
43 let packet = Packet::new_activity(None, None);
44 match client.send_and_wait(packet)?.filter() {
45 Ok(_packet) => println!("Activity has been cleared!"),
46 Err(e) => eprintln!("Couldn't clear activity: {}", e),
47 };
48
49 std::thread::sleep(std::time::Duration::from_secs(3));
50 client.disconnect()?;
51 println!("Disconnected");
52
53 Ok(())
54}More examples
examples/02_activity.rs (line 40)
7fn main() -> Result<()> {
8 let client = Client::new("<application_id>");
9
10 client.on("READY", |client, _packet| {
11 println!("Connected");
12
13 // === Create an activity ===
14
15 // You can create activities this way... (recommended)
16 let activity = Activity::new()
17 .details("In Workspace: test")
18 .state("Dealing with proc-macros")
19 .timestamps(Timestamps::new().start_now())
20 .button(Button::new("Get started!", "https://rustup.rs/"));
21
22 // Or this way...
23 let _activity = Activity {
24 details: Some("In Workspace: test".to_string()),
25 state: Some("Dealing with proc-macros".to_string()),
26 timestamps: Some(Timestamps::new().start_now()),
27 buttons: Some(vec![Button {
28 label: "Get started!".to_string(),
29 url: "https://rustup.rs/".to_string(),
30 }]),
31 ..Activity::default()
32 };
33 // Note that this method is more susceptible to errors as it skips structural checks.
34
35 // === Build the packet ===
36 let nonce = Packet::generate_nonce(); // Unique nonce for identifying the packet exchange
37
38 // You can manually build the activity packet with Packet::new()
39 // or you can use Packet::new_activity()
40 let activity_packet = Packet::new_activity(Some(&activity), Some(&nonce));
41
42 // === Listen for a response ===
43 client.once(nonce, |client, packet| {
44 // Setting up an activity is an operation that could fail,
45 // so the packet payload may contain a success or an error.
46 // You can use packet.filter() to automatically search for errors in its payload.
47 match packet.filter() {
48 Ok(_packet) => {
49 println!("Activity has been set!");
50
51 std::thread::sleep(std::time::Duration::from_secs(10));
52
53 if let Err(e) = client.send(Packet::new_activity(None, None)) {
54 eprintln!("Couldn't send packet: {}", e)
55 };
56 println!("Activity cleared!");
57 }
58 Err(e) => println!("Couldn't set activity: {}", e),
59 }
60 });
61
62 // Once you set up the listener, you can now send the activity packet.
63 if let Err(e) = client.send(activity_packet) {
64 eprintln!("Couldn't send packet: {}", e)
65 };
66 });
67
68 // Try to connect
69 client.connect()?;
70 std::io::stdin().read_line(&mut String::new()).unwrap();
71 client.disconnect()?;
72 println!("Disconnected");
73
74 Ok(())
75}Sourcepub fn generate_nonce() -> String
pub fn generate_nonce() -> String
Generates a unique nonce using UUID v4.
Examples found in repository?
examples/01_basics.rs (line 33)
7fn main() -> Result<(), Box<dyn std::error::Error>> {
8 // === Build a client ===
9
10 // Build your client instance (with your own application ID)
11 // You can create one in https://discord.com/developers/applications
12 let client = Client::new("<application_id>");
13
14 // Listen to "READY" event
15 // The "READY" event is triggered when the client has successfully connected to Discord
16 // and is ready to receive and send packets.
17 client.on("READY", |client, _packet| {
18 println!("Connected");
19 // You will receive as arguments a reference to the client instance you created and the incoming Discord packet.
20 // Once the client is connected, you can start interacting with Discord's IPC.
21
22 // === Build a packet ===
23 // A packet is built from an opcode and a payload.
24 // The opcode establishes the kind of operation to be performed
25 // The most common opcodes are Opcode::Frame (1) and Opcode::Ping (3).
26 // Frame is used for most operations, while Ping is only used to ping Discord.
27 let opcode = Opcode::Ping;
28 // The payload contains the command data in JSON format in addition to a
29 // unique nonce for identifying the packet exchange.
30 // The payload of a ping packet is optional; you can send an empty value if you prefer.
31 // You can listen to the opcode (4)Pong to handle the response
32 // or you can include a "nonce" field in the payload.
33 let nonce = Packet::generate_nonce();
34 let payload = json!({
35 "nonce": nonce,
36 "example_field": "ping"
37 });
38
39 let ping = Packet::new(opcode, payload);
40
41 // === Listen for a response ===
42 client.once(nonce, |_client, packet| {
43 // If you receive this, the ping was successful.
44 println!("Pong!");
45 // The received packet has the opcode (4)Pong and has the same payload as the one sent before.
46 println!("{}", packet);
47 });
48
49 // === Send the packet ===
50 // Once you set up the listener, you can now send your packet
51 if let Err(e) = client.send(ping) {
52 eprintln!("Couldn't send packet: {}", e)
53 };
54 // When a response is received, the listener will be triggered.
55 });
56
57 // Try to connect
58 client.connect()?;
59 std::io::stdin().read_line(&mut String::new()).unwrap();
60 client.disconnect()?;
61 println!("Disconnected");
62
63 Ok(())
64}More examples
examples/02_activity.rs (line 36)
7fn main() -> Result<()> {
8 let client = Client::new("<application_id>");
9
10 client.on("READY", |client, _packet| {
11 println!("Connected");
12
13 // === Create an activity ===
14
15 // You can create activities this way... (recommended)
16 let activity = Activity::new()
17 .details("In Workspace: test")
18 .state("Dealing with proc-macros")
19 .timestamps(Timestamps::new().start_now())
20 .button(Button::new("Get started!", "https://rustup.rs/"));
21
22 // Or this way...
23 let _activity = Activity {
24 details: Some("In Workspace: test".to_string()),
25 state: Some("Dealing with proc-macros".to_string()),
26 timestamps: Some(Timestamps::new().start_now()),
27 buttons: Some(vec![Button {
28 label: "Get started!".to_string(),
29 url: "https://rustup.rs/".to_string(),
30 }]),
31 ..Activity::default()
32 };
33 // Note that this method is more susceptible to errors as it skips structural checks.
34
35 // === Build the packet ===
36 let nonce = Packet::generate_nonce(); // Unique nonce for identifying the packet exchange
37
38 // You can manually build the activity packet with Packet::new()
39 // or you can use Packet::new_activity()
40 let activity_packet = Packet::new_activity(Some(&activity), Some(&nonce));
41
42 // === Listen for a response ===
43 client.once(nonce, |client, packet| {
44 // Setting up an activity is an operation that could fail,
45 // so the packet payload may contain a success or an error.
46 // You can use packet.filter() to automatically search for errors in its payload.
47 match packet.filter() {
48 Ok(_packet) => {
49 println!("Activity has been set!");
50
51 std::thread::sleep(std::time::Duration::from_secs(10));
52
53 if let Err(e) = client.send(Packet::new_activity(None, None)) {
54 eprintln!("Couldn't send packet: {}", e)
55 };
56 println!("Activity cleared!");
57 }
58 Err(e) => println!("Couldn't set activity: {}", e),
59 }
60 });
61
62 // Once you set up the listener, you can now send the activity packet.
63 if let Err(e) = client.send(activity_packet) {
64 eprintln!("Couldn't send packet: {}", e)
65 };
66 });
67
68 // Try to connect
69 client.connect()?;
70 std::io::stdin().read_line(&mut String::new()).unwrap();
71 client.disconnect()?;
72 println!("Disconnected");
73
74 Ok(())
75}Sourcepub fn decode_header(header: &[u8; 8]) -> Result<(u32, u32)>
pub fn decode_header(header: &[u8; 8]) -> Result<(u32, u32)>
Decodes a Discord IPC response header.
§Errors
- DecodeError: If the header is malformed, incomplete, or cannot be decoded.
Sourcepub fn filter(self) -> Result<Packet, BadResponseError>
pub fn filter(self) -> Result<Packet, BadResponseError>
Checks for errors in a Discord IPC response payload.
§Returns
Ok(Packet)if no error is found.Err(BadResponseError)if there is an error.
See BadResponseError
Examples found in repository?
examples/00_simple.rs (line 17)
7fn main() -> Result<(), Box<dyn std::error::Error>> {
8 // Build your client instance (with your own application ID)
9 // You can create one in https://discord.com/developers/applications
10 let client = Client::new_simple("<application_id>");
11
12 // `connect_and_wait()` is a blocking method that sends a connection request,
13 // waits for a direct response, and returns the response packet.
14 let connection_response = client.connect_and_wait()?;
15
16 // You can use `filter()` in any packet to search for an error response.
17 match connection_response.filter() {
18 Ok(_packet) => println!("Connected"),
19 Err(e) => {
20 eprintln!("Couldn't connect to Discord: {}", e);
21 return Ok(());
22 }
23 }
24
25 // === Set an activity ===
26 let activity = Activity::new().details("Simple activity");
27
28 // Build an activity packet.
29 // Pass Some(&activity) to set an activity or None to clear it.
30 // The second argument is a nonce used to identify a packet exchange, but it's not needed here,
31 // since `send_and_wait()` already waits for a direct response.
32 let packet = Packet::new_activity(Some(&activity), None);
33
34 // You can use `filter()` in `send_and_wait()` as it returns a packet
35 match client.send_and_wait(packet)?.filter() {
36 Ok(_packet) => println!("Activity has been set!"),
37 Err(e) => eprintln!("Couldn't set activity: {}", e),
38 };
39
40 std::thread::sleep(std::time::Duration::from_secs(10));
41
42 // === Clear the activity ===
43 let packet = Packet::new_activity(None, None);
44 match client.send_and_wait(packet)?.filter() {
45 Ok(_packet) => println!("Activity has been cleared!"),
46 Err(e) => eprintln!("Couldn't clear activity: {}", e),
47 };
48
49 std::thread::sleep(std::time::Duration::from_secs(3));
50 client.disconnect()?;
51 println!("Disconnected");
52
53 Ok(())
54}More examples
examples/02_activity.rs (line 47)
7fn main() -> Result<()> {
8 let client = Client::new("<application_id>");
9
10 client.on("READY", |client, _packet| {
11 println!("Connected");
12
13 // === Create an activity ===
14
15 // You can create activities this way... (recommended)
16 let activity = Activity::new()
17 .details("In Workspace: test")
18 .state("Dealing with proc-macros")
19 .timestamps(Timestamps::new().start_now())
20 .button(Button::new("Get started!", "https://rustup.rs/"));
21
22 // Or this way...
23 let _activity = Activity {
24 details: Some("In Workspace: test".to_string()),
25 state: Some("Dealing with proc-macros".to_string()),
26 timestamps: Some(Timestamps::new().start_now()),
27 buttons: Some(vec![Button {
28 label: "Get started!".to_string(),
29 url: "https://rustup.rs/".to_string(),
30 }]),
31 ..Activity::default()
32 };
33 // Note that this method is more susceptible to errors as it skips structural checks.
34
35 // === Build the packet ===
36 let nonce = Packet::generate_nonce(); // Unique nonce for identifying the packet exchange
37
38 // You can manually build the activity packet with Packet::new()
39 // or you can use Packet::new_activity()
40 let activity_packet = Packet::new_activity(Some(&activity), Some(&nonce));
41
42 // === Listen for a response ===
43 client.once(nonce, |client, packet| {
44 // Setting up an activity is an operation that could fail,
45 // so the packet payload may contain a success or an error.
46 // You can use packet.filter() to automatically search for errors in its payload.
47 match packet.filter() {
48 Ok(_packet) => {
49 println!("Activity has been set!");
50
51 std::thread::sleep(std::time::Duration::from_secs(10));
52
53 if let Err(e) = client.send(Packet::new_activity(None, None)) {
54 eprintln!("Couldn't send packet: {}", e)
55 };
56 println!("Activity cleared!");
57 }
58 Err(e) => println!("Couldn't set activity: {}", e),
59 }
60 });
61
62 // Once you set up the listener, you can now send the activity packet.
63 if let Err(e) = client.send(activity_packet) {
64 eprintln!("Couldn't send packet: {}", e)
65 };
66 });
67
68 // Try to connect
69 client.connect()?;
70 std::io::stdin().read_line(&mut String::new()).unwrap();
71 client.disconnect()?;
72 println!("Disconnected");
73
74 Ok(())
75}Trait Implementations§
Auto Trait Implementations§
impl Freeze for Packet
impl RefUnwindSafe for Packet
impl Send for Packet
impl Sync for Packet
impl Unpin for Packet
impl UnsafeUnpin for Packet
impl UnwindSafe for Packet
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more