Last active
October 5, 2020 02:57
-
-
Save seratch/a900efbbf68a31fdc96121ad0b9f4c97 to your computer and use it in GitHub Desktop.
Steps from Apps in Kotlin
This file contains hidden or 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
| plugins { | |
| id("org.jetbrains.kotlin.jvm") version "1.4.10" | |
| id("application") | |
| } | |
| repositories { | |
| mavenCentral() | |
| } | |
| dependencies { | |
| implementation(platform("org.jetbrains.kotlin:kotlin-bom")) | |
| implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") | |
| implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.9") | |
| implementation("com.slack.api:bolt-jetty:1.2.0-RC2") | |
| implementation("com.slack.api:slack-api-client-kotlin-extension:1.2.0-RC2") | |
| implementation("org.slf4j:slf4j-simple:1.7.30") // or logback-classic | |
| } | |
| application { | |
| mainClassName = "MyAppKt" // add "Kt" suffix for main function source file | |
| } | |
This file contains hidden or 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
| import com.slack.api.bolt.App | |
| import com.slack.api.bolt.jetty.SlackAppServer | |
| import com.slack.api.bolt.middleware.builtin.WorkflowStep | |
| import com.slack.api.model.block.Blocks.divider | |
| import com.slack.api.model.block.Blocks.section | |
| import com.slack.api.model.block.LayoutBlock | |
| import com.slack.api.model.block.composition.BlockCompositions.plainText | |
| import com.slack.api.model.kotlin_extension.block.withBlocks | |
| import com.slack.api.model.view.Views.view | |
| import com.slack.api.model.view.Views.viewTitle | |
| import com.slack.api.model.workflow.WorkflowSteps.stepInput | |
| import com.slack.api.model.workflow.WorkflowSteps.stepOutput | |
| import kotlinx.coroutines.GlobalScope | |
| import kotlinx.coroutines.async | |
| fun main() { | |
| System.setProperty("org.slf4j.simpleLogger.log.com.slack.api", "debug") | |
| val pseudoDatabase = mutableMapOf<String, MutableList<Map<String, Any?>>>() | |
| // export SLACK_BOT_TOKEN=xoxb- | |
| // export SLACK_SIGNING_SECRET= | |
| val app = App() | |
| val step = WorkflowStep.builder() | |
| .callbackId("copy_review") | |
| .edit { _, ctx -> | |
| ctx.configure(withBlocks { | |
| section { | |
| blockId("intro-section") | |
| plainText("Create a task in one of the listed projects. The link to the task and other details will be available as variable data in later steps.") | |
| } | |
| input { | |
| blockId("task_name_input") | |
| element { | |
| plainTextInput { | |
| actionId("task_name") | |
| placeholder("Write a task name") | |
| } | |
| } | |
| label("Task name") | |
| } | |
| input { | |
| blockId("task_description_input") | |
| element { | |
| plainTextInput { | |
| actionId("task_description") | |
| placeholder("Write a description for your task") | |
| } | |
| } | |
| label("Task description") | |
| } | |
| input { | |
| blockId("task_author_input") | |
| element { | |
| plainTextInput { | |
| actionId("task_author") | |
| placeholder("Write a task name") | |
| } | |
| } | |
| label("Task author") | |
| } | |
| }) | |
| ctx.ack() | |
| } | |
| .save { req, ctx -> | |
| val values = req.payload.view.state.values | |
| val inputs = mapOf( | |
| "taskName" to stepInput { it.value(values["task_name_input"]?.get("task_name")?.value) }, | |
| "taskDescription" to stepInput { it.value(values["task_description_input"]?.get("task_description")?.value) }, | |
| "taskAuthorEmail" to stepInput { it.value(values["task_author_input"]?.get("task_author")?.value) }, | |
| ) | |
| val outputs = listOf( | |
| stepOutput { it.name("taskName").type("text").label("Task Name") }, | |
| stepOutput { it.name("taskDescription").type("text").label("Task Description") }, | |
| stepOutput { it.name("taskAuthorEmail").type("text").label("Task Author Email") }, | |
| ) | |
| ctx.update(inputs, outputs) | |
| ctx.ack() | |
| } | |
| .executeAutoAcknowledgement(false) | |
| .execute { req, ctx -> | |
| val step = req.payload.event.workflowStep | |
| GlobalScope.async { | |
| try { | |
| val email = step.inputs["taskAuthorEmail"]?.value.toString() | |
| val outputs = mapOf( | |
| "taskName" to step.inputs["taskName"]?.value, | |
| "taskDescription" to step.inputs["taskDescription"]?.value, | |
| "taskAuthorEmail" to email, | |
| ) | |
| ctx.complete(outputs) | |
| val userLookup = ctx.client().usersLookupByEmail { it.email(email) } | |
| if (userLookup.isOk) { | |
| val userId = userLookup.user.id | |
| val newTask = mapOf( | |
| "taskName" to step.inputs["taskName"]?.value, | |
| "taskDescription" to step.inputs["taskDescription"]?.value, | |
| ) | |
| val tasks = pseudoDatabase.getOrDefault(userId, mutableListOf()) | |
| tasks.add(newTask) | |
| pseudoDatabase[userId] = tasks | |
| val blocks = mutableListOf<LayoutBlock>() | |
| tasks.forEach { task -> | |
| blocks.add(section { it.text(plainText { pt -> pt.text(task["taskName"].toString()) }) }) | |
| blocks.add(divider()) | |
| } | |
| ctx.client().viewsPublish { | |
| it.userId(userId).view(view { v -> | |
| v.type("home") | |
| .title(viewTitle { vt -> vt.type("plain_text").text("Your tasks!") }) | |
| .blocks(blocks) | |
| }) | |
| } | |
| } else { | |
| ctx.fail(mapOf("message" to "User not found by $email")) | |
| } | |
| } catch (e: Exception) { | |
| ctx.fail(mapOf("message" to "Something wrong! ($e)")) | |
| } | |
| } | |
| ctx.ack() | |
| } | |
| .build() | |
| app.step(step) | |
| val server = SlackAppServer(app) | |
| server.start() // http://localhost:3000/slack/events | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment