시작하기 전에 준비할 것
- 1구글 계정 하나 Gmail 주소가 있으면 됩니다. 무료 계정으로 다 됩니다.
- 2웹 브라우저 크롬을 권장합니다. 이 가이드의 모든 화면이 브라우저 안에서 일어납니다.
- 3설치는 없습니다 내려받거나 깔 것이 없습니다. 구글 스프레드시트만 열면 됩니다.
- 4코드 지식은 필요 없습니다 코드 두 개를 이 페이지에서 복사해 붙여넣기만 합니다.
스프레드시트 만들고 제목 줄 넣기
먼저 신청이 쌓일 표를 만듭니다. 브라우저 주소창에 sheets.new를 치고 Enter를 누릅니다. 빈 구글 스프레드시트가 새로 열립니다.
맨 윗줄(1행)에 제목 여섯 칸을 넣습니다. A1 칸을 누르고 아래 한 줄을 복사해 붙여넣으면, 여섯 칸에 한 번에 나뉘어 들어갑니다.
접수시각 이름 연락처 인원 희망일 메모이 표가 신청을 담을 곳입니다. 방문자가 폼을 낼 때마다 2행부터 한 줄씩 아래로 쌓입니다. 접수시각은 자동으로 채워집니다.
| 행 | 접수시각 | 이름 | 연락처 | 인원 | 희망일 | 메모 |
|---|---|---|---|---|---|---|
| 2 | 2026-08-22 14:03 | 김민수 | 010-2345-6789 | 2 | 2026-09-05 | 주차 되나요? |
| 3 | 2026-08-22 14:07 | 이서연 | 010-9876-5432 | 1 | 2026-09-05 |
스프레드시트 1행에 여섯 칸 제목(접수시각 … 메모)이 들어 있습니다.
앱스스크립트 편집기 열기
이 시트를 조종할 코드를 넣을 곳을 엽니다. 위쪽 메뉴에서 확장 프로그램을 누르고 Apps Script를 고릅니다.
새 탭이 하나 뜹니다. 이것이 코드를 넣는 편집기입니다. 왼쪽에 Code.gs라는 파일이 있고, 가운데 코드 칸에 기본 코드(function myFunction() { })가 들어 있습니다.
Code.gs가 보입니다.새 탭에 편집기가 떴고, 왼쪽에 Code.gs 파일이 보입니다.
서버 코드 붙여넣기
가운데 코드 칸의 기본 코드를 모두 지웁니다. 코드 칸을 한 번 누르고 Ctrl + A(맥은 ⌘ + A)로 전부 선택한 뒤 Delete로 지웁니다.
그 자리에 아래 코드를 붙여넣습니다. 오른쪽 복사 버튼을 누른 다음, 빈 칸에서 Ctrl + V로 붙입니다. 코드는 읽지 않아도 됩니다.
Code.gs 전체 코드 읽지 않아도 됩니다. 오른쪽 복사만 누르세요.
// 신청 접수 웹앱 - 서버 코드
// doGet: 방문자에게 신청 폼(Index.html)을 보여 준다.
// submit: 폼에서 보낸 내용을 스프레드시트 첫 시트에 한 줄로 넣고, 접수번호를 돌려준다.
// 이 스크립트는 스프레드시트에 딸려 있으므로(확장 프로그램 > Apps Script), 그 시트를 바로 조종한다.
function doGet() {
return HtmlService.createHtmlOutputFromFile('Index')
.setTitle('신청 접수')
.addMetaTag('viewport', 'width=device-width, initial-scale=1');
}
function submit(data) {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
var stamp = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), 'yyyy-MM-dd HH:mm');
sheet.appendRow([
stamp,
data.name,
data.phone,
data.count,
data.date,
data.memo
]);
return sheet.getLastRow() - 1; // 1행은 제목 줄이므로 빼면 접수번호가 된다
}이 코드가 하는 일은 두 가지입니다. 방문자에게 폼을 보여 주고(doGet), 방문자가 낸 신청을 시트 맨 아래에 한 줄로 넣습니다(submit). 고칠 곳은 없습니다.
function doGet()가 보이면 제대로 들어간 것입니다.Code.gs 코드 칸에 코드가 가득 차 있고, 맨 위에 function doGet()가 보입니다.
폼 화면 파일 추가하기
방문자가 볼 폼 화면을 담을 파일을 하나 더 만듭니다. 왼쪽 파일 옆의 +를 누르고 HTML을 고릅니다.
파일 이름을 묻습니다. Index라고 정확히 적습니다(대문자 I, 확장자 .html은 저절로 붙습니다).
Index입니다. 코드가 Index라는 파일을 찾아 폼을 띄웁니다. 이름이 다르면 7단계에서 흰 화면이나 오류가 뜹니다.새로 생긴 Index.html의 기본 내용을 Ctrl + A, Delete로 모두 지우고, 아래 코드를 붙여넣습니다.
Index.html 전체 코드 읽지 않아도 됩니다. 오른쪽 복사만 누르세요.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<base target="_top">
<style>
:root{ --accent:#0f9d58; --ink:#1b2030; --muted:#5b6472; --line:#e2e5ec; --bg:#f5f7f9; }
*{box-sizing:border-box}
body{ margin:0; background:var(--bg); color:var(--ink); line-height:1.6; padding:24px 16px;
font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Malgun Gothic",system-ui,sans-serif; }
.card{ max-width:440px; margin:0 auto; background:#fff; border:1px solid var(--line);
border-radius:16px; padding:28px 24px; box-shadow:0 8px 30px rgba(20,26,45,.08); }
h1{ font-size:22px; margin:0 0 6px; }
p.sub{ margin:0 0 22px; color:var(--muted); font-size:14.5px; }
label{ display:block; font-weight:700; font-size:14px; margin:14px 0 6px; }
input,textarea{ width:100%; padding:11px 13px; border:1px solid var(--line); border-radius:10px;
font-size:15px; font-family:inherit; background:#fff; color:var(--ink); }
input:focus,textarea:focus{ outline:none; border-color:var(--accent); }
textarea{ min-height:72px; resize:vertical; }
button{ width:100%; margin-top:22px; padding:14px; border:0; border-radius:10px;
background:var(--accent); color:#fff; font-size:16px; font-weight:700; cursor:pointer; }
button:disabled{ opacity:.6; cursor:default; }
.done{ text-align:center; padding:20px 0; }
.done .no{ display:inline-block; margin-top:10px; font-size:15px; background:#e7f4ee;
color:var(--accent); border-radius:999px; padding:8px 18px; font-weight:700; }
.err{ color:#c0392b; font-size:14px; margin-top:12px; text-align:center; display:none; }
</style>
</head>
<body>
<div class="card">
<div id="form-area">
<h1>신청 접수</h1>
<p class="sub">아래 내용을 채워 신청해 주세요.</p>
<label>이름</label>
<input id="name" type="text" placeholder="홍길동">
<label>연락처</label>
<input id="phone" type="tel" placeholder="010-0000-0000">
<label>인원</label>
<input id="count" type="number" min="1" value="1">
<label>희망일</label>
<input id="date" type="date">
<label>메모 (선택)</label>
<textarea id="memo" placeholder="궁금한 점이나 요청을 적어 주세요."></textarea>
<button id="btn" type="button" onclick="send()">신청하기</button>
<div class="err" id="err">이름과 연락처를 확인해 주세요.</div>
</div>
<div class="done" id="done-area" style="display:none">
<h1>접수되었습니다</h1>
<p class="sub">신청이 정상적으로 접수되었습니다.</p>
<div class="no">접수번호 <span id="rno"></span></div>
</div>
</div>
<script>
function send(){
var name = document.getElementById('name').value.trim();
var phone = document.getElementById('phone').value.trim();
var err = document.getElementById('err');
if(!name || !phone){ err.textContent = '이름과 연락처를 확인해 주세요.'; err.style.display = 'block'; return; }
err.style.display = 'none';
var btn = document.getElementById('btn');
btn.disabled = true; btn.textContent = '접수 중...';
var data = {
name: name,
phone: phone,
count: document.getElementById('count').value,
date: document.getElementById('date').value,
memo: document.getElementById('memo').value.trim()
};
google.script.run
.withSuccessHandler(function(no){
document.getElementById('form-area').style.display = 'none';
document.getElementById('rno').textContent = no;
document.getElementById('done-area').style.display = 'block';
})
.withFailureHandler(function(e){
btn.disabled = false; btn.textContent = '신청하기';
err.textContent = '잠시 후 다시 시도해 주세요.'; err.style.display = 'block';
})
.submit(data);
}
</script>
</body>
</html>
Code.gs와 Index.html 두 개가 보이면 됩니다.위쪽 저장 아이콘(디스크 모양)을 누르거나 Ctrl + S로 저장합니다.
왼쪽 파일 목록에 Code.gs와 Index.html 두 개가 있고, 저장했습니다.
웹앱으로 배포하기
이제 이 코드를 누구나 여는 웹 주소로 내보냅니다. 편집기 오른쪽 위 배포 버튼을 누르고 새 배포를 고릅니다.
창이 뜹니다. 왼쪽 위 톱니바퀴(유형 선택)를 눌러 웹 앱을 고릅니다. 그리고 아래 두 칸을 이렇게 맞춥니다.
- 실행 계정: 나 (내 계정)
- 액세스 권한이 있는 사용자: 모든 사용자
유형이 웹 앱, 액세스 권한이 모든 사용자인 상태에서 배포를 눌렀습니다.
권한 승인하기
처음 배포할 때 한 번, 구글이 "이 스크립트가 네 시트에 접근해도 되냐"고 묻습니다. 액세스 승인을 누릅니다. 구글 계정이 여러 개면 뜬 창에서 내 계정을 고릅니다.
다음에 "Google hasn't verified this app"(구글에서 확인하지 않은 앱)이라는 경고 화면이 뜹니다. 놀라지 않아도 됩니다. 왼쪽 아래 고급(Advanced)을 누르고, 아래에 나타난 (안전하지 않은 페이지)로 이동(Go to ... unsafe)을 누릅니다.
다음 화면에서 이 앱이 내 스프레드시트에 접근한다는 안내가 나옵니다. 아래 계속(Continue)을 누르면 승인이 끝납니다.
승인하면 배포 완료 화면이 뜨고, 가운데에 웹 앱 URL이 보입니다. 그 아래 복사를 눌러 주소를 복사해 둡니다.
https://script.google.com/...로 시작하는 웹 앱 URL이 나왔고, 복사했습니다.
웹앱 열어서 신청해 보기
복사한 URL을 새 탭 주소창에 붙여넣고 Enter를 누릅니다. 방금 만든 신청 폼이 뜹니다. 이름, 연락처, 인원, 희망일, 메모를 채우고 신청하기를 누릅니다.
잠시 뒤 화면이 바뀌며 "접수되었습니다"와 접수번호가 뜹니다. 첫 신청은 1번입니다.
화면에 "접수되었습니다"와 접수번호가 보입니다.
스프레드시트에 쌓였는지 확인하기
1단계에서 만든 스프레드시트 탭으로 돌아옵니다. 방금 낸 신청이 2행에 새 줄로 들어와 있습니다. 접수시각은 자동으로 채워졌습니다.
자주 막히는 곳
웹앱 주소를 열었더니 흰 화면이나 오류가 떠요
대개 HTML 파일 이름이 Index가 아닙니다. 코드는 Index라는 파일을 찾아 폼을 띄웁니다. 왼쪽 파일 목록에서 이름이 정확히 Index(대문자 I)인지 봅니다. 다르면 그 파일 이름 위에 마우스를 올려 점 세 개 > 이름 바꾸기로 Index로 바꾸고, 다시 저장한 뒤 배포합니다.
코드를 고쳤는데 웹앱에 반영이 안 돼요
배포는 그때의 코드를 사진처럼 찍어 둡니다. 고친 뒤에는 배포 > 배포 관리로 들어가 오른쪽 위 연필(수정)을 누르고, 버전을 새 버전으로 바꿔 다시 배포합니다. 이렇게 하면 URL이 그대로 유지됩니다. "새 배포"로 또 만들면 주소가 새로 생기니, 이미 남에게 준 주소를 살리려면 꼭 "배포 관리 > 수정"을 씁니다.
"확인되지 않은 앱"(Google hasn't verified this app)이라는 무서운 화면이 떠요
정상입니다. 내가 직접 만든 개인용 앱이라 구글 심사를 안 거쳐 뜨는 경고입니다. 화면이 영어로 떠도 고급(Advanced) > (안전하지 않은 페이지)로 이동(Go to ... unsafe) > 계속(Continue) 순서로 넘어가면 됩니다. 이 화면은 앱을 만든 나에게만, 그것도 처음 한 번만 뜹니다. 내가 URL을 보내 준 사람에게는 이 화면이 뜨지 않습니다(실행이 내 계정으로 되기 때문입니다).
신청한 사람도 내 신청 목록을 볼 수 있나요?
아니요. 방문자는 폼 화면만 봅니다. 신청이 쌓이는 스프레드시트는 그 파일을 가진 나만 봅니다. 방문자에게는 시트 주소가 노출되지 않습니다.
접수시각이 이상한 시간으로 찍혀요
스프레드시트의 시간대가 서울이 아닐 수 있습니다. 스프레드시트에서 파일 > 설정을 열고 시간대를 (GMT+09:00) 서울로 바꾼 뒤, 앱스스크립트를 다시 저장하고 배포합니다.
윈도우·맥 어디서든
이 가이드는 전부 브라우저 안에서 일어납니다. 윈도우든 맥이든 화면과 순서가 같습니다. 저장 단축키만 다릅니다. 윈도우는 Ctrl + S, 맥은 ⌘ + S입니다.
이제 원하는 형태로 바꾸기
여기까지 왔다면 웹앱을 만드는 흐름을 손에 익힌 것입니다. 이제 이 틀로 원하는 것을 만듭니다. 폼 항목을 바꾸려면 세 곳을 같이 맞춥니다. Index.html의 입력칸, 시트 1행 제목, Code.gs의 저장 순서입니다. 예를 들어 예약이면 날짜와 시간 칸을, 설문이면 선택지 칸을, 주문이면 품목과 수량 칸을 넣습니다.
신청이 들어올 때 나에게 메일 알림이 오게 하려면 submit 함수 끝에 MailApp.sendEmail 한 줄을 더합니다. 만드는 방법이 막히면, 지금까지처럼 AI에게 "이 코드에 이런 항목을 더해 줘"라고 물어 받은 코드를 같은 자리에 붙이면 됩니다. 방법은 바뀌지 않습니다. 바꾸는 것은 항목뿐입니다.