@@ -4,6 +4,10 @@ import {
44 EmbedBuilder ,
55 GuildMember ,
66 MessageFlags ,
7+ ActionRowBuilder ,
8+ ButtonBuilder ,
9+ ButtonStyle ,
10+ ComponentType ,
711} from "discord.js" ;
812import { LinkLogger } from "../utils/linkLogger.js" ;
913import {
@@ -309,39 +313,46 @@ export async function execute(
309313 {
310314 name : "📜 CONFIRMATION REQUIRED" ,
311315 value :
312- "React with 🖋️ within 1 minute to proceed with the linking ritual." ,
316+ "Click the button below within 1 minute to proceed with the linking ritual." ,
313317 inline : false ,
314318 } ,
315319 )
316320 . setFooter ( { text : "This confirmation will expire in 60 seconds" } )
317321 . setTimestamp ( ) ;
318322
319- const confirmationMessage = await interaction . reply ( {
323+ const row = new ActionRowBuilder < ButtonBuilder > ( ) . addComponents (
324+ new ButtonBuilder ( )
325+ . setCustomId ( "confirm_link" )
326+ . setLabel ( "🖋️ Confirm Linking" )
327+ . setStyle ( ButtonStyle . Primary ) ,
328+ ) ;
329+
330+ const reply = await interaction . reply ( {
320331 embeds : [ confirmationEmbed ] ,
332+ components : [ row ] ,
321333 flags : MessageFlags . Ephemeral ,
322334 } ) ;
323335
324- const message = await confirmationMessage . fetch ( ) ;
325-
326- try {
327- await message . react ( "🖋️" ) ;
328- } catch ( error ) {
329- console . error ( "Failed to add reaction:" , error ) ;
330- }
331-
332- const filter = ( reaction : any , user : any ) => {
333- return reaction . emoji . name === "🖋️" && user . id === interaction . user . id ;
334- } ;
335-
336336 try {
337- const collected = await message . awaitReactions ( {
338- filter,
339- max : 1 ,
337+ const collector = reply . createMessageComponentCollector ( {
338+ componentType : ComponentType . Button ,
340339 time : 60000 ,
341- errors : [ "time" ] ,
342340 } ) ;
343341
344- if ( collected . size > 0 ) {
342+ let confirmed = false ;
343+
344+ // In case I want to move this to non ephemeral later
345+ collector . on ( "collect" , async ( i ) => {
346+ if ( i . user . id !== interaction . user . id ) {
347+ await i . reply ( {
348+ content : "You cannot confirm another's linking ritual." ,
349+ flags : MessageFlags . Ephemeral ,
350+ } ) ;
351+ return ;
352+ }
353+ confirmed = true ;
354+ collector . stop ( ) ;
355+
345356 const { grantedRoleNames, failedRoleNames } = await manageFandomRoles (
346357 member ,
347358 fandomGroups ,
@@ -424,8 +435,33 @@ export async function execute(
424435 } ) ;
425436 }
426437
427- await interaction . followUp ( { embeds : [ successEmbed ] } ) ;
428- }
438+ await i . update ( {
439+ embeds : [ successEmbed ] ,
440+ components : [ ] ,
441+ } ) ;
442+ } ) ;
443+
444+ collector . on ( "end" , async ( ) => {
445+ if ( ! confirmed ) {
446+ const timeoutEmbed = new EmbedBuilder ( )
447+ . setColor ( "#FF0000" )
448+ . setTitle ( "⏰ LINKING RITUAL EXPIRED" )
449+ . setDescription (
450+ "**THE LINKING CONFIRMATION HAS EXPIRED. NO CHANGES WERE MADE.**" ,
451+ )
452+ . addFields ( {
453+ name : "TO RETRY" ,
454+ value :
455+ "Run the `/link` command again to restart the linking process." ,
456+ inline : false ,
457+ } ) ;
458+
459+ await interaction . editReply ( {
460+ embeds : [ timeoutEmbed ] ,
461+ components : [ ] ,
462+ } ) ;
463+ }
464+ } ) ;
429465 } catch ( error ) {
430466 const timeoutEmbed = new EmbedBuilder ( )
431467 . setColor ( "#FF0000" )
@@ -440,9 +476,9 @@ export async function execute(
440476 inline : false ,
441477 } ) ;
442478
443- await interaction . followUp ( {
479+ await interaction . editReply ( {
444480 embeds : [ timeoutEmbed ] ,
445- flags : MessageFlags . Ephemeral ,
481+ components : [ ] ,
446482 } ) ;
447483 }
448484 } catch ( error ) {
0 commit comments