MatrixApiClient.client

This commit is contained in:
2022-04-18 14:03:36 +02:00
parent e900c834dc
commit c4e9bd7841
6 changed files with 39 additions and 62 deletions

View File

@@ -4,7 +4,6 @@ import eu.fosil.okupamicoche.config.ConfigReader
import eu.fosil.okupamicoche.matrix.MatrixApiClient
import eu.fosil.okupamicoche.matrix.createAppService
import eu.fosil.okupamicoche.matrix.event.TravelEventContentSerializerMappings
import eu.fosil.okupamicoche.matrix.matrixApiClient
import io.ktor.server.engine.*
import io.ktor.server.netty.*
import net.folivo.trixnity.applicationserviceapi.server.matrixApplicationServiceApiServer
@@ -16,14 +15,13 @@ suspend fun main() {
requireNotNull(config)
// Init matrix client
requireNotNull(matrixApiClient)
MatrixApiClient.init()
MatrixApiClient.init(config)
// Start Ktor server
embeddedServer(Netty, port = 8080, host = "0.0.0.0") {
matrixApplicationServiceApiServer(
hsToken = config.tokens.homeserver,
applicationServiceApiServerHandler = createAppService(matrixApiClient),
applicationServiceApiServerHandler = createAppService(MatrixApiClient.client),
customMappings = TravelEventContentSerializerMappings
)
}.start(wait = true)

View File

@@ -1,7 +1,6 @@
package eu.fosil.okupamicoche.cli
import eu.fosil.okupamicoche.matrix.MatrixApiClient
import eu.fosil.okupamicoche.matrix.matrixApiClient
import eu.fosil.okupamicoche.model.TravelOptions
import eu.fosil.okupamicoche.usecase.Usecase
import eu.fosil.okupamicoche.usecase.travel.createTravel
@@ -39,8 +38,6 @@ object CommandParser {
) {
logger.info("command=$command args=$args")
try {
requireNotNull(matrixApiClient)
when (command) {
"create" -> handleCreate(user, room, args)
"join" -> Usecase.joinTravel(room, user)

View File

@@ -1,6 +1,6 @@
package eu.fosil.okupamicoche.matrix
import eu.fosil.okupamicoche.config.ConfigReader
import eu.fosil.okupamicoche.config.Config
import eu.fosil.okupamicoche.matrix.event.TravelEventContentSerializerMappings
import eu.fosil.okupamicoche.matrix.event.state.MembershipStateEventContent
import eu.fosil.okupamicoche.matrix.event.state.TravelCreatedStateEventContent
@@ -17,54 +17,52 @@ import net.folivo.trixnity.core.serialization.createEventContentSerializerMappin
private val logger = KotlinLogging.logger {}
val config = ConfigReader.load()
val matrixApiClient = if (config == null) null else MatrixClientServerApiClient(
baseUrl = Url(
(if (config.homeserver.secure) "https" else "http") +
"://${config.homeserver.host}:${config.homeserver.port}"
),
eventContentSerializerMappings = createEventContentSerializerMappings(TravelEventContentSerializerMappings)
).apply { accessToken.value = config.tokens.appService }
object MatrixApiClient {
var appServiceUserId: UserId? = null
var mainRoomId: RoomId? = null
var client = MatrixClientServerApiClient()
private var config: Config? = null
suspend fun init() {
requireNotNull(matrixApiClient)
suspend fun init(config: Config) {
this.config = config
client = MatrixClientServerApiClient(
baseUrl = Url(
(if (config.homeserver.secure) "https" else "http") +
"://${config.homeserver.host}:${config.homeserver.port}"
),
eventContentSerializerMappings = createEventContentSerializerMappings(TravelEventContentSerializerMappings)
).apply { accessToken.value = config.tokens.appService }
appServiceUserId = matrixApiClient.authentication.whoAmI().getOrThrow().userId
appServiceUserId = client.authentication.whoAmI().getOrThrow().userId
mainRoomId = createMainRoomIfNeeded()
}
suspend fun getDisplayName(userId: UserId) =
matrixApiClient?.users?.getDisplayName(userId)?.getOrNull() ?: userId.localpart
client.users.getDisplayName(userId).getOrNull() ?: userId.localpart
suspend fun isTravel(roomId: RoomId) =
matrixApiClient?.rooms?.getStateEvent<TravelCreatedStateEventContent>(
client.rooms.getStateEvent<TravelCreatedStateEventContent>(
roomId
)?.getOrNull() !== null
).getOrNull() !== null
suspend fun isDriver(roomId: RoomId, userId: UserId) =
matrixApiClient?.rooms?.getStateEvent<TravelCreatedStateEventContent>(
client.rooms.getStateEvent<TravelCreatedStateEventContent>(
roomId
)?.getOrNull()?.driver == userId.full
).getOrNull()?.driver == userId.full
suspend fun getTravelMembership(roomId: RoomId, userId: UserId) =
matrixApiClient?.rooms?.getStateEvent<MembershipStateEventContent>(
client.rooms.getStateEvent<MembershipStateEventContent>(
roomId,
userId.full.substring(1) // Synapse throws 403 if stateKey starts with '@'
)?.getOrNull()?.membership
).getOrNull()?.membership
suspend fun sendErrorTextMessage(
roomId: RoomId,
body: String,
formattedBody: String? = null
) {
requireNotNull(matrixApiClient)
val formattedBodyWithWarningIcon = "⚠️" + (formattedBody ?: body)
matrixApiClient.rooms.sendMessageEvent(
client.rooms.sendMessageEvent(
roomId,
RoomMessageEventContent.TextMessageEventContent(
body = body,
@@ -75,31 +73,30 @@ object MatrixApiClient {
}
private suspend fun createMainRoomIfNeeded(): RoomId? {
requireNotNull(config)
requireNotNull(matrixApiClient)
val config = requireNotNull(config)
val mainRoomId: RoomId?
val roomMainAlias = "#${config.mainRoom}:${config.homeserver.host}"
val roomAliasRes = matrixApiClient.rooms.getRoomAlias(RoomAliasId(roomMainAlias)).getOrNull()
val roomAliasRes = client.rooms.getRoomAlias(RoomAliasId(roomMainAlias)).getOrNull()
if (roomAliasRes == null) {
logger.info("Creating $roomMainAlias public room")
mainRoomId = matrixApiClient.rooms.createRoom(
mainRoomId = client.rooms.createRoom(
visibility = DirectoryVisibility.PUBLIC,
roomAliasId = RoomAliasId(roomMainAlias)
).getOrNull()
} else {
mainRoomId = roomAliasRes.roomId
val joinedToMainRoom = (matrixApiClient.rooms.getJoinedRooms().getOrNull()?.firstOrNull { roomId ->
val joinedToMainRoom = (client.rooms.getJoinedRooms().getOrNull()?.firstOrNull { roomId ->
roomId == mainRoomId
}) !== null
logger.info("alreadyJoinedToMainRoom=$joinedToMainRoom")
if (!joinedToMainRoom) {
matrixApiClient.rooms.joinRoom(mainRoomId)
client.rooms.joinRoom(mainRoomId)
}
val roomStateEvents = matrixApiClient.rooms.getState(mainRoomId).getOrNull()
val roomStateEvents = client.rooms.getState(mainRoomId).getOrNull()
roomStateEvents?.forEach { stateEvent ->
logger.debug("stateEvent=$stateEvent")
}

View File

@@ -3,12 +3,10 @@ package eu.fosil.okupamicoche.usecase.travel
import eu.fosil.okupamicoche.config.ConfigReader
import eu.fosil.okupamicoche.db.TravelEntity
import eu.fosil.okupamicoche.matrix.MatrixApiClient
import eu.fosil.okupamicoche.matrix.config
import eu.fosil.okupamicoche.matrix.db
import eu.fosil.okupamicoche.matrix.event.message.TravelCreatedMessageEventContent
import eu.fosil.okupamicoche.matrix.event.state.TRAVEL_CREATED_STATE_EVENT_TYPE
import eu.fosil.okupamicoche.matrix.event.state.TravelCreatedStateEventContent
import eu.fosil.okupamicoche.matrix.matrixApiClient
import eu.fosil.okupamicoche.model.Travel
import eu.fosil.okupamicoche.model.TravelOptions
import eu.fosil.okupamicoche.usecase.Usecase
@@ -52,8 +50,6 @@ suspend fun Usecase.createTravel(
}
private suspend fun createRoom(travelOptions: TravelOptions, driver: UserId): RoomId {
requireNotNull(matrixApiClient)
requireNotNull(config)
val appServiceUserId = requireNotNull(MatrixApiClient.appServiceUserId)
val newRoomAliasAndName = getRoomAliasAndName(travelOptions)
@@ -69,7 +65,7 @@ private suspend fun createRoom(travelOptions: TravelOptions, driver: UserId): Ro
)
)
return matrixApiClient.rooms.createRoom(
return MatrixApiClient.client.rooms.createRoom(
visibility = DirectoryVisibility.PUBLIC,
roomAliasId = newRoomAliasAndName.aliasId,
name = newRoomAliasAndName.name,
@@ -124,9 +120,7 @@ private fun getRoomAliasAttempt(roomAliasPrefix: String, attempt: Int): RoomAlia
}
private suspend fun isRoomAliasAvailable(roomAliasId: RoomAliasId): Boolean {
requireNotNull(matrixApiClient)
val roomId = matrixApiClient.rooms.getRoomAlias(roomAliasId).getOrNull()
val roomId = MatrixApiClient.client.rooms.getRoomAlias(roomAliasId).getOrNull()
logger.info { "$roomAliasId roomId=$roomId" }
return roomId == null
@@ -147,7 +141,6 @@ private suspend fun sendCreateMessageEvents(
travel: Travel,
createdFromRoomId: RoomId
) {
requireNotNull(matrixApiClient)
val mainRoomId = requireNotNull(MatrixApiClient.mainRoomId)
val instant = Instant.ofEpochMilli(travel.options.time)
@@ -158,20 +151,20 @@ private suspend fun sendCreateMessageEvents(
val displayName = MatrixApiClient.getDisplayName(travel.driver)
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(
MatrixApiClient.client.rooms.sendMessageEvent(
mainRoomId,
RoomMessageEventContent.TextMessageEventContent(messageBody)
)
// Send new travel message event to main room
matrixApiClient.rooms.sendMessageEvent(
MatrixApiClient.client.rooms.sendMessageEvent(
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(
MatrixApiClient.client.rooms.sendMessageEvent(
createdFromRoomId,
RoomMessageEventContent.TextMessageEventContent(messageBody)
)

View File

@@ -2,7 +2,6 @@ package eu.fosil.okupamicoche.usecase.travel
import eu.fosil.okupamicoche.matrix.MatrixApiClient
import eu.fosil.okupamicoche.matrix.event.state.MembershipStateEventContent
import eu.fosil.okupamicoche.matrix.matrixApiClient
import eu.fosil.okupamicoche.usecase.Usecase
import net.folivo.trixnity.core.model.RoomId
import net.folivo.trixnity.core.model.UserId
@@ -13,7 +12,6 @@ suspend fun Usecase.joinTravel(
roomId: RoomId,
userId: UserId
) {
requireNotNull(matrixApiClient)
val isTravel = MatrixApiClient.isTravel(roomId)
val isDriver = MatrixApiClient.isDriver(roomId, userId)
val membershipState = MatrixApiClient.getTravelMembership(roomId, userId)
@@ -23,7 +21,7 @@ suspend fun Usecase.joinTravel(
} else if (isDriver) {
MatrixApiClient.sendErrorTextMessage(roomId, "You are the driver, you don't need to join.")
} else if (membershipState == Membership.JOIN.value) {
MatrixApiClient.sendErrorTextMessage(roomId, "You were already joined.")
MatrixApiClient.sendErrorTextMessage(roomId, "You are already joined.")
} else {
sendJoinedMessageEvents(roomId, userId)
}
@@ -33,18 +31,16 @@ private suspend fun sendJoinedMessageEvents(
roomId: RoomId,
userId: UserId
) {
requireNotNull(matrixApiClient)
// Send text message to travel room
val displayName = MatrixApiClient.getDisplayName(userId)
val messageBody = "$displayName joined the travel!"
matrixApiClient.rooms.sendMessageEvent(
MatrixApiClient.client.rooms.sendMessageEvent(
roomId,
RoomMessageEventContent.TextMessageEventContent(messageBody)
)
// Send membership change state event to travel room
matrixApiClient.rooms.sendStateEvent(
MatrixApiClient.client.rooms.sendStateEvent(
roomId,
MembershipStateEventContent(userId, Membership.JOIN),
stateKey = userId.full.substring(1) // Synapse throws 403 if stateKey starts with '@'

View File

@@ -2,7 +2,6 @@ package eu.fosil.okupamicoche.usecase.travel
import eu.fosil.okupamicoche.matrix.MatrixApiClient
import eu.fosil.okupamicoche.matrix.event.state.MembershipStateEventContent
import eu.fosil.okupamicoche.matrix.matrixApiClient
import eu.fosil.okupamicoche.usecase.Usecase
import net.folivo.trixnity.core.model.RoomId
import net.folivo.trixnity.core.model.UserId
@@ -13,7 +12,6 @@ suspend fun Usecase.leaveTravel(
roomId: RoomId,
userId: UserId
) {
requireNotNull(matrixApiClient)
val isTravel = MatrixApiClient.isTravel(roomId)
val isDriver = MatrixApiClient.isDriver(roomId, userId)
val membershipState = MatrixApiClient.getTravelMembership(roomId, userId)
@@ -39,18 +37,16 @@ private suspend fun sendLeftMessageEvents(
roomId: RoomId,
userId: UserId
) {
requireNotNull(matrixApiClient)
// Send text message to travel room
val displayName = MatrixApiClient.getDisplayName(userId)
val messageBody = "$displayName left the travel."
matrixApiClient.rooms.sendMessageEvent(
MatrixApiClient.client.rooms.sendMessageEvent(
roomId,
RoomMessageEventContent.TextMessageEventContent(messageBody)
)
// Send membership change state event to travel room
matrixApiClient.rooms.sendStateEvent(
MatrixApiClient.client.rooms.sendStateEvent(
roomId,
MembershipStateEventContent(userId, Membership.LEAVE),
stateKey = userId.full.substring(1) // Synapse throws 403 if stateKey starts with '@'