mirror of
https://github.com/dsec-hub/dsec-discord-bot.git
synced 2026-09-22 07:44:26 +00:00
update interaction create
This commit is contained in:
parent
fb4c133ba6
commit
c818ddd8e5
1 changed files with 81 additions and 119 deletions
|
|
@ -5,122 +5,88 @@ use crate::{
|
|||
commands::verification::{StudentRow, VerificationModal},
|
||||
};
|
||||
use ::serenity::all::{
|
||||
ComponentInteraction, Context, CreateEmbed, CreateEmbedFooter, CreateInteractionResponse, CreateInteractionResponseFollowup, CreateInteractionResponseMessage, GuildId, RoleId
|
||||
Context, CreateEmbed, CreateEmbedFooter, CreateInteractionResponse,
|
||||
CreateInteractionResponseMessage, GuildId, RoleId,
|
||||
collector::ModalInteractionCollector,
|
||||
};
|
||||
use dotenv::dotenv;
|
||||
use poise::{modal, serenity_prelude as serenity};
|
||||
|
||||
struct ContextRef<'a>(&'a Context);
|
||||
impl AsRef<Context> for ContextRef<'_> {
|
||||
fn as_ref(&self) -> &Context {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
async fn embed_response(
|
||||
ctx: &serenity::Context,
|
||||
interaction: &ComponentInteraction,
|
||||
title: impl Into<String>,
|
||||
description: impl Into<String>,
|
||||
) -> Result<(), Error> {
|
||||
let embed = CreateEmbed::new().title(title).description(description);
|
||||
|
||||
let response = CreateInteractionResponse::Message(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.add_embed(embed)
|
||||
.ephemeral(true),
|
||||
);
|
||||
|
||||
interaction.create_response(ctx, response).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn embed_followup(
|
||||
ctx: &serenity::Context,
|
||||
interaction: &ComponentInteraction,
|
||||
title: impl Into<String>,
|
||||
description: impl Into<String>,
|
||||
) -> Result<(), Error> {
|
||||
let embed = CreateEmbed::new().title(title).description(description);
|
||||
|
||||
let response = CreateInteractionResponseFollowup::new()
|
||||
.add_embed(embed)
|
||||
.ephemeral(true);
|
||||
|
||||
interaction.create_followup(ctx, response).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
use poise::Modal as _;
|
||||
use poise::serenity_prelude as serenity;
|
||||
|
||||
pub async fn on_interaction_create(
|
||||
ctx: &serenity::Context,
|
||||
ctx: &Context,
|
||||
interaction: &serenity::Interaction,
|
||||
data: &Data,
|
||||
) -> Result<(), Error> {
|
||||
let Some(interaction) = interaction.as_message_component() else {
|
||||
let Some(component_interaction) = interaction.as_message_component() else {
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
if interaction.data.custom_id == "verify" {
|
||||
if component_interaction.data.custom_id == "verify" {
|
||||
dotenv().ok();
|
||||
let guild_id = match interaction.guild_id {
|
||||
let guild_id = match component_interaction.guild_id {
|
||||
Some(id) => id,
|
||||
None => {
|
||||
// user not in a server at all
|
||||
embed_response(
|
||||
ctx,
|
||||
interaction,
|
||||
"Unable to perform action",
|
||||
"Action can only be performed in the DSEC server",
|
||||
)
|
||||
.await?;
|
||||
|
||||
component_interaction.create_response(ctx, CreateInteractionResponse::Message(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.add_embed(CreateEmbed::new()
|
||||
.title("Unable to perform action")
|
||||
.description("Action can only be performed in the DSEC server"))
|
||||
.ephemeral(true),
|
||||
)).await?;
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
|
||||
let role_id_string = std::env::var("VERIFIED_ROLE_ID").expect("missing VERIFIED_ROLE_ID");
|
||||
|
||||
let role_id_u64: u64 = role_id_string
|
||||
.parse()
|
||||
.expect("Unable to parse VERIFIED_ROLE_ID into number");
|
||||
|
||||
let user_id = interaction.user.id;
|
||||
let user_id = component_interaction.user.id;
|
||||
let verified_role_id = RoleId::new(role_id_u64);
|
||||
|
||||
let discord_member = GuildId::member(guild_id, ctx, user_id).await?;
|
||||
let has_role = discord_member.roles.contains(&verified_role_id);
|
||||
|
||||
// Has role
|
||||
if has_role {
|
||||
embed_response(
|
||||
ctx,
|
||||
interaction,
|
||||
"Already Verified ✅",
|
||||
format!("You already have the <@&{}> role!", verified_role_id),
|
||||
)
|
||||
.await?;
|
||||
|
||||
if discord_member.roles.contains(&verified_role_id) {
|
||||
component_interaction.create_response(ctx, CreateInteractionResponse::Message(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.add_embed(CreateEmbed::new()
|
||||
.title("Already Verified ✅")
|
||||
.description(format!("You already have the <@&{}> role!", verified_role_id)))
|
||||
.ephemeral(true),
|
||||
)).await?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// modal
|
||||
let timeout = Duration::from_secs(120);
|
||||
let modal_custom_id = component_interaction.id.to_string();
|
||||
|
||||
let modal_data = modal::execute_modal_on_component_interaction::<VerificationModal>(
|
||||
ContextRef(ctx),
|
||||
interaction.clone(),
|
||||
None,
|
||||
Some(timeout),
|
||||
)
|
||||
.await?;
|
||||
let modal = VerificationModal::create(None, modal_custom_id.clone());
|
||||
component_interaction.create_response(ctx, modal).await?;
|
||||
|
||||
let modal_data = match modal_data {
|
||||
Some(data) => data,
|
||||
let modal_submit = ModalInteractionCollector::new(&ctx.shard)
|
||||
.filter(move |d| d.data.custom_id == modal_custom_id)
|
||||
.timeout(Duration::from_secs(120))
|
||||
.await;
|
||||
|
||||
let modal_submit = match modal_submit {
|
||||
Some(x) => x,
|
||||
None => return Ok(()),
|
||||
};
|
||||
|
||||
let modal_data = match VerificationModal::parse(modal_submit.data.clone()) {
|
||||
Ok(data) => data,
|
||||
Err(_) => {
|
||||
modal_submit.create_response(ctx, CreateInteractionResponse::Message(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.add_embed(CreateEmbed::new()
|
||||
.title("Error")
|
||||
.description("Failed to parse modal data. Please try again."))
|
||||
.ephemeral(true),
|
||||
)).await?;
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
|
||||
let input_student_id: &str = &modal_data.student_id.to_lowercase();
|
||||
let student_id = input_student_id
|
||||
.strip_prefix("s")
|
||||
|
|
@ -129,9 +95,7 @@ pub async fn on_interaction_create(
|
|||
let state = &data.state;
|
||||
|
||||
let student_in_cache: bool = {
|
||||
let cache: std::sync::MutexGuard<'_, std::collections::HashMap<String, String>> =
|
||||
state.student_cache.lock().expect("Failed to get cache");
|
||||
|
||||
let cache = state.student_cache.lock().expect("Failed to get cache");
|
||||
match cache.get(student_id) {
|
||||
Some(cached_name) => cached_name == &modal_data.name.to_lowercase(),
|
||||
None => false,
|
||||
|
|
@ -141,7 +105,7 @@ pub async fn on_interaction_create(
|
|||
if student_in_cache {
|
||||
discord_member.add_role(ctx, verified_role_id).await?;
|
||||
|
||||
let verified_cache_embed = CreateEmbed::new()
|
||||
let embed = CreateEmbed::new()
|
||||
.title("Verified ✅")
|
||||
.description(format!(
|
||||
"You have been assigned the <@&{}> role!",
|
||||
|
|
@ -149,16 +113,15 @@ pub async fn on_interaction_create(
|
|||
))
|
||||
.footer(CreateEmbedFooter::new("⚡ via cache"));
|
||||
|
||||
let verified_msg = CreateInteractionResponseFollowup::new()
|
||||
.add_embed(verified_cache_embed)
|
||||
.ephemeral(true);
|
||||
|
||||
interaction.create_followup(ctx, verified_msg).await?;
|
||||
modal_submit.create_response(ctx, CreateInteractionResponse::Message(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.add_embed(embed)
|
||||
.ephemeral(true),
|
||||
)).await?;
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// fetch from DB
|
||||
let student_data: Vec<StudentRow> = state
|
||||
.supabase
|
||||
.database()
|
||||
|
|
@ -171,19 +134,16 @@ pub async fn on_interaction_create(
|
|||
let result = student_data.iter().next();
|
||||
|
||||
if result.is_none() {
|
||||
// TODO: add user to "don't use this command for 5 minutes"
|
||||
|
||||
embed_followup(ctx,
|
||||
interaction,
|
||||
"Student ID not found!",
|
||||
"Your student ID is not found.
|
||||
It takes up to **a week** for your membership to be updated in the database since sign up.
|
||||
Try again later.").await?;
|
||||
|
||||
modal_submit.create_response(ctx, CreateInteractionResponse::Message(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.add_embed(CreateEmbed::new()
|
||||
.title("Student ID not found!")
|
||||
.description("Your student ID is not found.\nIt takes up to **a week** for your membership to be updated in the database since sign up.\nTry again later."))
|
||||
.ephemeral(true),
|
||||
)).await?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// get name from result
|
||||
let result_name = &result.unwrap().full_name;
|
||||
|
||||
{
|
||||
|
|
@ -197,24 +157,26 @@ pub async fn on_interaction_create(
|
|||
if &result_name.to_lowercase() == &modal_data.name.to_lowercase() {
|
||||
discord_member.add_role(ctx, verified_role_id).await?;
|
||||
|
||||
embed_followup(
|
||||
ctx,
|
||||
interaction,
|
||||
"Verified ✅",
|
||||
format!("You have been assigned the <@&{}> role!", verified_role_id),
|
||||
)
|
||||
.await?;
|
||||
let embed = CreateEmbed::new()
|
||||
.title("Verified ✅")
|
||||
.description(format!(
|
||||
"You have been assigned the <@&{}> role!",
|
||||
verified_role_id
|
||||
));
|
||||
|
||||
// post to logs channel
|
||||
|
||||
modal_submit.create_response(ctx, CreateInteractionResponse::Message(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.add_embed(embed)
|
||||
.ephemeral(true),
|
||||
)).await?;
|
||||
} else {
|
||||
embed_followup(
|
||||
ctx,
|
||||
interaction,
|
||||
"Name mismatch ❌",
|
||||
"Your student ID is present, however the name does not match. Try again.",
|
||||
)
|
||||
.await?;
|
||||
modal_submit.create_response(ctx, CreateInteractionResponse::Message(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.add_embed(CreateEmbed::new()
|
||||
.title("Name mismatch ❌")
|
||||
.description("Your student ID is present, however the name does not match. Try again."))
|
||||
.ephemeral(true),
|
||||
)).await?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue