Skip to content

Commit 6abd44d

Browse files
authored
Merge pull request #35 from DevKor-github/feature/kakao-done
Feature/kakao done
2 parents 59e97bc + 961e426 commit 6abd44d

56 files changed

Lines changed: 3775 additions & 313 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env

Lines changed: 0 additions & 1 deletion
This file was deleted.

.github/workflows/deploy.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ on:
44
push:
55
branches:
66
- main
7+
- feature/kakao-api
78
jobs:
89
deploy:
910
runs-on: ubuntu-latest
@@ -60,6 +61,8 @@ jobs:
6061
6162
export DB_PASSWORD='${{ secrets.DB_PASSWORD }}'
6263
export DISCORD_TOKEN='${{ secrets.DISCORD_TOKEN }}'
64+
export KAKAO_REST_API_KEY='${{ secrets.KAKAO_REST_API_KEY }}'
65+
export KAKAO_EVENT_API_KEY='${{ secrets.KAKAO_EVENT_API_KEY }}'
6366
6467
nohup java -jar build/libs/workingdead-0.0.1-SNAPSHOT.jar > app.log 2>&1 &
6568

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
HELP.md
22
.env
3+
dump.rdb
34
.gradle
45
build/
56
!gradle/wrapper/gradle-wrapper.jar

build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ dependencies {
3434
implementation 'org.flywaydb:flyway-core'
3535
implementation 'org.flywaydb:flyway-database-postgresql'
3636
implementation 'org.springframework.session:spring-session-jdbc'
37-
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
38-
implementation 'org.springframework.boot:spring-boot-starter-data-redis-reactive'
37+
// implementation 'org.springframework.boot:spring-boot-starter-data-redis'
38+
// implementation 'org.springframework.boot:spring-boot-starter-data-redis-reactive'
3939
implementation 'org.apache.commons:commons-pool2'
4040
compileOnly 'org.projectlombok:lombok'
4141
runtimeOnly 'com.h2database:h2'

codebase-analysis.md

Lines changed: 535 additions & 0 deletions
Large diffs are not rendered by default.
File renamed without changes.

src/main/java/com/workingdead/chatbot/command/WendyCommand.java renamed to src/main/java/com/workingdead/chatbot/discord/command/DiscordWendyCommand.java

Lines changed: 56 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,36 @@
1-
package com.workingdead.chatbot.command;
1+
package com.workingdead.chatbot.discord.command;
22

3-
import com.workingdead.chatbot.scheduler.WendyScheduler;
4-
import com.workingdead.chatbot.service.WendyService;
5-
import java.util.concurrent.CompletableFuture;
6-
import java.util.concurrent.TimeUnit;
3+
import com.workingdead.chatbot.discord.scheduler.DiscordWendyScheduler;
4+
import com.workingdead.chatbot.discord.service.DiscordWendyService;
5+
import java.util.List;
6+
import java.util.Map;
7+
import java.util.concurrent.ConcurrentHashMap;
78
import net.dv8tion.jda.api.entities.Member;
89
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
9-
import net.dv8tion.jda.api.entities.emoji.Emoji;
1010
import net.dv8tion.jda.api.events.interaction.component.EntitySelectInteractionEvent;
1111
import net.dv8tion.jda.api.events.interaction.component.StringSelectInteractionEvent;
1212
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
13-
import net.dv8tion.jda.api.events.message.react.MessageReactionAddEvent;
1413
import net.dv8tion.jda.api.hooks.ListenerAdapter;
1514
import net.dv8tion.jda.api.interactions.components.selections.EntitySelectMenu;
1615
import net.dv8tion.jda.api.interactions.components.selections.StringSelectMenu;
1716
import org.springframework.stereotype.Component;
1817

19-
import java.util.List;
20-
import java.util.Map;
21-
import java.util.concurrent.ConcurrentHashMap;
22-
2318
@Component
24-
public class WendyCommand extends ListenerAdapter {
25-
26-
private final WendyService wendyService;
27-
private final WendyScheduler wendyScheduler;
28-
19+
public class DiscordWendyCommand extends ListenerAdapter {
20+
21+
private final DiscordWendyService discordWendyService;
22+
private final DiscordWendyScheduler discordWendyScheduler;
23+
2924
private final Map<String, String> participantCheckMessages = new ConcurrentHashMap<>();
3025
private final Map<String, Boolean> waitingForDateInput = new ConcurrentHashMap<>();
3126

3227
private static final String ATTENDEE_SELECT_MENU_ID = "wendy-attendees";
3328
private static final String WEEK_SELECT_MENU_ID = "wendy-weeks";
3429
private static final String WEEK_SELECT_MENU_REVOTE_ID = "wendy-weeks-revote";
35-
36-
public WendyCommand(WendyService wendyService, WendyScheduler wendyScheduler) {
37-
this.wendyService = wendyService;
38-
this.wendyScheduler = wendyScheduler;
30+
31+
public DiscordWendyCommand(DiscordWendyService discordWendyService, DiscordWendyScheduler discordWendyScheduler) {
32+
this.discordWendyService = discordWendyService;
33+
this.discordWendyScheduler = discordWendyScheduler;
3934
}
4035

4136
@Override
@@ -52,45 +47,36 @@ public void onGuildJoin(net.dv8tion.jda.api.events.guild.GuildJoinEvent event) {
5247
@Override
5348
public void onMessageReceived(MessageReceivedEvent event) {
5449
if (event.getAuthor().isBot()) return;
55-
50+
5651
String content = event.getMessage().getContentRaw().trim();
5752
TextChannel channel = event.getChannel().asTextChannel();
5853
String channelId = channel.getId();
5954
Member member = event.getMember();
60-
61-
// 1.1 웬디 시작
55+
56+
// 웬디 시작
6257
if (content.equals("웬디 시작")) {
6358
handleStart(channel);
6459
return;
6560
}
66-
67-
// 4.1 도움말
61+
62+
// 도움말
6863
if (content.equals("/help") || content.equals("웬디 도움말")) {
6964
handleHelp(channel);
7065
return;
7166
}
72-
67+
7368
// 세션 체크
74-
if (!wendyService.isSessionActive(channelId)) {
69+
if (!discordWendyService.isSessionActive(channelId)) {
7570
return;
7671
}
77-
78-
// // 2.1~2.2 날짜 범위 입력
79-
// if (waitingForDateInput.getOrDefault(channelId, false)) {
80-
// Integer weeks = extractWeeks(content);
81-
// if (weeks != null) {
82-
// handleDateInput(channel, member, weeks, false);
83-
// return;
84-
// }
85-
// }
86-
87-
// 4.2 재투표
72+
73+
// 재투표
8874
if (content.equals("웬디 재투표")) {
8975
handleRevote(channel);
9076
return;
9177
}
92-
93-
// 3.1 웬디 종료
78+
79+
// 웬디 종료
9480
if (content.equals("웬디 종료")) {
9581
handleEnd(channel);
9682
return;
@@ -104,17 +90,16 @@ public void onEntitySelectInteraction(EntitySelectInteractionEvent event) {
10490
}
10591

10692
String channelId = event.getChannel().getId();
107-
if (!wendyService.isSessionActive(channelId)) {
93+
if (!discordWendyService.isSessionActive(channelId)) {
10894
return;
10995
}
11096

11197
event.getMentions().getMembers().forEach(member -> {
112-
wendyService.addParticipant(channelId, member.getId(), member.getEffectiveName());
113-
System.out.println("[Command] Participant added via select menu: " + member.getEffectiveName());
98+
discordWendyService.addParticipant(channelId, member.getId(), member.getEffectiveName());
99+
System.out.println("[Discord Command] Participant added via select menu: " + member.getEffectiveName());
114100
});
115101

116102
event.reply("참석자 명단이 업데이트됐어요!").setEphemeral(true).queue();
117-
118103
}
119104

120105
@Override
@@ -125,11 +110,10 @@ public void onStringSelectInteraction(StringSelectInteractionEvent event) {
125110
}
126111

127112
String channelId = event.getChannel().getId();
128-
if (!wendyService.isSessionActive(channelId)) {
113+
if (!discordWendyService.isSessionActive(channelId)) {
129114
return;
130115
}
131116

132-
// 하나만 선택하게 설정할 예정이므로 첫 번째 값만 사용
133117
String value = event.getValues().get(0);
134118
int weeks;
135119
try {
@@ -151,43 +135,17 @@ public void onStringSelectInteraction(StringSelectInteractionEvent event) {
151135
event.reply("투표 날짜 범위를 선택하셨어요!").setEphemeral(true).queue();
152136
}
153137

154-
// @Override
155-
// public void onMessageReactionAdd(MessageReactionAddEvent event) {
156-
// if (event.getUser() != null && event.getUser().isBot()) return;
157-
//
158-
// String channelId = event.getChannel().getId();
159-
// String messageId = event.getMessageId();
160-
//
161-
// String checkMessageId = participantCheckMessages.get(channelId);
162-
// if (checkMessageId == null || !checkMessageId.equals(messageId)) {
163-
// return;
164-
// }
165-
//
166-
// if (!event.getReaction().getEmoji().equals(Emoji.fromUnicode("✅"))) {
167-
// return;
168-
// }
169-
//
170-
// event.retrieveMember().queue(member -> {
171-
// if (member != null) {
172-
// wendyService.addParticipant(channelId, member.getId(), member.getEffectiveName());
173-
// System.out.println("[Command] Participant added: " + member.getEffectiveName());
174-
// }
175-
// });
176-
// }
177-
178138
private void handleStart(TextChannel channel) {
179139
String channelId = channel.getId();
180140
List<Member> members = channel.getMembers();
181-
182-
wendyService.startSession(channelId, members);
183-
141+
142+
discordWendyService.startSession(channelId, members);
143+
184144
channel.sendMessage("""
185145
안녕하세요! 일정 조율 도우미 웬디에요 :D
186146
지금부터 여러분의 일정 조율을 도와드릴게요
187147
""").queue();
188148

189-
190-
// 참석자 입력용 엔티티 셀렉트 메뉴 (유저 선택 드롭다운)
191149
EntitySelectMenu attendeeMenu = EntitySelectMenu.create(ATTENDEE_SELECT_MENU_ID, EntitySelectMenu.SelectTarget.USER)
192150
.setPlaceholder("참석자를 선택 / 검색해 주세요.")
193151
.setRequiredRange(1, 25)
@@ -197,7 +155,6 @@ private void handleStart(TextChannel channel) {
197155
.setActionRow(attendeeMenu)
198156
.queue();
199157

200-
// 2.1 날짜 범위 파악 질문 (드롭다운 방식)
201158
StringSelectMenu weekMenu = StringSelectMenu.create(WEEK_SELECT_MENU_ID)
202159
.setPlaceholder("몇 주 뒤의 일정을 계획하시나요?")
203160
.addOption("이번 주", "0")
@@ -213,54 +170,36 @@ private void handleStart(TextChannel channel) {
213170
.setActionRow(weekMenu)
214171
.queue();
215172
}
216-
173+
217174
private void handleDateInput(TextChannel channel, Member member, int weeks, boolean isRevote) {
218175
String channelId = channel.getId();
219176
String userMention = member.getAsMention();
220177
String channelName = channel.getName();
221-
178+
222179
waitingForDateInput.put(channelId, false);
223-
180+
224181
channel.sendMessage(userMention + " 님이 " + weeks + "주 뒤를 선택하셨어요!").queue();
225182
channel.sendMessage("해당 일정의 투표를 만들어드릴게요 :D").queue();
226183
channel.sendMessage("(투표 늦게 하는 사람 대머리🧑‍🦲)").queue();
227184
channel.sendMessage("투표를 생성 중입니다🛜").queue();
228-
229-
String voteUrl = isRevote
230-
? wendyService.recreateVote(channelId, channelName, weeks)
231-
: wendyService.createVote(channelId, channelName, weeks);
232-
185+
186+
String voteUrl = isRevote
187+
? discordWendyService.recreateVote(channelId, channelName, weeks)
188+
: discordWendyService.createVote(channelId, channelName, weeks);
189+
233190
channel.sendMessage(voteUrl).queue();
234-
wendyScheduler.startSchedule(channel);
235-
236-
237-
// // 투표 제한시간(24시간) + 30분 후 자동 종료 스케줄
238-
// CompletableFuture
239-
// .delayedExecutor(3 * 60 + 30, TimeUnit.SECONDS)
240-
// .execute(() -> {
241-
// String chId = channel.getId();
242-
// // 스케줄러 정리 + 세션 종료
243-
// wendyScheduler.stopSchedule(chId);
244-
// wendyService.endSession(chId);
245-
//
246-
// // 안내 메시지 전송
247-
// channel.sendMessage("""
248-
// 투표 제한 시간이 지나 웬디가 자동으로 종료되었어요 :D
249-
// 다시 일정 조율이 필요하시면 '웬디 시작'을 입력해 주세요!
250-
// """).queue();
251-
// });
191+
discordWendyScheduler.startSchedule(channel);
252192
}
253-
193+
254194
private void handleRevote(TextChannel channel) {
255195
String channelId = channel.getId();
256-
257-
if (!wendyService.hasPreviousVote(channelId)) {
196+
197+
if (!discordWendyService.hasPreviousVote(channelId)) {
258198
channel.sendMessage("아직 진행된 투표가 없어요🗑️").queue();
259199
return;
260200
}
261-
262-
wendyScheduler.stopSchedule(channelId);
263201

202+
discordWendyScheduler.stopSchedule(channelId);
264203

265204
StringSelectMenu weekMenu = StringSelectMenu.create(WEEK_SELECT_MENU_REVOTE_ID)
266205
.setPlaceholder("몇 주 뒤의 일정을 다시 계획하시나요?")
@@ -277,33 +216,33 @@ private void handleRevote(TextChannel channel) {
277216
.setActionRow(weekMenu)
278217
.queue();
279218
}
280-
219+
281220
private void handleEnd(TextChannel channel) {
282221
String channelId = channel.getId();
283-
284-
wendyScheduler.stopSchedule(channelId);
285-
wendyService.endSession(channelId);
286-
222+
223+
discordWendyScheduler.stopSchedule(channelId);
224+
discordWendyService.endSession(channelId);
225+
287226
participantCheckMessages.remove(channelId);
288227
waitingForDateInput.remove(channelId);
289-
228+
290229
channel.sendMessage("""
291230
웬디는 여기서 눈치껏 빠질게요 :D
292231
모두 알찬 시간 보내세요!
293232
""").queue();
294-
System.out.println("[Command] Session ended: " + channelId);
233+
System.out.println("[Discord Command] Session ended: " + channelId);
295234
}
296-
235+
297236
private void handleHelp(TextChannel channel) {
298237
channel.sendMessage("""
299238
웬디는 다음과 같은 기능이 있어요!
300-
239+
301240
**'웬디 시작'**: 일정 조율을 시작해요
302241
**'웬디 종료'**: 작동을 종료해요
303242
**'웬디 재투표'**: 동일한 참석자로 투표를 다시 올려요
304243
""").queue();
305244
}
306-
245+
307246
private Integer extractWeeks(String content) {
308247
String numbers = content.replaceAll("[^0-9]", "");
309248
if (numbers.isEmpty()) return null;

0 commit comments

Comments
 (0)