@@ -7,17 +7,10 @@ import {
77 Events ,
88 ModalBuilder ,
99 PermissionFlagsBits ,
10- StringSelectMenuBuilder ,
1110 TextInputBuilder ,
1211 TextInputStyle ,
1312} from 'discord.js' ;
1413import { buildTicketPermissionOverwrites , TICKET_VIEW_ROLE_IDS } from '../lib/ticket-permissions.js' ;
15- import { getAuthenticatedUserDomains } from '../lib/domain-picker.js' ;
16- import { getCollection } from '../lib/mongo.js' ;
17- import { getMe } from '../lib/open-domains.js' ;
18- import { getBase44Client } from '../lib/base44-agent.js' ;
19- import { verifyDomainRecords } from '../lib/dns-check.js' ;
20- import { persistUserTicketContext , buildTicketLoginUpdateMessage } from '../lib/ticket-session.js' ;
2114
2215const ticketCategoryId = process . env . TICKET_CATEGORY_ID || '1383178711511072928' ;
2316const closedTicketCategoryId = process . env . CLOSED_TICKET_CATEGORY_ID || '1383178786756890826' ;
@@ -107,38 +100,6 @@ async function closeTicketChannel(channel, user) {
107100 return { alreadyClosed : false } ;
108101}
109102
110- async function buildDomainSelectionComponents ( userId , ticketChannelId ) {
111- const domains = await getAuthenticatedUserDomains ( userId ) ;
112-
113- if ( ! domains . length ) {
114- return [
115- new ActionRowBuilder ( ) . addComponents (
116- new ButtonBuilder ( )
117- . setCustomId ( `login_ticket:${ ticketChannelId } ` )
118- . setLabel ( 'Login to speed up your ticket' )
119- . setStyle ( ButtonStyle . Primary )
120- ) ,
121- ] ;
122- }
123-
124- const selectMenu = new StringSelectMenuBuilder ( )
125- . setCustomId ( `select_domain:${ ticketChannelId } ` )
126- . setPlaceholder ( 'Select a domain to share details for' )
127- . addOptions ( domains . slice ( 0 , 25 ) . map ( ( domain ) => ( { label : domain , value : domain } ) ) ) ;
128-
129- return [ new ActionRowBuilder ( ) . addComponents ( selectMenu ) ] ;
130- }
131-
132- export async function respondToModalSubmission ( interaction , message ) {
133- if ( interaction . deferred || interaction . replied ) {
134- await interaction . editReply ( message ) . catch ( ( ) => { } ) ;
135- return ;
136- }
137-
138- await interaction . deferReply ( { flags : 64 } ) . catch ( ( ) => { } ) ;
139- await interaction . editReply ( message ) . catch ( ( ) => { } ) ;
140- }
141-
142103export function registerInteractionCreateEvent ( client , commands ) {
143104 client . on ( Events . InteractionCreate , async ( interaction ) => {
144105 if ( interaction . isChatInputCommand ( ) ) {
@@ -155,13 +116,13 @@ export function registerInteractionCreateEvent(client, commands) {
155116
156117 const reply = {
157118 content : 'There was an error while executing this command.' ,
158- flags : 64 ,
119+ ephemeral : true ,
159120 } ;
160121
161122 if ( interaction . deferred || interaction . replied ) {
162- await interaction . followUp ( reply ) . catch ( ( ) => { } ) ;
123+ await interaction . followUp ( reply ) ;
163124 } else {
164- await interaction . reply ( reply ) . catch ( ( ) => { } ) ;
125+ await interaction . reply ( reply ) ;
165126 }
166127 }
167128
@@ -197,7 +158,7 @@ export function registerInteractionCreateEvent(client, commands) {
197158 if ( interaction . isModalSubmit ( ) && interaction . customId === 'ticket_modal' ) {
198159 try {
199160 if ( ! interaction . inGuild ( ) ) {
200- await respondToModalSubmission ( interaction , { content : 'Tickets can only be created inside a server.' } ) ;
161+ await interaction . reply ( { content : 'Tickets can only be created inside a server.' , ephemeral : true } ) ;
201162 return ;
202163 }
203164
@@ -227,27 +188,23 @@ export function registerInteractionCreateEvent(client, commands) {
227188 components : [ row ] ,
228189 } ) ;
229190
230- const sessions = await getCollection ( 'sessions' ) ;
231- await persistUserTicketContext ( sessions , interaction . user . id , ticketChannel . id , interaction . guild . id ) ;
232-
233- const components = await buildDomainSelectionComponents ( interaction . user . id , ticketChannel . id ) ;
234-
235191 await ticketChannel . send ( {
236192 content : [
237193 'Please reply with a bit more detail so we can help you faster.' ,
238194 '1. What is the issue about?' ,
239195 '2. What category or urgency best fits this request?' ,
240196 ] . join ( '\n' ) ,
241- components,
242197 } ) ;
243198
244- await respondToModalSubmission ( interaction , {
199+ await interaction . reply ( {
245200 content : `Your ticket channel is ready: <#${ ticketChannel . id } >` ,
201+ ephemeral : true ,
246202 } ) ;
247203 } catch ( error ) {
248204 console . error ( error ) ;
249- await respondToModalSubmission ( interaction , {
205+ await interaction . reply ( {
250206 content : `Unable to create your ticket right now: ${ error . message } ` ,
207+ ephemeral : true ,
251208 } ) ;
252209 }
253210 return ;
@@ -259,139 +216,25 @@ export function registerInteractionCreateEvent(client, commands) {
259216 const channel = await interaction . guild . channels . fetch ( channelId ) . catch ( ( ) => null ) ;
260217
261218 if ( ! channel || channel . type !== ChannelType . GuildText ) {
262- await interaction . reply ( { content : 'This ticket channel could not be found.' , flags : 64 } ) . catch ( ( ) => { } ) ;
219+ await interaction . reply ( { content : 'This ticket channel could not be found.' , ephemeral : true } ) ;
263220 return ;
264221 }
265222
266223 const result = await closeTicketChannel ( channel , interaction . user ) ;
267224
268225 if ( result . alreadyClosed ) {
269- await interaction . reply ( { content : 'This ticket is already closed.' , flags : 64 } ) . catch ( ( ) => { } ) ;
226+ await interaction . reply ( { content : 'This ticket is already closed.' , ephemeral : true } ) ;
270227 return ;
271228 }
272229
273230 await channel . send ( {
274231 content : `Ticket closed by ${ interaction . user } . This channel is now read-only.` ,
275232 } ) ;
276233
277- await interaction . reply ( { content : 'Ticket closed successfully.' , flags : 64 } ) . catch ( ( ) => { } ) ;
278- } catch ( error ) {
279- console . error ( error ) ;
280- await interaction . reply ( { content : `Unable to close this ticket: ${ error . message } ` , flags : 64 } ) . catch ( ( ) => { } ) ;
281- }
282- }
283-
284- if ( interaction . isButton ( ) && interaction . customId . startsWith ( 'login_ticket:' ) ) {
285- const [ , channelId ] = interaction . customId . split ( ':' ) ;
286- const channel = await interaction . guild . channels . fetch ( channelId ) . catch ( ( ) => null ) ;
287-
288- await interaction . reply ( {
289- content : 'Starting the OpenDomains login flow for you now.' ,
290- flags : 64 ,
291- } ) . catch ( ( ) => { } ) ;
292-
293- if ( channel ) {
294- await channel . send ( { content : `${ interaction . user } is authenticating with OpenDomains to speed up their ticket.` } ) ;
295- }
296-
297- const command = commands . get ( 'login' ) ;
298- if ( command ) {
299- await command . execute ( {
300- ...interaction ,
301- deferReply : async ( ) => { } ,
302- editReply : async ( message ) => {
303- await interaction . followUp ( { content : typeof message === 'string' ? message : message . content , flags : 64 } ) . catch ( ( ) => { } ) ;
304- } ,
305- followUp : async ( message ) => {
306- await interaction . followUp ( { ...message , flags : 64 } ) . catch ( ( ) => { } ) ;
307- } ,
308- options : interaction . options ?? { } ,
309- user : interaction . user ,
310- } ) ;
311- }
312- return ;
313- }
314-
315- if ( interaction . isStringSelectMenu ( ) && interaction . customId . startsWith ( 'select_domain:' ) ) {
316- try {
317- const [ , channelId ] = interaction . customId . split ( ':' ) ;
318- const selectedDomain = interaction . values [ 0 ] ;
319- const channel = await interaction . guild . channels . fetch ( channelId ) . catch ( ( ) => null ) ;
320-
321- if ( ! channel ) {
322- await interaction . reply ( { content : 'That ticket channel could not be found.' , flags : 64 } ) . catch ( ( ) => { } ) ;
323- return ;
324- }
325-
326- const sessions = await getCollection ( 'sessions' ) ;
327- const session = await sessions . findOne ( { userId : interaction . user . id } ) ;
328-
329- if ( ! session ?. apiKey ) {
330- await interaction . reply ( { content : 'You need to be logged in to share domain details.' , flags : 64 } ) . catch ( ( ) => { } ) ;
331- return ;
332- }
333-
334- const account = await getMe ( session . apiKey ) ;
335- const userEmail = session ?. userEmail || account ?. email ;
336-
337- // Query Base24 DnsRecords for this domain using the user's email
338- const base44 = getBase44Client ( ) ;
339- const allRecords = await base44 . entities . DnsRecord . list ( { filter : { owner_email : userEmail } } ) ;
340- const domainRecords = allRecords . filter (
341- ( r ) => r . name ?. toLowerCase ( ) === selectedDomain . toLowerCase ( ) || r . subdomain ?. toLowerCase ( ) === selectedDomain . toLowerCase ( )
342- ) ;
343-
344- const digResult = await verifyDomainRecords ( selectedDomain ) ;
345- const embed = new EmbedBuilder ( )
346- . setTitle ( `Domain details for ${ selectedDomain } ` )
347- . setColor ( 0x5865f2 )
348- . setDescription ( 'Domain details from Base24 DNS records.' )
349- . addFields (
350- { name : 'Selected domain' , value : selectedDomain , inline : false } ,
351- {
352- name : 'Account' ,
353- value : account . email ?? account . display_name ?? 'Authenticated account' ,
354- inline : false ,
355- } ,
356- {
357- name : 'DNS verification' ,
358- value : digResult . ok ? `Verified: ${ digResult . summary } ` : `Not verified: ${ digResult . summary } ` ,
359- inline : false ,
360- }
361- ) ;
362-
363- if ( domainRecords . length ) {
364- domainRecords . slice ( 0 , 10 ) . forEach ( ( record ) => {
365- const status = record . status ? `[${ record . status . toUpperCase ( ) } ]` : '' ;
366- const verified = record . dns_verified ? '✓ Verified' : '✗ Unverified' ;
367- embed . addFields ( {
368- name : `${ record . name ?? selectedDomain } ${ status } ` ,
369- value : [
370- `Type: ${ record . record_type ?? 'unknown' } ` ,
371- `Content: ${ record . content ?? '—' } ` ,
372- `TTL: ${ record . ttl ? `${ record . ttl } s` : 'auto' } ` ,
373- `DNS: ${ verified } ` ,
374- ] . join ( '\n' ) ,
375- inline : false ,
376- } ) ;
377- } ) ;
378- } else {
379- embed . addFields ( { name : 'Records' , value : 'No DNS records were returned for this domain.' , inline : false } ) ;
380- }
381-
382- if ( digResult . answers ?. length ) {
383- embed . addFields ( {
384- name : 'dig output' ,
385- value : digResult . answers . slice ( 0 , 5 ) . join ( '\n' ) ,
386- inline : false ,
387- } ) ;
388- }
389-
390- await channel . send ( { content : `${ interaction . user } selected ${ selectedDomain } .` , embeds : [ embed ] } ) ;
391- await interaction . reply ( { content : `Shared details for ${ selectedDomain } .` , flags : 64 } ) . catch ( ( ) => { } ) ;
234+ await interaction . reply ( { content : 'Ticket closed successfully.' , ephemeral : true } ) ;
392235 } catch ( error ) {
393236 console . error ( error ) ;
394- await interaction . reply ( { content : `Unable to share domain details : ${ error . message } ` , flags : 64 } ) . catch ( ( ) => { } ) ;
237+ await interaction . reply ( { content : `Unable to close this ticket : ${ error . message } ` , ephemeral : true } ) ;
395238 }
396239 }
397240 } ) ;
0 commit comments