11package com .workingdead .chatbot .command ;
22
33import com .workingdead .chatbot .scheduler .WendyScheduler ;
4- import com .workingdead .meet .service .WendyService ;
4+ import com .workingdead .chatbot .service .WendyService ;
55import net .dv8tion .jda .api .entities .Member ;
66import net .dv8tion .jda .api .entities .channel .concrete .TextChannel ;
77import net .dv8tion .jda .api .entities .emoji .Emoji ;
8+ import net .dv8tion .jda .api .events .interaction .component .EntitySelectInteractionEvent ;
9+ import net .dv8tion .jda .api .events .interaction .component .StringSelectInteractionEvent ;
810import net .dv8tion .jda .api .events .message .MessageReceivedEvent ;
911import net .dv8tion .jda .api .events .message .react .MessageReactionAddEvent ;
1012import net .dv8tion .jda .api .hooks .ListenerAdapter ;
13+ import net .dv8tion .jda .api .interactions .components .selections .EntitySelectMenu ;
14+ import net .dv8tion .jda .api .interactions .components .selections .StringSelectMenu ;
1115import org .springframework .stereotype .Component ;
1216
1317import java .util .List ;
@@ -22,6 +26,10 @@ public class WendyCommand extends ListenerAdapter {
2226
2327 private final Map <String , String > participantCheckMessages = new ConcurrentHashMap <>();
2428 private final Map <String , Boolean > waitingForDateInput = new ConcurrentHashMap <>();
29+
30+ private static final String ATTENDEE_SELECT_MENU_ID = "wendy-attendees" ;
31+ private static final String WEEK_SELECT_MENU_ID = "wendy-weeks" ;
32+ private static final String WEEK_SELECT_MENU_REVOTE_ID = "wendy-weeks-revote" ;
2533
2634 public WendyCommand (WendyService wendyService , WendyScheduler wendyScheduler ) {
2735 this .wendyService = wendyService ;
@@ -54,14 +62,14 @@ public void onMessageReceived(MessageReceivedEvent event) {
5462 return ;
5563 }
5664
57- // 2.1~2.2 날짜 범위 입력
58- if (waitingForDateInput .getOrDefault (channelId , false )) {
59- Integer weeks = extractWeeks (content );
60- if (weeks != null ) {
61- handleDateInput (channel , member , weeks , false );
62- return ;
63- }
64- }
65+ // // 2.1~2.2 날짜 범위 입력
66+ // if (waitingForDateInput.getOrDefault(channelId, false)) {
67+ // Integer weeks = extractWeeks(content);
68+ // if (weeks != null) {
69+ // handleDateInput(channel, member, weeks, false);
70+ // return;
71+ // }
72+ // }
6573
6674 // 4.2 재투표
6775 if (content .equals ("웬디 재투표" )) {
@@ -75,30 +83,84 @@ public void onMessageReceived(MessageReceivedEvent event) {
7583 return ;
7684 }
7785 }
78-
86+
7987 @ Override
80- public void onMessageReactionAdd (MessageReactionAddEvent event ) {
81- if (event .getUser () != null && event .getUser ().isBot ()) return ;
82-
83- String channelId = event .getChannel ().getId ();
84- String messageId = event .getMessageId ();
85-
86- String checkMessageId = participantCheckMessages .get (channelId );
87- if (checkMessageId == null || !checkMessageId .equals (messageId )) {
88+ public void onEntitySelectInteraction (EntitySelectInteractionEvent event ) {
89+ if (!ATTENDEE_SELECT_MENU_ID .equals (event .getComponentId ())) {
8890 return ;
8991 }
90-
91- if (!event .getReaction ().getEmoji ().equals (Emoji .fromUnicode ("✅" ))) {
92+
93+ String channelId = event .getChannel ().getId ();
94+ if (!wendyService .isSessionActive (channelId )) {
9295 return ;
9396 }
94-
95- event .retrieveMember ().queue (member -> {
96- if (member != null ) {
97- wendyService .addParticipant (channelId , member .getId (), member .getEffectiveName ());
98- System .out .println ("[Command] Participant added: " + member .getEffectiveName ());
99- }
97+
98+ event .getMentions ().getMembers ().forEach (member -> {
99+ wendyService .addParticipant (channelId , member .getId (), member .getEffectiveName ());
100+ System .out .println ("[Command] Participant added via select menu: " + member .getEffectiveName ());
100101 });
102+
103+ event .reply ("참석자 명단이 업데이트됐어요!" ).setEphemeral (true ).queue ();
104+
101105 }
106+
107+ @ Override
108+ public void onStringSelectInteraction (StringSelectInteractionEvent event ) {
109+ String componentId = event .getComponentId ();
110+ if (!WEEK_SELECT_MENU_ID .equals (componentId ) && !WEEK_SELECT_MENU_REVOTE_ID .equals (componentId )) {
111+ return ;
112+ }
113+
114+ String channelId = event .getChannel ().getId ();
115+ if (!wendyService .isSessionActive (channelId )) {
116+ return ;
117+ }
118+
119+ // 하나만 선택하게 설정할 예정이므로 첫 번째 값만 사용
120+ String value = event .getValues ().get (0 );
121+ int weeks ;
122+ try {
123+ weeks = Integer .parseInt (value );
124+ } catch (NumberFormatException e ) {
125+ event .reply ("선택한 값이 올바르지 않아요. 다시 시도해주세요!" ).setEphemeral (true ).queue ();
126+ return ;
127+ }
128+
129+ TextChannel channel = event .getChannel ().asTextChannel ();
130+ Member member = event .getMember ();
131+ if (member == null ) {
132+ event .reply ("사용자 정보를 가져올 수 없어요. 다시 시도해주세요!" ).setEphemeral (true ).queue ();
133+ return ;
134+ }
135+
136+ boolean isRevote = WEEK_SELECT_MENU_REVOTE_ID .equals (componentId );
137+ handleDateInput (channel , member , weeks , isRevote );
138+ event .reply ("투표 날짜 범위를 선택하셨어요!" ).setEphemeral (true ).queue ();
139+ }
140+
141+ // @Override
142+ // public void onMessageReactionAdd(MessageReactionAddEvent event) {
143+ // if (event.getUser() != null && event.getUser().isBot()) return;
144+ //
145+ // String channelId = event.getChannel().getId();
146+ // String messageId = event.getMessageId();
147+ //
148+ // String checkMessageId = participantCheckMessages.get(channelId);
149+ // if (checkMessageId == null || !checkMessageId.equals(messageId)) {
150+ // return;
151+ // }
152+ //
153+ // if (!event.getReaction().getEmoji().equals(Emoji.fromUnicode("✅"))) {
154+ // return;
155+ // }
156+ //
157+ // event.retrieveMember().queue(member -> {
158+ // if (member != null) {
159+ // wendyService.addParticipant(channelId, member.getId(), member.getEffectiveName());
160+ // System.out.println("[Command] Participant added: " + member.getEffectiveName());
161+ // }
162+ // });
163+ // }
102164
103165 private void handleStart (TextChannel channel ) {
104166 String channelId = channel .getId ();
@@ -110,32 +172,50 @@ private void handleStart(TextChannel channel) {
110172 안녕하세요! 일정 조율 도우미 웬디에요 :D
111173 지금부터 여러분의 일정 조율을 도와드릴게요
112174 """ ).queue ();
113-
114- channel .sendMessage ("인원 파악을 위해 참석자분들은 ✅를 남겨주세요!" )
115- .queue (message -> {
116- participantCheckMessages .put (channelId , message .getId ());
117- message .addReaction (Emoji .fromUnicode ("✅" )).queue ();
118- System .out .println ("[Command] Session started: " + channelId );
119- });
120-
121- channel .sendMessage ("몇 주 뒤의 일정을 계획하시나요? :D\n (ex. 2주 뒤)" ).queue ();
122- waitingForDateInput .put (channelId , true );
175+
176+
177+ // 참석자 입력용 엔티티 셀렉트 메뉴 (유저 선택 드롭다운)
178+ EntitySelectMenu attendeeMenu = EntitySelectMenu .create (ATTENDEE_SELECT_MENU_ID , EntitySelectMenu .SelectTarget .USER )
179+ .setPlaceholder ("참석자분들을 선택하거나 검색해서 골라주세요" )
180+ .setRequiredRange (1 , 25 )
181+ .build ();
182+
183+ channel .sendMessage ("인원 파악을 위해 참석자분들을 알려주세요!\n 원하는 참석자들을 아래 드롭다운에서 선택해주세요." )
184+ .setActionRow (attendeeMenu )
185+ .queue ();
186+
187+ // 2.1 날짜 범위 파악 질문 (드롭다운 방식)
188+ StringSelectMenu weekMenu = StringSelectMenu .create (WEEK_SELECT_MENU_ID )
189+ .setPlaceholder ("몇 주 뒤의 일정을 계획하시나요?" )
190+ .addOption ("이번 주" , "0" )
191+ .addOption ("1주 뒤" , "1" )
192+ .addOption ("2주 뒤" , "2" )
193+ .addOption ("3주 뒤" , "3" )
194+ .addOption ("4주 뒤" , "4" )
195+ .addOption ("5주 뒤" , "5" )
196+ .addOption ("6주 뒤" , "6" )
197+ .build ();
198+
199+ channel .sendMessage ("몇 주 뒤의 일정을 계획하시나요? :D" )
200+ .setActionRow (weekMenu )
201+ .queue ();
123202 }
124203
125204 private void handleDateInput (TextChannel channel , Member member , int weeks , boolean isRevote ) {
126205 String channelId = channel .getId ();
127- String userName = member .getEffectiveName ();
206+ String userMention = member .getAsMention ();
207+ String channelName = channel .getName ();
128208
129209 waitingForDateInput .put (channelId , false );
130210
131- channel .sendMessage (userName + " 님이 " + weeks + "주 뒤를 선택하셨어요!" ).queue ();
211+ channel .sendMessage (userMention + " 님이 " + weeks + "주 뒤를 선택하셨어요!" ).queue ();
132212 channel .sendMessage ("해당 일정의 투표를 만들어드릴게요 :D" ).queue ();
133213 channel .sendMessage ("(투표 늦게 하는 사람 대머리🧑🦲)" ).queue ();
134214 channel .sendMessage ("투표를 생성 중입니다🛜" ).queue ();
135215
136216 String voteUrl = isRevote
137- ? wendyService .recreateVote (channelId , weeks )
138- : wendyService .createVote (channelId , weeks );
217+ ? wendyService .recreateVote (channelId , channelName , weeks )
218+ : wendyService .createVote (channelId , channelName , weeks );
139219
140220 channel .sendMessage (voteUrl ).queue ();
141221 wendyScheduler .startSchedule (channel );
@@ -150,8 +230,22 @@ private void handleRevote(TextChannel channel) {
150230 }
151231
152232 wendyScheduler .stopSchedule (channelId );
153- channel .sendMessage ("몇 주 뒤의 일정을 계획하시나요? :D\n (ex. 2주 뒤)" ).queue ();
154- waitingForDateInput .put (channelId , true );
233+
234+
235+ StringSelectMenu weekMenu = StringSelectMenu .create (WEEK_SELECT_MENU_REVOTE_ID )
236+ .setPlaceholder ("몇 주 뒤의 일정을 다시 계획하시나요?" )
237+ .addOption ("이번 주" , "0" )
238+ .addOption ("1주 뒤" , "1" )
239+ .addOption ("2주 뒤" , "2" )
240+ .addOption ("3주 뒤" , "3" )
241+ .addOption ("4주 뒤" , "4" )
242+ .addOption ("5주 뒤" , "5" )
243+ .addOption ("6주 뒤" , "6" )
244+ .build ();
245+
246+ channel .sendMessage ("몇 주 뒤의 일정을 계획하시나요? :D" )
247+ .setActionRow (weekMenu )
248+ .queue ();
155249 }
156250
157251 private void handleEnd (TextChannel channel ) {
0 commit comments