diff --git a/research/250828_slack_message_formatting_guide.md b/research/250828_slack_message_formatting_guide.md new file mode 100644 index 0000000..2f765eb --- /dev/null +++ b/research/250828_slack_message_formatting_guide.md @@ -0,0 +1,253 @@ +# Slack 메시지 포맷팅 가이드 + +**작성일**: 2025-08-28 +**카테고리**: 기술 리서치 +**관련**: Slack 통합, 브리핑 메시지 + +--- + +## 1. Slack 포맷팅 제약사항 + +### 지원 안 됨 +- **HTML**: 태그 렌더링 불가, 파일 첨부만 가능 +- **표준 Markdown**: 부분적 지원 (mrkdwn만 가능) +- **표(Table)**: 미지원 +- **색상/폰트 크기**: 커스터마이징 불가 + +### 지원됨 +- **mrkdwn**: Slack 전용 마크업 +- **Block Kit**: 블록 기반 UI 구성 + +--- + +## 2. mrkdwn 문법 + +### 기본 서식 +| 스타일 | 문법 | 예시 | +|--------|------|------| +| 굵게 | `*text*` | *굵은 텍스트* | +| 기울임 | `_text_` | _기울인 텍스트_ | +| 취소선 | `~text~` | ~취소선~ | +| 인라인 코드 | `` `code` `` | `코드` | +| 인용 | `> quote` | > 인용문 | + +### 링크 +``` + +``` + +### 코드 블록 +``` +``` +여러 줄 +코드 블록 +``` +``` + +### 리스트 +- 번호/불릿 목록은 자동 서식화 +- 중첩 목록은 제한적 지원 + +--- + +## 3. Block Kit 구성 + +### 주요 블록 타입 +1. **header**: 제목 (plain_text만) +2. **section**: 본문 (mrkdwn 지원) +3. **divider**: 구분선 +4. **context**: 보조 정보 (mrkdwn 지원) +5. **image**: 이미지 +6. **actions**: 버튼/메뉴 + +### 브리핑 메시지 예시 +```json +{ + "blocks": [ + { + "type": "header", + "text": { + "type": "plain_text", + "text": "📅 2025년 8월 28일 브리핑" + } + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "*📧 중요 이메일*\n• `긴급` AWS 결제 알림\n• `중요` 투자사 미팅 요청" + } + }, + { + "type": "divider" + }, + { + "type": "section", + "fields": [ + {"type": "mrkdwn", "text": "*📰 뉴스*\n3건"}, + {"type": "mrkdwn", "text": "*📋 일정*\n2건"} + ] + }, + { + "type": "context", + "elements": [ + { + "type": "mrkdwn", + "text": "업데이트: " + } + ] + } + ] +} +``` + +--- + +## 4. 자주 사용하는 패턴 + +### 제목과 내용 구분 +``` +*📊 일일 통계* +• 대화: 15건 +• 작업 완료: 8건 +• 대기 중: 3건 +``` + +### 상태 표시 +``` +✅ 완료: 서버 점검 +🔄 진행 중: 데이터 백업 +❌ 실패: API 연동 +``` + +### 날짜 포맷 (Unix timestamp) +``` + +``` + +--- + +## 5. Markdown → mrkdwn 변환 전략 + +### 변환 규칙 +| Markdown | mrkdwn 대체 | +|----------|------------| +| `# 제목` | `*제목*` + divider | +| `## 부제목` | `*부제목*` | +| 표 | section.fields (2열) 또는 코드블록 | +| 이미지 | image 블록 | +| HTML | 제거 또는 텍스트 변환 | + +### 코드 예시 +```python +def markdown_to_mrkdwn(text): + # 헤딩 변환 + text = re.sub(r'^# (.+)$', r'*\1*', text, flags=re.MULTILINE) + text = re.sub(r'^## (.+)$', r'*\1*', text, flags=re.MULTILINE) + + # 링크 변환 + text = re.sub(r'\[(.+?)\]\((.+?)\)', r'<\2|\1>', text) + + # 굵게/기울임 (주의: 충돌 가능) + text = re.sub(r'\*\*(.+?)\*\*', r'*\1*', text) + text = re.sub(r'_(.+?)_', r'_\1_', text) + + return text +``` + +--- + +## 6. 제약사항 우회 방법 + +### 표 대체 +```python +# 2열 표 → section.fields +"fields": [ + {"type": "mrkdwn", "text": "*항목*\n값1"}, + {"type": "mrkdwn", "text": "*수량*\n10"} +] + +# 3열 이상 → 코드블록 +``` +항목 | 수량 | 상태 +-------- | ---- | ---- +이메일 | 5 | 읽음 +작업 | 3 | 진행 +``` +``` + +### 긴 메시지 처리 +- 블록 50개 제한 +- 초기: 요약 표시 +- 버튼 클릭 시: response_url로 상세 전송 + +### 색상 대체 +- 이모지 활용: 🔴 긴급, 🟡 중요, 🟢 정상 +- 굵게/구분선으로 시각적 분리 + +--- + +## 7. 브리핑 메시지 실제 구현 + +```python +def create_briefing_blocks(data): + blocks = [ + { + "type": "header", + "text": {"type": "plain_text", "text": f"📅 {data['date']} 브리핑"} + } + ] + + # 이메일 섹션 + if data['emails']: + email_text = "*📧 받은 메일*\n" + for email in data['emails'][:5]: + priority = "🔴" if email['urgent'] else "⚪" + email_text += f"{priority} {email['subject']}\n" + + blocks.append({ + "type": "section", + "text": {"type": "mrkdwn", "text": email_text} + }) + + # 구분선 + blocks.append({"type": "divider"}) + + # 통계 + blocks.append({ + "type": "section", + "fields": [ + {"type": "mrkdwn", "text": f"*📊 레벨*\n{data['level']}"}, + {"type": "mrkdwn", "text": f"*⚡ 경험치*\n{data['exp']}"} + ] + }) + + return blocks +``` + +--- + +## 8. 주의사항 + +### API 사용 시 +- `text` 필드: 폴백용 (블록 미지원 클라이언트) +- `blocks` 필드: 실제 렌더링용 +- `mrkdwn: true` 기본값 (일부 필드는 명시 필요) + +### 성능 +- 블록 50개 제한 +- 메시지 크기 40KB 제한 +- 이미지는 URL 참조만 (직접 업로드 별도) + +### 호환성 +- 모바일/데스크톱 차이 고려 +- 알림 미리보기는 text 필드 사용 +- 스레드 응답 시 블록 상속 안 됨 + +--- + +## 참고 문서 +- [Block Kit Builder](https://app.slack.com/block-kit-builder) +- [Message Formatting](https://api.slack.com/reference/surfaces/formatting) +- [Block Kit Reference](https://api.slack.com/reference/block-kit) +- [mrkdwn Syntax](https://api.slack.com/reference/surfaces/formatting#basics) \ No newline at end of file