ReWords.AI API

웹훅

편집이 끝나면 서명된 ReWords.AI 웹훅을 받고, Node.js나 Python으로 X-Rewords-Signature HMAC를 검증합니다.

POST /edits에 callback_url을 넘기세요. 작업이 succeeded 또는 failed가 되면 GET /edits/{id}에서 받는 것과 같은 JSON을 그 URL로 POST합니다.

  • callback_url은 https URL이어야 합니다. 쿼리 문자열은 유지되므로 https://example.com/hooks/rewords?order=1234처럼 자체 참조값을 붙일 수 있습니다.
  • 받았음을 알리려면 10초 안에 아무 2xx 상태로 응답하세요. 그 밖의 모든 경우(다른 상태, 타임아웃, 연결 오류)는 실패로 봅니다.
  • 전송에 실패하면 이전 시도로부터 1분, 5분, 30분 뒤에 재시도하므로 마지막 재시도는 첫 시도로부터 약 36분 뒤입니다. 그 뒤에는 멈추며, GET /edits/{id}로는 여전히 결과를 받을 수 있습니다.
  • 재시도마다 같은 바이트와 같은 서명을 보냅니다. 재시도 때문에 같은 작업을 여러 번 받을 수 있으니, 편집 id로 이미 처리한 것은 무시하세요.
  • 모든 전송에는 서명이 붙습니다: X-Rewords-Signature: sha256=<16진수 64자>. 웹훅 시크릿으로 원본 요청 본문을 HMAC-SHA256한 값입니다. HMAC 키로는 whsec_ 접두사를 포함한 시크릿 문자열 전체를 쓰세요.

웹훅 시크릿

웹훅 시크릿은 계정마다 하나이며 모든 키가 공유합니다. API 키 페이지에서 확인할 수 있습니다. 그곳에서 재설정할 수도 있지만 이전 시크릿은 즉시 작동을 멈추므로 재설정한 직후 수신 측을 업데이트하세요.

서명 검증

검증에 실패하면 401로 요청을 거절하고 처리하지 마세요. 다시 보내도 잘못된 서명은 고쳐지지 않습니다.

Node.js
import crypto from 'node:crypto';

export function verify(rawBody, header, secret) {
  if (typeof header !== 'string') return false;
  const expected = Buffer.from('sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex'));
  const received = Buffer.from(header);
  return received.length === expected.length && crypto.timingSafeEqual(received, expected);
}
Python 3.8+
import hashlib, hmac
from typing import Optional

def verify(raw_body: bytes, header: Optional[str], secret: str) -> bool:
    if not header:
        return False
    expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(header.encode(), expected.encode())

JSON을 파싱하기 전에 원본 바이트로 검증하세요. 다시 직렬화하면 서명이 달라집니다. 예를 들어 Express에서는 express.raw({ type: 'application/json' })로 본문을 읽습니다.

이 페이지의 내용