Skip to content
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

Discord bot #27

Merged
merged 3 commits into from
Mar 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.gradle
.idea/
build
.envrc.local
5 changes: 5 additions & 0 deletions apps/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ plugins {
id("java")
}

repositories {
mavenCentral()
}

tasks.withType<Jar> {
manifest {
attributes["Main-Class"] = "com.agilogy.timetracking.app.ApiServerKt"
Expand Down Expand Up @@ -39,6 +43,7 @@ dependencies {
implementation(project(":postgresdb"))
implementation(project(":httpapi"))
implementation(project(":herokupostgres"))
implementation("net.dv8tion:JDA:5.0.0-alpha.22")
implementation(suspendApp)
implementation(suspendAppKtor)
implementation(hikariCp)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
package com.agilogy.timetracking.app

import arrow.continuations.ktor.server
import com.agilogy.heroku.postgres.loadHerokuPostgresConfig
import com.agilogy.timetracking.domain.TimeTrackingApp
import com.agilogy.timetracking.driveradapters.httpapi.TimeTrackingApi
import io.ktor.server.netty.Netty
import kotlinx.coroutines.awaitCancellation
import kotlin.time.Duration.Companion.seconds

fun main() = app {
fun startApiServer(timeTrackingApp: TimeTrackingApp) = app {
val port = System.getenv("PORT")?.let { it.toInt() } ?: 8080
val (jdbcUrl, username, password) = loadHerokuPostgresConfig()

val timeTrackingApi = TimeTrackingApi(timeTrackingApp(jdbcUrl, username, password))

val timeTrackingApi = TimeTrackingApi(timeTrackingApp)
server(Netty, port = port, host = "0.0.0.0", preWait = 5.seconds) {
timeTrackingApi.routes()
}
Expand Down
30 changes: 30 additions & 0 deletions apps/app/src/main/kotlin/com/agilogy/timetracking/app/BasicBot.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.agilogy.timetracking.app

import com.agilogy.timetracking.domain.TimeTrackingApp
import net.dv8tion.jda.api.JDABuilder
import net.dv8tion.jda.api.entities.Activity
import net.dv8tion.jda.api.interactions.commands.OptionType
import net.dv8tion.jda.api.interactions.commands.build.Commands

fun startBot(timeTrackingApp: TimeTrackingApp) = app {
val token = System.getenv("DISCORD_BOT_TOKEN")

// Create a new JDA instance
val jda = JDABuilder.createDefault(token)
.addEventListeners(EventsListener(timeTrackingApp))
.build()

// Register our first command /ping (don't use this method to often ;))
jda.updateCommands().addCommands(
Commands.slash("ping2", "Repeats messages back to you.")
.addOption(OptionType.STRING, "message", "The message to repeat."),
).queue()

jda.updateCommands().addCommands(
Commands.slash("projects", "Returns the list of projects configured."),
).queue()

// Set the activity to "I'm Ready"
jda.presence.activity = Activity.playing("Agilogy school")
}
class BasicBot
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.agilogy.timetracking.app

import com.agilogy.timetracking.domain.TimeTrackingApp
import kotlinx.coroutines.runBlocking
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent
import net.dv8tion.jda.api.events.message.MessageReceivedEvent
import net.dv8tion.jda.api.hooks.ListenerAdapter
import org.slf4j.Logger
import org.slf4j.LoggerFactory

class EventsListener(private val timeTrackingApp: TimeTrackingApp) : ListenerAdapter() {

private val logger: Logger = LoggerFactory.getLogger(javaClass)

// This gets called when a slash command gets used.
override fun onSlashCommandInteraction(event: SlashCommandInteractionEvent) {
// Check if this is our /ping command
if (event.name == "ping2") {
logger.info("Command /ping got used")

// Reply to the user
val startTime = System.currentTimeMillis()
event.reply("Ping ...").setEphemeral(true).queue {
it.editOriginal("Pong: ${System.currentTimeMillis() - startTime}ms").queue()
}
}
}

override fun onMessageReceived(event: MessageReceivedEvent) = runBlocking {
try {
logger.info("Message received: ${event.message.contentRaw} by ${event.author}")

if (!event.author.isBot) {
val response = if (event.message.contentRaw.trim().lowercase() == "projectes") {
timeTrackingApp.listProjects().joinToString(", ") { it.name }
} else {
"Hola ${event.author.name}! I don't understand."
}
event.channel.sendMessage(response).queue()
}
} catch (e: Exception) {
logger.error("Unexpected exception", e)
}
}
}
12 changes: 12 additions & 0 deletions apps/app/src/main/kotlin/com/agilogy/timetracking/app/Main.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.agilogy.timetracking.app

import com.agilogy.heroku.postgres.loadHerokuPostgresConfig

fun main() = app {
val (jdbcUrl, username, password) = loadHerokuPostgresConfig()

val timeTrackingApp = timeTrackingApp(jdbcUrl, username, password)

startBot(timeTrackingApp)
startApiServer(timeTrackingApp)
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ interface TimeTrackingApp {

suspend fun listTimeEntries(dateRange: ClosedRange<LocalDate>, developer: DeveloperName?):
List<Tuple5<DeveloperName, ProjectName, LocalDate, ClosedRange<LocalTime>, ZoneId>>

suspend fun listProjects(): List<ProjectName>
}

@JvmInline
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,6 @@ class TimeTrackingAppPrd(private val timeEntriesRepository: TimeEntriesRepositor
res
}
}

override suspend fun listProjects(): List<ProjectName> = listOf(ProjectName("Agilogy school"))
}
Loading