-
-
Save comdotlinux/38166004c95cecfe3c97a3e0a871c75b to your computer and use it in GitHub Desktop.
Building Slack apps with Ktor framework
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export SLACK_SIGNING_SECRET=(find this at Settings > Basic Information > App Credentials > Signing Secret) | |
export SLACK_BOT_TOKEN=xoxb-(find this at Settings > Install App) | |
gradle run |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ktor { | |
deployment { | |
port = 3000 | |
port = ${?PORT} | |
} | |
application { | |
modules = [com.example.ApplicationKt.module] | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example | |
import com.slack.api.bolt.App | |
import com.slack.api.bolt.AppConfig | |
import com.slack.api.bolt.request.Request | |
import com.slack.api.bolt.request.RequestHeaders | |
import com.slack.api.bolt.response.Response | |
import com.slack.api.bolt.util.QueryStringParser | |
import com.slack.api.bolt.util.SlackRequestParser | |
import com.slack.api.model.block.Blocks.asBlocks | |
import com.slack.api.model.block.Blocks.section | |
import com.slack.api.model.block.composition.BlockCompositions.markdownText | |
import com.slack.api.model.block.composition.BlockCompositions.plainText | |
import com.slack.api.model.block.element.BlockElements.button | |
import io.ktor.application.Application | |
import io.ktor.application.ApplicationCall | |
import io.ktor.application.call | |
import io.ktor.content.TextContent | |
import io.ktor.features.origin | |
import io.ktor.http.ContentType | |
import io.ktor.http.HttpStatusCode | |
import io.ktor.request.queryString | |
import io.ktor.request.receiveText | |
import io.ktor.request.uri | |
import io.ktor.response.header | |
import io.ktor.response.respond | |
import io.ktor.routing.post | |
import io.ktor.routing.routing | |
import io.ktor.util.toMap | |
val appConfig = AppConfig() | |
val requestParser = SlackRequestParser(appConfig) | |
val app = App(appConfig) | |
fun Application.module() { | |
app.command("/ktor") { _, ctx -> | |
ctx.ack(asBlocks( | |
section { section -> | |
section | |
.text(markdownText("Ktor is a framework for building asynchronous servers and clients in connected systems using the powerful Kotlin programming language.")) | |
.accessory( | |
button { btn -> | |
btn.actionId("link") | |
.text(plainText("Ktor website")) | |
.url("https://ktor.io/") | |
} | |
) | |
} | |
)) | |
} | |
app.blockAction("link") { _, ctx -> | |
ctx.ack() | |
} | |
routing { | |
post("/slack/events") { | |
respond(call, app.run(parseRequest(call))) | |
} | |
} | |
} | |
suspend fun parseRequest(call: ApplicationCall): Request<*> { | |
val requestBody = call.receiveText() | |
val queryString = QueryStringParser.toMap(call.request.queryString()) | |
val headers = RequestHeaders(call.request.headers.toMap()) | |
return requestParser.parse( | |
SlackRequestParser.HttpRequest.builder() | |
.requestUri(call.request.uri) | |
.queryString(queryString) | |
.requestBody(requestBody) | |
.headers(headers) | |
.remoteAddress(call.request.origin.remoteHost) | |
.build() | |
) | |
} | |
suspend fun respond(call: ApplicationCall, slackResp: Response) { | |
for (header in slackResp.headers) { | |
for (value in header.value) { | |
call.response.header(header.key, value) | |
} | |
} | |
call.response.status(HttpStatusCode.fromValue(slackResp.statusCode)) | |
if (slackResp.body != null) { | |
call.respond(TextContent(slackResp.body, ContentType.parse(slackResp.contentType))) | |
} | |
} | |
fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
buildscript { | |
repositories { | |
jcenter() | |
} | |
dependencies { | |
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" | |
} | |
} | |
apply plugin: 'kotlin' | |
apply plugin: 'application' | |
group 'com.example' | |
version '0.0.1' | |
mainClassName = "io.ktor.server.netty.EngineMain" | |
sourceSets { | |
main.kotlin.srcDirs = main.java.srcDirs = ['src'] | |
test.kotlin.srcDirs = test.java.srcDirs = ['test'] | |
main.resources.srcDirs = ['resources'] | |
test.resources.srcDirs = ['testresources'] | |
} | |
repositories { | |
mavenLocal() | |
jcenter() | |
} | |
dependencies { | |
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" | |
implementation "io.ktor:ktor-server-netty:$ktor_version" | |
implementation "com.slack.api:bolt:$slack_sdk_version" | |
implementation "ch.qos.logback:logback-classic:$logback_version" | |
testImplementation "io.ktor:ktor-server-tests:$ktor_version" | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ktor_version=1.3.0 | |
kotlin.code.style=official | |
kotlin_version=1.3.71 | |
logback_version=1.2.3 | |
slack_sdk_version=1.0.1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<configuration> | |
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> | |
<encoder> | |
<pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> | |
</encoder> | |
</appender> | |
<root level="trace"> | |
<appender-ref ref="STDOUT"/> | |
</root> | |
<logger name="org.eclipse.jetty" level="INFO"/> | |
<logger name="io.netty" level="INFO"/> | |
</configuration> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment