All Downloads are FREE. Search and download functionalities are using the official Maven repository.

muffin.interop.http.zio.ZRoutes.scala Maven / Gradle / Ivy

There is a newer version: 0.3.0
Show newest version
package muffin.interop.http.zio

import java.nio.charset.Charset

import cats.effect.Sync

import zhttp.http.*
import zhttp.service.*
import zhttp.service.server.ServerChannelFactory
import zio.*

import muffin.api.*
import muffin.codec.*
import muffin.codec.CodecSupport
import muffin.model.*
import muffin.router.*

object ZRoutes {

  def routes[R, To[_], From[_]](
      router: Router[RHttp[R]],
      codec: CodecSupport[To, From]
  ): Http[HttpR[R], Throwable, Request, Response] = {
    import codec.given
    Http
      .collectZIO[Request]
      .apply[HttpR[R], Throwable, Response] {
        case req @ Method.POST -> !! / "commands" / handler / command =>
          handleEvent[HttpR[R], String](req)(data => router.handleCommand(s"$handler::$command", decodeFormData(data)))
        case req @ Method.POST -> !! / "actions" / handler / actions  =>
          handleEvent[HttpR[R], String](req)(data => router.handleAction(s"$handler::$actions", HttpAction(data)))
        case req @ Method.POST -> !! / "dialogs" / handler / dialogs  =>
          handleEvent[HttpR[R], String](req)(data => router.handleDialog(s"$handler::$dialogs", HttpAction(data)))
      }
  }

  private given Decode[String] = s => Right(s)

  def handleEvent[R, In](
      request: Request
  )(fun: In => ZRHttp[HttpR[R], HttpResponse])(using decoder: Decode[In]): ZRHttp[HttpR[R], Response] =
    for {
      buf      <- request.body.asString(Charset.forName("UTF-8"))
      response <-
        decoder.apply(buf) match {
          case Left(error)  => ZIO.fail(error)
          case Right(value) => fun(value)
        }
    } yield Response.json(response.data)

  private def decodeFormData(str: String): CommandAction = {
    val parts =
      str.split('&').map {
        case s"$name=$value" => name -> value
      }.toMap
    CommandAction(
      ChannelId(parts("channel_id")),
      parts("channel_name"),
      parts("response_url"),
      parts("team_domain"),
      TeamId(parts("team_id")),
      parts.get("text"),
      parts("trigger_id"),
      UserId(parts("user_id")),
      parts("user_name")
    )
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy