DOCS/journey/ideas/slack_canvas_integration.md
2026-03-16 12:46:20 +09:00

11 KiB

tags, date, modified
tags date modified
Slack
Canvas
API
Robeing
Integration
Guide
2025-09-15 2025-09-15

로빙(Roboing)을 위한 Slack Canvas 연동 기술 가이드

1. 개요: Slack Canvas와 API의 이해

이 문서는 로빙이 Slack Canvas를 프로그래매틱하게 생성, 편집, 조회 및 공유하는 방법에 대한 기술적 절차와 제약 사항을 정리합니다. Slack의 공식 API 문서를 기반으로, 실제 구현에 필요한 모든 단계를 구체적으로 제시합니다.

1.1. Slack Canvas란?

Slack Canvas는 채널이나 대화에 정보를 영구적으로 고정할 수 있는 문서 기능입니다. API 관점에서 두 가지 주요 유형이 있습니다.

  • 독립 캔버스 (Standalone Canvas): 특정 채널에 종속되지 않는 독립적인 문서입니다. 프로젝트 위키, 개인 메모 등으로 활용할 수 있습니다.
  • 채널 캔버스 (Channel-attached Canvas): 특정 채널의 탭에 고정되는 문서입니다. 해당 채널의 온보딩 가이드, FAQ, 공지사항 등으로 사용하기에 적합합니다.

1.2. 핵심 API 엔드포인트

캔버스 조작은 주로 다음의 Web API를 통해 이루어집니다.

  • canvases.create: 새 캔버스를 생성합니다. (독립 또는 채널 탭)
  • canvases.edit: 캔버스의 내용을 수정합니다. (섹션 단위 삽입, 교체, 삭제)
  • canvases.sections.lookup: 특정 텍스트를 포함한 섹션(헤더 등)의 ID를 조회하여 편집 위치를 특정합니다.
  • canvases.access.set / canvases.access.delete: 캔버스에 대한 사용자 또는 채널 단위의 접근 권한을 설정하거나 삭제합니다.
  • files.list: types=canvas 파라미터를 사용하여 워크스페이스 내의 캔버스 목록을 조회합니다.
  • files.info: 개별 캔버스 파일의 메타데이터와 다운로드 URL 등을 조회합니다.

1.3. 콘텐츠 포맷: 캔버스 전용 마크다운

매우 중요한 제약 사항으로, 캔버스 API는 Slack 메시지에 사용되는 Block Kit을 지원하지 않습니다. 모든 콘텐츠는 document_content 객체 내에 type: "markdown"markdown: "..." 형태로 전달해야 합니다.

또한, 캔버스에서 사용되는 마크다운은 일반 마크다운과 약간의 차이가 있습니다.

  • 사용자 멘션: ![](@U0123ABCDE)
  • 채널 멘션: ![](#C0567EFGHI)
  • 지원 요소: 헤딩 (#, ##), 목록, 체크리스트, 테이블, 인용구 등을 지원합니다.

1.4. 인증: 필수 OAuth 스코프

로빙의 매니페스트 파일에 다음 스코프들이 포함되어야 합니다. 앱 재설치가 필요할 수 있습니다.

  • 필수 스코프:
    • canvases:write: 캔버스 생성, 편집, 삭제, 공유
    • canvases:read: 캔버스 섹션 조회 등 읽기 관련 작업
    • files:read: 캔버스 목록 조회 및 콘텐츠 다운로드
  • 선택적 스코프:
    • conversations:read: 채널 ID 탐색 및 정보 조회
    • chat:write: 캔버스 생성/수정 후 안내 메시지 전송

2. 앱 매니페스트 설정 예시

로빙의 slack.app.yml 또는 매니페스트 설정에 아래와 같이 스코프를 정의합니다.

_display_information:
  name: RO-BEING
features:
  bot_user:
    display_name: RO-BEING
    always_online: true
oauth_config:
  scopes:
    bot:
      # Canvas 필수 스코프
      - canvases:write
      - canvases:read
      - files:read

      # 선택적 스코프 (기능 확장을 위해 권장)
      - conversations:read
      - chat:write
      - users:read # 사용자 정보 조회용
settings:
  interactivity:
    is_enabled: true
  org_deploy_enabled: false
  socket_mode_enabled: true
  token_rotation_enabled: false

3. 핵심 구현 시나리오

3.1. 시나리오 1: 프로젝트 위키 (독립 캔버스)

목표: 새로운 프로젝트가 시작될 때, 관련 정보를 담은 독립적인 위키 캔버스를 생성하고, 내용을 지속적으로 갱신하며, 관련자에게 공유합니다.

구현 흐름:

  1. 생성: canvases.create를 호출하여 캔버스를 생성합니다. title과 초기 document_content (markdown)를 전달합니다. 응답으로 받은 canvas_id를 로빙의 내부 DB에 저장하여 관리합니다.

  2. 편집 (내용 추가/수정):

    • 문서 끝에 추가: canvases.editchanges 배열에 { "operation": "insert_at_end", "document_content": ... } 객체를 담아 호출합니다.
    • 특정 섹션 수정: canvases.sections.lookup을 사용하여 ## Action Items와 같은 헤더 텍스트로 section_id를 찾습니다. 그 후 canvases.editchanges 배열에 { "operation": "replace", "section_id": "...", "document_content": ... } 형태로 호출하여 해당 섹션만 교체합니다.
  3. 공유: canvases.access.set을 호출하여 접근 권한을 부여합니다.

    • 채널 공유: channel_ids 파라미터에 공유할 채널 ID 목록을 전달합니다.
    • 사용자 공유: user_ids 파라미터에 사용자 ID 목록을 전달합니다. (주의: 이 API가 성공하려면, 해당 사용자에게 사전에 캔버스 링크가 한 번 이상 공유된 적이 있어야 합니다.)
  4. 탐색 및 조회: files.list API에 types=canvas 쿼리를 사용하여 워크스페이스 내의 모든 캔버스를 검색합니다. 특정 캔버스의 file_id를 얻은 후, files.info로 상세 메타데이터를 조회하고, 응답에 포함된 url_privateAuthorization: Bearer <TOKEN> 헤더를 포함하여 요청하면 캔버스의 원본 콘텐츠를 다운로드할 수 있습니다.

3.2. 시나리오 2: 채널 온보딩/FAQ 자동화

목표: 새로운 채널이 생성되거나 로빙이 채널에 초대될 때, 해당 채널의 캔버스 탭에 온보딩 가이드와 FAQ를 자동으로 생성하고 주기적으로 업데이트합니다.

구현 흐름:

  1. 채널 식별: app_home_opened 이벤트나 채널 생성 관련 이벤트를 통해 channel_id를 확보합니다. (conversations:read 스코프 필요)

  2. 채널 탭에 캔버스 생성: canvases.create 호출 시, channel_id 파라미터를 함께 전달합니다. 이렇게 하면 생성된 캔버스가 자동으로 해당 채널의 캔버스 탭에 고정됩니다.

  3. 접근 제어: 채널에 연결된 캔버스는 기본적으로 채널 멤버들의 권한을 따릅니다. 추가적인 권한 설정이 필요하면 canvases.access.set을 사용합니다. (주의: DM이나 다인 DM 채널에는 channel_id로 권한을 설정할 수 없습니다.)

  4. 주기적 갱신: FAQ 내용이 변경될 경우, canvases.sections.lookup으로 ## 자주 묻는 질문과 같은 특정 헤더를 찾아 해당 섹션만 canvases.edit으로 교체하여 전체 문서를 덮어쓰지 않도록 합니다.

3.3. 시나리오 3: 회의록/인시던트 문서화

목표: 회의나 인시던트 대응이 끝난 후, 관련 대화 내용을 요약하여 캔버스 문서의 정해진 서식(템플릿)에 맞게 구조화하여 기록합니다. (예: Action Item은 체크리스트로, 담당자는 멘션으로)

구현 흐름:

  1. 템플릿 캔버스 준비: 미리 약속된 헤더(## 요약, ## 결정 사항, ## Action Items)를 가진 템플릿 캔버스를 준비하거나, 생성 시 동적으로 만듭니다.

  2. 콘텐츠 구조화: LLM을 통해 요약된 내용을 캔버스 전용 마크다운으로 변환합니다.

    • Action Item: - [ ] 내용 (@담당자)
    • 테이블: | 제목 | 내용 | |---|---|
    • 담당자/채널 멘션: ![](@U0123ABCDE), ![](#C0567EFGHI)
  3. 섹션별 내용 삽입: canvases.sections.lookup으로 각 헤더의 section_id를 찾은 뒤, canvases.editinsert_after operation을 사용하여 각 섹션 아래에 구조화된 콘텐츠를 삽입합니다.

  4. 이미지/파일 첨부: 스크린샷이나 관련 파일을 캔버스에 첨부해야 할 경우:

    • 먼저 해당 파일을 Slack에 업로드합니다.
    • files.info API로 업로드된 파일의 permalink를 조회합니다.
    • permalink를 사용하여 ![이미지 설명](<permalink>) 형태의 마크다운 문자열을 생성하여 캔버스에 삽입합니다.
  5. 완료 알림: 작업이 완료되면 chat.postMessage를 통해 관련 채널에 캔버스 링크와 함께 완료 사실을 알립니다.


4. 중요 제약 조건 및 권장 사항

  • 유료 플랜 전용: Canvas API는 Slack의 유료 플랜에서만 사용 가능합니다. 무료 플랜에서는 API 호출이 실패합니다.
  • DM/MPDM 공유 제약: canvases.access.set에서 channel_ids를 사용하여 DM이나 다인 DM(MPDM)에 권한을 부여할 수 없습니다. 반드시 user_ids를 사용해야 합니다.
  • 마크다운 변환 필수: 기존 메시지 Block Kit JSON을 캔버스에 직접 사용할 수 없습니다. 로빙이 생성하는 모든 콘텐츠는 캔버스 전용 마크다운으로 변환하는 로직이 반드시 필요합니다.
  • 이미지 첨부: 이미지는 외부 공개 URL을 사용하거나, Slack에 먼저 업로드한 후 permalink를 통해 참조해야 합니다. Base64 인코딩 방식 등은 지원되지 않습니다.
  • 데이터 보관 정책: 로빙이 캔버스 내용을 외부 DB에 장기 보관하거나 인덱싱할 경우, Slack의 데이터 보관 및 사용 정책을 준수해야 합니다. 민감 정보 처리 시 특히 주의가 필요합니다.

5. 검증 결과 (2025-03)

채널 탭 Canvas 읽기: files:read만으로 가능함.

  • 채널: C0ALCV5S0FL (ir컨설팅서비스-및-랜딩페이지)
  • Canvas "온보딩 회의": files.list(types=canvas, channel=...)files.infourl_private GET으로 본문(HTML) 다운로드 가능
  • canvas_id: F0AL6L34CV9
  • canvases.sections.lookup / canvases.editcanvases:read/canvases:write 스코프 추가 필요 (현재 Company-X 봇에 없음)
  • 검증 스크립트: rb8001/scripts/test_canvas_access.py

6. 빠른 구현을 위한 체크리스트

  1. [ ] 로빙의 Slack 앱 매니페스트에 canvases:write, canvases:read, files:read 스코프를 추가하고 앱을 재설치합니다.
  2. [ ] canvases.create를 호출하여 첫 캔버스를 생성하고, 반환된 canvas_id를 저장하는 로직을 구현합니다.
  3. [ ] canvases.sections.lookupcanvases.edit을 조합하여, 특정 헤더를 기준으로 내용을 수정하는 기능을 구현합니다.
  4. [ ] canvases.access.set을 사용하여 생성된 캔버스를 특정 채널이나 사용자에게 공유하는 기능을 구현하고, DM/MPDM의 제약사항을 코드 레벨에서 처리합니다.
  5. [ ] files.list (types=canvas)를 통해 캔버스를 검색하는 기능을 구현합니다.
  6. [ ] 사용자/채널 멘션을 캔버스 전용 마크다운(![](@U...), ![](#C...))으로 변환하는 유틸리티 함수를 작성합니다.