행사 등록

행사 등록5분 분량

행사와 축제를 위한 근무 시간 선택이 있는 자원봉사자 신청 폼

사람들이 근무 시간을 고르고 당일 연락처를 남기는 자원봉사자 신청 폼과, 인원이 부족한 근무 시간을 보여 주고 근무표를 만드는 스크립트.

Preet SutharIkiform 창업자

자원봉사자가 폼 하나에서 가능한 근무 시간을 모두 체크하고 전화번호, 티셔츠 사이즈, 비상 연락처를 적어 Ikiform으로 POST하게 하세요. Ikiform은 각 신청을 저장하고 코디네이터에게 이메일을 보내지만 근무 시간을 채우거나 마감하지는 않으므로, 필요 인원 대비 근무 시간별 자원봉사자를 세고 근무표를 쓰는 짧은 스크립트를 실행하세요. 부족한 근무 시간은 여유 있는 자원봉사자에게 직접 요청해 채우세요.

자원봉사자는 무엇이 다른가

RSVP는 '오시나요?'라는 질문 하나만 합니다. 자원봉사자 신청은 '언제'를 묻고, 그 답은 각 근무 시간에 필요한 인원과 비교할 때만 의미가 있습니다. 오전 7시 설치에는 여섯 명이 필요한데 두 명이 오고, 화창한 오후에는 열 명이 필요한데 열아홉 명이 옵니다. 할 일은 인원 세기가 아니라 빈자리 채우기입니다.

  • 하나의 선택이 아니라 가능한 시간. 사람들은 여러 근무 시간을 맡을 수 있습니다. 무엇이 필요한지 짐작하게 하지 말고, 가능한 근무 시간을 모두 받아서 배정하세요.
  • 당일 연락처. 이메일은 계획용입니다. 당일에는 휴대폰 번호와 자원봉사자별 비상 연락처가 필요합니다.
  • 주문할 것. 티셔츠, 목걸이 명찰, 점심을 사이즈와 수량별로.
  • 나이. 많은 행사는 자원봉사자마다 성인이거나 보호자의 동의가 필요합니다. 어떤 규칙이 적용되는지 소속 단체에 확인하세요. 체크박스는 답을 기록할 뿐 법적 확인은 아닙니다.

SignUpGenius 같은 자원봉사 플랫폼은 슬롯이 차면 닫히는 슬롯 기반 신청을 운영합니다. 슬롯별 강제 제한이 필요하다면 그런 플랫폼을 쓰세요. Ikiform은 폼을 내 사이트에 두고, 깔끔한 명단에서 근무 시간을 손으로 배정해도 괜찮은 주최자에게 맞습니다.

자원봉사자의 가능 시간을 빈자리가 보이는 근무표로 바꾸기신청 폼가능한 모든 근무 시간Ikiform저장, 코디네이터에게 이메일근무표 스크립트근무 시간별 인원 대비 필요인원rota.csv근무 시간별 이름과 전화번호설치: 6명 중 2명여유 인원에게 요청전송API부족자원봉사자의 가능 시간을 빈자리가 보이는 근무표로 바꾸기신청 폼가능한 모든 근무 시간Ikiform저장, 코디네이터에게 이메일근무표 스크립트근무 시간별 인원 대비 필요 인원rota.csv근무 시간별 이름과 전화번호설치: 6명 중2명여유 인원에게 요청전송API부족
  1. 자원봉사자가 신청 폼에서 가능한 근무 시간을 모두 체크하면, 폼이 Ikiform으로 POST합니다.
  2. Ikiform은 각 신청을 저장하고 코디네이터에게 이메일을 보냅니다.
  3. 스크립트가 API로 신청을 읽고, 근무 시간별로 필요 인원 대비 자원봉사자를 셉니다.
  4. 근무 시간마다 이름과 전화번호가 담긴 rota.csv를 씁니다.
  5. 설치 6명 중 2명처럼 부족한 근무 시간이 바로 드러나므로, 다른 곳에서 여유 있는 자원봉사자에게 요청할 수 있습니다.
Ikiform은 가능 시간을 보관합니다. 스크립트가 이를 충원 현황으로 바꾸고, 최종 결정은 코디네이터가 합니다.

폼

사람들이 훑어볼 수 있도록 근무 시간을 요일별로 묶으세요. 체크박스 이름이 shifts[]이므로 하나만 체크해도 목록으로 저장됩니다. 임베드를 지원하는 모든 사이트나 빌더에서 일반 HTML로 작동합니다.

volunteer.html
<form action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post">
  <label>Name <input name="name" autocomplete="name" required></label>
  <label>Email <input name="email" type="email" autocomplete="email" required></label>
  <label>Mobile number for the day <input name="phone" type="tel" autocomplete="tel" placeholder="+44 7700 900123" required></label>

  <fieldset>
    <legend>Shifts you can do</legend>
    <p>Saturday</p>
    <label><input type="checkbox" name="shifts[]" value="sat_setup"> 7:00 to 10:00, setup</label>
    <label><input type="checkbox" name="shifts[]" value="sat_day"> 10:00 to 14:00</label>
    <label><input type="checkbox" name="shifts[]" value="sat_late"> 14:00 to 18:00</label>
    <p>Sunday</p>
    <label><input type="checkbox" name="shifts[]" value="sun_day"> 10:00 to 14:00</label>
    <label><input type="checkbox" name="shifts[]" value="sun_pack"> 14:00 to 17:00, pack-down</label>
  </fieldset>

  <label>Where you'd like to help
    <select name="role">
      <option value="anywhere">Anywhere</option>
      <option value="welcome">Welcome desk</option>
      <option value="food">Food stall</option>
      <option value="stewarding">Stewarding</option>
    </select>
  </label>
  <label>T-shirt size
    <select name="tshirt" required>
      <option value="s">S</option><option value="m" selected>M</option><option value="l">L</option>
      <option value="xl">XL</option><option value="xxl">XXL</option>
    </select>
  </label>
  <label>Emergency contact name and number <input name="emergency_contact" required maxlength="160"></label>
  <label><input type="checkbox" name="adult" required> I'm 18 or over, or a parent or guardian is filling this in with me</label>

  <input type="hidden" name="_redirect" value="https://fair.example/volunteers/thanks">
  <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden>
  <button type="submit">Sign me up</button>
</form>

이 정의를 폼의 Fields 탭에 붙여 넣으세요. 그러면 어느 페이지에서 왔든 서버가 근무 시간이 없는 신청, 전화번호가 아닌 번호, 체크하지 않은 나이 확인란을 거부합니다.

미리보기

Ikiform의 검증기를 브라우저에서 실행합니다. 아무것도 전송되지 않습니다.

근무 변경 사항을 문자로 보내 드립니다. 국가 번호를 포함해 주세요.

가능한 근무 시간
shifts는 min_items: 1인 multi_select입니다. phone은 번호의 형식을 확인하는 phone 필드입니다. adult는 반드시 체크해야 합니다.
필드묻는 이유
phone근무 변경 문자와 당일 연락
shifts배정의 기준이 되는 가능 시간
role선호 사항. 안내 데스크를 원한 사람이 안내 데스크에 배정되도록
tshirt2주 전에 넣는 주문
emergency_contact마케팅이 아니라 응급 처치 팀을 위한 정보
adult자체 created_at을 가진 제출에 기록되는 단체의 나이 규칙
전화번호와 비상 연락처는 직접 신청하지 않는 사람에 관한 개인 정보입니다. 내보낸 파일은 비공개 장소에 보관하고, 근무표는 근무 책임자와만 공유하고, 행사 후에는 제출을 삭제하세요.

근무표를 만들고 빈자리 확인하기

현황이 필요할 때마다 Node와 시크릿 API 키로 실행하세요. 자원봉사자마다 최신 신청을 취해, 각 근무 시간을 충원, 부족, 여유로 출력하고, 근무 시간별 이름과 번호가 담긴 rota.csv를 씁니다.

rota.ts
import { writeFileSync } from "node:fs";
import { createClient } from "@ikiform/sdk";

const NEEDED: Record<string, number> = { sat_setup: 6, sat_day: 10, sat_late: 10, sun_day: 8, sun_pack: 6 };
const ikiform = createClient({ apiKey: process.env.IKIFORM_SECRET_KEY! });
const people = new Map<string, Record<string, unknown>>();

for await (const submission of ikiform.submissions.iterate({ formId: "frm_xxxxxxxxxxxxxxxx", status: "received", limit: 100 })) {
  const email = String(submission.fields.email ?? "").trim().toLowerCase();
  if (email && !people.has(email)) people.set(email, submission.fields);
}

const cell = (value: unknown) => `"${String(value ?? "").replaceAll('"', '""')}"`;
const rows = [["shift", "name", "phone", "role", "tshirt"].join(",")];

for (const [shift, needed] of Object.entries(NEEDED)) {
  const team = [...people.values()].filter((fields) => (fields.shifts as string[] | undefined)?.includes(shift));
  const state = team.length < needed ? `SHORT ${needed - team.length}` : team.length > needed ? "spare" : "ok";
  console.log(`${shift.padEnd(10)} ${team.length}/${needed} ${state}`);
  for (const fields of team) {
    rows.push([shift, fields.name, fields.phone, fields.role, fields.tshirt].map(cell).join(","));
  }
}

writeFileSync("rota.csv", `${rows.join("\n")}\n`);
  • 목록은 최신순으로 오므로, 가능 시간을 바꿔 다시 신청한 자원봉사자는 최신 응답으로 집계됩니다.
  • 한 사람이 체크한 모든 근무 시간 아래에 나타납니다. 이것은 가능 시간입니다. CSV에서 배정으로 줄이고, 각자에게 최종 근무 시간을 알려 주세요.
  • 이름에 들어간 쉼표와 따옴표는 이스케이프되므로, CSV가 어떤 스프레드시트에서든 깔끔하게 열립니다.

코드 없이 빠르게 보려면 Submissions에서 CSV를 내보내고 sat_setup 같은 근무 시간 값으로 shifts 열을 필터링하세요. 내보낸 파일에서 다중 선택 값은 한 셀에 합쳐져 있습니다.

가능 시간에서 배정으로

  1. 2주 전에 근무표를 실행하고 tshirt 개수로 티셔츠를 주문하세요.
  2. 부족한 근무 시간마다, 여유가 있으면서 그 근무 시간도 체크한 자원봉사자에게 메시지를 보내세요. 이미 가능하다고 한 사람들입니다.
  3. 이메일이나 메신저 도구로 자원봉사자마다 최종 근무 시간을 보내세요. 알림 이메일의 Reply는 바로 그 사람에게 갑니다.
  4. 전날, 근무 책임자용으로 전화번호가 들어간 근무표를 인쇄하세요.

Ikiform은 폼을 작성한 사람에게 이메일을 보내지 않습니다. 알림 이메일은 여러분과 팀에게만 가므로 자동 응답, 확인 이메일, 더블 옵트인이 없습니다. 이런 이메일은 웹훅으로 트리거해 이메일 도구에서 보내세요. 자원봉사자는 무엇을 신청했는지 잊어버리므로, 최종 근무표는 일주일 전과 전날 저녁에 한 번씩 직접 보내세요.

팀이 이미 대화하는 곳에서 신청 소식을 받으려면 웹훅을 Slack이나 Discord로 보내세요. 그러면 코디네이터가 부족한 근무 시간이 채워지는 것을 실시간으로 볼 수 있습니다.

모집하기 전에 확인하기

  1. 폼의 Allowed domains에 사이트 도메인을 추가하고, 개발하는 동안에는 localhost도 추가하세요. 비워 두면 어디서든 POST를 받습니다.
  2. 근무 시간 하나를 체크해 신청해 보세요. 대시보드에서 shifts는 값이 하나인 목록입니다.
  3. 근무 시간 없이, 또는 나이 확인란을 체크하지 않고 신청해 보세요. 브라우저가 막고, 직접 만든 POST는 422를 받습니다.
  4. 알림 수신자 각각의 받은편지함을 확인하세요. 각자 필드가 담긴 이메일을 받고, 폼에 email 필드가 있으면 Reply는 제출자에게 갑니다.
  5. 근무표 스크립트를 실행하세요. 테스트 신청은 해당 근무 시간 아래에 나오고, 나머지 근무 시간은 모두 부족으로 표시됩니다.
  6. 스프레드시트에서 rota.csv를 열고 전화번호 열을 확인하세요.

주의할 점

문제해결 방법
근무 시간 하나가 목록이 아니라 텍스트로 저장됩니다체크박스 이름이 [] 없이 shifts이고 정의된 필드가 없습니다. 이름을 shifts[]로 바꾸거나 shifts를 multi_select로 정의하세요.
phone에서 422번호가 전화번호처럼 보이지 않습니다. 정의에서처럼 도움말 텍스트에서 국가 번호를 요청하세요.
근무표에 자원봉사자가 두 번 나옵니다서로 다른 이메일 두 개로 신청했습니다. 손으로 합치세요. 스크립트는 이메일을 기준으로 합니다.
422 validation_failedPOST가 폼의 필드 정의와 맞지 않습니다. error.fields에 각 필드와 이유가 나옵니다. 입력의 name을 필드 ID와 맞추세요.
429 rate_limited한 방문자가 폼의 레이트 리밋보다 많이 보냈습니다. Standard는 방문자당 분당 5회를 허용합니다. Retry-After만큼 기다리거나, 공유 IP 하나에서 POST하는 폼이라면 Relaxed나 Custom을 고르세요.

질문

막히는 단계가 있거나 내 상황에 맞는 가이드가 필요하다면 이메일을 보내세요: hello@ikiform.com.