-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
/poll command: 發起投票,且一定時間後結束投票並展示投票結果 #100
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
🤖 OpenAI Summary of ChangesThe changes involve modifications to the functionality of the codebase, including adding new features, modifying existing functions, and adding dependencies. The changes could impact the behavior of the code and introduce bugs or security vulnerabilities. Therefore, a thorough review is necessary to ensure the logic, security, performance, and maintainability of the code.
Chat with 🤖 OpenAI Bot (
|
import tw.waterballsa.utopia.jda.JdaInstance.compositeListener | ||
import java.lang.reflect.Method |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤖 OpenAI
The import statements are not sorted in alphabetical order. Please sort them.
import tw.waterballsa.utopia.jda.JdaInstance.compositeListener | |
import java.lang.reflect.Method | |
import java.lang.reflect.Method | |
import tw.waterballsa.utopia.jda.JdaInstance.compositeListener | |
fun removeExpiredMembersPeriodically(jda: JDA, properties: WsaDiscordProperties) = listener { | ||
val guild = jda.getGuildById(properties.guildId)!! | ||
val role = jda.getRoleById(properties.wsaGaaSMemberRoleId)!! | ||
|
||
timer.onStart( | ||
removeExpiredMemberRolePeriodically(guild, role), | ||
now().atStartOfDay().toDate(), | ||
24.hours.inWholeMilliseconds | ||
) | ||
} | ||
|
||
private fun removeExpiredMemberRolePeriodically( | ||
guild: Guild, | ||
role: Role | ||
) = timerTask { | ||
observedMemberRepository.findAll() | ||
.filter { it.isCreatedTimeOver30Days() } | ||
.takeIf { it.isNotEmpty() } | ||
?.onEach { removeRoleFromRecord(guild, it, role) } | ||
?.map { it.id } | ||
?.let { observedMemberRepository.removeObservedMemberByIds(it) } | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤖 OpenAI
The new code adds a new function removeExpiredMembersPeriodically
that removes expired members from the observed member repository periodically. The implementation looks good, but there is an opportunity to improve performance by using a more efficient data structure for storing the observed members. Consider using a hash set or a map instead of a list to store the observed members to improve lookup time.
.../main/kotlin/tw/waterballsa/utopia/jda/extensions/GenericCommandInteractionEventExtension.kt
Show resolved
Hide resolved
.../main/kotlin/tw/waterballsa/utopia/jda/extensions/GenericCommandInteractionEventExtension.kt
Show resolved
Hide resolved
wsa-bot-commands.md
Outdated
## poll | ||
| Commands | Arguments | Description | | ||
|:--------:|:-------------------------------:|:-----------:| | ||
| poll | time time-unit question options | <TODO> | | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤖 OpenAI
The new /poll
command has been added to the document. The description for the command is missing and marked as <TODO>
. Please update the description to provide a clear explanation of what the command does and how it works.
audio-experience/src/main/kotlin/tw/waterballsa/utopia/audiox/MuteAudiences.kt
Show resolved
Hide resolved
audio-experience/src/main/kotlin/tw/waterballsa/utopia/audiox/MuteAudiences.kt
Outdated
Show resolved
Hide resolved
audio-experience/src/main/kotlin/tw/waterballsa/utopia/audiox/MuteAudiences.kt
Outdated
Show resolved
Hide resolved
private const val OPTION_QUESTION = "question" | ||
|
||
private const val OPTION_OPTIONS = "options" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤖 OpenAI
The pollOptionStrings
variable is not being used. Is this intentional? If so, please remove the variable declaration and assignment.
private const val OPTION_QUESTION = "question" | |
private const val OPTION_OPTIONS = "options" | |
// Remove pollOptionStrings variable declaration and assignment |
poll/src/main/kotlin/tw.waterballsa.utopia.poll/PollCommandListener.kt
Outdated
Show resolved
Hide resolved
.../main/kotlin/tw/waterballsa/utopia/jda/extensions/GenericCommandInteractionEventExtension.kt
Show resolved
Hide resolved
poll/src/main/kotlin/tw.waterballsa.utopia.poll/PollCommandListener.kt
Outdated
Show resolved
Hide resolved
poll/src/main/kotlin/tw.waterballsa.utopia.poll/PollCommandListener.kt
Outdated
Show resolved
Hide resolved
fun observeMember(properties: WsaDiscordProperties) = listener { | ||
on<SlashCommandInteractionEvent> { | ||
val targetUser = getOptionsByType(OptionType.USER).first().asMember!! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤖 OpenAI
The getOptionsByType
function call may throw an exception if no options of type OptionType.USER
are found. Consider adding error handling to handle this case.
fun observeMember(properties: WsaDiscordProperties) = listener { | |
on<SlashCommandInteractionEvent> { | |
val targetUser = getOptionsByType(OptionType.USER).first().asMember!! | |
val targetUser = getOptionsByType(OptionType.USER).firstOrNull()?.asMember | |
if (targetUser == null) { | |
replyEphemerally("No user option found.") | |
return@on | |
} |
val commandUser = member!! | ||
val gaaSMemberRoleId = properties.wsaGaaSMemberRoleId |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤖 OpenAI
Consider extracting the alphaRoleId
and wsaGaaSMemberRoleId
values into a separate function or class to avoid code duplication.
val commandUser = member!! | |
val gaaSMemberRoleId = properties.wsaGaaSMemberRoleId | |
private fun getRoleIds(properties: WsaDiscordProperties): Pair<Long, Long> { | |
return properties.wsaAlphaRoleId to properties.wsaGaaSMemberRoleId | |
} | |
// Usage | |
val (alphaRoleId, gaaSMemberRoleId) = getRoleIds(properties) |
when { | ||
interaction.fullCommandName != "gaas observe" -> return@on | ||
!commandUser.isAlphaMember(alphaRoleId) -> { | ||
replyEphemerally("權限不足") | ||
return@on | ||
} | ||
|
||
!targetUser.isGaaSMember(gaaSMemberRoleId) -> { | ||
replyEphemerally("${targetUser.asMention} 並非 GaaS 成員") | ||
return@on | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤖 OpenAI
Consider extracting the permission checks into a separate function or class to improve readability and maintainability.
when { | |
interaction.fullCommandName != "gaas observe" -> return@on | |
!commandUser.isAlphaMember(alphaRoleId) -> { | |
replyEphemerally("權限不足") | |
return@on | |
} | |
!targetUser.isGaaSMember(gaaSMemberRoleId) -> { | |
replyEphemerally("${targetUser.asMention} 並非 GaaS 成員") | |
return@on | |
} | |
} | |
private fun checkPermissions( | |
interaction: SlashCommandInteractionEvent, | |
commandUser: Member, | |
alphaRoleId: Long, | |
targetUser: Member?, | |
gaaSMemberRoleId: Long | |
): Boolean { | |
if (interaction.fullCommandName != "gaas observe" && interaction.fullCommandName != "gaas unobserve") { | |
return false | |
} | |
if (!commandUser.isAlphaMember(alphaRoleId)) { | |
replyEphemerally("權限不足") | |
return false | |
} | |
if (targetUser != null && !targetUser.isGaaSMember(gaaSMemberRoleId)) { | |
replyEphemerally("${targetUser.asMention} 並非 GaaS 成員") | |
return false | |
} | |
return true | |
} | |
// Usage | |
val (alphaRoleId, gaaSMemberRoleId) = getRoleIds(properties) | |
val targetUser = getOptionsByType(OptionType.USER).firstOrNull()?.asMember | |
if (!checkPermissions(interaction, commandUser, alphaRoleId, targetUser, gaaSMemberRoleId)) { | |
return@on | |
} |
if (observedMemberRepository.exists(targetUser.id)) { | ||
replyEphemerally("${targetUser.asMention} 已經在觀察名單") | ||
return@on | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤖 OpenAI
Consider extracting the check for an existing observed member into a separate function or class to improve readability and maintainability.
if (observedMemberRepository.exists(targetUser.id)) { | |
replyEphemerally("${targetUser.asMention} 已經在觀察名單") | |
return@on | |
} | |
private fun checkExistingObservedMember(targetUserId: String): Boolean { | |
if (observedMemberRepository.exists(targetUserId)) { | |
replyEphemerally("${targetUser.asMention} 已經在觀察名單") | |
return true | |
} | |
return false | |
} | |
// Usage | |
if (checkExistingObservedMember(targetUser.id)) { | |
return@on | |
} |
fun removeMember(properties: WsaDiscordProperties) = listener { | ||
on<SlashCommandInteractionEvent> { | ||
val targetUser = getOptionsByType(OptionType.USER).first().asMember!! | ||
val alphaRoleId = properties.wsaAlphaRoleId | ||
val commandUser = member!! | ||
val gaaSMemberRoleId = properties.wsaGaaSMemberRoleId | ||
|
||
when { | ||
interaction.fullCommandName != "gaas unobserve" -> return@on | ||
!commandUser.isAlphaMember(alphaRoleId) -> { | ||
replyEphemerally("權限不足") | ||
return@on | ||
} | ||
|
||
!targetUser.isGaaSMember(gaaSMemberRoleId) -> { | ||
replyEphemerally("${targetUser.asMention} 並非 GaaS 成員") | ||
return@on | ||
} | ||
} | ||
|
||
if (observedMemberRepository.exists(targetUser.id)) { | ||
observedMemberRepository.removeObservedMember(targetUser.id) | ||
} | ||
replyEphemerally("${targetUser.asMention} 已經從觀察名單移除") | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤖 OpenAI
Consider extracting the removeMember
function into a separate class or function to avoid code duplication with the observeMember
function.
fun removeMember(properties: WsaDiscordProperties) = listener { | |
on<SlashCommandInteractionEvent> { | |
val targetUser = getOptionsByType(OptionType.USER).first().asMember!! | |
val alphaRoleId = properties.wsaAlphaRoleId | |
val commandUser = member!! | |
val gaaSMemberRoleId = properties.wsaGaaSMemberRoleId | |
when { | |
interaction.fullCommandName != "gaas unobserve" -> return@on | |
!commandUser.isAlphaMember(alphaRoleId) -> { | |
replyEphemerally("權限不足") | |
return@on | |
} | |
!targetUser.isGaaSMember(gaaSMemberRoleId) -> { | |
replyEphemerally("${targetUser.asMention} 並非 GaaS 成員") | |
return@on | |
} | |
} | |
if (observedMemberRepository.exists(targetUser.id)) { | |
observedMemberRepository.removeObservedMember(targetUser.id) | |
} | |
replyEphemerally("${targetUser.asMention} 已經從觀察名單移除") | |
} | |
private fun removeObservedMember( | |
properties: WsaDiscordProperties, | |
interaction: SlashCommandInteractionEvent, | |
observedMemberRepository: ObservedMemberRepository | |
) = listener { | |
val targetUser = getOptionsByType(OptionType.USER).firstOrNull()?.asMember | |
val (alphaRoleId, gaaSMemberRoleId) = getRoleIds(properties) | |
val commandUser = member!! | |
if (!checkPermissions(interaction, commandUser, alphaRoleId, targetUser, gaaSMemberRoleId)) { | |
return@listener | |
} | |
if (!checkExistingObservedMember(targetUser!!.id)) { | |
observedMemberRepository.removeObservedMember(targetUser.id) | |
replyEphemerally("${targetUser.asMention} 已經從觀察名單移除") | |
} | |
} | |
// Usage | |
removeObservedMember(properties, interaction, observedMemberRepository) |
timer.onStart( | ||
removeExpiredMemberRolePeriodically(guild, role), | ||
now().atStartOfDay().toDate(), | ||
24.hours.inWholeMilliseconds | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤖 OpenAI
Consider using the Timer.scheduleAtFixedRate
function instead of onStart
to schedule the task to run periodically.
timer.onStart( | |
removeExpiredMemberRolePeriodically(guild, role), | |
now().atStartOfDay().toDate(), | |
24.hours.inWholeMilliseconds | |
) | |
timer.scheduleAtFixedRate( | |
removeExpiredMemberRolePeriodically(guild, role), | |
now().atStartOfDay().toDate(), | |
24.hours.inWholeMilliseconds | |
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review done.
poll/src/main/kotlin/tw.waterballsa.utopia.poll/PollCommandListener.kt
Outdated
Show resolved
Hide resolved
poll/src/main/kotlin/tw.waterballsa.utopia.poll/PollCommandListener.kt
Outdated
Show resolved
Hide resolved
poll/src/main/kotlin/tw.waterballsa.utopia.poll/PollCommandListener.kt
Outdated
Show resolved
Hide resolved
1) 取消表情 = 取消投票 2) 時間到之後取消 session
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Kudos, SonarCloud Quality Gate passed! |
fun GenericCommandInteractionEvent.getOptionAsLongInRange(name: String, range: LongRange): Long? { | ||
return getOptionAsLongWithValidation(name, "a long that within ${range.first} ~ ${range.last}") { | ||
range.contains(it) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤖 OpenAI
The getOptionAsLongInRange
function seems to have a typo in the name of the function. It should be getOptionAsLongWithValidation
. Also, the validation message could be improved by using a more readable format string. Consider changing line 19 to:
return getOptionAsLongWithValidation(name, "a long within the range ${range.first} to ${range.last}") {
range.contains(it)
}
} | ||
} | ||
|
||
fun GenericCommandInteractionEvent.getOptionAsLongInRange(name: String, range: LongRange): Long? { | ||
return getOptionAsLongWithValidation(name, "a long that within ${range.first} ~ ${range.last}") { | ||
range.contains(it) | ||
} | ||
} | ||
|
||
fun GenericCommandInteractionEvent.getOptionAsIntInRange(name: String, range: IntRange): Int? { | ||
return getOptionAsIntWithValidation(name, "a integer that within ${range.first} ~ ${range.last}") { | ||
range.contains(it) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤖 OpenAI
Note: This review was outside of the patch, so it was mapped to the patch with the greatest overlap. Original lines [24-28]
Similar to the previous hunk, the getOptionAsIntInRange
function has a typo in its name and should be changed to getOptionAsIntWithValidation
. Additionally, the validation message could be improved by using a more readable format string. Consider changing line 25 to:
return getOptionAsIntWithValidation(name, "an integer within the range ${range.first} to ${range.last}") {
range.contains(it)
}
return getOptionWithValidation(name, optionTypeName, validation) { it?.asString } | ||
} | ||
|
||
fun GenericCommandInteractionEvent.getOptionAsLongWithValidation(name: String, | ||
optionTypeName: String, | ||
validation: (Long) -> Boolean): Long? { | ||
return getOptionWithValidation(name, optionTypeName, validation) { it?.asLong } | ||
} | ||
|
||
fun GenericCommandInteractionEvent.getOptionAsIntWithValidation(name: String, | ||
optionTypeName: String, | ||
validation: (Int) -> Boolean): Int? { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤖 OpenAI
Note: This review was outside of the patch, so it was mapped to the patch with the greatest overlap. Original lines [48-52]
Similar to the previous hunk, the getOptionAsIntWithValidation
function seems to be missing a parameter for the option type name. Consider adding it as the second parameter and updating the call sites accordingly.
| Commands | Arguments | Description | | ||
|:----------------------:| -------------------------------------------------------------------------------------------------- | ---------------------------------------------------- | | ||
| gaas stats-avg-and-max | event-date-year(INTEGER): Year<br>event-date-month(INTEGER): Month<br>event-date-day(INTEGER): Day | Get Avg And Max Participants Number at Specific Date | | ||
| gaas observe | gaas-member(USER): GaaS Member | Add a specific member to the watchlist | | ||
| gaas unobserved | gaas-member(USER): GaaS Member | Remove a specific member from the watchlist | | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤖 OpenAI
The gaas
subcommand seems to be missing input validation for the gaas-member
argument. It is recommended to validate that the user provided as an argument is actually a member of the GaaS team before adding or removing them from the watchlist. This can prevent unauthorized access to sensitive information.
## russian-roulette | ||
| Commands | Arguments | Description | | ||
|:----------------:| --------- | ------------ | | ||
| russian-roulette | | GaaS Command | | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤖 OpenAI
The russian-roulette
subcommand seems to be incomplete. Please provide more details on what this command does and how it works.
| Commands | Arguments | Description | | ||
|:--------------:| ---------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | | ||
| audio breakout | room-size(INTEGER): Number of members per room.<br>countdown(INTEGER): Countdown time in seconds.<br>room-name(STRING): The name prefix of per room. | Create breakout rooms. | | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤖 OpenAI
The audio breakout
subcommand seems to be missing input validation for the room-size
, countdown
, and room-name
arguments. It is recommended to validate that these arguments are within reasonable limits and do not cause any performance issues or security vulnerabilities.
fun observeMember(properties: WsaDiscordProperties) = listener { | ||
on<SlashCommandInteractionEvent> { | ||
val targetUser = getOptionsByType(OptionType.USER).first().asMember!! | ||
val alphaRoleId = properties.wsaAlphaRoleId | ||
val commandUser = member!! | ||
val gaaSMemberRoleId = properties.wsaGaaSMemberRoleId | ||
|
||
when { | ||
interaction.fullCommandName != "gaas observe" -> return@on | ||
!commandUser.isAlphaMember(alphaRoleId) -> { | ||
replyEphemerally("權限不足") | ||
return@on | ||
} | ||
|
||
!targetUser.isGaaSMember(gaaSMemberRoleId) -> { | ||
replyEphemerally("${targetUser.asMention} 並非 GaaS 成員") | ||
return@on | ||
} | ||
} | ||
|
||
if (observedMemberRepository.exists(targetUser.id)) { | ||
replyEphemerally("${targetUser.asMention} 已經在觀察名單") | ||
return@on | ||
} | ||
|
||
observedMemberRepository.addObservedMember(targetUser.toObservedMemberRecord()) | ||
replyEphemerally("${targetUser.asMention} 已經成功加入觀察名單") | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤖 OpenAI
The observeMember
function seems to be handling a slash command event and adding a user to an observed member list. There are several issues with this code:
- The function is doing too many things at once, including input validation, permission checking, and database operations. It would be better to split these responsibilities into separate functions.
- The function is using magic strings for command names instead of constants or enums.
- The function is using
return@on
statements to exit early from the function. This can make the code harder to read and understand. - The function is not handling errors or exceptions that may occur during its execution.
fun observeMember(properties: WsaDiscordProperties) = listener { | |
on<SlashCommandInteractionEvent> { | |
val targetUser = getOptionsByType(OptionType.USER).first().asMember!! | |
val alphaRoleId = properties.wsaAlphaRoleId | |
val commandUser = member!! | |
val gaaSMemberRoleId = properties.wsaGaaSMemberRoleId | |
when { | |
interaction.fullCommandName != "gaas observe" -> return@on | |
!commandUser.isAlphaMember(alphaRoleId) -> { | |
replyEphemerally("權限不足") | |
return@on | |
} | |
!targetUser.isGaaSMember(gaaSMemberRoleId) -> { | |
replyEphemerally("${targetUser.asMention} 並非 GaaS 成員") | |
return@on | |
} | |
} | |
if (observedMemberRepository.exists(targetUser.id)) { | |
replyEphemerally("${targetUser.asMention} 已經在觀察名單") | |
return@on | |
} | |
observedMemberRepository.addObservedMember(targetUser.toObservedMemberRecord()) | |
replyEphemerally("${targetUser.asMention} 已經成功加入觀察名單") | |
} | |
fun observeMember(properties: WsaDiscordProperties) = listener { | |
on<SlashCommandInteractionEvent> { | |
val targetUser = getOptionsByType(OptionType.USER).first().asMember!! | |
val alphaRoleId = properties.wsaAlphaRoleId | |
val commandUser = member!! | |
val gaaSMemberRoleId = properties.wsaGaaSMemberRoleId | |
if (!isAuthorizedToObserve(commandUser, alphaRoleId)) { | |
replyEphemerally("權限不足") | |
return@on | |
} | |
if (!isGaaSMember(targetUser, gaaSMemberRoleId)) { | |
replyEphemerally("${targetUser.asMention} 並非 GaaS 成員") | |
return@on | |
} | |
try { | |
addObservedMember(targetUser.toObservedMemberRecord()) | |
replyEphemerally("${targetUser.asMention} 已經成功加入觀察名單") | |
} catch (e: Exception) { | |
log.error(e) { "Failed to add observed member ${targetUser.id}" } | |
replyEphemerally("無法加入觀察名單") | |
} | |
} | |
} | |
private fun isAuthorizedToObserve(user: Member, alphaRoleId: Long): Boolean { | |
return user.isAlphaMember(alphaRoleId) | |
} | |
private fun isGaaSMember(user: Member, gaaSMemberRoleId: Long): Boolean { | |
return user.isGaaSMember(gaaSMemberRoleId) | |
} | |
private fun addObservedMember(record: ObservedMemberRecord) { | |
if (observedMemberRepository.exists(record.id)) { | |
throw IllegalArgumentException("User ${record.id} already exists in observed member list") | |
} | |
observedMemberRepository.addObservedMember(record) | |
} |
---new_hunk---
110: private fun removeExpiredMemberRolePeriodically(
111: guild: Guild,
112: role: Role
113: ) = timerTask {
114: observedMemberRepository.findAll()
115: .filter { it.isCreatedTimeOver30Days() }
116: .takeIf { it.isNotEmpty() }
117: ?.onEach { removeRoleFromRecord(guild, it, role) }
118: ?.map { it.id }
119: ?.let { observedMemberRepository.removeObservedMemberByIds(it) }
120: }
121:
122: private fun removeRoleFromRecord(guild: Guild, record: ObservedMemberRecord, role: Role) {
123: guild.removeRoleFromMember(UserSnowflake.fromId(record.id), role).queue {
124: log.info { "[Observe] {\"Observe\" : \"Remove the expired Member [${record.name}]. \"}" }
125: }
126: }
---old_hunk---
---end_change_section---
<groupId>tw.waterballsa.utopia</groupId> | ||
<artifactId>audience-counter</artifactId> | ||
</dependency> | ||
|
||
<!-- <dependency>--> | ||
<!-- <groupId>tw.waterballsa.utopia</groupId>--> | ||
<!-- <artifactId>poll</artifactId>--> | ||
<!-- </dependency>--> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤖 OpenAI
A new dependency for poll
has been commented out. It's unclear why it was commented out, but if it's no longer needed, it should be removed entirely. If it is still needed, it should be uncommented and added to the dependencies section.
<groupId>tw.waterballsa.utopia</groupId> | |
<artifactId>audience-counter</artifactId> | |
</dependency> | |
<!-- <dependency>--> | |
<!-- <groupId>tw.waterballsa.utopia</groupId>--> | |
<!-- <artifactId>poll</artifactId>--> | |
<!-- </dependency>--> | |
<dependency> | |
<groupId>tw.waterballsa.utopia</groupId> | |
<artifactId>poll</artifactId> | |
</dependency> |
Why need this change? / Root cause:
Changes made:
Test Scope / Change impact:
/poll
Summary by OpenAI
Release Notes:
/poll
command to initiate a polling session and permit Discord members to cast their votes for various options within a specified amount of time.gaas
.MuteAudiences
class inaudio-experience
.discord-impl-jda
to retrieve options from a Discord slash command interaction event with validation.