Send room creation events to main room

This commit is contained in:
2022-04-17 00:58:45 +02:00
parent caf551c1be
commit 2e084a1fdb
4 changed files with 76 additions and 58 deletions

View File

@@ -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)
}
}
}

View File

@@ -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
)
}

View File

@@ -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
}
}

View File

@@ -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)
)
}
}