Slack App 만들기

[Slack App] 슬랙 앱 만들기 - view 구성하기

dohye1 2023. 1. 23. 16:22
반응형

이전글에서 말했지만

나는 슬랙앱 화면을 구성할때 slack-block-builder를 사용했다.

 

그래서 먼저 slack-block-builder를 설치해준다.

npm install slack-block-builder

슬랙앱의 컴포넌트는 계층이 존재한다.

왼쪽이 상위계층이고 오른쪽으로 갈수록 하위 계층이다.

하위계층에 있는 엘리먼트들은 무조건 상위계층안에 존재해야한다!

 

이 컴포넌트들은 모두 slack-block-builder에서 import해서 사용할 수 있다.

 

1. Surface

surface는 home, modal, message로 나뉘는데,

home은 슬랙앱의 메인화면에서 "Home" 탭을 눌렀을때 보여지는 화면이다.

그리고 modal은 말그대로 모달이다!

그리고 메시지는 슬랙앱이 전송하는 메시지 1개의 영역이다.

2. Block

block에서 자주 썼던것들을 적어보면

context, divider, section, input 등이 있다.

context는 텍스트에 이미지를 넣을수 있다.

  Context().elements([
      "이건 Context 의 글자",
      Image()
        .imageUrl(
          "https://cdn.imweb.me/upload/S201910012ff964777e0e3/62f9a36ea3cea.jpg"
        )
        .altText("dog"),
    ]),

위 처럼 elements 메서드에 컨텐츠 배열을 넘겨줄수있는데, 이미지와 텍스트를 번갈아서 넣어줄수있다.

 

Section을 살펴보자

Context와의 차이점을 보자면 Context는 보여질 컨텐츠를 배열로 넘겨주지만 

Section은 텍스트를 넘겨줘야한다. 그리고 accessorry라는 메서드를 통해 받는 컴포넌트를 오른쪽 상단에 보여준다.

accessorry는 옵셔널한 값이다.

Section()
      .blockId(`${id}`)
      .text("이건 Section 의 글자")
      .accessory(OverflowMenu().options([Option().text("test1").value("1")])),

위 사진을 보면 첫번째 텍스트는 Context이고, 둘째줄의 텍스트가 Section 이다.

두 컴포넌트의 또다른 차이점은 폰트사이즈가 다르다는것임!

작게표현하고싶은 텍스트는 Context, 좀 더 크게표현하고싶다면 Section을 사용하면된다.

 

Button이나 Select같은 interactive elements를 감쌀때는 Actions를 사용한다.

Actions()
    .elements([
        StaticSelect()
        .options(
          FILTER_OPTION.map((option) => constructOption(option))
        )
        .actionId("STATUS_FILTER")
        .initialOption(constructOption(initialFilter)),
    ]),

Divider는 말그대로 화면에 가로선을 그린다.

Input은 InputWrapper같은 느낌이다.

Input block 내부에 TextInput이나 DatePicker같은 데이터 입력 컴포넌트를 실제로 설정해줘야한다.

 

3. Block Element

Block element를 쓸때는 공식문서를 읽으면서 쓰면 된다!

그리고 Slack-block-builder에서 컴포넌트를 import해서 쓰면,

각 컴포넌트에 설정해줘야하는 메서드들을 IDE가 알려주기때문에 어떤값을 넣으면 되는구나하면서 설정해주면된다!

 

그리고 Md라는 컴포넌트가있는데, 이 Md를 유용하게썼다!!

슬랙앱을 만들때 텍스트의 컬러나 사이즈를 지정할수가없어서 어떻게 만들지 고민이 많았었는데,

Md컴포넌트를 사용해서 텍스트를 다르게 구성할 수 있어서 도움이 되었다.

텍스트를 넣어야하는 자리에 Md.bold('bold text') 이렇게 넣어주면 

bold 스타일의 텍스트가 들어간다.

 

그리고 Md.user에 사용자의 아이디를 넘겨주면 아래처럼 특정 사용자의 이름을 보여준다! 그리고 저 이름에 마우스를 올리면 사용자의 정보도 보여준다!

그럼 실제로 어떻게 view를 구성하고 슬랙앱에 전달했는지 코드를 보면 아래와 같다.

const result = HomeTab()
    .privateMetaData(JSON.stringify(metaData))
    .blocks(
      Blocks.Actions().elements([
        Button()
          .text("Receive")
          .primary(globalFilter === GlobalFilter.RECEIVED)
          .actionId("RECEIVED_FILTER"),
        Button()
          .text("Send")
          .primary(globalFilter === GlobalFilter.SENT)
          .actionId("SENT_FILTER"),
        Button()
          .text("Watcher")
          .primary(globalFilter === GlobalFilter.WATCHER)
          .actionId("WATCHER_FILTER"),
      ]),
      Blocks.Section()
        .text(Md.bold(`${HOME_TITLE}`))
        .accessory(
          Button()
            .text("Create")
            .actionId("CREATE_MODAL_OPENED")
            .primary()
        ),
      Blocks.Section().text(
        `${getTextByLocale(
          "Common.Status.Backlog"
        )} : ${backlog} / ${getTextByLocale(
          "Common.Status.Todo"
        )} : ${todo} / ${getTextByLocale(
          "Common.Status.InProgress"
        )} : ${progress} / ${getTextByLocale("Common.Status.Done")} : ${done}`
      ),
      Blocks.Divider(),
      Context().elements(`\n`),
      Blocks.Section().text(
        `<https://alot.info|About us> | <https://alot.info/support|Send feedback> | <https://alot.info/support|Help>`
      )
    )
    .buildToObject();

이 코드는 Home에 보여줄 view인데, 

HomeTab의 blocks 메서드에 여러개의 컴포넌트들을 쉼표로 구분해서 넣어주었다.

 

그리고 제일 마지막에 buildToObject()를 호출해서 객체형태로 만들어줘야한다!!!

 

  return await client.views.publish({
      user_id: user,
      view: OBJECT_형태의_VIEW_CODE
    });​

그리고 client.view.publish에 view 코드를 넘겨주면 슬랙앱 홈에 내가 구성한 화면이 그려진다!

 

view에서 actionId라는 값이 설정되어있는데, 이 값들은 버튼을 눌렀을때의 액션과 관련이있다.

 

슬랙앱에서 액션을 처리하는 방식은 다음 글에서 정리해보겠다!