# 로빙(RO-BEING)의 슬랙 캔버스(Canvas) 활용 방안

> Slack API 문서를 기반으로, 로빙이 캔버스를 읽고 쓰기 위해 필요한 스코프, 구현 흐름, 제약 사항을 3가지 시나리오로 나누어 구체적으로 정리한 문서입니다.

---

## 공통 이해 요약

**[현재 프로젝트 상태]** 캔버스 API 미사용 (canvases.create/edit/sections.lookup 호출 없음). canvases:read/write 스코프 미설정. files.list?types=canvas 탐색 미구현. canvases.access.set/delete 권한 관리 없음.

*   **캔버스 종류:** 독립 문서(standalone) 또는 채널에 붙은 문서(channel canvas)로 존재합니다.
*   **주요 API:**
    *   생성: `canvases.create`
    *   수정: `canvases.edit`
    *   섹션 조회: `canvases.sections.lookup`
    *   접근 권한: `canvases.access.set` / `delete`
*   **콘텐츠 포맷:** `document_content` 객체에 `type: "markdown"`과 `markdown` 문자열만 지원합니다. **Block Kit은 지원하지 않습니다.**
*   **탐색 및 읽기:** `files.list` API에 `types=canvas` 파라미터를 주어 검색하고, 반환된 파일 객체의 `url_private`를 `Authorization: Bearer <token>` 헤더와 함께 호출하여 본문을 다운로드합니다.
*   **필수 권한 (스코프):**
    *   `canvases:write`: 생성/편집/삭제/공유
    *   `canvases:read`: 섹션 조회 등 읽기 작업
    *   `files:read`: 파일/캔버스 목록 조회 및 다운로드
*   **제약 사항:**
    *   **유료 플랜 전용:** 캔버스 관련 API는 유료 플랜에서만 사용할 수 있습니다.
    *   **DM/다인 DM 공유:** 채널 ID가 아닌 사용자 ID(`user_ids`) 기준으로만 공유 가능하며, 사전에 해당 사용자에게 캔버스 링크가 공유된 이력이 있어야 합니다.
    *   **전용 마크다운:** 사용자(`![](@U123)`), 채널(`![](#C123)`) 멘션 문법이 일반 메시지와 다릅니다.

---

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

**목표:** 프로젝트 시작 시 독립적인 위키 캔버스를 만들고, 섹션별로 내용을 추가/교체하며, 필요시 특정 인원이나 채널에 공유합니다.

#### 필요 스코프
*   **필수:** `canvases:write`, `canvases:read`, `files:read`
*   **선택:** `conversations:read` (채널 ID 탐색용), `chat:write` (안내 메시지 전송용)

#### 구현 흐름
1.  **생성:** `canvases.create`를 호출하여 `title`과 `document_content` (markdown)를 포함한 캔버스를 생성하고, 반환된 `canvas_id`를 저장합니다.
2.  **공유 (선택):** `canvases.access.set`을 사용하여 `user_ids` 또는 `channel_ids`로 접근 권한을 부여합니다.
3.  **편집:**
    *   **문단 추가:** `canvases.edit`의 `changes` 배열에 `{operation: "insert_at_end", ...}`를 포함하여 호출합니다.
    *   **특정 위치 삽입:** `canvases.sections.lookup`으로 `section_id`를 찾은 뒤, `insert_after` / `insert_before` / `replace` operation을 사용합니다.
4.  **목록화/탐색:** `files.list?types=canvas`로 워크스페이스의 캔버스 목록을 조회하고, `url_private`로 본문을 다운로드합니다.

--- 

## 시나리오 2: 채널 온보딩/FAQ 자동화 (채널 캔버스)

**목표:** 새 채널이 생성되거나 로빙이 채널에 초대될 때, 해당 채널의 캔버스 탭에 "가이드/FAQ" 문서를 자동으로 생성하고 주기적으로 갱신합니다.

#### 필요 스코프
*   **필수:** `canvases:write`, `canvases:read`
*   **선택:** `conversations:read` (채널 ID 탐색), `chat:write` (갱신 알림), `files:read` (내부 파일/이미지 링크 삽입)

#### 구현 흐름
1.  **채널 식별:** `conversations.list` 또는 채널 생성 이벤트를 통해 `channel_id`를 확보합니다.
2.  **채널 탭에 캔버스 생성:** `canvases.create` 호출 시 `channel_id`를 함께 전달하면 해당 채널 탭에 캔버스가 자동으로 추가됩니다.
3.  **접근 제어:** `canvases.access.set`으로 채널 단위 접근 권한을 설정합니다.
4.  **주기적 갱신:** 캔버스 내 헤더(예: `## FAQ`)를 앵커로 삼아 `canvases.sections.lookup`으로 위치를 찾고, `canvases.edit`으로 해당 섹션만 교체합니다.

--- 

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

**목표:** 회의나 인시던트 종료 후, 대화 요약본을 캔버스의 정해진 서식(체크리스트, 테이블 등)에 맞춰 구조화하여 반영하고 관련 스크린샷을 첨부합니다.

#### 필요 스코프
*   **필수:** `canvases:write`, `canvases:read`
*   **선택:** `files:read` (이미지 퍼멀링크 조회), `chat:write` (완료 알림), `conversations:read` (관련 채널 탐색)

#### 구현 흐름
1.  **서식 정의:** 캔버스 내에 헤더(예: `# Summary`, `## Action items`)를 앵커로 미리 정의합니다.
2.  **섹션 위치 탐색:** `canvases.sections.lookup`에 `section_types:["h1","h2"]`와 `contains_text:"Action items"` 같은 조건을 주어 삽입할 위치의 `section_id`를 찾습니다.
3.  **내용 반영:** `canvases.edit`을 사용하여 `insert_after` 또는 `replace` operation을 수행합니다. 체크리스트(`- [ ]`), 테이블(파이프 `|` 문법) 등 캔버스 전용 마크다운을 사용합니다.
4.  **이미지 삽입:** 슬랙에 업로드된 파일은 `files.info`로 `permalink`를 얻은 뒤, 마크다운 `![alt](permalink)` 형식으로 본문에 삽입합니다.
5.  **완료 알림 (선택):** `chat.postMessage`를 통해 관련 채널에 캔버스 링크와 변경 요약 내용을 알립니다.

---

## 앱 매니페스트 및 스코프 설정 (예시)

```yaml
display_information:
  name: RO-BEING
features:
  bot_user:
    display_name: RO-BEING
    always_online: true
oauth_config:
  scopes:
    bot:
      - canvases:write
      - canvases:read
      - files:read
      - conversations:read       # 채널 탐색/확인 용도
      - chat:write               # 안내/알림 메시지 포스팅 시
settings:
  interactivity:
    is_enabled: true
```
> **중요:** 스코프 추가 후에는 앱을 워크스페이스에 재설치해야 합니다.

## 최소 구현 체크리스트

- [ ] **스코프 추가:** 매니페스트에 `canvases:write`, `canvases:read`, `files:read` 추가 후 앱 재설치.
- [ ] **생성:** `canvases.create`로 캔버스 생성 및 `canvas_id` 저장. (채널 탭 연동 시 `channel_id` 포함)
- [ ] **편집:** `canvases.sections.lookup` → `canvases.edit` 조합으로 위치 기반 편집 구현.
- [ ] **공유:** `canvases.access.set`으로 채널/사용자 접근 수준 설정. (DM/MPDM 제약 준수)
- [ ] **탐색:** `files.list?types=canvas`로 캔버스 검색 및 `url_private`로 본문 다운로드.
