Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add modal support #9

Draft
wants to merge 16 commits into
base: main
Choose a base branch
from
Draft
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
3 changes: 2 additions & 1 deletion examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ members = [
"e6_components",
"e7_embeds",
"e8_managing_commands",
"e9_accessing_other_data"
"e9_accessing_other_data",
"e10_modals"
]
13 changes: 13 additions & 0 deletions examples/e10_modals/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "e10_modals"
version = "0.1.0"
authors = ["Hugo Woesthuis <hugow2011@outlook.com>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
rusty_interaction = {path = "../../", features=["extended-handler"]}
actix-web = "3"
dotenv = "0.13.0"
env_logger = "0"
20 changes: 20 additions & 0 deletions examples/e10_modals/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Example 9: Accessing other data

From version 0.2.0, the `InteractionHandler` has a field called `data`. This is used to access other data, like database connections for example.

You can add data to the handler using `InteractionHandler::add_data()`. The backbone is an `AnyMap` and shares the same syntax with accessing data.


# Result
![Peek 2021-07-29 21-53](https://user-images.githubusercontent.com/10338882/127557511-724e139a-4a5c-44cf-b403-6d270bbd8953.gif)


# Running this example
You can use regular `cargo build` and `cargo run` commands.

To run this example:

`cargo run`. Note that you'll need to edit the `PUB_KEY`, `APP_ID` and `TOKEN` constants accordingly (it will panic if you don't give a vaild key).

# Useful documentation
- [InteractionHandler](https://docs.rs/rusty_interaction/latest/rusty_interaction/handler/struct.InteractionHandler.html)
51 changes: 51 additions & 0 deletions examples/e10_modals/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#[macro_use]
extern crate rusty_interaction;

use rusty_interaction::handler::{InteractionHandler, ManipulationScope};
use rusty_interaction::types::components::*;
use rusty_interaction::types::interaction::*;
// Relevant imports here
use rusty_interaction::types::modal::{Modal, ModalBuilder};

use rusty_interaction::Builder;

const PUB_KEY: &str = "57028473720a7c1d4666132a68007f0902034a13c43cc2c1658b10b5fc754311";
const APP_ID: u64 = 615112470033596416;

#[slash_command]
async fn test(
handler: &mut InteractionHandler,
ctx: Context,
) -> Result<InteractionResponse, std::convert::Infallible> {
println!("Got trigger");
let test_modal = ModalBuilder::default()
.custom_id("TEST_MODAL")
.title("My Test Modal")
.add_component(
ComponentTextBoxBuilder::default()
.placeholder("Some placeholder")
.max_length(100) // Sets a maximum of 100 chars
.label("My label")
.custom_id("MODAL_TEXT_BOX")
.required(true)
.style(ComponentTextBoxStyle::Paragraph) // Sets the textbox to be a paragraph style textbox (multiline)
.build()
.unwrap(),
)
.build()
.unwrap();

Ok(ctx.respond_with_modal(test_modal))
}

// The lib uses actix-web
#[actix_web::main]
async fn main() -> std::io::Result<()> {
env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));

let mut handle = InteractionHandler::new(APP_ID, PUB_KEY, None);

handle.add_global_command("summon", test);

return handle.run(10080).await;
}
13 changes: 11 additions & 2 deletions src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ impl InteractionHandler {
self.data.insert(data);
}
/// Binds an async function to a **global** command.
/// Your function must take a [`Context`] as an argument and must return a [`InteractionResponse`].
/// Your function must take a [`Context`] and optionally an [`InteractionHandler`] as an argument and must return a [`InteractionResponse`].
/// Make sure to use the `#[slash_command]` procedural macro to make it usable for the handler.
///
/// Like:
Expand Down Expand Up @@ -222,7 +222,7 @@ impl InteractionHandler {
}

/// Binds an async function to a **component**.
/// Your function must take a [`Context`] as an argument and must return a [`InteractionResponse`].
/// Your function must take a [`Context`] and optionally an [`InteractionHandler`] as an argument and must return a [`InteractionResponse`].
/// Use the `#[component_handler]` procedural macro for your own convinence.eprintln!
///
/// # Example
Expand Down Expand Up @@ -465,6 +465,7 @@ impl InteractionHandler {
match serde_json::from_str::<Interaction>(&body) {
Err(e) => {
// It's probably bad on our end if this code is reached.
// Could be that new features were implemented and breaks code
error!("Failed to decode interaction! Error: {}", e);
debug!("Body sent: {}", body);
return ERROR_RESPONSE!(400, format!("Bad body: {}", e));
Expand Down Expand Up @@ -546,6 +547,14 @@ impl InteractionHandler {
ERROR_RESPONSE!(501, "No associated handler found")
}
}
InteractionType::ApplicationCommandAutocomplete => {
//TODO: Implement autocomplete stuff
unimplemented!();
}
InteractionType::ModalSubmit => {
//TODO: Implement Modal submit event
unimplemented!();
}
}
}
}
Expand Down
15 changes: 8 additions & 7 deletions src/security.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use ed25519_dalek::Verifier;
use ed25519_dalek::{PublicKey, Signature};

use std::convert::TryInto;
/// If verification fails, it will return the `ValidationError` enum.
pub enum ValidationError {
/// For anything related to conversion errors
Expand All @@ -22,13 +22,14 @@ pub fn verify_discord_message(
body: &str,
) -> Result<(), ValidationError> {
let signature_bytes = hex::decode(signature)
.map_err(|_| ValidationError::KeyConversionError { name: "Signature" })?;
.map_err(|_| ValidationError::KeyConversionError { name: "Hex conversion" })?;

let signature_bytes: [u8; 64] = signature_bytes.try_into()
.map_err(|_| ValidationError::KeyConversionError {
name: "Signature Length",
})?;

let signature = Signature::from_bytes(signature_bytes.as_slice()).map_err(|_| {
ValidationError::KeyConversionError {
name: "From bytes conversion error",
}
})?;
let signature = Signature::new(signature_bytes);

// Format the data to verify (Timestamp + body)
let msg = format!("{}{}", timestamp, body);
Expand Down
Loading