Ver3.0 ๐ฌ Slack ์๋ฆผ์ AI๊ฐ ์๋์ผ๋ก ์์ฝํด์ ์ด๋ฉ์ผ๋ก ๋ณด๋ด์ฃผ๋ ์ค๋งํธ ์๋ํ ์์คํ ๊ตฌ์ถํ๊ธฐ

๐ฌ Slack ์๋ฆผ์ AI๊ฐ ์๋์ผ๋ก ์์ฝํด์ ์ด๋ฉ์ผ๋ก ๋ณด๋ด์ฃผ๋ ์ค๋งํธ ์๋ํ ์์คํ ๊ตฌ์ถํ๊ธฐ
์ ๋ฌด ํจ์จ 200% ์ฌ๋ ค์ฃผ๋ AI ์๋ํ ์์ด์ ํธ ์๋ฒฝ ๊ฐ์ด๋ โก
๐ฏ ์ ์ง๊ธ Slack ์๋ฆผ ์๋ํ๊ฐ ํ์ํ๊ฐ์?
์์ฆ ํ์ฌ ๋ค๋๋ฉด์ Slack ์ ์ฐ๋ ๊ณณ์ด ์ด๋จ์ด์ ใ
ใ
ใ
๊ทผ๋ฐ ์ง์ง ๋ฌธ์ ๋ ์๋ฆผ์ด ๋๋ฌด ๋ง๋ค๋ ๊ฑฐ์ฃ . ํ๋ฃจ์ ์๋ฐฑ ๊ฐ์ฉ ์์์ง๋ ๋ฉ์์ง๋ค... ์ค์ํ ๊ฑด์ง ์๋์ง๋ ๋ชจ๋ฅด๊ฒ ๊ณ , ๋์ค์ ํ์ธํ๋ ค๊ณ ํ๋ฉด ์ด๋ฏธ ์์ญ ๊ฐ๊ฐ ๋ ์์ฌ์๊ณ ๐ฑ
ํนํ ์ฌ๋ฌ ์ฑ๋์ ๋์์ ๊ด๋ฆฌํ๊ฑฐ๋, ํด์ธ ํ์๋ค๊ณผ ํ์
ํ๋ ๊ฒฝ์ฐ์๋ ์์ฐจ ๋๋ฌธ์ ์๋ฒฝ์ ์จ ๋ฉ์์ง๋ฅผ ์์นจ์ ํ์ธํ๋ ๊ฒฝ์ฐ๋ ๋ง์์์? ๊ทธ๋ด ๋๋ง๋ค "์ ์ด๊ฑฐ ์ค์ํ ๊ฑด๋ฐ ์ ๋ชป ๋ดค์ง..." ํ๋ฉด์ ํํํ๋ ๊ฒฝํ, ๋ค๋ค ์์ผ์์ฃ ?
๊ทธ๋์ ๋ฑ์ฅํ ๊ฒ ๋ฐ๋ก AI ์๋ ์์ฝ ์์คํ
์ด์์! Slack์ ์์ธ ์๋ฆผ๋ค์ AI๊ฐ ์์์ ๋ถ์ํ๊ณ ์์ฝํด์ ์ด๋ฉ์ผ๋ก ๊น๋ํ๊ฒ ์ ๋ฆฌํด์ฃผ๋ ๊ฑฐ์ฃ . ๋ง์น ๊ฐ์ธ ๋น์๊ฐ "์ค๋ ์ด๋ฐ ์ผ๋ค์ด ์์์ด์~" ํ๊ณ ๋ธ๋ฆฌํํด์ฃผ๋ ๋๋? ๐ค
๐ง ์์คํ ๊ตฌ์ถ์ ์ํ ํต์ฌ ๊ตฌ์ฑ์์
์ด ์๋ํ ์์คํ ์ ๋ง๋ค๋ ค๋ฉด ํฌ๊ฒ ์ธ ๊ฐ์ง ์์๊ฐ ํ์ํด์. ๊ฐ๊ฐ์ ์ญํ ์ ์ ํํ ์ดํดํ๋ ๊ฒ ์ค์ํ๋ต๋๋ค!
1๏ธโฃ Slack API ์ฐ๋
๋จผ์ Slack์์ ๋ฉ์์ง๋ฅผ ๊ฐ์ ธ์์ผ๊ฒ ์ฃ ? Slack์ ๊ฐ๋ฐ์ ์นํ์ ์ธ ํ๋ซํผ์ด๋ผ API๊ฐ ์์ฒญ ์ ๋์ด์์ด์ ใ
ใ
Slack API์ ์ฃผ์ ๊ธฐ๋ฅ:
โข conversations.history - ์ฑ๋์ ๋ฉ์์ง ํ์คํ ๋ฆฌ ๊ฐ์ ธ์ค๊ธฐ
โข users.info - ์ฌ์ฉ์ ์ ๋ณด ์กฐํ
โข reactions.get - ๋ฉ์์ง์ ๋ฌ๋ฆฐ ๋ฆฌ์ก์
ํ์ธ
โข RTM API - ์ค์๊ฐ ๋ฉ์์ง ์คํธ๋ฆฌ๋ฐ
Slack Bot์ ๋ง๋ค์ด์ ์ํฌ์คํ์ด์ค์ ์ค์นํ๋ฉด, ํน์ ์ฑ๋์ ๋ฉ์์ง๋ฅผ ์ค์๊ฐ์ผ๋ก ๋ชจ๋ํฐ๋งํ๊ฑฐ๋ ์ฃผ๊ธฐ์ ์ผ๋ก ์์งํ ์ ์์ด์. OAuth ํ ํฐ๋ง ์ ๋ฐ๊ธ๋ฐ์ผ๋ฉด ๋๋จธ์ง๋ ์ฌ์์!
2๏ธโฃ AI ์์ฝ ์์ง
์ด๊ฒ ์ง์ง ํต์ฌ์ด์ฃ ! ์์ฆ์ GPT-4, Claude, Gemini ๊ฐ์ ๊ฐ๋ ฅํ LLM๋ค์ด ๋ง์์ ์ ํ์ง๊ฐ ๋ค์ํด์.
AI ๋ชจ๋ธ ์ ํ ๊ธฐ์ค:
โข GPT-4: ๊ฐ์ฅ ๋ฒ์ฉ์ ์ด๊ณ ์์ ์ . API ํธ์ถ ๋น์ฉ์ ์ข ์์ง๋ง ํ์ง ์ต๊ณ ๐
โข Claude: ๊ธด ๋ฌธ๋งฅ ์ฒ๋ฆฌ์ ๊ฐํจ. 100K ํ ํฐ๊น์ง ์ฒ๋ฆฌ ๊ฐ๋ฅํด์ ๋๋ ๋ฉ์์ง ์์ฝ์ ์ ๋ฆฌ
โข Gemini: ๊ตฌ๊ธ ์ ํ์ด๋ผ Google Workspace์ ์ฐ๋ ์ข์. ๋ฌด๋ฃ ํฐ์ด๋ ๊ด์ฐฎ์
โข ์คํ์์ค ๋ชจ๋ธ: Llama, Mistral ๋ฑ. ์์ฒด ์๋ฒ์์ ๋๋ฆด ์ ์์ด์ ๋น์ฉ ์ ๊ฐ ๊ฐ๋ฅ
ํ๋กฌํํธ ์์ง๋์ด๋ง๋ ์ค์ํด์! "์ด ๋ฉ์์ง๋ค์ ์์ฝํด์ค"๋ณด๋ค๋ "๋ค์ Slack ๋ฉ์์ง๋ค์ ์ค์๋ ์์ผ๋ก ์ ๋ ฌํ๊ณ , ๊ฐ ๋ฉ์์ง๋ฅผ 2-3๋ฌธ์ฅ์ผ๋ก ์์ฝํ๋, ์ก์
์์ดํ
์ด ์์ผ๋ฉด ๋ณ๋๋ก ํ์ํด์ค" ์ด๋ฐ ์์ผ๋ก ๊ตฌ์ฒด์ ์ผ๋ก ์ง์ํ๋ ๊ฒ ์ข์ฃ ใ
ใ
3๏ธโฃ ์ด๋ฉ์ผ ๋ฐ์ก ์์คํ
์์ฝ๋ ๋ด์ฉ์ ์ด๋ฉ์ผ๋ก ๋ณด๋ด๋ ๋ถ๋ถ์ด์์. ์ฌ๊ธฐ๋ ์ฌ๋ฌ ๋ฐฉ๋ฒ์ด ์์ด์!
์ด๋ฉ์ผ ๋ฐ์ก ์ต์
:
โข SendGrid: ๊ฐ๋ฐ์๋ค์ด ๊ฐ์ฅ ๋ง์ด ์ฐ๋ ์๋น์ค. API ๊น๋ํ๊ณ ๋ฌด๋ฃ ํฐ์ด๋ ๋๋ํจ
โข AWS SES: ๋๋ ๋ฐ์ก์ ์ ๋ฆฌํ๊ณ ๋น์ฉ ์ ๋ ด. AWS ์ฐ๊ณ ์๋ค๋ฉด ์ต๊ณ ์ ์ ํ
โข Gmail API: ๊ฐ์ธ์ฉ์ผ๋ก ์ฐ๊ธฐ ์ข์. OAuth ์ค์ ๋ง ํ๋ฉด ๋ฌด๋ฃ๋ก ์ฌ์ฉ ๊ฐ๋ฅ
โข Mailgun: ์ ๋ฝ ์๋ฒ ์์ด์ GDPR ์ค์ ํ์ํ ๋ ์ข์
HTML ์ด๋ฉ์ผ ํ
ํ๋ฆฟ์ ์์๊ฒ ๋ง๋ค๋ฉด ๊ฐ๋
์ฑ์ด ํจ์ฌ ์ข์์ ธ์. ์์ฝ ๋ด์ฉ์ ์นด๋ ํ์์ผ๋ก ๋ฐฐ์นํ๊ณ , ์ค์๋์ ๋ฐ๋ผ ์์์ ๋ค๋ฅด๊ฒ ํ๋ฉด ํ๋์ ํ์
ํ๊ธฐ ์ฝ์ฃ !
์ด๋ฐ ์๋ํ ์์คํ ๊ตฌ์ถ์ด ์ฒ์์ด๋ผ ๋ง๋งํ์ ๊ฐ์? ์ฌ๋ฅ๋ท์์๋ Slack ๋ด ๊ฐ๋ฐ, AI ํ๋กฌํํธ ์์ง๋์ด๋ง, ์๋ํ ์ํฌํ๋ก์ฐ ์ค๊ณ ๋ฑ ๋ค์ํ ์ ๋ฌธ๊ฐ๋ค์ด ํ๋ํ๊ณ ์์ด์. ์ง์ ๊ตฌ์ถํ๊ธฐ ์ด๋ ต๋ค๋ฉด ์ ๋ฌธ๊ฐ์ ๋์์ ๋ฐ๋ ๊ฒ๋ ์ข์ ๋ฐฉ๋ฒ์ด๋๋๋ค! ๐
โ๏ธ ์ค์ ๊ตฌํ ๋จ๊ณ๋ณ ๊ฐ์ด๋
์, ์ด์ ๋ณธ๊ฒฉ์ ์ผ๋ก ๋ง๋ค์ด๋ณผ๊น์? ๋จ๊ณ๋ณ๋ก ์ฐจ๊ทผ์ฐจ๊ทผ ๋ฐ๋ผ์ค์๋ฉด ๋ฉ๋๋ค!
1. Slack API ์ฌ์ดํธ ์ ์
api.slack.com์ ๋ค์ด๊ฐ์ "Create an App" ๋ฒํผ ํด๋ฆญ! ์ฌ๊ธฐ์ "From scratch" ์ ํํ๋ฉด ๋ผ์.
2. ํ์ํ ๊ถํ(Scopes) ์ถ๊ฐ
Bot Token Scopes์์ ๋ค์ ๊ถํ๋ค์ ์ถ๊ฐํด์ฃผ์ธ์:
โข channels:history - ๊ณต๊ฐ ์ฑ๋ ๋ฉ์์ง ์ฝ๊ธฐ
โข channels:read - ์ฑ๋ ์ ๋ณด ์กฐํ
โข groups:history - ๋น๊ณต๊ฐ ์ฑ๋ ๋ฉ์์ง ์ฝ๊ธฐ
โข users:read - ์ฌ์ฉ์ ์ ๋ณด ์กฐํ
โข reactions:read - ๋ฆฌ์ก์
์ ๋ณด ์ฝ๊ธฐ
3. ์ํฌ์คํ์ด์ค์ ์ค์น
"Install to Workspace" ๋ฒํผ ๋๋ฅด๊ณ ๊ถํ ์น์ธํ๋ฉด ๋! Bot User OAuth Token์ด ์์ฑ๋๋๋ฐ ์ด๊ฑฐ ์ ๋ณต์ฌํด๋์ธ์. ๋์ค์ API ํธ์ถํ ๋ ํ์ํด์ ๐
์ด์ ์ฝ๋๋ฅผ ์์ฑํ ์ฐจ๋ก์์! Python์ผ๋ก ์์๋ฅผ ๋ค์ด๋ณผ๊ฒ์ (๋ค๋ฅธ ์ธ์ด๋ ๋น์ทํด์ ใ
ใ
)
๊ธฐ๋ณธ ๊ตฌ์กฐ:
import os
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError
from datetime import datetime, timedelta
# Slack ํด๋ผ์ด์ธํธ ์ด๊ธฐํ
client = WebClient(token=os.environ["SLACK_BOT_TOKEN"])
def fetch_messages(channel_id, hours=24):
"""
์ง์ ๋ ์ฑ๋์์ ์ต๊ทผ N์๊ฐ ๋์์ ๋ฉ์์ง ๊ฐ์ ธ์ค๊ธฐ
"""
try:
# ์๊ฐ ๊ณ์ฐ (Unix timestamp)
oldest_time = (datetime.now() - timedelta(hours=hours)).timestamp()
# ๋ฉ์์ง ์กฐํ
result = client.conversations_history(
channel=channel_id,
oldest=str(oldest_time),
limit=1000
)
messages = result["messages"]
# ์ค๋ ๋ ๋ต๊ธ๋ ๊ฐ์ ธ์ค๊ธฐ
all_messages = []
for msg in messages:
all_messages.append(msg)
# ์ค๋ ๋๊ฐ ์์ผ๋ฉด ๋ต๊ธ๋ ์์ง
if "thread_ts" in msg and msg.get("reply_count", 0) > 0:
thread_replies = client.conversations_replies(
channel=channel_id,
ts=msg["thread_ts"]
)
all_messages.extend(thread_replies["messages"][1:])
return all_messages
except SlackApiError as e:
print(f"Error: {e.response['error']}")
return []
# ์ฌ์ฉ ์์
channel_id = "C01234567" # ์ฑ๋ ID
messages = fetch_messages(channel_id, hours=24)
print(f"์์ง๋ ๋ฉ์์ง: {len(messages)}๊ฐ")
์ฃผ์์ฌํญ:
โข Rate Limit ์กฐ์ฌ! Slack API๋ Tier๋ณ๋ก ํธ์ถ ์ ํ์ด ์์ด์. ๋๋ ๋ฉ์์ง ์์ง ์ time.sleep() ์ถ๊ฐ ๊ถ์ฅ
โข ํ์ด์ง๋ค์ด์
์ฒ๋ฆฌ: ๋ฉ์์ง๊ฐ ๋ง์ผ๋ฉด has_more์ response_metadata ์ฒดํฌํด์ ์ถ๊ฐ ํธ์ถ ํ์
โข ๋ด ๋ฉ์์ง ํํฐ๋ง: msg.get("bot_id")๋ก ๋ด์ด ๋ณด๋ธ ๋ฉ์์ง๋ ์ ์ธํ๋ ๊ฒ ์ข์์
์์งํ ๋ฉ์์ง๋ฅผ AI์๊ฒ ๋ณด๋ด์ ์์ฝ๋ฐ๋ ๋ถ๋ถ์ด์์. OpenAI API ๊ธฐ์ค์ผ๋ก ์ค๋ช
ํ ๊ฒ์!
ํจ๊ณผ์ ์ธ ํ๋กฌํํธ ์ค๊ณ:
import openai
import json
openai.api_key = os.environ["OPENAI_API_KEY"]
def summarize_messages(messages):
"""
๋ฉ์์ง ๋ฆฌ์คํธ๋ฅผ AI๋ก ์์ฝ
"""
# ๋ฉ์์ง๋ฅผ ์ฝ๊ธฐ ์ข์ ํ์์ผ๋ก ๋ณํ
formatted_messages = []
for msg in messages:
user = msg.get("user", "Unknown")
text = msg.get("text", "")
timestamp = datetime.fromtimestamp(float(msg["ts"]))
formatted_messages.append({
"user": user,
"time": timestamp.strftime("%Y-%m-%d %H:%M"),
"content": text
})
# AI ํ๋กฌํํธ ๊ตฌ์ฑ
prompt = f"""
๋ค์์ Slack ์ฑ๋์์ ์์ง๋ {len(formatted_messages)}๊ฐ์ ๋ฉ์์ง์
๋๋ค.
์ด ๋ฉ์์ง๋ค์ ๋ถ์ํ์ฌ ๋ค์ ํ์์ผ๋ก ์์ฝํด์ฃผ์ธ์:
1. ์ ์ฒด ์์ฝ (3-5๋ฌธ์ฅ)
2. ์ฃผ์ ํ ํฝ๋ณ ์ ๋ฆฌ
- ๊ฐ ํ ํฝ๋ง๋ค ๊ด๋ จ ๋ฉ์์ง ์์ฝ
- ์ค์๋ ํ์ (๐ด ๊ธด๊ธ, ๐ก ์ค์, ๐ข ์ผ๋ฐ)
3. ์ก์
์์ดํ
(์๋ ๊ฒฝ์ฐ)
- ๋๊ฐ ๋ฌด์์ ํด์ผ ํ๋์ง ๋ช
ํํ
4. ์ฃผ๋ชฉํ ๋งํ ์๊ฒฌ์ด๋ ๊ฒฐ์ ์ฌํญ
๋ฉ์์ง ๋ฐ์ดํฐ:
{json.dumps(formatted_messages, ensure_ascii=False, indent=2)}
"""
try:
response = openai.ChatCompletion.create(
model="gpt-4-turbo-preview",
messages=[
{"role": "system", "content": "๋น์ ์ ์
๋ฌด ๋ฉ์์ง๋ฅผ ํจ์จ์ ์ผ๋ก ์์ฝํ๋ ์ ๋ฌธ๊ฐ์
๋๋ค."},
{"role": "user", "content": prompt}
],
temperature=0.3, # ์ผ๊ด์ฑ ์๋ ์์ฝ์ ์ํด ๋ฎ๊ฒ ์ค์
max_tokens=2000
)
summary = response.choices[0].message.content
return summary
except Exception as e:
print(f"AI ์์ฝ ์คํจ: {e}")
return None
# ์ฌ์ฉ ์์
summary = summarize_messages(messages)
print(summary)
ํ๋กฌํํธ ์ต์ ํ ํ:
โข ๊ตฌ์กฐํ๋ ์ถ๋ ฅ ์์ฒญ: JSON์ด๋ ๋งํฌ๋ค์ด ํ์์ผ๋ก ๋ฐ์ผ๋ฉด ์ด๋ฉ์ผ ํ
ํ๋ฆฟ์ ๋ฃ๊ธฐ ์ฌ์์
โข ์์ ์ ๊ณต: Few-shot learning์ผ๋ก ์ํ๋ ์คํ์ผ์ ์์๋ฅผ ํ๋กฌํํธ์ ํฌํจ
โข ํ ํฐ ๊ด๋ฆฌ: ๋ฉ์์ง๊ฐ ๋๋ฌด ๋ง์ผ๋ฉด ์ฒญํฌ๋ก ๋๋ ์ ์ฒ๋ฆฌํ๊ณ ๋์ค์ ๋ณํฉ
โข ์ปจํ
์คํธ ์ ์ง: ์ด์ ์์ฝ ๋ด์ฉ์ ์ฐธ๊ณ ํ๊ฒ ํ๋ฉด ์ฐ์์ฑ ์๋ ๋ฆฌํฌํธ ์์ฑ ๊ฐ๋ฅ ใ
ใ
์ด์ ์์ฝ๋ ๋ด์ฉ์ ์์ ์ด๋ฉ์ผ๋ก ๋ง๋ค์ด๋ณผ๊น์? HTML ํ
ํ๋ฆฟ์ ์ฌ์ฉํ๋ฉด ํจ์ฌ ๋ณด๊ธฐ ์ข์์!
SendGrid๋ฅผ ์ฌ์ฉํ ๋ฐ์ก ์ฝ๋:
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import Mail, Email, To, Content
def create_email_html(summary, date):
"""
์์ฝ ๋ด์ฉ์ HTML ์ด๋ฉ์ผ๋ก ๋ณํ
"""
html_template = f"""
<!DOCTYPE html>
<html>
<head>
<style>
body {{ font-family: 'Segoe UI', Arial, sans-serif; background-color: #f5f7fa; margin: 0; padding: 20px; }}
.container {{ max-width: 700px; margin: 0 auto; background: white; border-radius: 12px; box-shadow: 0 4px 15px rgba(0,0,0,0.1); }}
.header {{ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 30px; border-radius: 12px 12px 0 0; }}
.content {{ padding: 30px; line-height: 1.8; color: #333; }}
.topic {{ background: #f8f9fa; padding: 20px; margin: 20px 0; border-radius: 8px; border-left: 4px solid #667eea; }}
.urgent {{ border-left-color: #e74c3c; }}
.important {{ border-left-color: #f39c12; }}
.footer {{ text-align: center; padding: 20px; color: #999; font-size: 0.9em; }}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1 style="margin:0;">๐ Slack ์ผ์ผ ์์ฝ ๋ฆฌํฌํธ</h1>
<p style="margin:10px 0 0 0; opacity:0.9;">{date}</p>
</div>
<div class="content">
{summary}
</div>
<div class="footer">
<p>์ด ๋ฆฌํฌํธ๋ AI๊ฐ ์๋์ผ๋ก ์์ฑํ์ต๋๋ค ๐ค</p>
<p>๋ฌธ์์ฌํญ์ support@yourcompany.com์ผ๋ก ์ฐ๋ฝ์ฃผ์ธ์</p>
</div>
</div>
</body>
</html>
"""
return html_template
def send_email(to_email, summary):
"""
์ด๋ฉ์ผ ๋ฐ์ก
"""
today = datetime.now().strftime("%Y๋
%m์ %d์ผ")
message = Mail(
from_email=Email("noreply@yourcompany.com", "Slack Summary Bot"),
to_emails=To(to_email),
subject=f"[Slack ์์ฝ] {today} ์
๋ฌด ๋ฆฌํฌํธ",
html_content=Content("text/html", create_email_html(summary, today))
)
try:
sg = SendGridAPIClient(os.environ.get('SENDGRID_API_KEY'))
response = sg.send(message)
print(f"์ด๋ฉ์ผ ๋ฐ์ก ์ฑ๊ณต! Status: {response.status_code}")
return True
except Exception as e:
print(f"์ด๋ฉ์ผ ๋ฐ์ก ์คํจ: {e}")
return False
# ์ฌ์ฉ ์์
send_email("user@company.com", summary)
์ด๋ฉ์ผ ๋์์ธ ํ:
โข ๋ชจ๋ฐ์ผ ๋ฐ์ํ์ผ๋ก ๋ง๋ค๊ธฐ! ์์ฆ์ ๋ค๋ค ํฐ์ผ๋ก ์ด๋ฉ์ผ ํ์ธํ์์์ ๐ฑ
โข ์ค์ํ ๋ด์ฉ์ ์๋จ์ ๋ฐฐ์น (F-ํจํด ์ฝ๊ธฐ ๊ณ ๋ ค)
โข ์์ ์ฝ๋ฉ์ผ๋ก ์ฐ์ ์์ ํ์ (๋นจ๊ฐ=๊ธด๊ธ, ๋
ธ๋=์ค์, ์ด๋ก=์ผ๋ฐ)
โข ํด๋ฆญ ๊ฐ๋ฅํ ๋งํฌ ์ถ๊ฐ (์๋ณธ Slack ๋ฉ์์ง๋ก ๋ฐ๋ก ์ด๋)
โข ๋คํฌ๋ชจ๋ ์ง์ํ๋ฉด ๋ ์ข์์ ใ
ใ
๐ ์๋ํ ์ค์ผ์ค๋ง ์ค์
์ด์ ์ด ๋ชจ๋ ๊ณผ์ ์ ์๋์ผ๋ก ๋์๊ฐ๊ฒ ๋ง๋ค์ด์ผ์ฃ ! ์ฌ๋ฌ ๋ฐฉ๋ฒ์ด ์๋๋ฐ, ์ํฉ์ ๋ง๊ฒ ์ ํํ๋ฉด ๋ผ์.
| ๋ฐฉ๋ฒ | ์ฅ์ | ๋จ์ | ์ถ์ฒ ์ํฉ |
|---|---|---|---|
| Cron Job | ๊ฐ๋จํ๊ณ ์ง๊ด์ ์๋ฒ ์ ์ด ๊ฐ๋ฅ |
์๋ฒ ํ์ ๊ด๋ฆฌ ๋ถ๋ด |
์์ฒด ์๋ฒ ๋ณด์ ์ |
| AWS Lambda | ์๋ฒ๋ฆฌ์ค ๋น์ฉ ํจ์จ์ ํ์ฅ์ฑ ์ข์ |
์ฝ๋ ์คํํธ ์คํ ์๊ฐ ์ ํ |
ํด๋ผ์ฐ๋ ์ ํธ ์ |
| GitHub Actions | ๋ฌด๋ฃ ์ฝ๋์ ํตํฉ ์ค์ ์ฌ์ |
์คํ ์๊ฐ ์ ํ ๊ณต๊ฐ ์ ์ฅ์ ํ์ |
๊ฐ์ธ ํ๋ก์ ํธ |
| Zapier/Make | ๋
ธ์ฝ๋ ๋น ๋ฅธ ๊ตฌ์ถ |
๋น์ฉ ๋์ ์ปค์คํฐ๋ง์ด์ง ์ ํ |
๋น ๋ฅธ ํ๋กํ ํ์ |
๊ฐ์ฅ ๋ง์ด ์ฐ๋ ๋ฐฉ๋ฒ์ด์์! ์๋ฒ ๊ด๋ฆฌ ์์ด ์๋์ผ๋ก ๋์๊ฐ๋๊น ํธํ์ฃ ใ
ใ
1. Lambda ํจ์ ์์ฑ
โข Python 3.11 ๋ฐํ์ ์ ํ
โข ๋ฉ๋ชจ๋ฆฌ 512MB, ํ์์์ 5๋ถ ์ค์
โข ํ๊ฒฝ ๋ณ์์ API ํค๋ค ์ ์ฅ (SLACK_BOT_TOKEN, OPENAI_API_KEY, SENDGRID_API_KEY)
2. ์์กด์ฑ ํจํค์ง ํฌํจ
Lambda Layer๋ก ๋ง๋ค๊ฑฐ๋ deployment package์ ํฌํจ์์ผ์ผ ํด์:
# requirements.txt
slack-sdk==3.23.0
openai==1.3.0
sendgrid==6.10.0
# ํจํค์ง ์ค์น ๋ฐ ์์ถ
pip install -r requirements.txt -t ./package
cd package
zip -r ../lambda_function.zip .
cd ..
zip -g lambda_function.zip lambda_function.py
3. EventBridge ๊ท์น ์์ฑ
โข ๋งค์ผ ์ค์ 9์์ ์คํ: cron(0 0 * * ? *) (UTC ๊ธฐ์ค์ด๋ ํ๊ตญ ์๊ฐ ๊ณ ๋ ค!)
โข ์ฃผ์ค ์ค์ 9์๋ง: cron(0 0 ? * MON-FRI *)
โข 4์๊ฐ๋ง๋ค: rate(4 hours)
4. Lambda ํจ์ ์ฝ๋
import json
import boto3
from slack_integration import fetch_messages
from ai_summarizer import summarize_messages
from email_sender import send_email
def lambda_handler(event, context):
"""
Lambda ๋ฉ์ธ ํธ๋ค๋ฌ
"""
try:
# 1. Slack ๋ฉ์์ง ์์ง
print("๋ฉ์์ง ์์ง ์์...")
channel_id = "C01234567"
messages = fetch_messages(channel_id, hours=24)
if not messages:
print("์๋ก์ด ๋ฉ์์ง๊ฐ ์์ต๋๋ค.")
return {
'statusCode': 200,
'body': json.dumps('No new messages')
}
print(f"{len(messages)}๊ฐ ๋ฉ์์ง ์์ง ์๋ฃ")
# 2. AI ์์ฝ
print("AI ์์ฝ ์์...")
summary = summarize_messages(messages)
if not summary:
raise Exception("์์ฝ ์์ฑ ์คํจ")
print("์์ฝ ์๋ฃ")
# 3. ์ด๋ฉ์ผ ๋ฐ์ก
print("์ด๋ฉ์ผ ๋ฐ์ก ์์...")
recipients = ["team@company.com", "manager@company.com"]
for recipient in recipients:
send_email(recipient, summary)
print("๋ชจ๋ ์์
์๋ฃ!")
return {
'statusCode': 200,
'body': json.dumps({
'message': 'Success',
'messages_processed': len(messages),
'emails_sent': len(recipients)
})
}
except Exception as e:
print(f"์ค๋ฅ ๋ฐ์: {str(e)}")
# ์ค๋ฅ ์๋ฆผ (SNS ๋ฑ์ผ๋ก)
sns = boto3.client('sns')
sns.publish(
TopicArn='arn:aws:sns:region:account:alert-topic',
Subject='Slack Summary Bot ์ค๋ฅ',
Message=f'์ค๋ฅ ๋ด์ฉ: {str(e)}'
)
return {
'statusCode': 500,
'body': json.dumps({'error': str(e)})
}
๋ชจ๋ํฐ๋ง ์ค์ :
โข CloudWatch Logs๋ก ์คํ ๋ก๊ทธ ํ์ธ
โข CloudWatch Alarms๋ก ์คํจ ์ ์๋ฆผ
โข X-Ray๋ก ์ฑ๋ฅ ์ถ์
โข Cost Explorer๋ก ๋น์ฉ ๋ชจ๋ํฐ๋ง (๋ณดํต ์ $1-5 ์ ๋ ๋์์ ใ
ใ
)
๐จ ๊ณ ๊ธ ๊ธฐ๋ฅ ์ถ๊ฐํ๊ธฐ
๊ธฐ๋ณธ ์์คํ ์ด ์์ฑ๋๋ค๋ฉด ์ด์ ๋ ์ค๋งํธํ๊ฒ ๋ง๋ค์ด๋ณผ๊น์? ์ค๋ฌด์์ ์ง์ง ์ ์ฉํ ๊ธฐ๋ฅ๋ค์ด์์!
๐ ์ง๋ฅํ ํํฐ๋ง
๋ชจ๋ ๋ฉ์์ง๋ฅผ ๋ค ์์ฝํ ํ์๋ ์์์์? AI๊ฐ ์ค์ํ ๊ฒ๋ง ๊ณจ๋ผ๋ด๊ฒ ๋ง๋ค์ด๋ด
์๋ค!
ํํฐ๋ง ๊ธฐ์ค ์์:
def filter_important_messages(messages):
"""
์ค์ํ ๋ฉ์์ง๋ง ํํฐ๋ง
"""
important_messages = []
for msg in messages:
text = msg.get("text", "").lower()
# ์ค์๋ ์ ์ ๊ณ์ฐ
importance_score = 0
# ํค์๋ ๊ธฐ๋ฐ ์ ์
urgent_keywords = ["๊ธด๊ธ", "urgent", "asap", "์ค์", "deadline", "๋ง๊ฐ"]
for keyword in urgent_keywords:
if keyword in text:
importance_score += 3
# ๋ฉ์
ํ์ธ
if f"<@{MY_USER_ID}>" in text:
importance_score += 2
# ๋ฆฌ์ก์
์
reaction_count = msg.get("reaction_count", 0)
importance_score += min(reaction_count, 3)
# ์ค๋ ๋ ๋ต๊ธ ์
reply_count = msg.get("reply_count", 0)
if reply_count > 5:
importance_score += 2
# ํน์ ์ฌ์ฉ์์ ๋ฉ์์ง (์: CEO, ํ์ฅ)
if msg.get("user") in IMPORTANT_USERS:
importance_score += 2
# ์ ์๊ฐ 5 ์ด์์ด๋ฉด ์ค์ํ ๋ฉ์์ง๋ก ๋ถ๋ฅ
if importance_score >= 5:
msg["importance_score"] = importance_score
important_messages.append(msg)
# ์ ์ ์์ผ๋ก ์ ๋ ฌ
important_messages.sort(key=lambda x: x["importance_score"], reverse=True)
return important_messages
์ด๋ ๊ฒ ํ๋ฉด ์ ๋ง ์ค์ํ ๋ฉ์์ง๋ง ์์ฝ๋๋๊น ์ด๋ฉ์ผ์ด ํจ์ฌ ๊ฐ๊ฒฐํด์ ธ์! ๋ ธ์ด์ฆ๋ ์ค์ด๊ณ ์๊ทธ๋์ ๋์ด๋ ๊ฑฐ์ฃ ๐
๐ ๊ฐ์ฑ ๋ถ์ ๋ฐ ๋ถ์๊ธฐ ํ์
ํ์ ๋ถ์๊ธฐ๋ ๊ฐ์ ์ํ๋ ํ์ ํ ์ ์์ด์. ํนํ ๋ฆฌ๋ชจํธ ํ์ด๋ผ๋ฉด ๋ ์ ์ฉํ์ฃ !
def analyze_sentiment(messages):
"""
๋ฉ์์ง์ ์ ๋ฐ์ ์ธ ๊ฐ์ฑ ๋ถ์
"""
prompt = f"""
๋ค์ ๋ฉ์์ง๋ค์ ์ ๋ฐ์ ์ธ ๋ถ์๊ธฐ์ ๊ฐ์ ์ ๋ถ์ํด์ฃผ์ธ์:
1. ์ ์ฒด์ ์ธ ํ ๋ถ์๊ธฐ (๊ธ์ ์ /์ค๋ฆฝ์ /๋ถ์ ์ )
2. ์ฃผ์ ๊ฐ์ ํค์๋
3. ์ฃผ๋ชฉํ ๋งํ ๋ณํ๋ ์ด์
4. ํ ์ฌ๊ธฐ ์งํ (1-10์ )
๋ฉ์์ง: {messages}
"""
response = openai.ChatCompletion.create(
model="gpt-4",
messages=[{"role": "user", "content": prompt}]
)
return response.choices[0].message.content
์ด๊ฑธ ์ด๋ฉ์ผ์ ํฌํจ์ํค๋ฉด ๋งค๋์ ๋ค์ด ํ ์ํ๋ฅผ ํ๋์ ํ์ ํ ์ ์์ด์. "์ค๋ ํ ๋ถ์๊ธฐ๊ฐ ์ข ์ ์ข๋ค? ๋ฌด์จ ์ผ ์๋?" ์ด๋ฐ ์์ผ๋ก ๋น ๋ฅด๊ฒ ๋์ ๊ฐ๋ฅํ์ฃ ใ ใ
๐ฏ ๊ฐ์ธํ๋ ์์ฝ
์ฌ๋๋ง๋ค ๊ด์ฌ์ฌ๊ฐ ๋ค๋ฅด์์์? ๊ฐ์์๊ฒ ๋ง์ถคํ ์์ฝ์ ๋ณด๋ด๋ ๊ฑฐ์์!
def personalized_summary(messages, user_profile):
"""
์ฌ์ฉ์ ํ๋กํ ๊ธฐ๋ฐ ๋ง์ถค ์์ฝ
"""
# ์ฌ์ฉ์ ๊ด์ฌ ํค์๋
interests = user_profile.get("interests", [])
department = user_profile.get("department", "")
role = user_profile.get("role", "")
# ๊ด๋ จ ๋ฉ์์ง ํํฐ๋ง
relevant_messages = []
for msg in messages:
text = msg.get("text", "").lower()
# ๊ด์ฌ ํค์๋ ๋งค์นญ
for interest in interests:
if interest.lower() in text:
relevant_messages.append(msg)
break
# ๋ถ์ ๊ด๋ จ ๋ฉ์์ง
if department.lower() in text:
relevant_messages.append(msg)
# ๊ฐ์ธํ๋ ํ๋กฌํํธ
prompt = f"""
๋ค์ ๋ฉ์์ง๋ค์ {role} ์ญํ ์ {department} ๋ถ์ ์ง์ ๊ด์ ์์ ์์ฝํด์ฃผ์ธ์.
ํนํ {', '.join(interests)} ๊ด๋ จ ๋ด์ฉ์ ์ค์ ์ ์ผ๋ก ๋ค๋ค์ฃผ์ธ์.
๋ฉ์์ง: {relevant_messages}
"""
# AI ์์ฝ
summary = openai.ChatCompletion.create(
model="gpt-4",
messages=[{"role": "user", "content": prompt}]
)
return summary.choices[0].message.content
๊ฐ๋ฐ์๋ ๊ธฐ์ ๊ด๋ จ ๋ด์ฉ์, ๋ง์ผํฐ๋ ์บ ํ์ธ ๊ด๋ จ ๋ด์ฉ์ ๋ ์์ธํ ๋ฐ๋ ์์ด์ฃ . ์ ๋ณด ๊ณผ๋ถํ๋ฅผ ์ค์ด๊ณ ๊ฐ์์๊ฒ ํ์ํ ์ ๋ณด๋ง ์ ๋ฌํ๋ ๊ฒ ํต์ฌ์ด์์! ๐ฏ
๐ ํธ๋ ๋ ๋ถ์ ๋ฐ ์ธ์ฌ์ดํธ
๋จ์ ์์ฝ์ ๋์ด์ ํจํด๊ณผ ํธ๋ ๋๋ฅผ ์ฐพ์๋ด๋ ๊ฑฐ์์. ์ด๊ฒ ์ง์ง ๊ณ ๊ธ ๊ธฐ๋ฅ์ด์ฃ ใ ใ
def analyze_trends(messages_history):
"""
์ง๋ ์ผ์ฃผ์ผ ๋ฉ์์ง ํธ๋ ๋ ๋ถ์
"""
# ์ผ๋ณ ๋ฉ์์ง ์ ์ง๊ณ
daily_counts = {}
topic_frequency = {}
user_activity = {}
for msg in messages_history:
date = datetime.fromtimestamp(float(msg["ts"])).date()
user = msg.get("user", "Unknown")
# ์ผ๋ณ ์นด์ดํธ
daily_counts[date] = daily_counts.get(date, 0) + 1
# ์ฌ์ฉ์๋ณ ํ๋
user_activity[user] = user_activity.get(user, 0) + 1
# ํ ํฝ ์ถ์ถ (๊ฐ๋จํ ํค์๋ ๊ธฐ๋ฐ)
text = msg.get("text", "")
# ... ํ ํฝ ๋ถ์ ๋ก์ง
# AI๋ก ์ธ์ฌ์ดํธ ์์ฑ
prompt = f"""
๋ค์ ๋ฐ์ดํฐ๋ฅผ ๋ถ์ํ์ฌ ์ธ์ฌ์ดํธ๋ฅผ ์ ๊ณตํด์ฃผ์ธ์:
์ผ๋ณ ๋ฉ์์ง ์: {daily_counts}
์ฌ์ฉ์๋ณ ํ๋: {user_activity}
๋ค์ ํญ๋ชฉ์ ํฌํจํด์ฃผ์ธ์:
1. ์ฃผ๋ชฉํ ๋งํ ๋ณํ๋ ํจํด
2. ๊ฐ์ฅ ํ๋ฐํ ํ ํฝ
3. ์ฐธ์ฌ๋ ๋ณํ
4. ๋ค์ ์ฃผ ์์ ์ด์
"""
insights = openai.ChatCompletion.create(
model="gpt-4",
messages=[{"role": "user", "content": prompt}]
)
return insights.choices[0].message.content
์ด๋ฐ ์ธ์ฌ์ดํธ๋ฅผ ์ฃผ๊ฐ ๋ฆฌํฌํธ๋ก ๋ง๋ค๋ฉด ๊ฒฝ์์ง์ด ์์ฒญ ์ข์ํด์ ใ ใ ใ "์ฐ๋ฆฌ ํ ์ปค๋ฎค๋์ผ์ด์ ์ด ์ด๋ ๊ฒ ๋ณํ๊ณ ์๊ตฌ๋" ํ๊ณ ๋ฐ์ดํฐ ๊ธฐ๋ฐ์ผ๋ก ์์ฌ๊ฒฐ์ ํ ์ ์๊ฑฐ๋ ์!
โข ํ ํฐ ๊ด๋ฆฌ: API ํค๋ ์ ๋ ์ฝ๋์ ํ๋์ฝ๋ฉํ์ง ๋ง๊ณ ํ๊ฒฝ๋ณ์๋ ์ํฌ๋ฆฟ ๋งค๋์ ์ฌ์ฉ
โข ๋ฐ์ดํฐ ์ํธํ: ๋ฉ์์ง ๋ด์ฉ์ ์ ์ฅํ ๋๋ ๋ฐ๋์ ์ํธํ
โข ์ ๊ทผ ๊ถํ: ์ต์ ๊ถํ ์์น ์ ์ฉ. ํ์ํ ์ฑ๋๋ง ์ ๊ทผ
โข ๋ก๊ทธ ๊ด๋ฆฌ: ๋ฏผ๊ฐํ ์ ๋ณด๊ฐ ๋ก๊ทธ์ ๋จ์ง ์๋๋ก ์ฃผ์
โข GDPR ์ค์: ์ ๋ฝ ์ฌ์ฉ์ ์์ผ๋ฉด ๋ฐ์ดํฐ ๋ณด๊ด ๊ธฐ๊ฐ, ์ญ์ ๊ถ๋ฆฌ ๋ฑ ๊ณ ๋ ค
โข ์ฌ์ฉ์ ๋์: ํ์๋ค์๊ฒ ์๋ํ ์์คํ ์ฌ์ฉ์ ์๋ฆฌ๊ณ ๋์ ๋ฐ๊ธฐ
๐ ํธ๋ฌ๋ธ์ํ ๊ฐ์ด๋
์ค์ ๋ก ์ด์ํ๋ค ๋ณด๋ฉด ์ฌ๋ฌ ๋ฌธ์ ๊ฐ ์๊ธฐ์ฃ ใ ใ ์์ฃผ ๋ฐ์ํ๋ ์ด์๋ค๊ณผ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ ๋ฆฌํด๋ดค์ด์!
๋ฌธ์ 1: Rate Limit ์ด๊ณผ
์ฆ์: rate_limited ์๋ฌ ๋ฐ์
์์ธ: Slack API ํธ์ถ ์ ํ ์ด๊ณผ (Tier 1: ๋ถ๋น 1ํ, Tier 2: ๋ถ๋น 20ํ ๋ฑ)
ํด๊ฒฐ์ฑ
:
import time
from functools import wraps
def rate_limit_handler(max_retries=3, delay=60):
"""
Rate limit ์๋ฌ ์๋ ์ฌ์๋ ๋ฐ์ฝ๋ ์ดํฐ
"""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
for attempt in range(max_retries):
try:
return func(*args, **kwargs)
except SlackApiError as e:
if e.response["error"] == "rate_limited":
retry_after = int(e.response.headers.get("Retry-After", delay))
print(f"Rate limited. ์ฌ์๋๊น์ง {retry_after}์ด ๋๊ธฐ...")
time.sleep(retry_after)
else:
raise
raise Exception("์ต๋ ์ฌ์๋ ํ์ ์ด๊ณผ")
return wrapper
return decorator
@rate_limit_handler()
def fetch_messages_safe(channel_id):
return client.conversations_history(channel=channel_id)
๋ฌธ์ 2: AI ์์ฝ ํ์ง ์ ํ
์ฆ์: ์์ฝ์ด ๋๋ฌด ์งง๊ฑฐ๋, ์ค์ํ ๋ด์ฉ ๋๋ฝ, ์ผ๊ด์ฑ ์์
์์ธ: ํ๋กฌํํธ ์ค๊ณ ๋ฌธ์ , ์ปจํ
์คํธ ๋ถ์กฑ, ๋ชจ๋ธ ์ ํ ์ค๋ฅ
ํด๊ฒฐ์ฑ
:
โข ํ๋กฌํํธ ๊ฐ์ : ๋ ๊ตฌ์ฒด์ ์ธ ์ง์์ฌํญ ์ถ๊ฐ
โข ์์ ์ ๊ณต: Few-shot learning์ผ๋ก ์ํ๋ ์คํ์ผ ํ์ต
โข ์ฒญํฌ ์ฒ๋ฆฌ: ๊ธด ๋ํ๋ ๋๋ ์ ์ฒ๋ฆฌ ํ ๋ณํฉ
โข ๋ชจ๋ธ ์
๊ทธ๋ ์ด๋: GPT-3.5 โ GPT-4๋ก ๋ณ๊ฒฝ
โข Temperature ์กฐ์ : 0.3-0.5 ์ฌ์ด๋ก ์ค์ (์ผ๊ด์ฑ ํฅ์)
๋ฌธ์ 3: ์ด๋ฉ์ผ ์คํธ ์ฒ๋ฆฌ
์ฆ์: ๋ฐ์กํ ์ด๋ฉ์ผ์ด ์คํธํจ์ผ๋ก ๊ฐ๋ ๊ฒฝ์ฐ
ํด๊ฒฐ์ฑ
:
โข SPF/DKIM/DMARC ์ค์ : ๋๋ฉ์ธ ์ธ์ฆ ํ์
โข ๋ฐ์ ์ ํํ ๊ด๋ฆฌ: ์ ์ง์ ์ผ๋ก ๋ฐ์ก๋ ๋๋ฆฌ๊ธฐ
โข ๋ด์ฉ ์ต์ ํ: ์คํธ ํค์๋ ํผํ๊ธฐ, ํ
์คํธ/์ด๋ฏธ์ง ๋น์จ ์ ์ ํ
โข ์์ ์ ๊ด๋ฆฌ: ๋ฐ์ก ๋ฉ์ผ ์ฃผ์ ์ ๊ฑฐ, ๊ตฌ๋
์ทจ์ ๊ธฐ๋ฅ ์ ๊ณต
โข ์ ๋ฌธ ์๋น์ค ์ฌ์ฉ: SendGrid, AWS SES ๊ฐ์ ๊ฒ์ฆ๋ ํ๋ซํผ ํ์ฉ
๋ฌธ์ 4: Lambda ํ์์์
์ฆ์: ๋ฉ์์ง๊ฐ ๋ง์ ๋ Lambda ์คํ ์๊ฐ ์ด๊ณผ
ํด๊ฒฐ์ฑ
:
def lambda_handler_optimized(event, context):
"""
ํ์์์ ๋ฐฉ์ง๋ฅผ ์ํ ์ต์ ํ๋ ํธ๋ค๋ฌ
"""
remaining_time = context.get_remaining_time_in_millis()
# ๋จ์ ์๊ฐ์ด 1๋ถ ๋ฏธ๋ง์ด๋ฉด ์กฐ๊ธฐ ์ข
๋ฃ
if remaining_time < 60000:
print("์๊ฐ ๋ถ์กฑ. ๋ค์ ์คํ์์ ์ฒ๋ฆฌ...")
return {'statusCode': 202, 'body': 'Partial completion'}
# ๋ฐฐ์น ์ฒ๋ฆฌ
batch_size = 50
messages = fetch_messages(channel_id)
for i in range(0, len(messages), batch_size):
batch = messages[i:i+batch_size]
# ๋จ์ ์๊ฐ ์ฒดํฌ
if context.get_remaining_time_in_millis() < 30000:
# ์ฒ๋ฆฌ ์ค๋จํ๊ณ ์ํ ์ ์ฅ
save_checkpoint(i)
break
process_batch(batch)
return {'statusCode': 200}
๋๋ Step Functions๋ก ์ํฌํ๋ก์ฐ๋ฅผ ๋๋ ์ ์ฒ๋ฆฌํ๋ ๊ฒ๋ ์ข์ ๋ฐฉ๋ฒ์ด์์!
๐ฐ ๋น์ฉ ์ต์ ํ ์ ๋ต
AI ์๋ํ๋ ํธํ๋ฐ ๋น์ฉ์ด ๊ฑฑ์ ๋์์ฃ ? ์ค์ ๋ก ์ด์ํ๋ฉด์ ๋น์ฉ์ ์ค์ด๋ ๊ฟํ๋ค์ด์์ ใ ใ
| ํญ๋ชฉ | ์ ์์ ๋น์ฉ | ์ ๊ฐ ๋ฐฉ๋ฒ |
|---|---|---|
| OpenAI API | $10-50 | โข ์บ์ฑ ํ์ฉ โข ์ ๋ ดํ ๋ชจ๋ธ ์ฌ์ฉ (GPT-3.5) โข ํ ํฐ ์ ์ต์ ํ |
| AWS Lambda | $1-5 | โข ๋ฉ๋ชจ๋ฆฌ ์ต์ ํ โข ์คํ ์๊ฐ ๋จ์ถ โข ๋ฌด๋ฃ ํฐ์ด ํ์ฉ |
| SendGrid | $0-15 | โข ๋ฌด๋ฃ ํฐ์ด (์ผ 100ํต) โข ๋ถํ์ํ ๋ฐ์ก ์ค์ด๊ธฐ |
| ๋ฐ์ดํฐ ์ ์ฅ | $1-3 | โข S3 Intelligent-Tiering โข ์ค๋๋ ๋ฐ์ดํฐ ์ญ์ |
| ํฉ๊ณ | $12-73 | ์ต์ ํ ์ $5-20 ๊ฐ๋ฅ |
1. ์ค๋งํธ ์บ์ฑ
๊ฐ์ ๋ด์ฉ์ ๋ฐ๋ณต ์์ฝํ์ง ์๋๋ก Redis๋ DynamoDB์ ์บ์ฑํ์ธ์. ์ค๋ณต API ํธ์ถ์ 70% ์ด์ ์ค์ผ ์ ์์ด์!
2. ๋ฐฐ์น ์ฒ๋ฆฌ
๋ฉ์์ง๋ฅผ ํ๋์ฉ ์์ฝํ์ง ๋ง๊ณ ์ฌ๋ฌ ๊ฐ๋ฅผ ํ ๋ฒ์ ์ฒ๋ฆฌํ๋ฉด API ํธ์ถ ํ์๊ฐ ํ ์ค์ด๋ค์ฃ .
3. ์กฐ๊ฑด๋ถ ์คํ
์ ๋ฉ์์ง๊ฐ ์์ผ๋ฉด ์์ ์คํํ์ง ์๊ธฐ. ์ฃผ๋ง์ด๋ ํด์ผ์๋ ์คํตํ๋ ๊ฒ๋ ๋ฐฉ๋ฒ์ด์์.
4. ์คํ์์ค ๋ชจ๋ธ ๊ณ ๋ ค
Llama 2, Mistral ๊ฐ์ ์คํ์์ค ๋ชจ๋ธ์ ์์ฒด ์๋ฒ์์ ๋๋ฆฌ๋ฉด ์ฅ๊ธฐ์ ์ผ๋ก ๋น์ฉ ์ ๊ฐ ๊ฐ๋ฅํด์. ์ด๊ธฐ ํฌ์๋ ํ์ํ์ง๋ง์ ใ ใ
๐ ์ค์ ํ์ฉ ์ฌ๋ก
์ค์ ๋ก ์ด ์์คํ ์ ์ด๋ป๊ฒ ํ์ฉํ๊ณ ์๋์ง ๋ช ๊ฐ์ง ์ฌ๋ก๋ฅผ ๊ณต์ ํ ๊ฒ์!
์ฌ๋ก 1: ์คํํธ์ ์ ์ฌ ์ปค๋ฎค๋์ผ์ด์ ๊ด๋ฆฌ
์ํฉ: 50๋ช
๊ท๋ชจ ์คํํธ์
, 10๊ฐ ์ด์์ Slack ์ฑ๋ ์ด์
๊ตฌํ:
โข ๋งค์ผ ์ค์ 9์์ ์ ๋ ์ฃผ์ ๋ด์ฉ ์์ฝ ๋ฐ์ก
โข ๋ถ์๋ณ๋ก ๋ค๋ฅธ ์ฑ๋ ์กฐํฉ ๊ตฌ๋
โข CEO๋ ์ ์ฒด ์์ฝ, ํ์ฅ์ ํด๋น ํ ์์ฝ๋ง ์์
โข ๊ธด๊ธ ํค์๋ ๊ฐ์ง ์ ์ฆ์ ์๋ฆผ
ํจ๊ณผ:
โข ํ์ ์๊ฐ 30% ๊ฐ์ (์ด๋ฏธ ์์ฝ์ผ๋ก ํ์
)
โข ์ ๋ณด ๋๋ฝ ์ฌ๊ณ 80% ๊ฐ์
โข ์ง์ ๋ง์กฑ๋ ์์น (์ ๋ณด ๊ณผ๋ถํ ํด์)
โข ์์ฌ๊ฒฐ์ ์๋ ํฅ์
์ฌ๋ก 2: ๊ธ๋ก๋ฒ ํ ํ์ ์ง์
์ํฉ: ํ๊ตญ-๋ฏธ๊ตญ-์ ๋ฝ 3๊ฐ ์ง์ญ ํ ํ์
๊ตฌํ:
โข ์์ฐจ ๊ณ ๋ คํ ๋ง์ถค ๋ฐ์ก ์๊ฐ
โข ๊ฐ ์ง์ญ ๊ทผ๋ฌด ์๊ฐ๋ ๋ฉ์์ง๋ง ํํฐ๋ง
โข ๋ค๊ตญ์ด ์์ฝ ์ง์ (๋ฒ์ญ API ์ฐ๋)
โข ํ์์กด๋ณ ์ค์ ์ด๋ฒคํธ ํ์ด๋ผ์ดํธ
ํจ๊ณผ:
โข ์์ฐจ๋ก ์ธํ ์ปค๋ฎค๋์ผ์ด์
์ง์ฐ 50% ๊ฐ์
โข ๊ฐ ํ์ ์งํ ์ํฉ ์ค์๊ฐ ํ์
โข ๋ถํ์ํ ๋๊ธฐํ ๋ฏธํ
๊ฐ์
โข ๊ธ๋ก๋ฒ ํ์
ํจ์จ์ฑ ๋ํญ ํฅ์
์ฌ๋ก 3: ๊ณ ๊ฐ ์ง์ํ ์ด์ ์ต์ ํ
์ํฉ: 24์๊ฐ ๊ณ ๊ฐ ์ง์ ์ฑ๋ ์ด์
๊ตฌํ:
โข ๊ณ ๊ฐ ๋ฌธ์ ์๋ ๋ถ๋ฅ ๋ฐ ์ฐ์ ์์ ์ง์
โข ๋ฏธํด๊ฒฐ ์ด์ ์๋ ์ถ์
โข ๊ต๋ ๊ทผ๋ฌด ์ ์ธ์์ธ๊ณ ์๋ ์์ฑ
โข ์ฃผ๊ฐ ํธ๋ ๋ ๋ฆฌํฌํธ (์์ฃผ ๋ฌป๋ ์ง๋ฌธ ๋ฑ)
ํจ๊ณผ:
โข ์๋ต ์๊ฐ 40% ๋จ์ถ
โข ์ธ์์ธ๊ณ ๋๋ฝ ์ ๋กํ
โข ๋ฐ๋ณต ๋ฌธ์ ํจํด ํ์
์ผ๋ก FAQ ๊ฐ์
โข ๊ณ ๊ฐ ๋ง์กฑ๋ 15% ์์น
๐ฎ ๋ฏธ๋ ๋ฐ์ ๋ฐฉํฅ
์ด ๊ธฐ์ ์ ๊ณ์ ์งํํ๊ณ ์์ด์! ์์ผ๋ก ์ด๋ค ๋ฐฉํฅ์ผ๋ก ๋ฐ์ ํ ์ง ์ดํด๋ณผ๊น์?
1. ๋ฉํฐ๋ชจ๋ฌ AI ํตํฉ
ํ
์คํธ๋ฟ๋ง ์๋๋ผ ์ด๋ฏธ์ง, ํ์ผ, ์์ฑ ๋ฉ์์ง๊น์ง ๋ถ์ํ๋ ๊ฑฐ์์.
โข ๊ณต์ ๋ ์คํฌ๋ฆฐ์ท ์๋ ๋ถ์
โข ์์ฑ ๋ฉ์์ง ํ
์คํธ ๋ณํ ๋ฐ ์์ฝ
โข ์ฐจํธ๋ ๊ทธ๋ํ ๋ฐ์ดํฐ ์ถ์ถ
โข ๋น๋์ค ๋ฏธํ
๋
นํ ์๋ ์์ฝ
GPT-4V๋ Gemini Pro Vision ๊ฐ์ ๋ฉํฐ๋ชจ๋ฌ ๋ชจ๋ธ์ด ๋์ค๋ฉด์ ์ด๋ฏธ ๊ฐ๋ฅํด์ง๊ณ ์์ด์!
2. ์์ธก ๋ฐ ์ถ์ฒ ๊ธฐ๋ฅ
๊ณผ๊ฑฐ ๋ฐ์ดํฐ๋ฅผ ํ์ตํด์ ๋ฏธ๋๋ฅผ ์์ธกํ๋ ๊ฑฐ์ฃ .
โข "๋ด์ผ ์ด ์ด์๊ฐ ์ค์ํด์ง ๊ฒ ๊ฐ์์"
โข "์ด ์ฌ๋์๊ฒ ์ด ์ ๋ณด๋ฅผ ๊ณต์ ํ๋ ๊ฒ ์ข๊ฒ ์ด์"
โข "๋ค์ ์ฃผ ๋ง๊ฐ ๋ฆฌ์คํฌ๊ฐ ์๋ ํ๋ก์ ํธ 3๊ฐ"
โข "ํ ๋ฒ์์ ์ํ ๊ฐ์ง ๋ฐ ์กฐ๊ธฐ ๊ฒฝ๋ณด"
๋จธ์ ๋ฌ๋ ๋ชจ๋ธ์ ์ถ๊ฐ๋ก ํ์ต์ํค๋ฉด ๊ฐ๋ฅํด์. ์ง์ง ๋๋ํ ๋น์๊ฐ ๋๋ ๊ฑฐ์ฃ ใ
ใ
ใ
3. ์์ฐ์ด ์ธํฐํ์ด์ค
์ด๋ฉ์ผ๋ก ๋ฐ๊ธฐ๋ง ํ๋ ๊ฒ ์๋๋ผ ๋ํ๋ก ์ํธ์์ฉํ๋ ๊ฑฐ์์.
โข "์ด์ ๋ง์ผํ
ํ ๋
ผ์ ๋ด์ฉ ์๋ ค์ค"
โข "์ด๋ฒ ์ฃผ ๋ด๊ฐ ๋์น ์ค์ํ ๋ฉ์์ง ์์ด?"
โข "๊นํ์ฅ๋์ด ์ธ๊ธํ ํ๋ก์ ํธ ์งํ ์ํฉ์?"
Slack ๋ด์ด๋ ์ด๋ฉ์ผ ๋ต์ฅ์ผ๋ก ์ง๋ฌธํ๋ฉด AI๊ฐ ์ฆ์ ๋ต๋ณํด์ฃผ๋ ์์ด์ฃ . ์ด๋ฏธ ์ผ๋ถ ๊ธฐ์
์์ ์๋ฒ ์ด์ ์ค์ด์์!
4. ์์ ์๋ํ๋ ์ํฌํ๋ก์ฐ
์์ฝ๋ง ํ๋ ๊ฒ ์๋๋ผ ์ก์
๊น์ง ์๋์ผ๋ก ์ทจํ๋ ๊ฑฐ์์.
โข ๊ธด๊ธ ์ด์ ๊ฐ์ง โ ์๋์ผ๋ก Jira ํฐ์ผ ์์ฑ
โข ํ์ ์ผ์ ์กฐ์จ ํ์ โ ์๋์ผ๋ก ์บ๋ฆฐ๋ ์ด๋ ๋ฐ์ก
โข ์น์ธ ์์ฒญ ๊ฐ์ง โ ํด๋น ๋ด๋น์์๊ฒ ์๋ฆผ
โข ๋ฐ๋ณต ์ง๋ฌธ ๊ฐ์ง โ ์๋์ผ๋ก FAQ ์
๋ฐ์ดํธ
AI ์์ด์ ํธ๊ฐ ๋จ์ ์ ๋ณด ์ ๋ฌ์ ๋์ด ์ค์ ์
๋ฌด๋ฅผ ์ฒ๋ฆฌํ๋ ์์ค๊น์ง ๊ฐ๋ ๊ฑฐ์ฃ . ์ด๊ฒ ๋ฐ๋ก AI ์๋ํ์ ์ต์ข
๋ชฉํ์์! ๐
๐ ํ์ต ๋ฆฌ์์ค ๋ฐ ์ปค๋ฎค๋ํฐ
๋ ๊น์ด ๊ณต๋ถํ๊ณ ์ถ์ผ์ ๋ถ๋ค์ ์ํ ์๋ฃ๋ค์ด์์!
๐ ๊ณต์ ๋ฌธ์
โข Slack API: api.slack.com/docs - ๊ฐ์ฅ ์ ํํ๊ณ ์ต์ ์ ๋ณด
โข OpenAI API: platform.openai.com/docs - GPT ๋ชจ๋ธ ์ฌ์ฉ๋ฒ
โข AWS Lambda: docs.aws.amazon.com/lambda - ์๋ฒ๋ฆฌ์ค ๋ฐฐํฌ
โข SendGrid: docs.sendgrid.com - ์ด๋ฉ์ผ ๋ฐ์ก ๊ฐ์ด๋
๐ป ์คํ์์ค ํ๋ก์ ํธ
GitHub์์ "slack summarizer" ๊ฒ์ํ๋ฉด ๋ง์ ์์ ์ฝ๋๊ฐ ๋์์! ํนํ:
โข slack-digest: ๊ธฐ๋ณธ์ ์ธ ์์ฝ ๋ด ๊ตฌํ
โข ai-slack-bot: GPT ํตํฉ ์์
โข slack-analytics: ๋ฉ์์ง ๋ถ์ ๋๊ตฌ
์ด๋ฐ ํ๋ก์ ํธ๋ค์ ํฌํฌํด์ ์ปค์คํฐ๋ง์ด์งํ๋ฉด ๊ฐ๋ฐ ์๊ฐ์ ํฌ๊ฒ ์ค์ผ ์ ์์ด์!
๐ ์ปค๋ฎค๋ํฐ
โข Slack Community: ๊ณต์ ๊ฐ๋ฐ์ ์ปค๋ฎค๋ํฐ
โข Reddit r/slackdev: ๊ฐ๋ฐ์๋ค์ ์ง๋ฌธ๊ณผ ๋ต๋ณ
โข Stack Overflow: ๊ตฌ์ฒด์ ์ธ ๊ธฐ์ ๋ฌธ์ ํด๊ฒฐ
โข Discord ์๋ฒ: AI ์๋ํ ๊ด๋ จ ์ค์๊ฐ ํ ๋ก
๋งํ๋ ๋ถ๋ถ ์์ผ๋ฉด ์ด๋ฐ ์ปค๋ฎค๋ํฐ์์ ๋ฌผ์ด๋ณด์ธ์. ๋ค๋ค ์น์ ํ๊ฒ ๋์์ค์ ใ
ใ
ํผ์ ๊ตฌ์ถํ๊ธฐ ์ด๋ ต๊ฑฐ๋ ์๊ฐ์ด ๋ถ์กฑํ์ ๊ฐ์? ์ฌ๋ฅ๋ท์๋ Slack ์๋ํ, AI ํตํฉ, ์ํฌํ๋ก์ฐ ์ต์ ํ ์ ๋ฌธ๊ฐ๋ค์ด ๋ง์ด ํ๋ํ๊ณ ์์ด์. ํ๋ก์ ํธ ๊ท๋ชจ์ ์์ฐ์ ๋ง๋ ์ ๋ฌธ๊ฐ๋ฅผ ์ฐพ์ ์๋ด๋ฐ์๋ณด์ธ์. ๋๋ก๋ ์ ๋ฌธ๊ฐ์ ๋์์ด ์๊ฐ๊ณผ ๋น์ฉ์ ๋ ์ ์ฝํด์ฃผ๊ธฐ๋ ํ๋๊น์! ๐ผ
โ ์ฒดํฌ๋ฆฌ์คํธ: ์์ํ๊ธฐ ์ ์
๋ณธ๊ฒฉ์ ์ผ๋ก ์์ํ๊ธฐ ์ ์ ์ด๊ฒ๋ค์ ์ฒดํฌํด๋ณด์ธ์!
โ Slack ์ํฌ์คํ์ด์ค ๊ด๋ฆฌ์ ๊ถํ ํ๋ณด
โ ๊ฐ๋ฐ ํ๊ฒฝ ์ค์ (Python/Node.js ๋ฑ)
โ ํด๋ผ์ฐ๋ ๊ณ์ ์์ฑ (AWS/GCP/Azure)
โ API ํค ๋ฐ๊ธ (OpenAI, SendGrid ๋ฑ)
โ ๋ฒ์ ๊ด๋ฆฌ ์์คํ ์ค๋น (Git)
โ ํ ์คํธ ์ฑ๋ ์์ฑ
์กฐ์ง์ ์ค๋น์ฌํญ:
โ ํ์๋ค์๊ฒ ์๋ํ ๊ณํ ๊ณต์
โ ๊ฐ์ธ์ ๋ณด ์ฒ๋ฆฌ ๋ฐฉ์นจ ๊ฒํ
โ ์์ฐ ์น์ธ (API ๋น์ฉ ๋ฑ)
โ ํ์ผ๋ฟ ํ ์คํธ ๊ทธ๋ฃน ์ ์
โ ํผ๋๋ฐฑ ์์ง ๋ฐฉ๋ฒ ๊ฒฐ์
โ ๋กค๋ฐฑ ๊ณํ ์๋ฆฝ
๋ณด์ ์ฒดํฌ๋ฆฌ์คํธ:
โ API ํค ์์ ํ ์ ์ฅ์์ ๋ณด๊ด
โ ์ต์ ๊ถํ ์์น ์ ์ฉ
โ ๋ก๊ทธ ๋ฏผ๊ฐ์ ๋ณด ๋ง์คํน
โ ๋ฐ์ดํฐ ์ํธํ ์ค์
โ ๋ฐฑ์ ๊ณํ ์๋ฆฝ
โ ๋ชจ๋ํฐ๋ง ์๋ฆผ ์ค์
๐ฌ ๋ง๋ฌด๋ฆฌํ๋ฉฐ
์... ์ฌ๊ธฐ๊น์ง ์ฝ์ผ์
จ๋ค๋ฉด ์ ๋ง ๋๋จํ์ธ์! ใ
ใ
ใ
์ด์ Slack ์๋ฆผ์ AI๋ก ์๋ ์์ฝํด์ ์ด๋ฉ์ผ๋ก ๋ฐ๋ ์์คํ
์ ๋ง๋ค ์ค๋น๊ฐ ๋ค ๋์ด์! ๐
์ฒ์์๋ ๋ณต์กํด ๋ณด์ผ ์ ์์ง๋ง, ํ ๋จ๊ณ์ฉ ์ฐจ๊ทผ์ฐจ๊ทผ ๋ฐ๋ผ๊ฐ๋ฉด ์๊ฐ๋ณด๋ค ์ด๋ ต์ง ์์์. ๊ทธ๋ฆฌ๊ณ ํ ๋ฒ ๋ง๋ค์ด๋๋ฉด ์ ๋ง ํธํ๊ฑฐ๋ ์. ๋งค์ผ ์์นจ ๊น๋ํ๊ฒ ์ ๋ฆฌ๋ ์์ฝ์ ๋ฐ์๋ณด๋ ๊ธฐ๋ถ... ์ง์ง ์ต๊ณ ์์ ๐
ํต์ฌ ํฌ์ธํธ ์ ๋ฆฌ:
โข Slack API๋ก ๋ฉ์์ง ์์ง โ AI๋ก ์์ฝ โ ์ด๋ฉ์ผ ๋ฐ์ก์ 3๋จ๊ณ ์ํฌํ๋ก์ฐ
โข ํด๋ผ์ฐ๋ ์๋น์ค ํ์ฉ์ผ๋ก ์๋ฒ ๊ด๋ฆฌ ๋ถ๋ด ์ ๋ก
โข ํ๋กฌํํธ ์์ง๋์ด๋ง์ด ์์ฝ ํ์ง์ ํต์ฌ
โข ๋ณด์๊ณผ ๊ฐ์ธ์ ๋ณด ๋ณดํธ๋ ํ์!
โข ์ง์์ ์ธ ๊ฐ์ ๊ณผ ์ต์ ํ๊ฐ ์ค์
์ด ๊ธฐ์ ์ ๋จ์ํ ํธ์์ฑ์ ๋์ด์ ์
๋ฌด ๋ฐฉ์ ์์ฒด๋ฅผ ๋ฐ๊ฟ ์ ์์ด์. ์ ๋ณด ๊ณผ๋ถํ ์๋์ ์ ๋ง ์ค์ํ ๊ฒ๋ง ๊ณจ๋ผ์ ๋ณด์ฌ์ฃผ๋ AI ๋น์... ์ด๊ฒ ๋ฐ๋ก ๋ฏธ๋์ ์ผํ๋ ๋ฐฉ์์ด ์๋๊น์?
์์์ด ๋ฐ์ด๋ผ๊ณ ํ์์์! ์ผ๋จ ๊ฐ๋จํ ๋ฒ์ ๋ถํฐ ๋ง๋ค์ด๋ณด๊ณ , ์ ์ฐจ ๊ธฐ๋ฅ์ ์ถ๊ฐํด๋๊ฐ์ธ์. ๊ทธ๋ฆฌ๊ณ ๋งํ๋ ๋ถ๋ถ ์์ผ๋ฉด ์ปค๋ฎค๋ํฐ์ ๋ฌผ์ด๋ณด๊ฑฐ๋, ์ฌ๋ฅ๋ท์์ ์ ๋ฌธ๊ฐ์ ๋์์ ๋ฐ๋ ๊ฒ๋ ์ข์ ๋ฐฉ๋ฒ์ด์์ ใ
ใ
์ฌ๋ฌ๋ถ์ ์๋ํ ํ๋ก์ ํธ๊ฐ ์ฑ๊ณตํ๊ธธ ๋ฐ๋๊ฒ์! ํ์ดํ
! ๐ชโจ
๐ ์ง๊ธ ๋ฐ๋ก ์์ํด๋ณด์ธ์!
๋น์ ์ ์
๋ฌด ํจ์จ์ 200% ์ฌ๋ ค์ค AI ์๋ํ๊ฐ ๊ธฐ๋ค๋ฆฌ๊ณ ์์ด์!
๊ด๋ จ ํค์๋
๋๊ธ 0
์ง์์ธ์ ์ฒ - ์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
- ์ ์๊ถ ๋ฐ ์์ ๊ถ: ๋ณธ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ๋ ์ AI ๊ธฐ์ ๋ก ์์ฑ๋์์ผ๋ฉฐ, ๋ํ๋ฏผ๊ตญ ์ ์๊ถ๋ฒ ๋ฐ ๊ตญ์ ์ ์๊ถ ํ์ฝ์ ์ํด ๋ณดํธ๋ฉ๋๋ค.
- AI ์์ฑ ์ปจํ ์ธ ์ ๋ฒ์ ์ง์: ๋ณธ AI ์์ฑ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ์ง์ ์ฐฝ์๋ฌผ๋ก ์ธ์ ๋๋ฉฐ, ๊ด๋ จ ๋ฒ๊ท์ ๋ฐ๋ผ ์ ์๊ถ ๋ณดํธ๋ฅผ ๋ฐ์ต๋๋ค.
- ์ฌ์ฉ ์ ํ: ์ฌ๋ฅ๋ท์ ๋ช ์์ ์๋ฉด ๋์ ์์ด ๋ณธ ์ปจํ ์ธ ๋ฅผ ๋ณต์ , ์์ , ๋ฐฐํฌ, ๋๋ ์์ ์ ์ผ๋ก ํ์ฉํ๋ ํ์๋ ์๊ฒฉํ ๊ธ์ง๋ฉ๋๋ค.
- ๋ฐ์ดํฐ ์์ง ๊ธ์ง: ๋ณธ ์ปจํ ์ธ ์ ๋ํ ๋ฌด๋จ ์คํฌ๋ํ, ํฌ๋กค๋ง, ๋ฐ ์๋ํ๋ ๋ฐ์ดํฐ ์์ง์ ๋ฒ์ ์ ์ฌ์ ๋์์ด ๋ฉ๋๋ค.
- AI ํ์ต ์ ํ: ์ฌ๋ฅ๋ท์ AI ์์ฑ ์ปจํ ์ธ ๋ฅผ ํ AI ๋ชจ๋ธ ํ์ต์ ๋ฌด๋จ ์ฌ์ฉํ๋ ํ์๋ ๊ธ์ง๋๋ฉฐ, ์ด๋ ์ง์ ์ฌ์ฐ๊ถ ์นจํด๋ก ๊ฐ์ฃผ๋ฉ๋๋ค.

๋๊ธ ์์ฑ
์ด ๊ธ์ ๋ํ ์ฌ๋ฌ๋ถ์ ์๊ฐ์ ๋ค๋ ค์ฃผ์ธ์
๋ก๊ทธ์ธ์ด ํ์ํฉ๋๋ค
๋๊ธ์ ์์ฑํ๋ ค๋ฉด ๋จผ์ ๋ก๊ทธ์ธํด์ฃผ์ธ์.