komf icon indicating copy to clipboard operation
komf copied to clipboard

Notifications fail if no "title url" set and cannot set title url to "$series.metadata.links[i].url"

Open vodkapmp opened this issue 7 months ago • 2 comments

When configuring notifications in the komelia webui, if I don't set a title url, I get the following error:

18:18:06.372 [OkHttp https://discord.com/...] INFO http.logging -- --> GET https://discord.com/api/webhooks/REDACTED/REDACTED
18:18:06.595 [OkHttp https://discord.com/...] INFO http.logging -- <-- 200 https://discord.com/api/webhooks/REDACTED/REDACTED (222ms, unknown-length body)
18:18:06.872 [OkHttp https://discord.com/...] INFO http.logging -- --> POST https://discord.com/api/webhooks/REDACTED/REDACTED (109743-byte body)
18:18:07.145 [OkHttp https://discord.com/...] INFO http.logging -- <-- 400 https://discord.com/api/webhooks/REDACTED/REDACTED (273ms, 17-byte body)
18:18:07.146 [DefaultDispatcher-worker-1] ERROR snd.komf.notifications.NotificationsEventHandler -- catching
io.ktor.client.plugins.ClientRequestException: Client request(POST https://discord.com/api/webhooks/REDACTED/REDACTED) invalid: 400 . Text: "{"embeds": ["0"]}"
        at io.ktor.client.plugins.DefaultResponseValidationKt$addDefaultResponseValidation$1$1.invokeSuspend(DefaultResponseValidation.kt:52)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100)
        at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:586)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:829)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:717)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:704)

When I try and set the title to $series.metadata.links[i].url which is the only url that to me makes sense to set it to I get this:

18:20:07.572 [DefaultDispatcher-worker-30] ERROR io.ktor.server.Application -- Unhandled: POST - /api/notifications/discord/send
org.apache.velocity.runtime.parser.ParseException: Lexical error: org.apache.velocity.runtime.parser.TokenMgrError: Lexical error at line 1, column 31.  Encountered: "i" (105), after : ""
        at org.apache.velocity.runtime.parser.StandardParser.parse(StandardParser.java:202)
        at org.apache.velocity.runtime.RuntimeInstance.parse(RuntimeInstance.java:1341)
        at snd.komf.notifications.VelocityTemplates.templateFromString(VelocityTemplates.kt:37)
        at snd.komf.notifications.discord.DiscordVelocityTemplates.render(DiscordVelocityTemplates.kt:131)
        at snd.komf.notifications.discord.DiscordWebhookService.toRequest(DiscordWebhookService.kt:54)
        at snd.komf.notifications.discord.DiscordWebhookService.send(DiscordWebhookService.kt:39)
        at snd.komf.app.api.NotificationRoutes$discordSendRoute$1.invokeSuspend(NotificationRoutes.kt:101)
        at snd.komf.app.api.NotificationRoutes$discordSendRoute$1.invoke(NotificationRoutes.kt)
        at snd.komf.app.api.NotificationRoutes$discordSendRoute$1.invoke(NotificationRoutes.kt)
        at io.ktor.server.routing.RoutingNode$buildPipeline$1$1.invokeSuspend(RoutingNode.kt:116)
        at io.ktor.server.routing.RoutingNode$buildPipeline$1$1.invoke(RoutingNode.kt)
        at io.ktor.server.routing.RoutingNode$buildPipeline$1$1.invoke(RoutingNode.kt)
        at io.ktor.util.pipeline.PipelineJvmKt.pipelineStartCoroutineUninterceptedOrReturn(PipelineJvm.kt:15)
        at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:131)
        at io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:89)
        at io.ktor.util.pipeline.SuspendFunctionGun.execute$ktor_utils(SuspendFunctionGun.kt:109)
        at io.ktor.util.pipeline.Pipeline.execute(Pipeline.kt:79)
        at io.ktor.server.routing.RoutingRoot$executeResult$$inlined$execute$1.invokeSuspend(Pipeline.kt:481)
        at io.ktor.server.routing.RoutingRoot$executeResult$$inlined$execute$1.invoke(Pipeline.kt)
        at io.ktor.server.routing.RoutingRoot$executeResult$$inlined$execute$1.invoke(Pipeline.kt)
        at io.ktor.util.debug.ContextUtilsKt.initContextInDebugMode(ContextUtils.kt:17)
        at io.ktor.server.routing.RoutingRoot.executeResult(RoutingRoot.kt:193)
        at io.ktor.server.routing.RoutingRoot.interceptor(RoutingRoot.kt:66)
        at io.ktor.server.routing.RoutingRoot$Plugin$install$1.invokeSuspend(RoutingRoot.kt:143)
        at io.ktor.server.routing.RoutingRoot$Plugin$install$1.invoke(RoutingRoot.kt)
        at io.ktor.server.routing.RoutingRoot$Plugin$install$1.invoke(RoutingRoot.kt)
        at io.ktor.util.pipeline.PipelineJvmKt.pipelineStartCoroutineUninterceptedOrReturn(PipelineJvm.kt:15)
        at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:131)
        at io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:89)
        at io.ktor.server.engine.BaseApplicationEngineKt$installDefaultTransformationChecker$1.invokeSuspend(BaseApplicationEngine.kt:112)
        at io.ktor.server.engine.BaseApplicationEngineKt$installDefaultTransformationChecker$1.invoke(BaseApplicationEngine.kt)
        at io.ktor.server.engine.BaseApplicationEngineKt$installDefaultTransformationChecker$1.invoke(BaseApplicationEngine.kt)
        at io.ktor.util.pipeline.PipelineJvmKt.pipelineStartCoroutineUninterceptedOrReturn(PipelineJvm.kt:15)
        at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:131)
        at io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:89)
        at io.ktor.server.application.hooks.CallFailed$install$1$1.invokeSuspend(CommonHooks.kt:45)
        at io.ktor.server.application.hooks.CallFailed$install$1$1.invoke(CommonHooks.kt)
        at io.ktor.server.application.hooks.CallFailed$install$1$1.invoke(CommonHooks.kt)
        at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:43)
        at kotlinx.coroutines.CoroutineScopeKt.coroutineScope(CoroutineScope.kt:285)
        at io.ktor.server.application.hooks.CallFailed$install$1.invokeSuspend(CommonHooks.kt:44)
        at io.ktor.server.application.hooks.CallFailed$install$1.invoke(CommonHooks.kt)
        at io.ktor.server.application.hooks.CallFailed$install$1.invoke(CommonHooks.kt)
        at io.ktor.util.pipeline.PipelineJvmKt.pipelineStartCoroutineUninterceptedOrReturn(PipelineJvm.kt:15)
        at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:131)
        at io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:89)
        at io.ktor.util.pipeline.SuspendFunctionGun.execute$ktor_utils(SuspendFunctionGun.kt:109)
        at io.ktor.util.pipeline.Pipeline.execute(Pipeline.kt:79)
        at io.ktor.server.engine.DefaultEnginePipelineKt$defaultEnginePipeline$1$invokeSuspend$$inlined$execute$1.invokeSuspend(Pipeline.kt:481)
        at io.ktor.server.engine.DefaultEnginePipelineKt$defaultEnginePipeline$1$invokeSuspend$$inlined$execute$1.invoke(Pipeline.kt)
        at io.ktor.server.engine.DefaultEnginePipelineKt$defaultEnginePipeline$1$invokeSuspend$$inlined$execute$1.invoke(Pipeline.kt)
        at io.ktor.util.debug.ContextUtilsKt.initContextInDebugMode(ContextUtils.kt:17)
        at io.ktor.server.engine.DefaultEnginePipelineKt$defaultEnginePipeline$1.invokeSuspend(DefaultEnginePipeline.kt:123)
        at io.ktor.server.engine.DefaultEnginePipelineKt$defaultEnginePipeline$1.invoke(DefaultEnginePipeline.kt)
        at io.ktor.server.engine.DefaultEnginePipelineKt$defaultEnginePipeline$1.invoke(DefaultEnginePipeline.kt)
        at io.ktor.util.pipeline.PipelineJvmKt.pipelineStartCoroutineUninterceptedOrReturn(PipelineJvm.kt:15)
        at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:131)
        at io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:89)
        at io.ktor.util.pipeline.SuspendFunctionGun.execute$ktor_utils(SuspendFunctionGun.kt:109)
        at io.ktor.util.pipeline.Pipeline.execute(Pipeline.kt:79)
        at io.ktor.server.cio.CIOApplicationEngine$handleRequest$2$invokeSuspend$$inlined$execute$1.invokeSuspend(Pipeline.kt:481)
        at io.ktor.server.cio.CIOApplicationEngine$handleRequest$2$invokeSuspend$$inlined$execute$1.invoke(Pipeline.kt)
        at io.ktor.server.cio.CIOApplicationEngine$handleRequest$2$invokeSuspend$$inlined$execute$1.invoke(Pipeline.kt)
        at io.ktor.util.debug.ContextUtilsKt.initContextInDebugMode(ContextUtils.kt:17)
        at io.ktor.server.cio.CIOApplicationEngine$handleRequest$2.invokeSuspend(CIOApplicationEngine.kt:229)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100)
        at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:113)
        at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:89)
        at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:586)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:820)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:717)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:704)

Setting it to an actual plaintext url like google.com works just fine.

vodkapmp avatar May 11 '25 16:05 vodkapmp

There's a bug in notification settings where if you've set the title url template before, you can't remove it You'll need to manually remove thetitle_url.vm template file in discord directory. That directory should be in the same directory as komf jar file or in config volume that you mount in docker.

Also i in the template context is the index of an array, for example if you know there's at least one link it'll be $series.metadata.links[0].url otherwise you can iterate through links in a loop

#foreach ($link in $series.metadata.links)
${link.url}
#end

Snd-R avatar May 11 '25 16:05 Snd-R

There's a bug in notification settings where if you've set the title url template before, you can't remove it You'll need to manually remove thetitle_url.vm template file in discord directory. That directory should be in the same directory as komf jar file or in config volume that you mount in docker.

Doing this changes nothing, same error message when a notification is triggered if the URL field is blank. (deleted file and restarted the docker container)

Also i in the template context is the index of an array, for example if you know there's at least one link it'll be $series.metadata.links[0].url otherwise you can iterate through links in a loop

Setting this to 0 for example, or 1 etc for that matter causes the same error as leaving the title_url field blank: io.ktor.client.plugins.ClientRequestException: Client request(POST https://discord.com/api/webhooks/REDACTED/REDACTED) invalid: 400 . Text: "{"embeds": ["0"]}"

vodkapmp avatar May 11 '25 17:05 vodkapmp