Slack Next-gen Platform – The Simplest “Hello World”

This is translation of Slack Next-gen Platform – The Simplest “Hello World” – DEV Community 👩‍💻👨‍💻 ” written by Kaz (SDK Engineering & DevRel at Slack), I do not include any personal opinion here except guessing when meaning of original text is not clear for me)

이 글은 슬랙의 SDK Engineering / DevRel 인 Kaz 의 글을 번역한것입니다. 저의 개인 의견은 들어가지 않으며, 일부 원문의 의미가 애매한 경우에만 부연 설명을 달았습니다.


이 튜토리얼에서는, Slack 의 Next generation Platform(이하 차세대 플랫폼) 을 사용하는 방법에 대해서 배워볼 수 있습니다.

아실수도 있는데요, slack create 명령어를 사용하여 새로운 app 을 만들 때, 오피셜 “헬로우 월드” 프로젝트 템플릿을 사용해볼 수 있습니다. 해당 프로젝트의 템플릿 코드는 다음 링크에서 확인할 수 있습니다.

https://github.com/slack-samples/deno-hello-world

플랫폼을 배우는데 좋은 템플릿입니다. 많은 것을 다뤄볼 수 있기 때문입니다. (앱 매니페스트, 트리거, 워크플로, 빌트인 폼 펑션, 커스텀 펑션, 빌트인 메세지 펑션, 표준 디렉토리 구조 등)

그렇지만, 이번 튜토리얼에서는 최소한의 빌딩 블락, 앱 매니페스트, 트리거, 워크플로, 빌트인 메세지 펑션의 의미들에 대해서만 배워보겠습니다. 모든 것을 하나씩 이해해가는것은 우회로 처럼 보이기도 하지만 지름길이기도 합니다. (하나하나 이해하는 것이 중요하다 라는 의미로 쓴것 같네요)

Prerequisites (준비사항)

만약 Slack 의 차세대 플랫폼을 처음 다뤄보신다면, 공식 퀵 스타트 가이드를 읽어보세요. 퀵 스타트 가이드에서 언급된 바와 같이, Slack CLI 을 설정하고, 유료 슬랙 워크스페이스에 연결해두어야 합니다.

이 글을 쓰는 현재 시점 (2022년 12월) 기준으로, 차세대플랫폼은 아직 오픈 베타 상태입니다. 그래서, Slack 워크스페이스 관리자가 beta feature 를 켜주어야 합니다. (https://my.slack.com/admin/settings#permissions)

여기까지 끝났으면 이제 첫번째 앱을 만들 준비가 되었습니다. 시작해보죠

Create a black project (빈 프로젝트 생성)

새로운 프로젝트를 시작할 때 slack create 명령어를 사용할 수 있습니다.

$ slack create
? Select a template to build from:

  Hello World
  A simple workflow that sends a greeting

  Scaffolded project
  A solid foundational project that uses a Slack datastore

> Blank project
  A, well.. blank project

  To see all available samples, visit github.com/slack-samples.

Hello World 템플릿도 보이시겠지만, 지금은 Blank Project 를 선택해주세요

프로젝트가 생성되고 나면 slack run 명령어가 문제없이 동작하는지 확인해봅시다. 이 명령어는 “dev”버전의 새로운 앱을 여러분들의 Slack 워크스페이스에 설치합니다. 끝나면 앱의 봇 유저가 워크스페이스내에 존재하게 되며, 앱의 봇이 API 콜을 할 수 있도록 token 값을 확인할 수 있습니다.

$ cd dreamy-gazelle-453
$ slack run
? Choose a workspace  seratch  T03E94MJU
   App is not installed to this workspace

Updating dev app install for workspace "Acme Corp"

⚠️  Outgoing domains
   No allowed outgoing domains are configured
   If your function makes network requests, you will need to allow the outgoing domains
   Learn more about upcoming changes to outgoing domains: https://api.slack.com/future/changelog
seratch of Acme Corp
Connected, awaiting events

connected, awaiting events 메세지를 확인할 수 있다면, 앱이 성공적으로 Slack 에 연결된 것입니다. 여기서 “Ctrl + C” 를 눌러, 이 앱의 프로세스를 종료할 수 있습니다.

이 앱에는 아직 아무것도 없는 상태입니다. 그러므로, 몇가지 파일들을 이 프로젝트에 추가해보도록 하죠. 아마 이미 보셨을텐데 , Slack 의 차세대 플랫폼에서 실행되는 앱은 Deno(a novel JavaScript runtime) 으로 실행됩니다. 그래서 프로젝트를 위한 코딩/편집을 위해서는 VS Code공식 Deno 플러그인을 사용하는 것을 권장합니다.

Hello World with Webhook Trigger

차세대플랫폼의 앱에서는 여러개의 워크플로를 가질 수 있습니다. 또한 각 워크플로 별로 트리거를 가질 수 있습니다. 트리거는 연동된 워크플로를 시작하기 위한 방법이며, 이전의 Slack 플랫폼과 다른점중 한가지 입니다.

어떻게 트리거가 동작하는지 배워보기 위해서, “Incoming Webhooks 트리거”를 한번 써보도록 해보죠. 다음과 같은 과정을 거칠 것입니다.

  • 워크플로와 트리거를 포함한 workflow_and_trigger.ts 생성
  • Slack 워크스페이스의 채널 ID 확인하여 코드내에 적용
  • manifest.ts 에 워크플로 추가
  • slack run 명령어를 통한 최종 셋팅이 적용된 앱 재설치
  • 트리거 생성 (slack triggers create –trigger-def ./workflow_and_trigger.ts 명령어 실행)
  • webhook URL 로 POST 요청을 보내서 워크플로 시작

워크플로와 트리거를 포함한 workflow_and_trigger.ts 생성

workflow_and_trigger.ts 파일을 만들고, 아래 내용으로 저장합니다.

// -------------------------
// Workflow definition
// -------------------------
import { DefineWorkflow, Schema } from "deno-slack-sdk/mod.ts";

// Don't forget to add this workflow to manifest.ts!
export const workflow = DefineWorkflow({
  callback_id: "hello-world-workflow",
  title: "Hello World Workflow",
  input_parameters: { properties: {}, required: [] },
});

// Send a message in a channel using the built-in function
workflow.addStep(Schema.slack.functions.SendMessage, {
  channel_id: "C03E94MKS", // TODO: Grab the ID in Slack UI
  message: "Hello World!",
});

// -------------------------
// Trigger Definition
// -------------------------
import { Trigger } from "deno-slack-api/types.ts";
// This trigger starts the workflow when the webhook URL receives an HTTP request
const trigger: Trigger<typeof workflow.definition> = {
  type: "webhook", // Incoming Webhooks
  name: "Hello World Trigger",
  // Need to embed the workflow's callback_id here
  workflow: `#/workflows/${workflow.definition.callback_id}`,
};

// As long as the trigger object is default exported,
// you can generate a trigger with this code:
// $ slack triggers create --trigger-def ./workflow_and_trigger.ts
export default trigger;

이 소스파일은 두가지 일을 합니다.

  • 앱을 위한 새로운 워크플로 정의
  • 워크플로를 시작할 수 있는 webhook 트리거 정의

몇가지 일이 더 남았습니다. 다음으로 넘어가보죠.

Slack 워크스페이스의 채널 ID 확인하여 코드내에 적용

workflow_and_trigger.ts 파일내의 TODO 코멘트를 보시면 다음과 같은 항목이 있습니다.

channel_id: "C03E94MKS", // TODO: Grab the ID in Slack UI

채널 ID 를 확인하기 위해서 일단 공개채널을 하나 골라주십시요. (현 시점기준으로, 베타 플랫폼에서는 공개채널만 지원됩니다. GA 가 되면 비공개채널도 지원할 것입니다.)

채널 ID 를 확인하기 위한 가장 쉬운 방법은 Slack 클라이언트의 UI 에서 채널이름을 선택한후, 우클릭 -> 채널 세부정보 보기를 보시면 “C” 로 시작하는 문자열을 보실 수 있습니다. 그게 채널의 ID 값 입니다.

이 방법외에는 해당채널의 메세지중 하나를 고르시고, “링크 복사” 를 해보시면, 그 안에 동일하게 “C” 로 시작하는 부분을 확인하실 수 있습니다. (https://my.slack.com/archives/..)

채널 ID 가 확인되면, workflow_and_trigger.ts 코드내의 채널 ID 를 바꿔줍니다.

manifest.ts 에 워크플로 추가

다음으로, manifest.ts 파일에 아래와 같이 워크플로를 추가합니다. 그리고 manifest.ts 파일내의 workflow 정수값을 임포트하고, workflow 배열내의 객체에 레퍼런스를 추가하여 줍니다. (제가 개발쪽은 일자무식이라 번역이 제대로 된건지 모르겠네요)

import { Manifest } from "deno-slack-sdk/mod.ts";
// Import the workflow you've just created
import { workflow as HelloWorld } from "./workflow_and_trigger.ts";

export default Manifest({
  name: "dreamy-gazelle-453",
  description: "Hello World!",
  icon: "assets/default_new_app_icon.png",
  // Add the imported workflow here
  workflows: [HelloWorld],
  outgoingDomains: [],
  botScopes: ["commands", "chat:write", "chat:write.public"],
});

slack run 명령어를 통한 최종 셋팅이 적용된 앱 재설치

필요한 모든 변경이 완료되었습니다. 아직 터미널을 열어두신 상태라면, 똑같은 커맨드를 다시한번 실행해주시면 됩니다. (slack run), 별다른 에러메세지가 나오지 않는다면 모든게 좋은 상태입니다.

slack run 커맨드를 종료해도 좋습니다만(ctrl +c), 일단 냅두시고 다른 터미널 윈도우를 하나 더 오픈하여 다른 명령어를 실행해보도록 하죠.

Webhook 트리거 생성

이제 워크플로가 준비되었으며 이 워크플로는 Slack 의 클라우드 인프라에서 실행됩니다. 이제 이 워크플로를 실행하기 위한 webhook 트리거를 만들 수 있습니다. app manifest 에 workflow 를 추가한다하더라도 트리거를 자동으로 만들지 않기 때문에, 트리거를 만들어주어야 합니다.

slack triggers create 명령어를 실행하면 트리거를 만들 수 있습니다.

두가지 옵션을 볼 수 있을텐데, 지금은 일단 (dev) 가 달린 것을 선택해주세요.

$ slack triggers create --trigger-def ./workflow_and_trigger.ts
? Choose an app  [Use arrows to move, type to filter]
   seratch  T03E94MJU
   App is not installed to this workspace

>  seratch (dev)  T03E94MJU
   dreamy-gazelle-453 (dev) A04DHV08MPF

만약 “workflow not found” 에러가 발생한다면, manifest.ts 에 워크플로를 추가하는 것을 깜박했거나, 가장 최신의 manafest data 를 가지고 앱을 재설치 하지 않았다는 의미입니다.

정상적으로 잘 진행이 되었다면, 다음과 같은 결과물을 볼 수 있습니다. 이렇게 생성된 webhook URL 로 워크플로를 시작할 수 있습니다. 별도의 인증과정이 없기 때문에 wehbook URL 은 공개적으로 오픈하시면 안됩니다.

$ slack triggers create --trigger-def ./workflow_and_trigger.ts
? Choose an app  seratch (dev)  T03E94MJU
   dreamy-gazelle-453 (dev) A04DHV08MPF

Trigger created
   Trigger ID:   Ft04DLR5XXXX
   Trigger Type: webhook
   Trigger Name: Hello World Trigger
   Webhook URL:  https://hooks.slack.com/triggers/T11111/22222/xxxxx

webhook URL 로 POST 요청을 보내서 워크플로 시작

이제 첫번째 워크플로를 실행할 때입니다! POST 요청을 webhook URL 로 보내보세요.

curl -XPOST https://hooks.slack.com/triggers/T11111/22222/xxxxx

{“ok”:true} 메세지가 나온다면, 성공적으로 실행된 것입니다. 이제 Slack 워크스페이스의 채널로 이동하여, 메세지를 확인해봅시다.

다음과 같이 “Hello World” 메세지를 보실 수 있을 것입니다. 축하합니다!

다시한번 지금 어떤것들을 했는지 정리해봅시다.

  • 빈 프로젝트 생성
  • workflow_and_trigger.ts 파일을 생성하여 워크플로와 webhook 트리거를 정의
  • 워크플로를 manifest.ts 에 추가
  • slack run 명령어 실행을 통하여 앱 재설치
  • slack triggers create 명령어를 실행하여 트리거 생성
  • POST 요청을 보내서 트리거 실행

이 과정들이 당신이 생각했던 것보다 훨씬 쉽고, 간단했다고 느껴지길 바랍니다.

아참, 만약 트리거를 실행하기 전에 slack run 명령어를 종료해둔 상태라면, slack run 명령어를 종료했는데도 워크플로가 동작하는 것을 보고 좀 놀랄 수도 있는데요. 놀라시는게 정상이며 차세대플랫폼에서는 이러한 방식으로 동작합니다. 기존의 앱 동작방식과는 다르게, 트리거와 워크플로를 다루는 워크플로 엔진이 여러분들의 로컬이 아닌 Slack 의 클라우드 인프라에서 동작하기 때문입니다. 따라서, 여러분의 워크플로아 별도의 커스텀 펑션(다른 튜토리얼에서 설정 드리겠습니다.) 을 가지고 있지 않다면, slack run 을 계속해서 실행해 둘필요가 없습니다.

Hello World with Link Trigger

지금까지 webhook 트리거를 만들고 사용하는 방법에 대해 배웠습니다. 다음은 “link” 트리거를 한번 해보도록 하죠. link 트리거는 Slack 클라이언트 UI 상에서 사람들이 “link” 를 클릭하면 워크플로가 살행되도록 할 수 있습니다.

workflow_and_trigger.ts 를 다음과 같이 바꿔주세요.

// -------------------------
// Workflow definition
// -------------------------
import { DefineWorkflow, Schema } from "deno-slack-sdk/mod.ts";

// Don't forget to add this workflow to manifest.ts!
export const workflow = DefineWorkflow({
  callback_id: "hello-world-workflow",
  title: "Hello World Workflow",
  input_parameters: {
    properties: {
      // The channel ID passed from the link trigger
      channel_id: { type: Schema.slack.types.channel_id },
    },
    required: ["channel_id"],
  },
});

// Send a message in a channel using the built-in function
workflow.addStep(Schema.slack.functions.SendMessage, {
  // Set the channel ID given by trigger -> workflow
  channel_id: workflow.inputs.channel_id,
  message: "Hello World!",
});

// -------------------------
// Trigger Definition
// -------------------------
import { Trigger } from "deno-slack-api/types.ts";
// This trigger starts the workflow when an end-user clicks the link
const trigger: Trigger<typeof workflow.definition> = {
  type: "shortcut",
  name: "Hello World Trigger",
  workflow: `#/workflows/${workflow.definition.callback_id}`,
  inputs: {
    // The channel where you click the link trigger
    channel_id: { value: "{{data.channel_id}}" },
  },
};

// As long as the trigger object is default exported,
// you can generate a trigger with this code:
// $ slack triggers create --trigger-def ./workflow_and_trigger.ts
export default trigger;

보신바와 같이 많은 것이 변경되었는데요, 변경된 것들은 다음과 같습니다.

  • workflow 가 채널 ID 를 입력값으로 받음
  • SendMessage 펑션이 입력받은 채널 ID 를 사용함 (hard-coded 된 채널ID 값 대신)
  • 트리거 타입shortcut 으로 변경되었으며, link 트리거를 의미함
  • 트리거가 입력받은 채널 ID 를 워크플로로 전달함

slack run 을 실행하여 별다른 에러 메세지가 발생하는지 확인해보세요. 없다면 slack triggers create –trigger-def ./workflow_and_trigger.ts 를 실행하여 새로운 link 트리거를 만듭니다.

$ slack triggers create --trigger-def ./workflow_and_trigger.ts
? Choose an app  seratch (dev)  T03E94MJU
   dreamy-gazelle-453 (dev) A04DHV08MPF

Trigger created
   Trigger ID:   Ft04DEBXXXX
   Trigger Type: shortcut
   Trigger Name: Hello World Trigger
   URL: https://slack.com/shortcuts/Ft04DEBXXXXX/YYYY

https 로 시작하는 URL 이 link URL 입니다. 연결된 워크스페이스내에서만 유효합니다. 이 링크를 메세지로 공유하던가 북마크로 지정해둘수도 있겠죠. link URL 이 공유되면, unfurl 이 진행되며 워크플로우 스타트 버튼을 볼 수 있습니다.

start 를 눌러보시면 hello world 메세지가 채널에 바로 표시됩니다!

Wrapping up

이 튜토리얼을 통해서 다음과 같은 점들을 배워보셨습니다.

  • 워크플로 생성
  • manifest.ts 에 워크플로 추가
  • 워크플로를 시작하기 위한 webhook 트리거 생성
  • 워크플로를 시작하기 위한 link 트리거 생성

튜토리얼에 사용된 프로젝트는 다음 링크에서 확인해보실 수 있습니다. https://github.com/seratch/slack-next-generation-platform-tutorials/tree/main/01_The_Simplest_Hello_World

간단하게 해보기 위해서 저는 워크플로와 트리거를 workflow_and_trigger.ts 라는 단일 파일내에 정의해두었고, 잘 동작하시는걸 볼 수 있습니다. 그렇지만 일반적으로 권장되는 구조는 다음과 같습니다.(워크플로와 트리거를 별도의 파일에서 정의)

$ tree
.
├── manifest.ts
├── triggers
│   ├── link.ts
│   └── webhook.ts
└── workflows
    └── hello_world.ts.

표준 프로젝트 구조에 대해서 공부해보고 싶으시다면, “hello World” 또는 “Scaffold project” 템플릿을 사용하여 프로젝트를 만들어보세죠.

또한, github.com/slack-samples orgarnization 에서 다른 템플릿을 사용해보실 수 도 있습니다. 예를 들어 https://github.com/slack-samples/deno-request-time-off  템플릿을 사용해보고 싶다면 다음과 같이 하면 됩니다.

slack create my-time-off-app -t slack-samples/deno-request-time-off

튜토리얼을 즐기셨기를 바랍니다. 차세대플랫폼에 대한 추가적인 튜토리얼을 몇가지 더 공유해보도록 하겠습니다. 어떤 의견이나 코멘트가 있으시다면 트위터(@seratch) 나 제가 확인해볼 수 있는 어떤 장소에 남겨주세요.

Happy hacking with Slack’s next-generation platform 🚀

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다