Skip to content

ByteAlex/worker-wasm-interactions-rs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Cloudflare Worker WASM Interactions for Rust

Latest Version

Simply build your interaction based discord bot on Cloudflare Workers using Rust.

Example Code

use phf::phf_map;
use worker::*;
use worker_wasm_interactions_rs::{CustomIdPattern, Interactions, RouterExt};
use worker_wasm_interactions_rs::twilight_model::guild::PartialMember;
use worker_wasm_interactions_rs::twilight_model::id::Id;

static GENDERS: phf::Map<&'static str, u64> = phf_map! {
    "male" => 1031539478478721064,
    "female" => 1031539718460018758,
    "non-binary" => 1031539776123322418,
};

fn log_request(req: &Request) {
    console_log!(
        "{} - [{}]",
        Date::now().to_string(),
        req.path(),
    );
}

#[event(fetch)]
pub async fn main(req: Request, env: Env, _ctx: Context) -> Result<Response> {
    log_request(&req);

    let mut interactions = Interactions::new(env.secret("DISCORD_PUBLIC_KEY")?.to_string(),
                                             env.secret("DISCORD_TOKEN")?.to_string());

    interactions.register_application_command_handler("ping", |context| async move {
        context.followup(true, |builder| {
            builder.content("Pong");
        })
    });

    interactions.register_message_component_handler(CustomIdPattern::starts_with("gender-"), |context| async move {
        if !context.raw.is_guild() {
            return context.followup(true, |builder| {
                builder.content("Not suitable for DM use!");
            });
        }
        let member = context.raw.member.as_ref().expect("Guild Interaction requires member");
        let gender = &context.data.custom_id[7..];
        let content = if let Some(gender_role_id) = GENDERS.get(gender) {
            let guild_id = context.guild_id().expect("Guild Interaction requires guild_id");
            let member_id = context.user_id().expect("User object required");
            if has_role(&member, gender_role_id) {
                context.rest.remove_guild_member_role(&guild_id.get(), &member_id.get(), gender_role_id)
                    .await
                    .map_err(worker_wasm_interactions_rs::util::map_error)?;
                "Removed role"
            } else {
                context.rest.add_guild_member_role(&guild_id.get(), &member_id.get(), gender_role_id)
                    .await
                    .map_err(worker_wasm_interactions_rs::util::map_error)?;
                "Added role"
            }
        } else {
            "Unknown gender role"
        };
        context.followup(true, move |builder| {
            builder.content(content);
        })
    });

    let router = Router::with_data(interactions);

    router
        .get("/", |_, _| Response::ok("Hello from Workers!"))
        .interactions("/interaction")
        .get("/worker-version", |_, ctx| {
            let version = ctx.var("WORKERS_RS_VERSION")?.to_string();
            Response::ok(version)
        })
        .run(req, env)
        .await
}

fn has_role(member: &PartialMember, role_id: &u64) -> bool {
    member.roles.iter().any(|role| role.eq(role_id))
}

About

Cloudflare Worker WASM Interactions for Rust

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages