DOCS/research/250828_slack_message_formatting_guide.md
happybell80 dc0232ae63 docs: Slack 메시지 포맷팅 가이드 추가
- mrkdwn 문법 정리
- Block Kit 사용법
- Markdown to mrkdwn 변환 전략
- 브리핑 메시지 구현 예시
- 제약사항 및 우회 방법
2025-08-28 20:56:14 +09:00

5.5 KiB

Slack 메시지 포맷팅 가이드

작성일: 2025-08-28
카테고리: 기술 리서치
관련: Slack 통합, 브리핑 메시지


1. Slack 포맷팅 제약사항

지원 안 됨

  • HTML: 태그 렌더링 불가, 파일 첨부만 가능
  • 표준 Markdown: 부분적 지원 (mrkdwn만 가능)
  • 표(Table): 미지원
  • 색상/폰트 크기: 커스터마이징 불가

지원됨

  • mrkdwn: Slack 전용 마크업
  • Block Kit: 블록 기반 UI 구성

2. mrkdwn 문법

기본 서식

스타일 문법 예시
굵게 *text* 굵은 텍스트
기울임 _text_ 기울인 텍스트
취소선 ~text~ 취소선
인라인 코드 `code` 코드
인용 > quote > 인용문

링크

<https://ro-being.com|로빙 홈페이지>

코드 블록

여러 줄 코드 블록

리스트

  • 번호/불릿 목록은 자동 서식화
  • 중첩 목록은 제한적 지원

3. Block Kit 구성

주요 블록 타입

  1. header: 제목 (plain_text만)
  2. section: 본문 (mrkdwn 지원)
  3. divider: 구분선
  4. context: 보조 정보 (mrkdwn 지원)
  5. image: 이미지
  6. actions: 버튼/메뉴

브리핑 메시지 예시

{
  "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": "업데이트: <!date^1724806800^{date} {time}|2025-08-28 09:00>"
        }
      ]
    }
  ]
}

4. 자주 사용하는 패턴

제목과 내용 구분

*📊 일일 통계*
• 대화: 15건
• 작업 완료: 8건
• 대기 중: 3건

상태 표시

✅ 완료: 서버 점검
🔄 진행 중: 데이터 백업
❌ 실패: API 연동

날짜 포맷 (Unix timestamp)

<!date^1724806800^{date_short} {time}|2025-08-28 09:00>

5. Markdown → mrkdwn 변환 전략

변환 규칙

Markdown mrkdwn 대체
# 제목 *제목* + divider
## 부제목 *부제목*
section.fields (2열) 또는 코드블록
이미지 image 블록
HTML 제거 또는 텍스트 변환

코드 예시

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. 제약사항 우회 방법

표 대체

# 2열 표 → section.fields
"fields": [
    {"type": "mrkdwn", "text": "*항목*\n값1"},
    {"type": "mrkdwn", "text": "*수량*\n10"}
]

# 3열 이상 → 코드블록
항목 수량 상태
이메일 5 읽음
작업 3 진행

긴 메시지 처리

  • 블록 50개 제한
  • 초기: 요약 표시
  • 버튼 클릭 시: response_url로 상세 전송

색상 대체

  • 이모지 활용: 🔴 긴급, 🟡 중요, 🟢 정상
  • 굵게/구분선으로 시각적 분리

7. 브리핑 메시지 실제 구현

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 필드 사용
  • 스레드 응답 시 블록 상속 안 됨

참고 문서