리드 수집 폼4분 분량
파일 업로드 없는 견적 요청 폼 만들기
자료를 업로드 대신 공유 링크로 받고, 모든 요청에 기한을 붙이고, 링크가 많은 리드가 스팸으로 분류되지 않게 하는 견적 요청 폼입니다.
Ikiform은 파일 업로드를 422 files_not_supported로 거부하므로, 자료는 url 필드에 공유 폴더 링크로 받으세요. 모든 요청이 같은 형태로 도착하도록 서비스와 예산은 선택형으로 두고, 성공 메시지에서 처리 기간을 약속하세요. 그런 다음 각 요청을 기한과 함께 팀에 보내 약속이 지켜지게 하세요.
견적 요청이 다른 점
견적 요청에는 자료가 따라옵니다. 브리프, 평면도, 부품 스프레드시트, 작년 디자인 같은 것들입니다. 흔한 해답은 파일 입력이지만 여기서는 동작하지 않으며, 이를 피해 설계하기 전에 이유를 알아 둘 만합니다.
파일 업로드는 아직 지원하지 않습니다. 파일이 담긴 POST는 422 files_not_supported를 받습니다. 파일만이 아니라 POST 전체가 거부되므로, 폼이 오류를 보여 주고 입력을 유지하지 않으면 PDF를 첨부한 방문자는 입력한 모든 것을 잃습니다. 공유 링크는 이 문제를 피하고 나름의 장점도 있습니다. 고객이 보낸 뒤에도 파일을 추가할 수 있고, 크기 제한이 없고, 큰 파일이 받은편지함을 차지하지 않습니다.
- 파일 입력에서는 방문자가 brief.pdf를 첨부하고 브라우저가 multipart POST를 보냅니다.
- Ikiform이 422 files_not_supported로 POST 전체를 거부합니다.
- 아무것도 저장되지 않으므로 이메일도 웹훅도 나가지 않습니다.
- 링크 필드에서는 방문자가 공유 폴더 링크를 붙여 넣습니다.
- Ikiform이 유효한 https URL인지 확인하고 요청을 저장합니다.
- 링크가 알림 이메일과 채팅에 도착하고, 팀의 누구나 열 수 있습니다.
필드
견적 요청 템플릿에는 전화번호, 회사, 일정까지 모든 필드가 있습니다. 아래 버전은 이를 줄이고 링크 필드를 추가했습니다. http: 링크나 drive.google.com만 있는 링크를 넣어 url 필드가 어떻게 응답하는지 보세요.
미리보기
Ikiform의 검증기를 브라우저에서 실행합니다. 아무것도 전송되지 않습니다.
files_url은 https_only인 url 필드이므로 drive.google.com/...만 넣으면 https://drive.google.com/...으로 저장되고, http: 링크는 거부됩니다.| 필드 | 이런 형태인 이유 |
|---|---|
files_url | 파일마다 필드 하나가 아니라 폴더 링크 하나. 안의 내용은 고객이 관리하고 나중에 추가할 수 있습니다 |
service | 누가 견적을 낼지 정합니다. 레이블 이름을 바꿔도 값은 라우팅을 위해 유지됩니다 |
budget | 선택이며, 아무것도 보내지 않는 Not sure yet(아직 모름) 선택지가 있습니다. 예산을 필수로 하면 리드를 잃습니다 |
details | 필수, 최소 20자. 견적에는 범위가 필요하고, 여기서 나옵니다 |
폼
일반 HTML입니다. type="url"은 휴대폰에서 알맞은 키보드를 띄우고, 도움말이 폴더 공유 방법을 알려 주므로 첫 링크가 비공개였을 때 한 번 더 주고받을 일을 줄입니다.
<form action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="POST">
<label for="name">Name</label>
<input id="name" name="name" autocomplete="name" required />
<label for="email">Work email</label>
<input id="email" name="email" type="email" autocomplete="email" required />
<label for="service">What do you need?</label>
<select id="service" name="service" required>
<option value="design">Design</option>
<option value="development">Development</option>
<option value="both">Design and development</option>
</select>
<label for="budget">Budget</label>
<select id="budget" name="budget">
<option value="">Not sure yet</option>
<option value="under_5k">Under $5,000</option>
<option value="5k_20k">$5,000 to $20,000</option>
<option value="over_20k">Over $20,000</option>
</select>
<label for="files_url">Link to your files</label>
<input id="files_url" name="files_url" type="url" inputmode="url" placeholder="https://drive.google.com/..." aria-describedby="files-help" />
<p id="files-help">A shared folder with the brief, mockups or specs. Set it so anyone with the link can view.</p>
<label for="details">What should the quote cover?</label>
<textarea id="details" name="details" rows="5" minlength="20" required></textarea>
<input type="hidden" name="_redirect" value="https://example.com/quote/thanks" />
<input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
<button>Request a quote</button>
</form><input type="file">이 있다면 제거하세요. 비어 있으면 건너뜁니다. 파일을 고르면 multipart나 FormData POST는 통째로 실패하고, 일반 urlencoded 폼은 파일 이름만 보냅니다. 어느 쪽이든 파일은 도착하지 않습니다.링크와 스팸 점수
견적 폼은 실제 리드가 일부러 링크를 보내는 유일한 곳인데, 링크는 스팸 신호입니다. 모든 필드를 합쳐 링크가 3개 이상이면 점수에 2가 더해집니다. url 필드는 전체 https:// 링크로 저장되므로 집계에 포함됩니다.
| 요청 내용 | 점수 | 결과 |
|---|---|---|
| 폴더 링크 | 0 | 수신 |
폴더 링크와 details의 링크 두 개 | +2 | 수신 |
| 같은 링크 세 개를 같은 필드로 24시간 안에 다시 보냄 | +2와 +3 | 스팸, 5점 |
세 번째 행은 첫 제출이 실패했다고 생각한 실제 사람입니다. 그래서 폼에는 링크 필드가 세 개가 아니라 하나여야 하고, 성공 상태는 오해의 여지가 없어야 합니다. 매주 Spam 필터를 확인하세요. 스팸 아님으로 표시하면 그때 이메일과 웹훅이 전송됩니다.
모든 요청에 기한 붙이기
성공 메시지는 영업일 이틀 안에 견적을 약속합니다. 이 Cloudflare Worker는 그 약속을 팀이 볼 수 있는 날짜로 바꿉니다. 웹훅을 검증하고, created_at에서 기한을 계산하고, 파일 링크와 함께 요청을 견적 채널에 올립니다.
import { verifyWebhook, WebhookVerificationError } from "@ikiform/sdk/webhooks";
function addWorkingDays(from: Date, days: number) {
const date = new Date(from);
while (days > 0) {
date.setUTCDate(date.getUTCDate() + 1);
const day = date.getUTCDay();
if (day !== 0 && day !== 6) days -= 1;
}
return date.toISOString().slice(0, 10);
}
export default {
async fetch(request: Request, env: { IKIFORM_WEBHOOK_SECRET: string; SLACK_QUOTES_WEBHOOK: string }) {
const payload = await request.text();
let event;
try {
event = await verifyWebhook({ payload, headers: request.headers, secret: env.IKIFORM_WEBHOOK_SECRET });
} catch (error) {
if (error instanceof WebhookVerificationError) return new Response(error.reason, { status: 400 });
throw error;
}
if (event.type !== "submission.created") return new Response(null, { status: 204 });
const quote = event.data.fields;
const due = addWorkingDays(new Date(event.data.created_at), 2);
const lines = [
`Quote due *${due}*: ${quote.service} for ${quote.name} (${quote.budget ?? "budget not given"})`,
quote.files_url ? `Files: ${quote.files_url}` : "No files linked. Ask for them in the first reply.",
`Reply: mailto:${quote.email}`,
];
const response = await fetch(env.SLACK_QUOTES_WEBHOOK, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ text: lines.join("\n") }),
});
if (!response.ok) return new Response(`Slack answered ${response.status}`, { status: 502 });
return new Response(null, { status: 204 });
},
};- 영업일은 UTC 기준 토요일과 일요일을 건너뜁니다. 공휴일을 고려해 견적을 낸다면 추가하세요.
files_url이 없으면 빈 줄 대신 첫 답장에서 파일을 요청하라는 알림을 만듭니다.- Slack이 실패할 때
502로 응답하면 Ikiform이 같은 전달을 재시도하므로 요청이 누락되지 않습니다.
Webhooks에 Worker의 URL을 추가하고, whsec_ 시크릿을 IKIFORM_WEBHOOK_SECRET에 복사하고, Slack URL을 시크릿으로 저장하세요. 수신 웹훅을 만드는 방법은 Slack 가이드에서 다룹니다.
작동 확인하기
- Google Drive나 Dropbox 폴더 링크로 제출하세요. 알림 이메일의 링크를 시크릿 창에서 열어 볼 수 있는지 확인하세요.
http:링크로 제출하세요. POST가422로 거부되고 메시지에files_url이 지목됩니다.- 템플릿에서
type="file"을 검색해 Ikiform으로 POST하는 견적 폼에서 모두 제거하세요. - 견적 채널을 확인하세요. 메시지에 영업일 이틀 뒤의 기한과 파일 링크가 표시됩니다.
- 알림 이메일에서 Reply를 누르세요. 폼에 입력한 주소로 작성됩니다.
주의할 점
- 비공개 링크. 가장 흔한 실패는 소유자만 열 수 있는 링크입니다. 도움말에 공유 방법을 적고, 기다리지 말고 첫 답장에서 접근 권한을 요청하세요.
- 파일은 있는데 폴더가 없는 고객. 첫 이메일에 첨부 파일로 답장하라고 안내하세요. reply-to 덕분에 파일이 팀과의 일반 이메일 스레드에 들어갑니다.
- 긴 범위 설명. 알림 이메일은 값을 최대 500자까지 보여 줍니다.
details전체 텍스트는 대시보드와 웹훅에 있습니다. - 접수 확인 이메일은 없습니다. Ikiform은 폼을 작성한 사람에게 이메일을 보내지 않습니다. 페이지의 메시지가 접수 확인이므로 처리 기간을 구체적으로 적으세요.
질문
아직은 안 됩니다. 파일이 포함된 POST는 422 files_not_supported로 거부됩니다. 대신 공유 드라이브 URL 같은 파일 링크를 요청하세요.
url 필드에 공유 폴더 링크 하나를 요청하고, 도움말에 링크가 있는 누구나 볼 수 있어야 한다고 적으세요. 고객은 요청을 보낸 뒤에도 폴더에 파일을 추가할 수 있습니다.
링크가 3개 이상이면 스팸 점수에 2가 더해지고, 같은 필드를 24시간 안에 다시 보내면 3이 더해져 임계값 5에 닿습니다. 링크 필드를 하나로 유지하고, 요청을 스팸 아님으로 표시해 이메일과 웹훅을 보내세요.
네. required를 끄고, 아직 모름처럼 값이 빈 첫 번째 옵션을 추가하세요. 빈 선택은 아무것도 보내지 않으며, Ikiform은 예산 없이 요청을 저장합니다.
막히는 단계가 있거나 내 상황에 맞는 가이드가 필요하다면 이메일을 보내세요: hello@ikiform.com.