Skip to content

Instantly share code, notes, and snippets.

@Krever
Last active June 13, 2025 20:56
Show Gist options
  • Select an option

  • Save Krever/eee34f786bfbb9854ae12c17c88889a4 to your computer and use it in GitHub Desktop.

Select an option

Save Krever/eee34f786bfbb9854ae12c17c88889a4 to your computer and use it in GitHub Desktop.

Revisions

  1. Krever revised this gist Jun 13, 2025. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions chatops.scala
    Original file line number Diff line number Diff line change
    @@ -41,6 +41,7 @@ case class MessageResponse(

    // allows to receive data from the platform
    trait InboundGateway {
    // todo: id will be required to keep processing between restarts
    def registerAction(handler: InteractionContext => IO[Unit]): IO[ButtonInteraction]
    }

  2. Krever revised this gist Jun 13, 2025. 1 changed file with 22 additions and 19 deletions.
    41 changes: 22 additions & 19 deletions chatops.scala
    Original file line number Diff line number Diff line change
    @@ -2,6 +2,28 @@ package chatops4s

    import cats.effect.IO


    object UsageExample {
    val inbound: InboundGateway = ???
    val outbound: OutboundGateway = ???

    for {
    approveAction <- inbound.registerAction(ctx => IO(println(s"Approved by ${ctx.userId}")))
    rejectAction <- inbound.registerAction(ctx => IO(println(s"Rejected by ${ctx.userId}")))
    msg = Message(
    text = "Deploy to production?",
    interactions = Seq(
    approveAction.render("Approve"),
    rejectAction.render("Reject"),
    ),
    )
    response <- outbound.sendToChannel("channel123", msg)
    _ <- outbound.sendToThread(response.messageId, Message("Thanks for your feedback"))
    } yield ()

    }


    // allows to put data into the platform, probably based on sttp
    trait OutboundGateway {
    def sendToChannel(channelId: String, message: Message): IO[MessageResponse]
    @@ -38,22 +60,3 @@ trait ButtonInteraction {
    // Direct mapping of api - object we put in the request
    case class Button(label: String, value: String)

    object UsageExample {
    val inbound: InboundGateway = ???
    val outbound: OutboundGateway = ???

    for {
    approveAction <- inbound.registerAction(ctx => IO(println(s"Approved by ${ctx.userId}")))
    rejectAction <- inbound.registerAction(ctx => IO(println(s"Rejected by ${ctx.userId}")))
    msg = Message(
    text = "Deploy to production?",
    interactions = Seq(
    approveAction.render("Approve"),
    rejectAction.render("Reject"),
    ),
    )
    response <- outbound.sendToChannel("channel123", msg)
    _ <- outbound.sendToThread(response.messageId, Message("Thanks for your feedback"))
    } yield ()

    }
  3. Krever created this gist Jun 13, 2025.
    59 changes: 59 additions & 0 deletions chatops.scala
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,59 @@
    package chatops4s

    import cats.effect.IO

    // allows to put data into the platform, probably based on sttp
    trait OutboundGateway {
    def sendToChannel(channelId: String, message: Message): IO[MessageResponse]
    def sendToThread(messageId: String, message: Message): IO[MessageResponse]
    }

    case class Message(
    text: String,
    interactions: Seq[Button] = Seq(),
    )

    case class MessageResponse(
    messageId: String,
    )

    // allows to receive data from the platform
    trait InboundGateway {
    def registerAction(handler: InteractionContext => IO[Unit]): IO[ButtonInteraction]
    }

    // who clicked what where
    case class InteractionContext(
    userId: String,
    channelId: String,
    messageId: String,
    )

    // registered interaction
    // handler was registered and produced this object that can be used to accept data
    trait ButtonInteraction {
    def render(label: String): Button
    }

    // Direct mapping of api - object we put in the request
    case class Button(label: String, value: String)

    object UsageExample {
    val inbound: InboundGateway = ???
    val outbound: OutboundGateway = ???

    for {
    approveAction <- inbound.registerAction(ctx => IO(println(s"Approved by ${ctx.userId}")))
    rejectAction <- inbound.registerAction(ctx => IO(println(s"Rejected by ${ctx.userId}")))
    msg = Message(
    text = "Deploy to production?",
    interactions = Seq(
    approveAction.render("Approve"),
    rejectAction.render("Reject"),
    ),
    )
    response <- outbound.sendToChannel("channel123", msg)
    _ <- outbound.sendToThread(response.messageId, Message("Thanks for your feedback"))
    } yield ()

    }