<repo_name>fbodr/slackmsg<file_sep>/README.md
# slack webhook with kotlin dsl

This is "quick and dirty" example(study) on using slack webhooks for sending messagens, and using kotlin dsl for creating the message.<file_sep>/src/main/kotlin/org/fabiodarosa/slackmsg/client/SlackClient.kt
package org.fabiodarosa.slackmsg.client

import okhttp3.MediaType
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.OkHttpClient
import okhttp3.Request
import org.fabiodarosa.slackmsg.dsl.SlackMessage
import org.fabiodarosa.slackmsg.dsl.toJson

fun SlackMessage.toRequestBody(toMediaType: MediaType) = toJson().toRequestBody(toMediaType)

class SlackClient {

    fun sendMessage(message: SlackMessage, channel: String? = null) {
        val client = OkHttpClient()
        val webHookUrl = System.getenv("WEBHOOK_URL")

        val request = Request.Builder()
            .url(webHookUrl)
            .post(message.toRequestBody("application/json".toMediaType()))
            .build()

        client.newCall(request).execute().use { response ->
            if (!response.isSuccessful) {
                println("ERROR: " + response.body!!.string())
            } else {
                println("OK: " + response.body!!.string())
            }
        }
    }

}<file_sep>/src/main/kotlin/org/fabiodarosa/slackmsg/main.kt
package org.fabiodarosa.slackmsg

import org.fabiodarosa.slackmsg.client.SlackClient
import org.fabiodarosa.slackmsg.dsl.slackMessage

fun main() {

    val slackClient = SlackClient()
    val myMessage = slackMessage {

        text {
            + "_italic_"
            + "*bold*"
            + "~strike~"
        }
        markDown{
            + "_italic_"
            + "*bold*"
            + "~strike~"
        }

        json {
             """{"id": "123"}"""
        }
    }

    slackClient.sendMessage(message = myMessage)
}
<file_sep>/settings.gradle.kts
rootProject.name = "slackbot"

<file_sep>/src/main/kotlin/org/fabiodarosa/slackmsg/dsl/SlackMessageDsl.kt
package org.fabiodarosa.slackmsg.dsl

import com.google.gson.Gson
val json = Gson()

abstract class SlackBlock(
    val type: String
)

class SectionBlock(
    val text: TextField
): SlackBlock("section")

abstract class TextField (
    val type: String,
    val text: String
)

class PlainText(text: String): TextField("plain_text", text)
class MarkDownText(text: String): TextField("mrkdwn", text)
class JsonText(json: String): TextField("mrkdwn", "```$json```")

class SlackMessage(
    val blocks: List<SlackBlock>
)
fun SlackMessage.toJson(): String = json.toJson(this)

class PlainTextBuilder() {
    private var textBuffer: StringBuffer = StringBuffer()
    operator fun String.unaryPlus() {
        if(textBuffer.isNotEmpty()) {
            textBuffer.append("\n")
        }
        textBuffer.append(this)
    }
    fun build() = SectionBlock(PlainText(textBuffer.toString()))
}
class MarkDownTextBuilder() {
    private var textBuffer: StringBuffer = StringBuffer()
    operator fun String.unaryPlus() {
        if(textBuffer.isNotEmpty()) {
            textBuffer.append("\n")
        }
        textBuffer.append(this)
    }
    fun build() = SectionBlock(MarkDownText(textBuffer.toString()))
}

class SlackMessageBuilder {
    private val blocks: MutableList<SlackBlock> = mutableListOf()

    fun text(body: PlainTextBuilder.() -> Unit) = blocks.add(PlainTextBuilder().apply(body).build())
    fun markDown(body: MarkDownTextBuilder.() -> Unit) =  blocks.add(MarkDownTextBuilder().apply(body).build())
    fun json(body: () -> String) = blocks.add(SectionBlock(JsonText(body())))

    fun build() = SlackMessage(blocks)
}

fun slackMessage(body: SlackMessageBuilder.() -> Unit): SlackMessage =
    SlackMessageBuilder().apply(body).build()

