- ideas/slack_canvas_integration.md로 배치 - 불필요한 integrations 폴더 제거 - Canvas API 구현 가이드 및 예시 코드 포함
10 KiB
tags, date, modified
| tags | date | modified | ||||||
|---|---|---|---|---|---|---|---|---|
|
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: "..." 형태로 전달해야 합니다.
또한, 캔버스에서 사용되는 마크다운은 일반 마크다운과 약간의 차이가 있습니다.
- 사용자 멘션:
 - 채널 멘션:
 - 지원 요소: 헤딩 (
#,##), 목록, 체크리스트, 테이블, 인용구 등을 지원합니다.
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: 프로젝트 위키 (독립 캔버스)
목표: 새로운 프로젝트가 시작될 때, 관련 정보를 담은 독립적인 위키 캔버스를 생성하고, 내용을 지속적으로 갱신하며, 관련자에게 공유합니다.
구현 흐름:
-
생성:
canvases.create를 호출하여 캔버스를 생성합니다.title과 초기document_content(markdown)를 전달합니다. 응답으로 받은canvas_id를 로빙의 내부 DB에 저장하여 관리합니다. -
편집 (내용 추가/수정):
- 문서 끝에 추가:
canvases.edit의changes배열에{ "operation": "insert_at_end", "document_content": ... }객체를 담아 호출합니다. - 특정 섹션 수정:
canvases.sections.lookup을 사용하여## Action Items와 같은 헤더 텍스트로section_id를 찾습니다. 그 후canvases.edit의changes배열에{ "operation": "replace", "section_id": "...", "document_content": ... }형태로 호출하여 해당 섹션만 교체합니다.
- 문서 끝에 추가:
-
공유:
canvases.access.set을 호출하여 접근 권한을 부여합니다.- 채널 공유:
channel_ids파라미터에 공유할 채널 ID 목록을 전달합니다. - 사용자 공유:
user_ids파라미터에 사용자 ID 목록을 전달합니다. (주의: 이 API가 성공하려면, 해당 사용자에게 사전에 캔버스 링크가 한 번 이상 공유된 적이 있어야 합니다.)
- 채널 공유:
-
탐색 및 조회:
files.listAPI에types=canvas쿼리를 사용하여 워크스페이스 내의 모든 캔버스를 검색합니다. 특정 캔버스의file_id를 얻은 후,files.info로 상세 메타데이터를 조회하고, 응답에 포함된url_private에Authorization: Bearer <TOKEN>헤더를 포함하여 요청하면 캔버스의 원본 콘텐츠를 다운로드할 수 있습니다.
3.2. 시나리오 2: 채널 온보딩/FAQ 자동화
목표: 새로운 채널이 생성되거나 로빙이 채널에 초대될 때, 해당 채널의 캔버스 탭에 온보딩 가이드와 FAQ를 자동으로 생성하고 주기적으로 업데이트합니다.
구현 흐름:
-
채널 식별:
app_home_opened이벤트나 채널 생성 관련 이벤트를 통해channel_id를 확보합니다. (conversations:read스코프 필요) -
채널 탭에 캔버스 생성:
canvases.create호출 시,channel_id파라미터를 함께 전달합니다. 이렇게 하면 생성된 캔버스가 자동으로 해당 채널의 캔버스 탭에 고정됩니다. -
접근 제어: 채널에 연결된 캔버스는 기본적으로 채널 멤버들의 권한을 따릅니다. 추가적인 권한 설정이 필요하면
canvases.access.set을 사용합니다. (주의: DM이나 다인 DM 채널에는channel_id로 권한을 설정할 수 없습니다.) -
주기적 갱신: FAQ 내용이 변경될 경우,
canvases.sections.lookup으로## 자주 묻는 질문과 같은 특정 헤더를 찾아 해당 섹션만canvases.edit으로 교체하여 전체 문서를 덮어쓰지 않도록 합니다.
3.3. 시나리오 3: 회의록/인시던트 문서화
목표: 회의나 인시던트 대응이 끝난 후, 관련 대화 내용을 요약하여 캔버스 문서의 정해진 서식(템플릿)에 맞게 구조화하여 기록합니다. (예: Action Item은 체크리스트로, 담당자는 멘션으로)
구현 흐름:
-
템플릿 캔버스 준비: 미리 약속된 헤더(
## 요약,## 결정 사항,## Action Items)를 가진 템플릿 캔버스를 준비하거나, 생성 시 동적으로 만듭니다. -
콘텐츠 구조화: LLM을 통해 요약된 내용을 캔버스 전용 마크다운으로 변환합니다.
- Action Item:
- [ ] 내용 (@담당자) - 테이블:
| 제목 | 내용 | |---|---| - 담당자/채널 멘션:
,
- Action Item:
-
섹션별 내용 삽입:
canvases.sections.lookup으로 각 헤더의section_id를 찾은 뒤,canvases.edit의insert_afteroperation을 사용하여 각 섹션 아래에 구조화된 콘텐츠를 삽입합니다. -
이미지/파일 첨부: 스크린샷이나 관련 파일을 캔버스에 첨부해야 할 경우:
- 먼저 해당 파일을 Slack에 업로드합니다.
files.infoAPI로 업로드된 파일의permalink를 조회합니다.- 이
permalink를 사용하여형태의 마크다운 문자열을 생성하여 캔버스에 삽입합니다.
-
완료 알림: 작업이 완료되면
chat.postMessage를 통해 관련 채널에 캔버스 링크와 함께 완료 사실을 알립니다.
4. 중요 제약 조건 및 권장 사항
- 유료 플랜 전용: Canvas API는 Slack의 유료 플랜에서만 사용 가능합니다. 무료 플랜에서는 API 호출이 실패합니다.
- DM/MPDM 공유 제약:
canvases.access.set에서channel_ids를 사용하여 DM이나 다인 DM(MPDM)에 권한을 부여할 수 없습니다. 반드시user_ids를 사용해야 합니다. - 마크다운 변환 필수: 기존 메시지
Block KitJSON을 캔버스에 직접 사용할 수 없습니다. 로빙이 생성하는 모든 콘텐츠는 캔버스 전용 마크다운으로 변환하는 로직이 반드시 필요합니다. - 이미지 첨부: 이미지는 외부 공개 URL을 사용하거나, Slack에 먼저 업로드한 후
permalink를 통해 참조해야 합니다. Base64 인코딩 방식 등은 지원되지 않습니다. - 데이터 보관 정책: 로빙이 캔버스 내용을 외부 DB에 장기 보관하거나 인덱싱할 경우, Slack의 데이터 보관 및 사용 정책을 준수해야 합니다. 민감 정보 처리 시 특히 주의가 필요합니다.
5. 빠른 구현을 위한 체크리스트
- [ ] 로빙의 Slack 앱 매니페스트에
canvases:write,canvases:read,files:read스코프를 추가하고 앱을 재설치합니다. - [ ]
canvases.create를 호출하여 첫 캔버스를 생성하고, 반환된canvas_id를 저장하는 로직을 구현합니다. - [ ]
canvases.sections.lookup과canvases.edit을 조합하여, 특정 헤더를 기준으로 내용을 수정하는 기능을 구현합니다. - [ ]
canvases.access.set을 사용하여 생성된 캔버스를 특정 채널이나 사용자에게 공유하는 기능을 구현하고, DM/MPDM의 제약사항을 코드 레벨에서 처리합니다. - [ ]
files.list(types=canvas)를 통해 캔버스를 검색하는 기능을 구현합니다. - [ ] 사용자/채널 멘션을 캔버스 전용 마크다운(
,)으로 변환하는 유틸리티 함수를 작성합니다.