콘텐츠로 이동

OpenClaw 웹훅 설정: 외부 서비스와 5분 만에 연동하기

외부 서비스에서 발생한 이벤트를 내 시스템에 연결하고 싶을 때가 많죠? 매번 수동으로 확인하는 대신, 특정 이벤트가 발생했을 때 자동으로 작업을 시작하게 만들고 싶을 거예요. 이럴 때 Webhooks가 정말 유용해요. Gateway를 통해 외부 트리거를 위한 HTTP 엔드포인트를 노출하는 방법을 알아볼게요.

Gateway는 외부 트리거를 위해 작은 HTTP webhook 엔드포인트를 노출할 수 있어요.

{
hooks: {
enabled: true,
token: "shared-secret",
path: "/hooks",
// Optional: restrict explicit `agentId` routing to this allowlist.
// Omit or include "*" to allow any agent.
// Set [] to deny all explicit `agentId` routing.
allowedAgentIds: ["hooks", "main"],
},
}

참고 사항:

  • hooks.enabled=true일 때는 hooks.token 설정이 필수예요.
  • hooks.path의 기본값은 /hooks예요.

모든 요청에는 hook 토큰이 포함되어야 해요. 헤더를 사용하는 방식을 추천해요:

  • Authorization: Bearer <token> (추천)
  • x-openclaw-token: <token>
  • Query-string 토큰은 거부돼요 (?token=...은 400을 반환해요).
  • hooks.token 소유자는 해당 gateway의 hook ingress 표면에 대해 전체 신뢰를 받는 호출자로 간주해요. Hook 페이로드 내용은 여전히 신뢰할 수 없는 것으로 처리되지만, 이는 별도의 비소유자 인증 경계는 아니에요.

Payload:

{ "text": "System line", "mode": "now" }
  • text 필수 (string): 이벤트에 대한 설명이에요 (예: “New email received”).
  • mode 선택 사항 (now | next-heartbeat): 즉시 heartbeat를 트리거할지(기본값 now), 아니면 다음 주기적 체크까지 기다릴지 결정해요.

효과:

  • main 세션에 시스템 이벤트를 큐에 추가해요.
  • mode=now인 경우, 즉시 heartbeat를 트리거해요.

Payload:

{
"message": "Run this",
"name": "Email",
"agentId": "hooks",
"sessionKey": "hook:email:msg-123",
"wakeMode": "now",
"deliver": true,
"channel": "last",
"to": "+15551234567",
"model": "openai/gpt-5.2-mini",
"thinking": "low",
"timeoutSeconds": 120
}
  • message 필수 (string): 에이전트가 처리할 프롬프트나 메시지예요.
  • name 선택 사항 (string): 세션 요약에서 접두사로 사용되는 hook의 이름이에요 (예: “GitHub”).
  • agentId 선택 사항 (string): 이 hook을 특정 에이전트로 라우팅해요. 알 수 없는 ID는 기본 에이전트로 대체돼요. 설정하면 hook은 확인된 에이전트의 workspace와 설정을 사용하여 실행돼요.
  • sessionKey 선택 사항 (string): 에이전트 세션을 식별하는 데 사용되는 키예요. 기본적으로 hooks.allowRequestSessionKey=true가 아니면 이 필드는 거부돼요.
  • wakeMode 선택 사항 (now | next-heartbeat): 즉시 heartbeat를 트리거할지(기본값 now), 아니면 다음 주기적 체크까지 기다릴지 결정해요.
  • deliver 선택 사항 (boolean): true인 경우 에이전트의 응답이 메시징 채널로 전송돼요. 기본값은 true예요. 단순한 heartbeat 확인 응답은 자동으로 건너뛰어요.
  • channel 선택 사항 (string): 전송할 메시징 채널이에요. last 또는 설정된 채널이나 플러그인 ID(예: discord, matrix, telegram, whatsapp)를 사용하세요. 기본값은 last예요.
  • to 선택 사항 (string): 채널의 수신자 식별자예요 (예: WhatsApp/Signal의 전화번호, Telegram의 채팅 ID, Discord/Slack/Mattermost의 채널 ID, Microsoft Teams의 대화 ID). 기본값은 main 세션의 마지막 수신자예요.
  • model 선택 사항 (string): 모델 오버라이드예요 (예: anthropic/claude-sonnet-4-6 또는 별칭). 제한이 있는 경우 허용된 모델 목록에 있어야 해요.
  • thinking 선택 사항 (string): 사고 수준(thinking level) 오버라이드예요 (예: low, medium, high).
  • timeoutSeconds 선택 사항 (number): 에이전트 실행의 최대 지속 시간(초)이에요.

효과:

  • 격리된 에이전트 턴을 실행해요 (자체 세션 키 사용).
  • 항상 main 세션에 요약을 게시해요.
  • wakeMode=now인 경우, 즉시 heartbeat를 트리거해요.

/hooks/agent 페이로드의 sessionKey 오버라이드는 기본적으로 비활성화되어 있어요.

  • 추천: 고정된 hooks.defaultSessionKey를 설정하고 요청 오버라이드는 꺼두세요.
  • 선택 사항: 필요한 경우에만 요청 오버라이드를 허용하고, 접두사를 제한하세요.

추천 설정:

{
hooks: {
enabled: true,
token: "${OPENCLAW_HOOKS_TOKEN}",
defaultSessionKey: "hook:ingress",
allowRequestSessionKey: false,
allowedSessionKeyPrefixes: ["hook:"],
},
}

호환성 설정 (이전 동작):

{
hooks: {
enabled: true,
token: "${OPENCLAW_HOOKS_TOKEN}",
allowRequestSessionKey: true,
allowedSessionKeyPrefixes: ["hook:"], // strongly recommended
},
}

커스텀 hook 이름은 hooks.mappings를 통해 확인돼요(설정 참조). 매핑을 통해 임의의 페이로드를 wake 또는 agent 액션으로 변환할 수 있으며, 선택적으로 템플릿이나 코드 변환을 사용할 수 있어요.

매핑 옵션 요약:

  • hooks.presets: ["gmail"]은 내장된 Gmail 매핑을 활성화해요.
  • hooks.mappings를 사용하면 설정에서 match, action, 템플릿을 정의할 수 있어요.
  • hooks.transformsDir + transform.module은 커스텀 로직을 위한 JS/TS 모듈을 로드해요.
    • hooks.transformsDir가 설정된 경우, OpenClaw 설정 디렉토리 하위의 transforms 루트 내에 있어야 해요 (일반적으로 ~/.openclaw/hooks/transforms).
    • transform.module은 유효한 transforms 디렉토리 내에서 확인되어야 해요 (경로 탐색/탈출 시도는 거부돼요).
  • 일반적인 수신 엔드포인트(페이로드 기반 라우팅)를 유지하려면 match.source를 사용하세요.
  • TS 변환에는 런타임에 TS 로더(예: bun 또는 tsx)나 미리 컴파일된 .js가 필요해요.
  • 답장을 채팅 화면으로 라우팅하려면 매핑에 deliver: true와 channel/to를 설정하세요 (channel 기본값은 last이며 WhatsApp으로 대체돼요).
  • agentId는 hook을 특정 에이전트로 라우팅해요. 알 수 없는 ID는 기본 에이전트로 대체돼요.
  • hooks.allowedAgentIds는 명시적인 agentId 라우팅을 제한해요. 모든 에이전트를 허용하려면 생략하거나 *를 포함하세요. 명시적인 agentId 라우팅을 거부하려면 []로 설정하세요.
  • hooks.defaultSessionKey는 명시적인 키가 제공되지 않을 때 hook 에이전트 실행을 위한 기본 세션을 설정해요.
  • hooks.allowRequestSessionKey는 /hooks/agent 페이로드가 sessionKey를 설정할 수 있는지 제어해요 (기본값: false).
  • hooks.allowedSessionKeyPrefixes는 요청 페이로드와 매핑에서 명시적인 sessionKey 값을 선택적으로 제한해요.
  • allowUnsafeExternalContent: true는 해당 hook에 대해 외부 콘텐츠 안전 래퍼를 비활성화해요 (위험하므로 신뢰할 수 있는 내부 소스에만 사용하세요).
  • openclaw webhooks gmail setup은 openclaw webhooks gmail run을 위한 hooks.gmail 설정을 작성해요. 전체 Gmail 감시 흐름은 Gmail Pub/Sub을 참조하세요.
  • /hooks/wake의 경우 200
  • /hooks/agent의 경우 200 (비동기 실행 수락됨)
  • 인증 실패 시 401
  • 동일한 클라이언트에서 인증 실패가 반복될 경우 429 (Retry-After 확인)
  • 잘못된 페이로드의 경우 400
  • 페이로드 크기 초과 시 413
Terminal window
curl -X POST http://127.0.0.1:18789/hooks/wake \
-H 'Authorization: Bearer SECRET' \
-H 'Content-Type: application/json' \
-d '{"text":"New email received","mode":"now"}'
Terminal window
curl -X POST http://127.0.0.1:18789/hooks/agent \
-H 'x-openclaw-token: SECRET' \
-H 'Content-Type: application/json' \
-d '{"message":"Summarize inbox","name":"Email","wakeMode":"next-heartbeat"}'

해당 실행에 대한 모델을 오버라이드하려면 에이전트 페이로드(또는 매핑)에 model을 추가하세요:

Terminal window
curl -X POST http://127.0.0.1:18789/hooks/agent \
-H 'x-openclaw-token: SECRET' \
-H 'Content-Type: application/json' \
-d '{"message":"Summarize inbox","name":"Email","model":"openai/gpt-5.2-mini"}'

agents.defaults.models를 강제하는 경우, 오버라이드할 모델이 해당 목록에 포함되어 있는지 확인하세요.

Terminal window
curl -X POST http://127.0.0.1:18789/hooks/gmail \
-H 'Authorization: Bearer SECRET' \
-H 'Content-Type: application/json' \
-d '{"source":"gmail","messages":[{"from":"Ada","subject":"Hello","snippet":"Hi"}]}'
  • Hook 엔드포인트는 loopback, tailnet 또는 신뢰할 수 있는 리버스 프록시 뒤에 두세요.
  • 전용 hook 토큰을 사용하고, gateway 인증 토큰을 재사용하지 마세요.
  • Hook 수신 시 피해 범위를 좁힐 수 있도록 엄격한 tools.profile과 샌드박싱이 적용된 전용 hook 에이전트를 사용하는 것이 좋아요.
  • 무차별 대입 공격을 늦추기 위해 동일한 클라이언트 주소의 반복된 인증 실패는 속도가 제한돼요.
  • 멀티 에이전트 라우팅을 사용하는 경우, hooks.allowedAgentIds를 설정하여 명시적인 agentId 선택을 제한하세요.
  • 호출자가 선택한 세션이 필요한 경우가 아니면 hooks.allowRequestSessionKey=false를 유지하세요.
  • 요청 sessionKey를 활성화하는 경우, hooks.allowedSessionKeyPrefixes를 제한하세요 (예: ["hook:"]).
  • Webhook 로그에 민감한 원시 페이로드가 포함되지 않도록 주의하세요.
  • Hook 페이로드는 신뢰할 수 없는 것으로 간주되며 기본적으로 안전 경계로 래핑돼요. 특정 hook에 대해 이를 비활성화해야 하는 경우, 해당 hook의 매핑에서 allowUnsafeExternalContent: true를 설정하세요 (위험함).

설정 과정에서 도움이 필요하신가요? AI Setup Assistant에게 물어보세요!

OpenClaw

OpenClaw Expert

아직 막혀 있나요?

이 문서에서 답을 못 찾았다면 OpenClaw Expert에게 바로 물어보세요.