Skip to content

Commit 979f0a1

Browse files
committed
Refactor/#24 사용자 랜덤 선택 기능 개선 (#25)
* refactor: Changed command options - Added count query in random-user-pick command * refactor: Changed `getRandomUserByChannel` Logic - Changed logic to get user info with guild(server) information * chore: Removed unused function
1 parent 6795ba7 commit 979f0a1

File tree

4 files changed

+47
-75
lines changed

4 files changed

+47
-75
lines changed

internal/handler/commands.go

+9
Original file line numberDiff line numberDiff line change
@@ -80,5 +80,14 @@ var commands = []*discordgo.ApplicationCommand{
8080
{
8181
Name: commandRandomUserPick,
8282
Description: "채널에 있는 사용자 중 랜덤으로 한 명을 선택합니다.",
83+
Options: []*discordgo.ApplicationCommandOption{
84+
{
85+
Type: discordgo.ApplicationCommandOptionInteger,
86+
Name: "count",
87+
Description: "랜덤으로 선택할 사용자 수를 입력해주세요.",
88+
Required: false,
89+
MinValue: func() *float64 { v := 1.0; return &v }(),
90+
},
91+
},
8392
},
8493
}

internal/handler/handlers.go

+38-35
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"day-day-review/internal/util"
77
"fmt"
88
"log"
9+
"math/rand"
910
"strconv"
1011
"strings"
1112
"time"
@@ -183,52 +184,54 @@ func getScrumsByDate(session *discordgo.Session, interaction *discordgo.Interact
183184

184185
// getRandomUserByChannel 채널에 있는 사용자 중 랜덤으로 한 명을 선택합니다.
185186
func getRandomUserByChannel(session *discordgo.Session, interaction *discordgo.InteractionCreate) {
186-
channel, err := session.Channel(interaction.ChannelID)
187-
// 채널 정보를 불러오는 중 오류가 발생하면 에러 메시지를 전송합니다.
188-
if err != nil {
189-
logErrorAndSendMessage(session, interaction, "채널을 불러오는 중 오류가 발생했습니다.", err)
190-
return
187+
count := 1
188+
// 옵션을 받았을 경우 옵션 값을 사용합니다.
189+
if options := interaction.ApplicationCommandData().Options; len(options) > 0 {
190+
count = int(options[0].IntValue())
191191
}
192-
// 음성 채널이 아니면 에러 메시지를 전송합니다.
193-
if channel.Type != discordgo.ChannelTypeGuildVoice {
194-
sendMessage(session, interaction, "음성 채널에서만 사용할 수 있는 명령어입니다.")
195-
return
196-
}
197-
guild, err := session.State.Guild(channel.GuildID)
198-
// 서버 정보를 불러오는 중 오류가 발생하면 에러 메시지를 전송합니다.
192+
log.Println("GetRandomUserByChannel | Received count:", count)
193+
guild, err := session.State.Guild(guildId)
194+
// 채널 정보를 불러오는 중 오류가 발생하면 에러 메시지를 전송합니다.
199195
if err != nil {
200196
logErrorAndSendMessage(session, interaction, "서버 정보를 불러오는 중 오류가 발생했습니다.", err)
201197
return
202198
}
203-
var members []*discordgo.Member // 음성 채널에 있는 사용자 목록을 저장합니다.
204-
memberMap := make(map[string]*discordgo.Member) // 사용자 ID를 키로 사용자 정보를 저장합니다.
205-
for _, member := range guild.Members {
206-
memberMap[member.User.ID] = member
207-
}
208-
209-
// 음성 채널에 있는 사용자 목록을 불러옵니다.
210-
for _, vs := range guild.VoiceStates {
211-
if vs.ChannelID == channel.ID {
212-
if member, ok := memberMap[vs.UserID]; ok {
213-
members = append(members, member)
199+
// 채널에 참여중인 사용자를 불러옵니다.
200+
var members []string
201+
for _, voiceState := range guild.VoiceStates {
202+
if voiceState.ChannelID == interaction.ChannelID {
203+
member, err := session.GuildMember(guildId, voiceState.UserID)
204+
if err != nil {
205+
log.Printf("Error getting member: %v", err)
206+
continue
207+
}
208+
username := member.Nick
209+
if username == "" {
210+
username = member.User.GlobalName
214211
}
212+
members = append(members, username)
215213
}
216214
}
217-
log.Printf("Members: %+v", members)
218-
// 음성 채널에 사용자가 없으면 에러 메시지를 전송합니다.
219-
if len(members) == 0 {
220-
sendMessage(session, interaction, "음성 채널에 사용자가 없습니다.")
215+
// 채널에 참여중인 사용자가 없거나 요청한 사용자 수가 채널에 참여중인 사용자 수보다 많을 경우 에러 메시지를 전송합니다.
216+
log.Printf("GetRandomUserByChannel | Current member arr: %+v", members)
217+
if len(members) == 0 || count > len(members) {
218+
logErrorAndSendMessage(session, interaction, "채널에 참여중인 사용자가 부족합니다.", nil)
221219
return
222220
}
223-
224-
// 음성 채널에 있는 사용자 중 랜덤으로 한 명을 선택합니다.
225-
randomMember := members[util.PickRandomNumber(len(members))]
226-
// 사용자의 닉네임이 없으면 사용자 이름을 사용합니다.
227-
username := randomMember.Nick
228-
if username == "" {
229-
username = randomMember.User.GlobalName
221+
// 모든 사용자를 선택할 경우 모든 사용자를 선택했다는 메시지를 전송합니다.
222+
if count == len(members) {
223+
sendMessage(session, interaction, "모든 사용자가 선택되었습니다.")
224+
return
230225
}
231-
sendMessage(session, interaction, fmt.Sprintf("랜덤으로 선택된 사람은 %s입니다!", username))
226+
// 랜덤으로 사용자를 선택합니다.
227+
r := rand.New(rand.NewSource(time.Now().UnixNano()))
228+
r.Shuffle(len(members), func(i, j int) {
229+
members[i], members[j] = members[j], members[i]
230+
})
231+
members = members[:count]
232+
// 선택된 사용자를 메시지로 전송합니다.
233+
sendMessage(session, interaction, fmt.Sprintf("선택된 사람은 %v 입니다!", strings.Join(members, ", ")))
234+
return
232235
}
233236

234237
// retrospectiveToString 회고 목록을 문자열로 변환합니다.

internal/util/util.go

-11
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package util
33
import (
44
"fmt"
55
"io"
6-
"math/rand"
76
"os"
87
"strings"
98
"time"
@@ -56,13 +55,3 @@ func LoadFile(filePath string) ([]byte, error) {
5655
}
5756
return arr, nil
5857
}
59-
60-
// PickRandomNumber 0부터 upperBound-1 사이의 랜덤한 숫자를 반환 (upperBound는 포함하지 않음) upperBound가 0 이하일 경우 0을 반환
61-
func PickRandomNumber(upperBound int) int {
62-
if upperBound <= 0 {
63-
return 0
64-
}
65-
source := rand.NewSource(time.Now().UnixNano())
66-
r := rand.New(source)
67-
return r.Intn(upperBound)
68-
}

internal/util/util_test.go

-29
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package util
22

33
import (
44
"os"
5-
"strconv"
65
"testing"
76
"time"
87
)
@@ -109,31 +108,3 @@ func TestLoadFile_InvalidFile(t *testing.T) {
109108
t.Errorf("expected error, but nil")
110109
}
111110
}
112-
113-
func TestPickRandomNumber_ValidInput(t *testing.T) {
114-
testCases := []int{1, 10, 100, 1000, 10000}
115-
for _, tc := range testCases {
116-
t.Run("UpperBound: "+strconv.Itoa(tc), func(t *testing.T) {
117-
// Act
118-
actual := PickRandomNumber(tc)
119-
// Assert
120-
if actual < 0 || actual >= tc {
121-
t.Errorf("expected 0 <= actual < %d, but got %d", tc, actual)
122-
}
123-
})
124-
}
125-
}
126-
127-
func TestPickRandomNumber_InputLessThenOrEqualZero(t *testing.T) {
128-
testCases := []int{0, -1, -10, -100, -1000}
129-
for _, tc := range testCases {
130-
t.Run("UpperBound: "+strconv.Itoa(tc), func(t *testing.T) {
131-
// Act
132-
actual := PickRandomNumber(tc)
133-
// Assert
134-
if actual != 0 {
135-
t.Errorf("expected 0, but got %d", actual)
136-
}
137-
})
138-
}
139-
}

0 commit comments

Comments
 (0)