建立 Claude 與 Slack 的對話機器人

要建立一個 Claude 與 Slack 整合的對話機器人,讓使用者可以在 Slack 裡對 Claude 提問並獲得即時回應,我會一步一步帶你完成這個流程。


🧠 整體流程概覽

  1. 建立 Claude API 金鑰(Anthropic)
  2. 建立 Slack App 並設定 Bot 權限
  3. 用 Python / Node.js 撰寫伺服器邏輯(Webhook)
  4. 接收 Slack 訊息 → 發送給 Claude → 將回覆送回 Slack

✅ 1. 申請 Claude API 金鑰

前往 https://console.anthropic.com 註冊帳號 →
進入 Settings > API Keys → 產生 API 金鑰(複製並妥善保存)


✅ 2. 建立 Slack App

➤ Slack App 建立方式:

  1. 前往 https://api.slack.com/apps
  2. 點選 Create New App
    • From scratch
    • 命名為:ClaudeBot
    • 選擇你要安裝的 Workspace
  3. 前往「OAuth & Permissions」,新增下列權限:
    • chat:write(允許 bot 發送訊息)
    • channels:history(讀取頻道訊息)
    • app_mentions:read(讀取 @ 機器人提及)
    • commands(如使用 /claude
  4. 點「Install to Workspace」 → 獲得 Bot Token

✅ 3. 撰寫伺服器端程式碼(Python FastAPI 版本)

建議使用 FastAPI + httpx + uvicorn

📦 安裝套件:

pip install fastapi uvicorn httpx python-dotenv

📁 .env 檔(放在根目錄)

SLACK_BOT_TOKEN=xoxb-xxxxxxxxxxxx
SLACK_SIGNING_SECRET=xxxxxxxxxxxx
CLAUDE_API_KEY=sk-ant-xxxxxxxxxxxx

🧠 main.py(核心程式)

import os
import hmac
import hashlib
import time
import httpx
from fastapi import FastAPI, Request, Header
from dotenv import load_dotenv
from fastapi.responses import JSONResponse

load_dotenv()

app = FastAPI()

SLACK_BOT_TOKEN = os.getenv("SLACK_BOT_TOKEN")
SLACK_SIGNING_SECRET = os.getenv("SLACK_SIGNING_SECRET")
CLAUDE_API_KEY = os.getenv("CLAUDE_API_KEY")
CLAUDE_API_URL = "https://api.anthropic.com/v1/messages"
CLAUDE_MODEL = "claude-3-haiku-20240307"

# 驗證 Slack Request
def verify_slack_signature(req: Request, timestamp, signature):
    body = req._body.decode()
    basestring = f"v0:{timestamp}:{body}".encode()
    computed = 'v0=' + hmac.new(SLACK_SIGNING_SECRET.encode(), basestring, hashlib.sha256).hexdigest()
    return hmac.compare_digest(computed, signature)

@app.post("/slack/events")
async def slack_events(request: Request,
                       x_slack_signature: str = Header(None),
                       x_slack_request_timestamp: str = Header(None)):
    # 驗證 timestamp
    if abs(time.time() - int(x_slack_request_timestamp)) > 60 * 5:
        return JSONResponse(status_code=400, content={"error": "Invalid timestamp"})

    body = await request.body()
    request._body = body

    if not verify_slack_signature(request, x_slack_request_timestamp, x_slack_signature):
        return JSONResponse(status_code=403, content={"error": "Invalid signature"})

    data = await request.json()

    # Slack 事件挑戰驗證
    if data.get("type") == "url_verification":
        return {"challenge": data["challenge"]}

    # 監聽 @ClaudeBot 提及
    if data.get("event", {}).get("type") == "app_mention":
        user_msg = data["event"]["text"]
        channel = data["event"]["channel"]

        reply = await ask_claude(user_msg)

        await send_slack_message(channel, reply)

    return {"ok": True}


async def ask_claude(user_message: str) -> str:
    headers = {
        "x-api-key": CLAUDE_API_KEY,
        "anthropic-version": "2023-06-01",
        "content-type": "application/json"
    }
    payload = {
        "model": CLAUDE_MODEL,
        "max_tokens": 1024,
        "messages": [{"role": "user", "content": user_message}]
    }

    async with httpx.AsyncClient() as client:
        res = await client.post(CLAUDE_API_URL, headers=headers, json=payload)
        if res.status_code == 200:
            result = res.json()
            return result["content"][0]["text"]
        else:
            return f"Claude 錯誤:{res.status_code}"


async def send_slack_message(channel: str, text: str):
    url = "https://slack.com/api/chat.postMessage"
    headers = {
        "Authorization": f"Bearer {SLACK_BOT_TOKEN}",
        "Content-Type": "application/json"
    }
    payload = {
        "channel": channel,
        "text": text
    }
    async with httpx.AsyncClient() as client:
        await client.post(url, headers=headers, json=payload)

▶️ 執行伺服器

uvicorn main:app --reload --port 8000

🔁 4. 將你的伺服器部署並連結 Slack

  1. 使用 ngrok 或 Render/Heroku 部署伺服器
  2. 在 Slack App 的 Event Subscriptions 中:
    • 開啟 Events
    • 輸入你的 URL:https://yourdomain.com/slack/events
    • 訂閱事件:
      • app_mention
      • message.channels(可選)

✅ 測試效果

  1. 進入你的 Slack 測試頻道
  2. 輸入:
    @ClaudeBot 你可以幫我總結這段文章嗎?
    
  3. Claude 回覆就在幾秒內出現 🎉

🧠 延伸功能(選配)

  • 支援 /claude 指令而不是只靠 @mention
  • 增加多輪對話記憶(上下文儲存)
  • 支援 Claude 模型切換(Haiku / Sonnet / Opus)
  • 支援回傳圖片 / 格式化文字

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *