메시지 및 서식 있는 블록 보내기
일반 텍스트, 마크다운, Block Kit JSON으로 Slack 메시지 형식을 지정합니다.
메시지 및 서식 있는 블록 보내기은(는) CoddyKit의 무료 AI Agents 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 AI Agents 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. AI Agents 강의에는 총 4개의 강의가 포함되어 있습니다.
say()로 간단한 텍스트 메시지 보내기
Slack 메시지를 게시하는 가장 간단한 방법은 say(text)입니다. 텍스트는 Slack의 마크다운 변형인 mrkdwn을 지원합니다. *bold*, _italic_, ~strike~, `code`와 같은 형식과 <@USERID> 같은 멘션을 사용할 수 있습니다.
@app.event('app_mention')
def handle_mention(event, say):
user = event['user']
# Simple text response with mrkdwn formatting
say(
text=(
f'Hello <@{user}>!\n'
'*Agent Report:*\n'
'- Tasks completed: `42`\n'
'- Errors: `0`\n'
'- _Runtime: 3.2 seconds_'
),
mrkdwn=True # enabled by default
)
# Slack mentions
say(f'<@{user}> your request is being processed')
say('Posting to <!channel>: all hands meeting tomorrow')Block Kit 소개
Block Kit은 풍부하고 대화형인 메시지를 만들기 위한 Slack의 UI 프레임워크입니다. 일반 텍스트 대신 유형이 지정된 블록인 section, header, divider, actions, context를 조합해 메시지를 구성합니다. 블록은 say() 또는 chat_postMessage()의 blocks 매개변수에 목록으로 전달합니다.
@app.event('app_mention')
def handle_mention(event, say):
blocks = [
{
'type': 'header',
'text': {'type': 'plain_text', 'text': 'Agent Status Report'}
},
{
'type': 'divider'
},
{
'type': 'section',
'text': {
'type': 'mrkdwn',
'text': '*Status:* Running\n*Tasks:* 42 completed'
}
}
]
say(
text='Agent Status Report', # fallback for notifications
blocks=blocks
)텍스트 필드가 있는 Section 블록
section 블록은 가장 다용도로 사용할 수 있습니다. 텍스트(mrkdwn 또는 plain_text), 필드 키-값 쌍 목록, 액세서리 요소(버튼, 이미지, 오버플로 메뉴)를 표시할 수 있습니다. 나란히 배치할 키-값 쌍에는 fields를 사용하십시오. 대시보드에 특히 유용합니다.
def build_task_summary_blocks(tasks):
blocks = [
{
'type': 'header',
'text': {'type': 'plain_text', 'text': 'Daily Task Summary'}
},
{
'type': 'section',
'text': {
'type': 'mrkdwn',
'text': f'Processed *{len(tasks)} tasks* today.'
}
},
{
'type': 'section',
'fields': [
{'type': 'mrkdwn', 'text': f'*Completed:*\n{sum(1 for t in tasks if t["status"]=="done")}'},
{'type': 'mrkdwn', 'text': f'*Failed:*\n{sum(1 for t in tasks if t["status"]=="error")}'},
{'type': 'mrkdwn', 'text': f'*Pending:*\n{sum(1 for t in tasks if t["status"]=="pending")}'},
{'type': 'mrkdwn', 'text': f'*Avg Time:*\n3.2s'}
]
}
]
return blocks
# --- demo ---
tasks = [
{'status': 'done'}, {'status': 'done'}, {'status': 'error'}, {'status': 'pending'}
]
blocks = build_task_summary_blocks(tasks)
for b in blocks:
print(b)
Header 및 Divider 블록
큰 섹션 제목에는 header 블록을 사용하고, 시각적으로 구분할 때는 divider 블록을 사용하십시오. header 블록은 plain_text만 지원하며 mrkdwn은 지원하지 않습니다. 두 블록을 조합하면 구조가 잘 정리된 보고서 메시지를 만들 수 있습니다.
def build_report_message(title, sections):
blocks = []
# Header
blocks.append({
'type': 'header',
'text': {'type': 'plain_text', 'text': title, 'emoji': True}
})
for section_title, content in sections:
# Divider between sections
blocks.append({'type': 'divider'})
# Section header as bold mrkdwn
blocks.append({
'type': 'section',
'text': {'type': 'mrkdwn', 'text': f'*{section_title}*\n{content}'}
})
return blocks
blocks = build_report_message(
title='Weekly Agent Report',
sections=[
('Emails Processed', '142 emails classified, 38 replies drafted'),
('Tasks Completed', '89 tasks completed, 3 failures logged')
]
)
# --- demo ---
for b in blocks:
print(b)
버튼이 있는 Action 블록
Actions 블록에는 버튼과 같은 대화형 요소가 들어 있습니다. 각 버튼에는 클릭을 처리기로 라우팅할 때 사용하는 action_id, text, 그리고 데이터를 전달하는 선택적 value가 있습니다. 주요 CTA에는 style: 'primary'를 사용하고, 파괴적인 작업에는 style: 'danger'를 사용하십시오.
def build_approval_message(task_id, task_description):
blocks = [
{
'type': 'section',
'text': {
'type': 'mrkdwn',
'text': f'*Task ready for approval:*\n{task_description}'
}
},
{
'type': 'actions',
'elements': [
{
'type': 'button',
'text': {'type': 'plain_text', 'text': 'Approve'},
'style': 'primary',
'action_id': 'approve_task',
'value': task_id
},
{
'type': 'button',
'text': {'type': 'plain_text', 'text': 'Reject'},
'style': 'danger',
'action_id': 'reject_task',
'value': task_id
}
]
}
]
return blocks
# --- demo ---
blocks = build_approval_message('task_42', 'Deploy backend v2.3 to production')
for b in blocks:
print(b)
메타데이터를 위한 Context 블록
Context 블록은 메시지 하단에 작고 부가적인 텍스트를 표시합니다. 타임스탬프, 출처 또는 에이전트 버전 정보와 같은 메타데이터에 적합합니다. mrkdwn과 이미지(작은 아이콘용)를 지원합니다.
import datetime
def add_context_footer(blocks, agent_version='v1.2'):
timestamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M UTC')
blocks.append({
'type': 'context',
'elements': [
{
'type': 'mrkdwn',
'text': f'Generated by Agent {agent_version} | {timestamp}'
}
]
})
return blocks
# Full message with context footer
blocks = [
{
'type': 'section',
'text': {'type': 'mrkdwn', 'text': 'Analysis complete. See results below.'}
}
]
blocks = add_context_footer(blocks)
print(f'Message has {len(blocks)} blocks')텍스트 필드의 mrkdwn
Slack의 mrkdwn은 마크다운의 일부 기능을 지원합니다. 에이전트 메시지에 사용할 수 있는 주요 서식 옵션은 굵게, 기울임꼴, 코드, 링크, 채널 멘션, 사용자 멘션, 목록입니다. 이러한 기능을 사용하면 AI가 생성한 콘텐츠를 Slack에서 읽기 쉽게 만들 수 있습니다.
def format_ai_response_as_mrkdwn(title, bullet_points, code_snippet=None):
lines = [f'*{title}*']
for point in bullet_points:
lines.append(f'• {point}')
if code_snippet:
lines.append(f'```{code_snippet}```') # code block
return '\n'.join(lines)
content = format_ai_response_as_mrkdwn(
title='Security Issues Found',
bullet_points=[
'SQL injection risk in `user_search()` function',
'Hardcoded API key in `config.py` line 42',
'Missing HTTPS on login endpoint'
],
code_snippet='SELECT * FROM users WHERE id = " + userId + "\n# ^ UNSAFE: use parameterized queries'
)
print(content)respond()를 사용한 임시 메시지
임시 메시지는 작업을 실행한 사용자에게만 보이고 다른 채널 구성원에게는 보이지 않습니다. 채널을 불필요하게 복잡하게 만들 필요가 없는 상태 업데이트, 오류 메시지, 확인 메시지에 사용하십시오. respond()(슬래시 명령) 또는 chat_postEphemeral()을 통해서만 사용할 수 있습니다.
@app.command('/check-status')
def handle_status(ack, respond, body, client):
ack()
user_id = body['user_id']
channel_id = body['channel_id']
# Ephemeral: only the user who ran /check-status sees this
respond(
text='Checking agent status...',
response_type='ephemeral'
)
status = get_agent_status()
# Or use chat_postEphemeral for more control
client.chat_postEphemeral(
channel=channel_id,
user=user_id,
text=f'Agent Status: {status}',
blocks=build_status_blocks(status)
)전송 후 메시지 업데이트
메시지를 게시한 후에는 채널과 메시지 타임스탬프(ts)를 지정한 client.chat_update()를 사용해 메시지를 업데이트할 수 있습니다. 진행 상황을 업데이트할 때 유용합니다. 처음에는 '처리 중...' 메시지를 게시한 다음, 작업이 끝나면 결과로 업데이트할 수 있습니다.
@app.command('/analyze')
def handle_analyze(ack, say, respond, body, client):
ack()
text = body.get('text', '')
channel = body['channel_id']
# Post initial message
initial = client.chat_postMessage(
channel=channel,
text='Analyzing... this may take a moment.'
)
message_ts = initial['ts']
# Do the work
import threading
def do_work():
result = slow_ai_analysis(text)
# Update the original message with the result
client.chat_update(
channel=channel,
ts=message_ts,
text=f'Analysis complete: {result}',
blocks=build_result_blocks(result)
)
threading.Thread(target=do_work, daemon=True).start()특정 채널에 게시하기
client.chat_postMessage(channel=channel_id, text=...)를 사용하면 봇이 액세스할 수 있는 모든 채널에 게시할 수 있습니다. Slack API에서 채널 ID를 확인하거나 채널을 마우스 오른쪽 버튼으로 클릭하여 확인하십시오. 프로그래밍 방식으로 이름을 기준으로 채널을 찾으려면 conversations_list()를 사용합니다.
def post_alert_to_channel(client, channel_name, alert_message):
# Look up channel ID by name
result = client.conversations_list(
types='public_channel,private_channel',
limit=200
)
channel_id = None
for ch in result['channels']:
if ch['name'] == channel_name:
channel_id = ch['id']
break
if not channel_id:
print(f'Channel #{channel_name} not found')
return None
# Post the alert
response = client.chat_postMessage(
channel=channel_id,
text=alert_message,
unfurl_links=False, # don't expand URLs
unfurl_media=False
)
print(f'Posted to #{channel_name}: ts={response["ts"]}')
return response
# --- demo: minimal stand-in for the Slack client ---
class _FakeClient:
def conversations_list(self, **kwargs):
return {'channels': [{'name': 'alerts', 'id': 'C123'}, {'name': 'general', 'id': 'C456'}]}
def chat_postMessage(self, **kwargs):
print(f"[slack] postMessage to {kwargs['channel']}: {kwargs['text']}")
return {'ts': '1699999999.000100'}
post_alert_to_channel(_FakeClient(), 'alerts', 'Disk usage above 90% on web-1')
Block Kit 메시지 빌더 패턴
데이터를 받아 블록 목록을 반환하는 빌더 함수를 사용하십시오. 이렇게 하면 메시지 서식 지정과 비즈니스 로직이 분리되며, 여러 이벤트 처리기에서 블록을 재사용할 수 있습니다.
def build_alert_blocks(level, title, details, link=None):
level_emoji = {'info': ':information_source:',
'warning': ':warning:', 'error': ':x:'}.get(level, '')
blocks = [
{
'type': 'header',
'text': {'type': 'plain_text', 'text': f'{level_emoji} {title}'}
},
{
'type': 'section',
'text': {'type': 'mrkdwn', 'text': details}
}
]
if link:
blocks.append({
'type': 'actions',
'elements': [{
'type': 'button',
'text': {'type': 'plain_text', 'text': 'View Details'},
'url': link,
'action_id': 'view_details'
}]
})
import datetime
blocks.append({
'type': 'context',
'elements': [{'type': 'mrkdwn',
'text': datetime.datetime.now().strftime('%Y-%m-%d %H:%M UTC')}]
})
return blocks
# --- demo ---
blocks = build_alert_blocks('warning', 'High latency', 'p95 latency is 3.2s', link='https://dash.example.com')
for b in blocks:
print(b)
빠른 확인: 블록 유형
Slack Block Kit에 대한 이해도를 확인해 보십시오.
풍부한 메시지 복습
이제 에이전트가 전문적이고 대화형인 Slack 메시지를 게시할 수 있습니다.
- say(text) — 간단한 mrkdwn 텍스트이며 *bold*, _italic_, `code`, 멘션을 지원합니다
- say(blocks=[...]) — 구조화된 레이아웃을 위한 Block Kit입니다
- header — 큰 섹션 제목이며 plain_text만 지원합니다
- section — 선택적 필드(키-값 표) 또는 하나의 액세서리를 포함할 수 있는 텍스트 본문입니다
- divider — 가로 구분선입니다
- actions — 버튼과 대화형 요소를 담는 컨테이너입니다
- context — 하단에 표시되는 작은 메타데이터 텍스트입니다
- respond(response_type='ephemeral') — 작업을 실행한 사용자에게만 보이는 메시지입니다
- chat_update(ts=...) — 이전에 게시한 메시지를 새 콘텐츠로 업데이트합니다
AI 튜터와 함께 AI Agents을(를) 배우세요 — 무료
브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.
- 코스
- 60
- 레슨
- 239
자주 묻는 질문
“메시지 및 서식 있는 블록 보내기” 강의는 무료인가요?
네 — “메시지 및 서식 있는 블록 보내기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 AI Agents 강의 전체를 잠금 해제할 수 있습니다. AI Agents 강의에는 총 4개의 강의가 포함되어 있습니다.
“메시지 및 서식 있는 블록 보내기”에서 뭘 배우나요?
일반 텍스트, 마크다운, Block Kit JSON으로 Slack 메시지 형식을 지정합니다. 브라우저에서 직접 실행하는 실습 코드로 AI Agents을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
AI Agents을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 AI Agents은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.
“메시지 및 서식 있는 블록 보내기” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 AI Agents 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 AI Agents 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- Slack Bolt SDK 기초
- 이벤트 및 슬래시 명령 수신
- 메시지 및 서식 있는 블록 보내기
- 팀 알림 봇 만들기