Trigger.dev 웹훅 대기: Sume 실행용 waitpoint 토큰
Trigger.dev waitpoint 토큰을 만들고 token.url을 Sume 실행의 webhook_url로 보내면, Sume가 실행 결과를 POST할 때 wait.forToken()이 반환됩니다.

Trigger.dev 태스크가 Sume 웹훅을 기다리게 하려면, wait.createToken()으로 waitpoint 토큰을 만들고 token.url을 실행의 communication.webhook_url로 보낸 뒤 wait.forToken()을 호출하세요. 실행이 완료되거나 실패하면 Sume가 그 URL로 영수증을 한 번 POST하고, 그 JSON 본문이 토큰의 출력이 됩니다.
Sume에는 Trigger.dev 전용 연동이 없으므로, 태스크가 fetch로 API를 직접 호출합니다. Sume 관련 사실은 Format 호출하기 (영문), 실행과 결과 (영문), Run 웹훅 (영문)에서, Trigger.dev 동작은 2026-09-27에 확인한 Trigger.dev 문서에서 가져왔습니다. 웹훅 계약은 Sume Format 실행 수명주기에서 다룹니다.
waitpoint 토큰은 Sume 실행과 어떻게 대응하나요?
토큰 규칙마다 여러분이 시작하는 실행에 미치는 결과가 있습니다.
| Trigger.dev | Sume 쪽 |
|---|---|
wait.createToken({ timeout })은 id와 url이 있는 토큰을 반환합니다. timeout의 기본값은 "10m"입니다. | 실행의 90분 상한을 넘게 설정합니다. |
token.url로 POST하면 토큰이 완료되고, 그 JSON 본문이 출력이 됩니다. | Sume는 실행이 완료되거나 실패할 때 종료 영수증을 한 번 POST합니다. |
wait.forToken()은 { ok, output, error }를 반환하며, 발생할 수 있는 오류는 타임아웃뿐입니다. | 취소되거나 건너뛴 실행은 POST하지 않으므로 그 토큰은 타임아웃됩니다. |
createToken에 같은 idempotencyKey를 다시 쓰면 캐시된 토큰(isCached: true)이 반환됩니다. | 재시도해도 같은 token.url을 받으므로 Sume 요청 본문도 그대로입니다. |
| Trigger.dev Cloud는 몇 초 넘게 기다리는 태스크를 일시 중지합니다. | 영상 실행은 몇 분이 걸립니다. |
태스크는 어떤 모습인가요?
키는 Trigger.dev 환경 변수로 저장하되 만들 때 Secret으로 표시하고, process.env에서 읽으세요. 태스크는 토큰을 만들고, 토큰 URL로 카탈로그 Format 실행을 시작하고, 기다린 다음, 자신의 키로 실행을 읽습니다.
import { task, wait } from "@trigger.dev/sdk";
export const productVideo = task({
id: "product-video",
run: async (payload: { orderId: string; photoUrl: string }) => {
const auth = { Authorization: `Bearer ${process.env.SUME_API_KEY}` };
const token = await wait.createToken({
timeout: "2h", idempotencyKeyTTL: "3h",
idempotencyKey: `sume-${payload.orderId}-v1`,
});
const res = await fetch("https://api.sume.com/v1/formats/sume/sume-product-commercial/runs", {
method: "POST",
headers: { ...auth, "Content-Type": "application/json", "Idempotency-Key": `order-${payload.orderId}-v1` },
body: JSON.stringify({
instruction: "Make a vertical product commercial from the attached photo.",
attachments: [{ type: "input_image", image_url: payload.photoUrl }],
communication: { webhook_url: token.url },
}),
});
const created = await res.json();
if (!res.ok) throw new Error(`Sume ${res.status} ${created.error?.code}`);
const result = await wait.forToken(token); // ok is false only on a timeout
const run = await fetch(`https://api.sume.com/v1/format-runs/${created.data.id}`, { headers: auth });
return { delivered: result.ok, run: (await run.json()).data };
},
});토큰은 얼마나 기다려야 하나요?
기본값인 10분보다 길어야 합니다. 롱폼 호스트 영상은 보통 15~30분이면 끝납니다. Sume는 created_at으로부터 90분이 지난 실행을 failed로 강제 종료하므로, 두 시간 타임아웃이면 스스로 끝나는 모든 실행을 기다릴 수 있습니다. 여러분의 타임아웃은 실행을 취소하지 않습니다. 실행은 계속 진행되며 계속 과금되고, 그래서 태스크는 타임아웃 뒤에도 실행을 읽습니다.
태스크는 토큰의 출력을 믿어도 되나요?
그것만으로는 믿을 수 없습니다. 출력은 POST의 JSON 본문인 반면 Sume의 HMAC 서명은 x-sume-webhook-signature 헤더에 실려 오므로, 태스크는 출력에서 서명을 확인할 수 없습니다. 토큰은 결과를 확인하러 가라는 신호로 보고, 위 코드처럼 여러분의 키로 GET /v1/format-runs/{run_id}를 읽으세요. 그 data가 웹훅에 담겼던 것과 같은 영수증입니다. 이 읽기는 payload: null로 도착하는, 1 MiB를 넘는 영수증도 처리합니다.
재시도할 때 두 번째 유료 실행은 어떻게 피하나요?
Trigger.dev는 태스크가 예외를 던지면 태스크를 재시도하며, 재시도는 토큰과 실행을 다시 만듭니다. 멱등성 키 두 개와 습관 하나가 이를 안전하게 만듭니다.
- Sume
Idempotency-Key: 같은 키와 본문이면 원래 실행과 함께200이 돌아오고 두 번째 청구는 없습니다. - 토큰의
idempotencyKey: 재시도하면 캐시된 토큰과 그 URL을 받으므로 Sume 본문이 정말로 같아집니다. 현재 코드에서는 Sume 키를 확인할 때 비교하는 본문에 웹훅 URL도 포함되므로, 같은 키에 새 URL을 보내면409 idempotency_conflict가 돌아옵니다.idempotencyKeyTTL의 기본값은 1시간이므로 전체 대기 시간보다 길게 설정하세요. .unwrap()을 호출하지 말고result.ok를 확인하세요..unwrap()은 타임아웃이 나면 예외를 던져 태스크를 재시도로 보냅니다.
출처
관련 글
연동 카테고리의 다른 글
- Vercel AI SDK: Sume API 도구 호출로 영상 생성하기
Vercel AI SDK에서는 서버에서 Sume의 POST /v1/videos를 호출하는 tool()로 영상을 생성하세요. 도구는 Job id를 돌려주고, 클립은 폴링으로 받습니다.
- Vercel Cron Jobs: 중복 없이 매일 Sume API 호출하기
Vercel cron job이 라우트에 GET을 보내면 라우트가 날짜 기반 Idempotency-Key로 Sume API를 호출하므로, 중복 호출이 두 번 과금될 수 없습니다.
- Vercel 함수 타임아웃과 영상 생성: 웹훅을 쓰세요
Vercel Function은 기본적으로 300초에 멈추지만 Sume 영상 실행은 몇 분이 걸립니다. webhook_url과 함께 제출하고 바로 반환한 뒤, 서명된 POST를 검증하세요.
- Windsurf MCP 서버: Devin Desktop에 Sume 추가
Windsurf는 이제 Devin Desktop입니다. API 키 헤더로 Sume 호스팅 MCP 서버를 Devin Local 에이전트나 레거시 Cascade 에이전트에 추가하세요.
작성자 Sume