프리토타입을 이용하여 사용자 이메일 정보를 수집하려고 한다.

기존에 내가 해본 방법은 java spring boots를 javac으로 만들어 aws ec2에 올리고 h2 db에 저장하는 방식이었는데, 현 상황에서는 이 정보를 수집하기 위해 db가 필요하지도 않고 aws운영 비용도 부담해야하기에 적절하지 않다고 판단했다.
고로 이메일 정도를 저장할 수 있는 다른 가벼운 방법을 찾아보던 중, 스프레드 시트의 확장 프로그램인 app script를 이용해 post 요청만으로 추가할 수 있다는 방법을 알게 되었다.
하지만 현재 기능 구현이 제대로 되지 않는 문제에 봉착했기에 오늘 그 디버깅을 진행해보려고 한다.
우선 아래는 스프레트 시트에 데이터를 추가해주는 app script이다.
function doPost(e) {
try {
// ✅ 명확하게 스프레드시트 ID 설정
const sheet = SpreadsheetApp.openById('~~~~~~~~~').getSheetByName('시트1');
const params = JSON.parse(e.postData.contents);
const email = params.email;
if (!email || !validateEmail(email)) {
throw new Error("유효하지 않은 이메일 형식입니다.");
}
// ✅ 스프레드시트에 데이터 추가
sheet.appendRow([new Date(), email]);
// ✅ 응답 반환
const result = {
status: "success",
email: email
};
return ContentService
.createTextOutput(JSON.stringify(result))
.setMimeType(ContentService.MimeType.JSON);
} catch (error) {
Logger.log(error);
return ContentService
.createTextOutput(JSON.stringify({ status: "error", message: error.message }))
.setMimeType(ContentService.MimeType.JSON);
}
}
// ✅ 이메일 유효성 검사 함수
function validateEmail(email) {
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return regex.test(email);
}
아래는 웹 페이지에서 버튼 이벤트 시 post요청하는 script부분이다
<script>
const fadeInElements = document.querySelectorAll('.fade-in');
const slideInLeftElements = document.querySelectorAll('.slide-in-left');
const slideInRightElements = document.querySelectorAll('.slide-in-right');
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('active');
observer.unobserve(entry.target);
}
});
}, {
threshold: 0.2
});
fadeInElements.forEach(element => {
observer.observe(element);
});
slideInLeftElements.forEach(element => {
observer.observe(element);
});
slideInRightElements.forEach(element => {
observer.observe(element);
});
const submitEmail = async (event) => {
event.preventDefault();
const email = document.getElementById('email').value;
if (!email) {
alert('이메일을 입력해주세요.');
return;
}
try {
const response = await fetch('https://script.google.com/macros/s/~~~~~~~~~~~~/exec', {
method: 'POST',
mode: 'cors', // ✅ CORS 설정 추가
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ email })
});
if (!response.ok) {
throw new Error(`HTTP 오류! 상태 코드: ${response.status}`);
}
const result = await response.json();
if (result.status === "success") {
alert(`이메일이 등록되었습니다: ${result.email}`); // ✅ 템플릿 리터럴 사용 수정
} else {
alert(`등록 실패: ${result.message}`);
}
} catch (error) {
console.error('전송 오류:', error);
alert('서버에 연결할 수 없습니다. 배포 상태 및 URL을 확인해주세요.');
}
};
</script>

현재 문제 사항은 html에서 버튼 누를 시 제대로 요청은 보내지는 듯 하나, 스프레드 시트에 추가가 안된다.
1차적으로 로그를 직접 찍어보려고 한다. 표시한 두 메시지 모두 접근 가능했다.

2차적으로 로그를 찍어보았는데 표시한 두 메시지 모두 접근 불가능했다.

GPT가 제안한 해결 방법은 다음과 같다.
첫번째로 html Script를 수정해보자. 버튼을 await가 아닌 onclick=이벤트로 설정하고 아래와 같이 수정하였다.
const submitEmail = async (event) => {
event.preventDefault();
const email = document.getElementById('email').value;
if (!email) {
alert('이메일을 입력해주세요.');
return;
}
try {
alert("send request");
const response = await fetch('https://script.google.com/macros/s/~~~~~~~~~~~~~/exec', {
method: 'POST',
//mode: 'cors', // ✅ CORS 설정 추가
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ email })
});
alert("get response"); // ✅ 여기까지 오면 응답이 정상적으로 온 상태
if (!response.ok) {
throw new Error(`HTTP 오류! 상태 코드: ${response.status}`);
}
const result = await response.json();
if (result.status === "success") {
alert(`이메일이 등록되었습니다: ${result.email}`); // ✅ 템플릿 리터럴 사용 수정
} else {
alert(`등록 실패: ${result.message}`);
}
} catch (error) {
console.error('전송 오류:', error);
alert('서버에 연결할 수 없습니다. 배포 상태 및 URL을 확인해주세요.');
}
};


까지 도달했음을 알 수 있었다.
다시 GPT에게 자문을 구해보자.
배포 상태를 변경해보았다.


둘 다 여전히 작동이 안된다.
https://3d-yeju.tistory.com/105
를 참고했는데도 똑같다..

수정후도 같다.

구글 시트 API 추가
ajax 로 reqeust를 보내고 헤더 script에 jquery를 추가하였다.
$(document).ready(function() {
$('#contactForm').on('submit', function(event) {
event.preventDefault();
// 입력 값 가져오기
var name = $('#name').val();
var email = $('#email').val();
var message = $('#message').val();
console.log(name, email, message);
$.ajax({
type: "POST",
url: "https://script.google.com/macros/s/~~~~~~~/exec",
data: {
"이름": name,
"이메일": email,
"문의사항": message
},
success: function(response) {
alert('사전예약이 성공적으로 접수되었습니다.');
$('#contactForm')[0].reset(); // 폼 초기화
},
error: function(err) {
alert('오류가 발생했습니다. 다시 시도해주세요.');
console.log(err);
}
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
그리고 추가적으로 구글 애널리틱스 연동하여 클릭율 조회.