웹훅 (JSON)

각 Google 설문지 응답을 서명된 JSON으로 내 엔드포인트, Zapier, Make, n8n에 보내고 서명을 검증하기

웹훅 규칙은 일치하는 각 응답을 JSON으로 지정한 URL에 POST합니다. CRM, 스프레드시트 도구, 자체 서버, 또는 Zapier, Make, n8n 같은 자동화 플랫폼에 데이터를 보낼 때 쓰세요.

웹훅 규칙 만들기

  1. + 새 규칙을 클릭하고 웹훅을 고릅니다
  2. 시점: 모든 응답을 그대로 두거나 승인 후에만 / 거부될 때를 고르고 승인자를 지정합니다. 일치하는 응답만 보내려면 추가 조건을 넣으세요
  3. 대상: 엔드포인트 URL을 붙여넣습니다 (HTTPS만 가능). 메시지 단계는 없습니다. 규칙은 고정 JSON 페이로드를 보냅니다. URL 아래의 페이로드 보기에서 양식 질문이 담긴 페이로드를 확인하고 복사할 수 있습니다
  4. 규칙 만들기를 클릭한 뒤, 한 번만 표시되는 서명 비밀키를 복사합니다 (아래 참고)

테스트 보내기는 서명된 샘플 페이로드를 엔드포인트로 보내고 돌아온 HTTP 상태를 보여 줍니다. 저장된 URL은 암호화되어 보관되고 가려진 형태로 표시됩니다. 새 URL을 붙여넣으려면 교체를 클릭하세요.

페이로드

각 요청은 POST, Content-Type: application/json이며 본문은 다음과 같습니다:

{
  "version": 1,
  "event": "submitted",
  "form": { "id": "1AbC...", "name": "Workshop sign-up" },
  "response": {
    "id": "a3f1...",
    "submittedAt": "2026-01-31T09:30:00.000Z",
    "respondentEmail": "respondent@example.com",
    "answers": [
      { "questionId": "q1", "title": "Your name", "value": "Ada Lovelace" },
      { "questionId": "q3", "title": "Department", "value": "Ops" }
    ]
  },
  "rule": { "id": "rule id", "name": "Zapier: new lead" }
}
  • event는 submitted, approved, rejected 중 하나이며 X-Skyfield-Event 헤더에도 담깁니다
  • response.respondentEmail은 설문지가 이메일 주소를 수집하지 않는 한 null입니다
  • answers[].value는 항상 문자열이며, 체크박스 답변은 , 로 이어집니다
  • rule.id와 rule.name은 실행된 규칙을 가리킵니다. 규칙에 이름이 없으면 name은 null입니다
  • approved와 rejected일 때는 approval: { "decision": "approved", "decidedBy": "Dana" }가 추가됩니다. decidedBy는 승인자가 승인 페이지에 입력한 이름이며, 없으면 승인자의 이메일, 그것도 없으면 null입니다

위 형태가 유지되는 한 version은 1로 남습니다. 새 필드가 추가될 수는 있지만, 버전을 올리지 않고 필드를 제거하거나 이름을 바꾸지는 않습니다.

서명 검증하기

모든 요청에는 X-Skyfield-Signature 헤더가 있습니다: sha256=<hex>, 즉 규칙의 서명 비밀키를 키로 한 원본 요청 본문의 HMAC-SHA256입니다. 요청을 신뢰하기 전에 검증하세요.

비밀키(whsec_...)는 규칙에 처음 웹훅 URL을 넣고 저장한 직후 한 번만 표시됩니다. 그때 복사하세요. 다시 표시할 수 없습니다. 나중에 URL을 교체해도 비밀키는 그대로입니다. 잃어버렸다면 규칙을 열고 새 서명 비밀키를 클릭한 뒤 저장하세요. 새 비밀키가 한 번 표시되고 이전 비밀키는 즉시 동작을 멈춥니다.

HMAC은 수신한 본문 바이트 그대로에 대해 계산하세요. JSON을 먼저 파싱한 뒤 다시 직렬화하면 공백이 바뀌어 비교가 실패합니다.

Node.js

import { createHmac, timingSafeEqual } from 'node:crypto'

// rawBody: string or Buffer of the request body, before any JSON parsing
function verify(rawBody, header, secret) {
  const expected = 'sha256=' + createHmac('sha256', secret).update(rawBody).digest('hex')
  const a = Buffer.from(expected)
  const b = Buffer.from(header ?? '')
  return a.length === b.length && timingSafeEqual(a, b)
}

// Express example: use express.raw() so req.body is the untouched bytes
app.post('/hook', express.raw({ type: 'application/json' }), (req, res) => {
  if (!verify(req.body, req.get('X-Skyfield-Signature'), process.env.SKYFIELD_SECRET))
    return res.status(401).end()
  const payload = JSON.parse(req.body)
  res.status(200).end()
})

Python

import hmac, hashlib

def verify(raw_body: bytes, header: str, secret: str) -> bool:
    digest = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest("sha256=" + digest, header or "")

# Flask example
@app.post("/hook")
def hook():
    if not verify(request.get_data(), request.headers.get("X-Skyfield-Signature"), SECRET):
        return "", 401
    payload = request.get_json()
    return "", 200

아무 2xx 상태로 응답하세요. 본문은 무시됩니다.

Zapier, Make, n8n

셋 모두 일반 JSON 웹훅을 받습니다:

  • Zapier: 트리거 Webhooks by Zapier, 이벤트 Catch Hook (서명을 직접 검증하려면 Catch Raw Hook). Zapier가 보여 주는 URL을 규칙에 붙여 넣으세요
  • Make: Webhooks 모듈의 Custom webhook을 추가하고 URL을 복사합니다
  • n8n: Webhook 노드를 추가하고 메서드를 POST로 설정한 뒤 프로덕션 URL을 사용합니다

규칙에서 테스트를 보낸 다음 플랫폼에서 response.answers 필드를 매핑하세요. 샘플 페이로드는 예시 답변을 사용하므로 모든 필드가 들어 있습니다.

전송과 한도

  • 엔드포인트는 공개 인터넷에서 HTTPS로 접근할 수 있어야 합니다. 사설 주소와 로컬 주소는 저장할 때 거부됩니다
  • 리디렉션은 따라가지 않습니다. 최종 URL을 사용하세요
  • 엔드포인트는 5초 안에 응답해야 합니다. 시간 초과나 5xx 응답은 한 번 재시도합니다
  • 404 또는 410 응답은 엔드포인트가 없어졌다는 뜻입니다. 규칙이 일시중지되고 이메일이 한 통 갑니다. 규칙에 새 URL을 붙여넣으면 다시 작동합니다
  • 기록 페이지에 각 전송과 엔드포인트가 돌려준 HTTP 상태가 나열됩니다
  • 일시중지되었거나 꺼진 웹훅 규칙은 양식의 다른 규칙을 막지 않습니다

알아 두기

  • 웹훅 규칙은 보내는 시점을 따르므로, 엔드포인트가 모든 제출 대신 승인 결정만 받을 수도 있습니다. 보내는 시점을 참고하세요
  • 검증된 응답만 보내려면 규칙의 보내는 시점을 승인 후에만으로 설정하고 승인자를 고르세요. 승인을 참고하세요. 그러면 페이로드에 approval.decision이 들어갑니다
  • 채널 변경… 으로 웹훅 규칙을 이메일이나 채팅 채널로 옮길 수 있습니다. 새 대상은 거기서 지정하세요. 다시 웹훅으로 바꾸면 URL을 새로 붙여넣어야 합니다
  • 웹훅 규칙에는 유효한 라이선스가 필요합니다. 무료 체험도 포함됩니다. 라이선스가 필요한 기능을 참고하세요