From 2e084a1fdb4af3f8edb042e334f81cb03fbdaa37 Mon Sep 17 00:00:00 2001 From: Eneko Nieto Date: Sun, 17 Apr 2022 00:58:45 +0200 Subject: [PATCH] Send room creation events to main room --- src/main/kotlin/eu/fosil/okupamicoche/Main.kt | 53 ++++--------------- .../event/TravelCreatedStateEventContent.kt | 7 ++- .../okupamicoche/matrix/matrixApiClient.kt | 52 +++++++++++++++--- .../usecase/travel/createTravel.kt | 22 +++++--- 4 files changed, 76 insertions(+), 58 deletions(-) diff --git a/src/main/kotlin/eu/fosil/okupamicoche/Main.kt b/src/main/kotlin/eu/fosil/okupamicoche/Main.kt index 9140a92..1ca2f71 100644 --- a/src/main/kotlin/eu/fosil/okupamicoche/Main.kt +++ b/src/main/kotlin/eu/fosil/okupamicoche/Main.kt @@ -7,60 +7,29 @@ import eu.fosil.okupamicoche.matrix.event.TravelEventContentSerializerMappings import eu.fosil.okupamicoche.matrix.matrixApiClient import io.ktor.server.engine.* import io.ktor.server.netty.* -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.flow.filter -import kotlinx.coroutines.flow.firstOrNull -import kotlinx.coroutines.launch import mu.KotlinLogging import net.folivo.trixnity.appservice.MatrixAppserviceProperties import net.folivo.trixnity.appservice.rest.matrixAppserviceModule -import net.folivo.trixnity.clientserverapi.model.rooms.Visibility -import net.folivo.trixnity.core.model.RoomAliasId private val logger = KotlinLogging.logger {} suspend fun main() { + // Load config from file val config = ConfigReader.load() - requireNotNull(config) + + // Init matrix client requireNotNull(matrixApiClient) MatrixApiClient.init() - coroutineScope { - launch { - val roomMainAlias = "#${config.mainRoom}:${config.homeserver.host}" - val roomAliasRes = matrixApiClient.rooms.getRoomAlias(RoomAliasId(roomMainAlias)).getOrNull() - if (roomAliasRes == null) { - logger.info("Creating $roomMainAlias public room") - matrixApiClient.rooms.createRoom( - visibility = Visibility.PUBLIC, - roomAliasId = RoomAliasId(roomMainAlias) - ) - } else { - val mainRoomId = roomAliasRes.roomId - val joinedToMainRoom = (matrixApiClient.rooms.getJoinedRooms().getOrNull()?.filter { roomId -> - roomId == mainRoomId - }?.firstOrNull()) !== null - logger.info("alreadyJoinedToMainRoom=$joinedToMainRoom") + // Start Ktor server + embeddedServer(Netty, port = 8080, host = "0.0.0.0") { + matrixAppserviceModule( + properties = MatrixAppserviceProperties(config.tokens.homeserver), + appserviceService = createAppService(matrixApiClient), + customMappings = TravelEventContentSerializerMappings + ) + }.start(wait = true) - if (!joinedToMainRoom) { - matrixApiClient.rooms.joinRoom(mainRoomId) - } - - val roomStateRes = matrixApiClient.rooms.getState(mainRoomId).getOrNull() - roomStateRes?.collect { stateEvent -> - logger.debug("stateEvent=$stateEvent") - } - } - - embeddedServer(Netty, port = 8080, host = "0.0.0.0") { - matrixAppserviceModule( - properties = MatrixAppserviceProperties(config.tokens.homeserver), - appserviceService = createAppService(matrixApiClient), - customMappings = TravelEventContentSerializerMappings - ) - }.start(wait = true) - } - } } diff --git a/src/main/kotlin/eu/fosil/okupamicoche/matrix/event/TravelCreatedStateEventContent.kt b/src/main/kotlin/eu/fosil/okupamicoche/matrix/event/TravelCreatedStateEventContent.kt index 4d168e3..0e1a8c7 100644 --- a/src/main/kotlin/eu/fosil/okupamicoche/matrix/event/TravelCreatedStateEventContent.kt +++ b/src/main/kotlin/eu/fosil/okupamicoche/matrix/event/TravelCreatedStateEventContent.kt @@ -19,13 +19,16 @@ data class TravelCreatedStateEventContent( @SerialName("time") val time: Long, @SerialName("places") - val places: Int + val places: Int, + @SerialName("description") + val description: String ) : StateEventContent { constructor(travelOptions: TravelOptions, driver: UserId) : this( driver.full, travelOptions.from, travelOptions.to, travelOptions.time, - travelOptions.places + travelOptions.places, + travelOptions.description ) } diff --git a/src/main/kotlin/eu/fosil/okupamicoche/matrix/matrixApiClient.kt b/src/main/kotlin/eu/fosil/okupamicoche/matrix/matrixApiClient.kt index bb9f9bb..73a87bf 100644 --- a/src/main/kotlin/eu/fosil/okupamicoche/matrix/matrixApiClient.kt +++ b/src/main/kotlin/eu/fosil/okupamicoche/matrix/matrixApiClient.kt @@ -3,13 +3,18 @@ package eu.fosil.okupamicoche.matrix import eu.fosil.okupamicoche.config.ConfigReader import eu.fosil.okupamicoche.matrix.event.TravelEventContentSerializerMappings import io.ktor.http.* -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.firstOrNull +import mu.KotlinLogging import net.folivo.trixnity.clientserverapi.client.MatrixClientServerApiClient +import net.folivo.trixnity.clientserverapi.model.rooms.Visibility +import net.folivo.trixnity.core.model.RoomAliasId +import net.folivo.trixnity.core.model.RoomId import net.folivo.trixnity.core.model.UserId import net.folivo.trixnity.core.serialization.events.DefaultEventContentSerializerMappings +private val logger = KotlinLogging.logger {} + val config = ConfigReader.load() val matrixApiClient = if (config == null) null else MatrixClientServerApiClient( baseUrl = Url( @@ -21,13 +26,46 @@ val matrixApiClient = if (config == null) null else MatrixClientServerApiClient( object MatrixApiClient { var appServiceUserId: UserId? = null + var mainRoomId: RoomId? = null - fun init() { + suspend fun init() { requireNotNull(matrixApiClient) - val ioScope = CoroutineScope(Dispatchers.IO) - ioScope.launch { - appServiceUserId = matrixApiClient.users.whoAmI().getOrThrow().userId + appServiceUserId = matrixApiClient.users.whoAmI().getOrThrow().userId + mainRoomId = createMainRoomIfNeeded() + } + + private suspend fun createMainRoomIfNeeded(): RoomId? { + requireNotNull(config) + requireNotNull(matrixApiClient) + + val mainRoomId: RoomId? + + val roomMainAlias = "#${config.mainRoom}:${config.homeserver.host}" + val roomAliasRes = matrixApiClient.rooms.getRoomAlias(RoomAliasId(roomMainAlias)).getOrNull() + if (roomAliasRes == null) { + logger.info("Creating $roomMainAlias public room") + mainRoomId = matrixApiClient.rooms.createRoom( + visibility = Visibility.PUBLIC, + roomAliasId = RoomAliasId(roomMainAlias) + ).getOrNull() + } else { + mainRoomId = roomAliasRes.roomId + val joinedToMainRoom = (matrixApiClient.rooms.getJoinedRooms().getOrNull()?.filter { roomId -> + roomId == mainRoomId + }?.firstOrNull()) !== null + logger.info("alreadyJoinedToMainRoom=$joinedToMainRoom") + + if (!joinedToMainRoom) { + matrixApiClient.rooms.joinRoom(mainRoomId) + } + + val roomStateRes = matrixApiClient.rooms.getState(mainRoomId).getOrNull() + roomStateRes?.collect { stateEvent -> + logger.debug("stateEvent=$stateEvent") + } } + + return mainRoomId } } diff --git a/src/main/kotlin/eu/fosil/okupamicoche/usecase/travel/createTravel.kt b/src/main/kotlin/eu/fosil/okupamicoche/usecase/travel/createTravel.kt index 6faa254..20b6f2b 100644 --- a/src/main/kotlin/eu/fosil/okupamicoche/usecase/travel/createTravel.kt +++ b/src/main/kotlin/eu/fosil/okupamicoche/usecase/travel/createTravel.kt @@ -34,7 +34,7 @@ data class RoomAliasAndName( suspend fun createTravel( travelOptions: TravelOptions, driver: UserId, - roomId: RoomId + createdFromRoomId: RoomId ) { val newRoomId = createRoom(travelOptions, driver) val travel = Travel( @@ -43,7 +43,7 @@ suspend fun createTravel( travelOptions ) - sendCreateMessageEvents(travel, roomId) + sendCreateMessageEvents(travel, createdFromRoomId) transaction(db) { TravelEntity.new(travel) @@ -133,27 +133,35 @@ private fun getRoomName(travelOptions: TravelOptions, attempt: Int): String { private suspend fun sendCreateMessageEvents( travel: Travel, - roomId: RoomId + createdFromRoomId: RoomId ) { requireNotNull(matrixApiClient) + val mainRoomId = requireNotNull(MatrixApiClient.mainRoomId) val instant = Instant.ofEpochMilli(travel.options.time) val date = DateTimeFormatter.ofPattern("yyyy/MM/dd").withZone(ZoneId.systemDefault()).format(instant) val time = DateTimeFormatter.ofPattern("H:mm").withZone(ZoneId.systemDefault()).format(instant) - // Send text message + // Send text message to main room val displayName = matrixApiClient.users.getDisplayName(travel.driver).getOrNull() ?: travel.driver.full val messageBody = "$displayName created a new travel! ${travel.options.from}-${travel.options.to}" + " on $date $time with ${travel.options.places} free places." matrixApiClient.rooms.sendMessageEvent( - roomId, + mainRoomId, RoomMessageEventContent.TextMessageEventContent(messageBody) ) - // Send new travel event + // Send new travel message event to main room matrixApiClient.rooms.sendMessageEvent( - roomId, + mainRoomId, TravelCreatedMessageEventContent(travel) ) + // Send text message to room where create command was sent (if it is not main room) + if (createdFromRoomId != mainRoomId) { + matrixApiClient.rooms.sendMessageEvent( + createdFromRoomId, + RoomMessageEventContent.TextMessageEventContent(messageBody) + ) + } }