MatrixApiClient.client
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
@@ -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)
|
||||
)
|
||||
|
||||
@@ -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 '@'
|
||||
|
||||
@@ -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 '@'
|
||||
|
||||
Reference in New Issue
Block a user