diff --git a/src/main/kotlin/dev/usbharu/hideout/Application.kt b/src/main/kotlin/dev/usbharu/hideout/Application.kt index 5052c79c..90701529 100644 --- a/src/main/kotlin/dev/usbharu/hideout/Application.kt +++ b/src/main/kotlin/dev/usbharu/hideout/Application.kt @@ -8,6 +8,7 @@ import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import dev.usbharu.hideout.config.Config import dev.usbharu.hideout.config.ConfigData import dev.usbharu.hideout.domain.model.job.DeliverPostJob +import dev.usbharu.hideout.domain.model.job.DeliverReactionJob import dev.usbharu.hideout.domain.model.job.ReceiveFollowJob import dev.usbharu.hideout.plugins.* import dev.usbharu.hideout.repository.IUserRepository @@ -135,4 +136,10 @@ fun Application.worker() { activityPubService.processActivity(this, it) } } + + kJob.register(DeliverReactionJob) { + execute { + activityPubService.processActivity(this, it) + } + } } diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Like.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Like.kt index c4eb3abf..625a83ef 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Like.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Like.kt @@ -11,13 +11,13 @@ open class Like : Object { protected constructor() : super() constructor( - type: List, + type: List = emptyList(), name: String?, actor: String?, id: String?, `object`: String?, content: String?, - tag: List + tag: List = emptyList() ) : super( type = add(type, "Like"), name = name, diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/entity/User.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/entity/User.kt index 45af9cc2..6754df4f 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/entity/User.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/entity/User.kt @@ -18,7 +18,7 @@ data class User( ) { override fun toString(): String { return "User(id=$id, name='$name', domain='$domain', screenName='$screenName', description='$description'," + - " password=****, inbox='$inbox', outbox='$outbox', url='$url', publicKey='$publicKey'," + - " privateKey=****, createdAt=$createdAt)" + " password=****, inbox='$inbox', outbox='$outbox', url='$url', publicKey='$publicKey'," + + " privateKey=****, createdAt=$createdAt)" } } diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/job/HideoutJob.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/job/HideoutJob.kt index a1b896b8..9d10cb23 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/job/HideoutJob.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/job/HideoutJob.kt @@ -21,4 +21,5 @@ object DeliverReactionJob : HideoutJob("DeliverReactionJob") { val postUrl = string("postUrl") val actor = string("actor") val inbox = string("inbox") + val id = string("id") } diff --git a/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Users.kt b/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Users.kt index 8609e439..24a45006 100644 --- a/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Users.kt +++ b/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Users.kt @@ -42,11 +42,11 @@ fun Route.users(userService: IUserService, userApiService: IUserApiService) { authenticate(TOKEN_AUTH, optional = true) { get { val userParameter = ( - call.parameters["name"] - ?: throw ParameterNotExistException( - "Parameter(name='userName@domain') does not exist." - ) + call.parameters["name"] + ?: throw ParameterNotExistException( + "Parameter(name='userName@domain') does not exist." ) + ) if (userParameter.toLongOrNull() != null) { return@get call.respond(userApiService.findById(userParameter.toLong())) } else { @@ -92,11 +92,11 @@ fun Route.users(userService: IUserService, userApiService: IUserApiService) { route("/following") { get { val userParameter = ( - call.parameters["name"] - ?: throw ParameterNotExistException( - "Parameter(name='userName@domain') does not exist." - ) + call.parameters["name"] + ?: throw ParameterNotExistException( + "Parameter(name='userName@domain') does not exist." ) + ) if (userParameter.toLongOrNull() != null) { return@get call.respond(userApiService.findFollowings(userParameter.toLong())) } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubReactionServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubReactionServiceImpl.kt new file mode 100644 index 00000000..3f60c8a7 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubReactionServiceImpl.kt @@ -0,0 +1,57 @@ +package dev.usbharu.hideout.service.activitypub + +import dev.usbharu.hideout.config.Config +import dev.usbharu.hideout.domain.model.ap.Like +import dev.usbharu.hideout.domain.model.hideout.entity.Reaction +import dev.usbharu.hideout.domain.model.job.DeliverReactionJob +import dev.usbharu.hideout.exception.PostNotFoundException +import dev.usbharu.hideout.plugins.postAp +import dev.usbharu.hideout.repository.IPostRepository +import dev.usbharu.hideout.service.job.JobQueueParentService +import dev.usbharu.hideout.service.user.IUserService +import io.ktor.client.* +import kjob.core.job.JobProps +import org.koin.core.annotation.Single + +@Single +class ActivityPubReactionServiceImpl( + private val userService: IUserService, + private val jobQueueParentService: JobQueueParentService, + private val iPostRepository: IPostRepository, + private val httpClient: HttpClient +) : ActivityPubReactionService { + override suspend fun reaction(like: Reaction) { + val followers = userService.findFollowersById(like.userId) + val user = userService.findById(like.userId) + val post = + iPostRepository.findOneById(like.postId) ?: throw PostNotFoundException("${like.postId} was not found.") + followers.forEach { follower -> + jobQueueParentService.schedule(DeliverReactionJob) { + props[it.actor] = user.url + props[it.reaction] = "❤" + props[it.inbox] = follower.inbox + props[it.postUrl] = post.url + props[it.id] = post.id.toString() + } + } + } + + override suspend fun reactionJob(props: JobProps) { + val inbox = props[DeliverReactionJob.inbox] + val actor = props[DeliverReactionJob.actor] + val postUrl = props[DeliverReactionJob.postUrl] + val id = props[DeliverReactionJob.id] + val content = props[DeliverReactionJob.reaction] + httpClient.postAp( + urlString = inbox, + username = "$actor#pubkey", + jsonLd = Like( + name = "Like", + actor = actor, + `object` = postUrl, + id = "${Config.configData.url}/like/note/$id", + content = content + ) + ) + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubServiceImpl.kt index e5360563..d369b006 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubServiceImpl.kt @@ -6,6 +6,7 @@ import dev.usbharu.hideout.config.Config.configData import dev.usbharu.hideout.domain.model.ActivityPubResponse import dev.usbharu.hideout.domain.model.ap.Follow import dev.usbharu.hideout.domain.model.job.DeliverPostJob +import dev.usbharu.hideout.domain.model.job.DeliverReactionJob import dev.usbharu.hideout.domain.model.job.HideoutJob import dev.usbharu.hideout.domain.model.job.ReceiveFollowJob import dev.usbharu.hideout.exception.JsonParseException @@ -22,7 +23,8 @@ class ActivityPubServiceImpl( private val activityPubUndoService: ActivityPubUndoService, private val activityPubAcceptService: ActivityPubAcceptService, private val activityPubCreateService: ActivityPubCreateService, - private val activityPubLikeService: ActivityPubLikeService + private val activityPubLikeService: ActivityPubLikeService, + private val activityPubReactionService: ActivityPubReactionService ) : ActivityPubService { val logger: Logger = LoggerFactory.getLogger(this::class.java) @@ -71,6 +73,7 @@ class ActivityPubServiceImpl( ) DeliverPostJob -> activityPubNoteService.createNoteJob(job.props as JobProps) + DeliverReactionJob -> activityPubReactionService.reactionJob(job.props as JobProps) } } } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/reaction/ReactionServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/reaction/ReactionServiceImpl.kt index 0c8daadf..a0e62e54 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/reaction/ReactionServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/reaction/ReactionServiceImpl.kt @@ -20,7 +20,7 @@ class ReactionServiceImpl( override suspend fun sendReaction(name: String, userId: Long, postId: Long) { if (reactionRepository.reactionAlreadyExist(postId, userId, 0)) { - //delete + // delete } else { val reaction = Reaction(reactionRepository.generateId(), 0, postId, userId) reactionRepository.save(reaction)