TypeScript에서 CAPTCHA 작업 결과 안전하게 처리하기
result.solution을 읽기 전에 result.status를 기준으로 분기하세요. 사용 가능한 솔루션은 ready에만 포함되며, 이 경우에도 요청한 제품에 필요한 필드를 확인해야 합니다. Kasada는 헤더를 반환하고, reCAPTCHA와 TMPT는 용도가 서로 다른 토큰을 반환합니다.
이 페이지의 내용
솔루션을 읽기 전에 상태로 타입 좁히기
입력에는 SDK가 내보내는 TaskRequest를, 응답에는 TaskResult를 사용하세요. 상태로 타입을 좁히면 any나 컴파일러에 무조건 신뢰하라고 지시하는 타입 단언 없이도 TypeScript가 미완료 작업, 실패, 준비 완료를 구분할 수 있습니다.
import { Solvethree, type TaskRequest, type TaskResult } from '@solvethree/sdk';
const client = new Solvethree({ apiKey: process.env.SOLVETHREE_API_KEY! });
const input: TaskRequest = { site: 'accounts.example.com', action: 'login', proxy: process.env.SOLVETHREE_PROXY! };
function inspect(result: TaskResult): void {
switch (result.status) {
case 'pending':
case 'solving':
console.log('Retrieve this task again:', result.id);
return;
case 'failed':
console.error('Failed task:', result.id, result.errorCode);
return;
case 'ready':
// Solution fields depend on the requested product; check optional fields.
if (!result.solution.token || !result.solution.userAgent || !result.solution.secChUa) {
throw new Error('Expected a complete reCAPTCHA solution');
}
console.log('Ready task:', result.id);
// Submit token privately with its browser identity and original proxy.
return;
}
}
inspect(await client.createTask(input, { waitMs: 0 }));
// Save the returned ID and call getTask while pending/solving with a deadline.이 예제는 작업 하나를 생성하고 즉시 반환된 응답을 확인합니다. pending과 solving이면 다시 조회하고, failed이면 처리를 중단하며, ready이면 솔루션 검증 단계로 넘어갑니다. ready 분기를 헬퍼로 분리한다면 매개변수에 내보낸 ReadyTask 타입을 사용하세요. 이렇게 하면 상태 타입이 좁혀지지만, 제품별 솔루션 필드가 모두 필수로 바뀌지는 않습니다.
이 입력은 reCAPTCHA를 요청하므로 가드는 토큰과 브라우저 식별 정보 필드 2개를 모두 확인합니다. 하지만 이 검사로 대상이 토큰을 수락한다고 보장할 수는 없습니다. 예제는 의도적으로 토큰을 출력하지 않습니다.
- Node.js 22+를 사용하고 API 문서에 안내된 공식 SDK tarball 설치 방법을 따르세요. npm 레지스트리에 릴리스가 있다고 가정하지 마세요.
- 서버 환경에
SOLVETHREE_API_KEY와SOLVETHREE_PROXY를 설정하세요.!단언은 런타임에 환경 변수 누락 여부를 검증하지 않습니다. accounts.example.com과login을 사용할 호스트 이름과 액션으로 바꾸세요. 사이트에는 이미 활성 워크스페이스 프로필이 있어야 합니다. 사이트 프로필 설정을 참고하세요.
새 작업이 아니라 저장한 ID로 폴링
이 예제는 폴링을 호출자에게 맡깁니다. 작업 생성은 폴링 루프 밖에서 수행하세요. createTask를 다시 호출하는 것은 첫 번째 작업의 완료 여부를 확인하는 방법이 아닙니다.
- 1.
생성 결과의 ID 저장
반환된 ID가 비어 있지 않은 문자열인지 확인한 뒤 조회에 사용하세요. 성공한 프록시를 선택할 때도 원래 요청이 필요하므로 ID를 원래 요청과 연결해 보관하세요.
- 2.
동일한 작업 조회
상태가
pending또는solving인 동안 로컬 제한 시간을 두고 저장한 ID로getTask를 호출하세요. 각 응답을 처리하기 전에 응답의 ID가 저장한 ID와 일치하는지 확인하세요. ID 일치는 어떤 작업을 처리 중인지를 알려 줄 뿐, 성공 여부를 나타내지는 않습니다. - 3.
최종 결과에서 중단
ready이면 요청한 제품에 필요한 필드를 검증하세요.failed이면errorCode와error를 모두 확인한 뒤 해당 작업의 폴링을 중단하세요. 요청 오류는 별도로 처리하세요. 조회 요청이 실패했다고 해서 작업 자체가 최종 실패한 것은 아닙니다.
ID를 받기 전에 생성 요청 시간이 초과되더라도 작업이 생성되지 않았다고 가정하지 마세요. requestId를 제공했다면 같은 값으로 동일한 요청을 다시 제출해 기존 작업을 복구할 수 있습니다. 입력을 바꾼 채 같은 값을 재사용하면 충돌이 발생하며, 새 값을 생성해도 원래 작업을 복구할 수 없습니다.
ready 결과에도 적절한 제품 핸들러가 필요합니다
원래 요청을 기준으로 핸들러를 선택한 다음, 예상되는 솔루션 필드를 확인하세요. 토큰이 있다는 사실만으로는 reCAPTCHA 응답과 TMPT 쿠키 값을 구분할 수 없습니다.
| 요청한 제품 | 솔루션 값 | 사용 방법 |
|---|---|---|
| reCAPTCHA Enterprise | solution.token | 지정한 호스트 이름과 액션의 reCAPTCHA 토큰으로 제출하세요. |
| KasadaTask | solution.headers | 반환된 헤더를 함께 적용하세요. 이 결과를 토큰으로 취급하지 마세요. |
| TicketmasterTmptTask | solution.token | reCAPTCHA 토큰이 아니라 원시 tmpt 쿠키 값으로 사용하세요. |
독립형 Kasada는 현재 임의의 사이트가 아니라 www.ticketmaster.com의 HTTPS 대상만 지원합니다. 해당 헤더 핸들러는 범용 Kasada 연동 기능이 아닙니다.
각 제품에서는 반환된 userAgent와 secChUa, 그리고 성공한 프록시를 사용해 제출하세요. 프록시 후보를 사용하는 경우 첫 번째 후보가 성공했다고 가정하지 말고 successfulProxy(originalTask, readyResult)를 사용하세요. SDK는 대상을 상대로 솔루션을 대신 적용하지 않으며, ready라고 해서 이후 요청이 수락된다고 보장하지는 않습니다.
출처 및 API 레퍼런스
첫 작업을 실행하세요.
워크스페이스 크레딧 $5로 시작하세요.