mirror of
https://github.com/DreamExposure/DisCal-Discord-Bot.git
synced 2026-05-02 23:29:34 -05:00
Add events slash command
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
package org.dreamexposure.discal.client.commands
|
||||
|
||||
import discord4j.core.event.domain.interaction.SlashCommandEvent
|
||||
import org.dreamexposure.discal.client.message.Responder
|
||||
import org.dreamexposure.discal.client.message.embed.EventEmbed
|
||||
import org.dreamexposure.discal.core.`object`.GuildSettings
|
||||
import org.dreamexposure.discal.core.extensions.discord4j.getCalendar
|
||||
import org.dreamexposure.discal.core.utils.getCommonMsg
|
||||
import org.springframework.stereotype.Component
|
||||
import reactor.core.publisher.Flux
|
||||
import reactor.core.publisher.Mono
|
||||
import reactor.function.TupleUtils
|
||||
import java.time.Instant
|
||||
|
||||
@Component
|
||||
class EventsCommand : SlashCommand {
|
||||
override val name = "events"
|
||||
override val ephemeral = false
|
||||
|
||||
override fun handle(event: SlashCommandEvent, settings: GuildSettings): Mono<Void> {
|
||||
return when (event.options[0].name) {
|
||||
"upcoming" -> upcomingEventsSubcommand(event, settings)
|
||||
"ongoing" -> ongoingEventsSubcommand(event, settings)
|
||||
"today" -> eventsTodaySubcommand(event, settings)
|
||||
else -> Mono.empty() //Never can reach this, makes compiler happy.
|
||||
}
|
||||
}
|
||||
|
||||
private fun upcomingEventsSubcommand(event: SlashCommandEvent, settings: GuildSettings): Mono<Void> {
|
||||
//Determine which calendar they want to use...
|
||||
val calNumMono = Mono.justOrEmpty(event.options[0].getOption("calendar").flatMap { it.value })
|
||||
.map { it.asLong().toInt() }
|
||||
.defaultIfEmpty(1)
|
||||
|
||||
val amountMono = Mono.justOrEmpty(event.options[0].getOption("amount").flatMap { it.value })
|
||||
.map { it.asLong().toInt() }
|
||||
.defaultIfEmpty(1)
|
||||
|
||||
return Mono.zip(calNumMono, amountMono).flatMap(TupleUtils.function { calNumb, amount ->
|
||||
if (amount < 1 || amount > 15) {
|
||||
Responder.followupEphemeral(event, getMessage("upcoming.failure.outOfRange", settings))
|
||||
}
|
||||
|
||||
event.interaction.guild.flatMap { guild ->
|
||||
guild.getCalendar(calNumb).flatMap { cal ->
|
||||
cal.getUpcomingEvents(amount).collectList().flatMap { events ->
|
||||
if (events.isEmpty()) {
|
||||
Responder.followup(event, getMessage("upcoming.success.none", settings))
|
||||
} else if (events.size == 1) {
|
||||
Responder.followup(
|
||||
event,
|
||||
getMessage("upcoming.success.one", settings),
|
||||
EventEmbed.getFull(guild, settings, events[0])
|
||||
)
|
||||
} else {
|
||||
Responder.followup(event, getMessage("upcoming.success.many", settings, "${events.size}"))
|
||||
.flatMapMany {
|
||||
Flux.fromIterable(events)
|
||||
}.flatMap {
|
||||
Responder.followup(event, EventEmbed.getCondensed(guild, settings, it))
|
||||
}.then()
|
||||
}
|
||||
}
|
||||
}.switchIfEmpty(Responder.followupEphemeral(event, getCommonMsg("error.notFound.calendar", settings)))
|
||||
}
|
||||
}).then()
|
||||
}
|
||||
|
||||
private fun ongoingEventsSubcommand(event: SlashCommandEvent, settings: GuildSettings): Mono<Void> {
|
||||
return Mono.justOrEmpty(event.options[0].getOption("calendar").flatMap { it.value })
|
||||
.map { it.asLong().toInt() }
|
||||
.defaultIfEmpty(1).flatMap { calNum ->
|
||||
event.interaction.guild.flatMap { guild ->
|
||||
guild.getCalendar(calNum).flatMap { cal ->
|
||||
cal.getOngoingEvents().collectList().flatMap { events ->
|
||||
if (events.isEmpty()) {
|
||||
Responder.followupEphemeral(
|
||||
event,
|
||||
getMessage("ongoing.success.none", settings)
|
||||
)
|
||||
} else if (events.size == 1) {
|
||||
Responder.followup(
|
||||
event,
|
||||
getMessage("ongoing.success.one", settings),
|
||||
EventEmbed.getFull(guild, settings, events[0])
|
||||
)
|
||||
} else {
|
||||
Responder.followup(event,
|
||||
getMessage("ongoing.success.many", settings, "${events.size}")
|
||||
).flatMapMany {
|
||||
Flux.fromIterable(events)
|
||||
}.flatMap {
|
||||
Responder.followup(event, EventEmbed.getCondensed(guild, settings, it))
|
||||
}.then()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}.then()
|
||||
}
|
||||
|
||||
private fun eventsTodaySubcommand(event: SlashCommandEvent, settings: GuildSettings): Mono<Void> {
|
||||
return Mono.justOrEmpty(event.options[0].getOption("calendar").flatMap { it.value })
|
||||
.map { it.asLong().toInt() }
|
||||
.defaultIfEmpty(1).flatMap { calNum ->
|
||||
event.interaction.guild.flatMap { guild ->
|
||||
guild.getCalendar(calNum).flatMap { cal ->
|
||||
cal.getEventsInNext24HourPeriod(Instant.now()).collectList().flatMap { events ->
|
||||
if (events.isEmpty()) {
|
||||
Responder.followupEphemeral(
|
||||
event,
|
||||
getMessage("today.success.none", settings)
|
||||
)
|
||||
} else if (events.size == 1) {
|
||||
Responder.followup(
|
||||
event,
|
||||
getMessage("today.success.one", settings),
|
||||
EventEmbed.getFull(guild, settings, events[0])
|
||||
)
|
||||
} else {
|
||||
Responder.followup(event,
|
||||
getMessage("today.success.many", settings, "${events.size}")
|
||||
).flatMapMany {
|
||||
Flux.fromIterable(events)
|
||||
}.flatMap {
|
||||
Responder.followup(event, EventEmbed.getCondensed(guild, settings, it))
|
||||
}.then()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}.then()
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,15 @@ object Responder {
|
||||
return sendFollowup(event, spec)
|
||||
}
|
||||
|
||||
fun followup(event: InteractionCreateEvent, message: String, embed: EmbedCreateSpec): Mono<MessageData> {
|
||||
val spec = WebhookExecuteRequest.builder()
|
||||
.content(message)
|
||||
.addEmbed(embed.asRequest())
|
||||
.build()
|
||||
|
||||
return sendFollowup(event, spec)
|
||||
}
|
||||
|
||||
fun followupEphemeral(event: InteractionCreateEvent, embed: EmbedCreateSpec): Mono<MessageData> {
|
||||
val spec = WebhookExecuteRequest.builder()
|
||||
.addEmbed(embed.asRequest())
|
||||
@@ -40,6 +49,14 @@ object Responder {
|
||||
return sendFollowupEphemeral(event, spec)
|
||||
}
|
||||
|
||||
fun followupEphemeral(event: InteractionCreateEvent, message: String, embed: EmbedCreateSpec): Mono<MessageData> {
|
||||
val spec = WebhookExecuteRequest.builder()
|
||||
.content(message)
|
||||
.addEmbed(embed.asRequest())
|
||||
.build()
|
||||
|
||||
return sendFollowupEphemeral(event, spec)
|
||||
}
|
||||
|
||||
private fun sendFollowup(event: InteractionCreateEvent, request: WebhookExecuteRequest) =
|
||||
event.interactionResponse.createFollowupMessage(MultipartRequest.ofRequest(request))
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package org.dreamexposure.discal.client.message.embed
|
||||
|
||||
import discord4j.core.`object`.entity.Guild
|
||||
import discord4j.core.spec.EmbedCreateSpec
|
||||
import org.dreamexposure.discal.core.`object`.GuildSettings
|
||||
import org.dreamexposure.discal.core.entities.Event
|
||||
import java.time.Instant
|
||||
|
||||
object EventEmbed : EmbedMaker {
|
||||
fun getFull(guild: Guild, settings: GuildSettings, event: Event): EmbedCreateSpec {
|
||||
val builder = defaultBuilder(guild, settings)
|
||||
.title(getMessage("event", "full.title", settings))
|
||||
.footer(getMessage("event", "full.footer", settings, event.eventId), null)
|
||||
.color(event.color.asColor())
|
||||
|
||||
if (event.name.isNotEmpty())
|
||||
builder.addField(getMessage("event", "full.field.name", settings), event.name, false)
|
||||
if (event.description.isNotEmpty())
|
||||
builder.addField(getMessage("event", "full.field.desc", settings), event.description, false)
|
||||
|
||||
builder.addField(getMessage("event", "full.field.start", settings), timestamp(event.start), true)
|
||||
builder.addField(getMessage("event", "full.field.end", settings), timestamp(event.end), true)
|
||||
|
||||
if (event.location.isNotEmpty())
|
||||
builder.addField(getMessage("event", "full.field.location", settings), event.location, false)
|
||||
|
||||
builder.addField(getMessage("event", "full.field.cal", settings), "${event.calendar.calendarNumber}", false)
|
||||
|
||||
if (event.image.isNotEmpty())
|
||||
builder.image(event.image)
|
||||
|
||||
return builder.build()
|
||||
}
|
||||
|
||||
fun getCondensed(guild: Guild, settings: GuildSettings, event: Event): EmbedCreateSpec {
|
||||
val builder = defaultBuilder(guild, settings)
|
||||
.title(getMessage("event", "con.title", settings))
|
||||
.footer(getMessage("event", "con.footer", settings, event.eventId), null)
|
||||
.color(event.color.asColor())
|
||||
|
||||
if (event.name.isNotEmpty())
|
||||
builder.addField(getMessage("event", "con.field.name", settings), event.name, false)
|
||||
|
||||
builder.addField(getMessage("event", "con.field.start", settings), timestamp(event.start), true)
|
||||
|
||||
if (event.location.isNotEmpty())
|
||||
builder.addField(getMessage("event", "con.field.location", settings), event.location, false)
|
||||
|
||||
if (event.image.isNotEmpty())
|
||||
builder.thumbnail(event.image)
|
||||
|
||||
return builder.build()
|
||||
}
|
||||
|
||||
|
||||
private fun timestamp(time: Instant): String = "<t:${time.toEpochMilli() / 1000}:F>"
|
||||
}
|
||||
Reference in New Issue
Block a user