👋 소개: 왜 이런 짓을 시작했나요?
안녕하세요! 허세임입니다.
지난 3년간 운영해 온 구글 폼만 수십 개가 넘습니다. 강의 신청, 강의 후기 등등... 그런데 가장 큰 문제는 이 소중한 고객 데이터가 구글 드라이브 구석구석에 '파편화(Fragmentation)'되어 있다는 점이었습니다.
문제 1: 어떤 폼은 시트와 연결돼 있지만, 어떤 폼은 시트 없이 응답만 쌓여있음 (일명 '고아 폼').
문제 2: A라는 고객이 3년 전 이벤트에도 참여하고, 어제 문의도 남겼는데, 이 두 사람이 동일 인물인지 알 방법이 없음.
문제 3: 고객들이 주관식으로 정성껏 남겨준 니즈(Needs)와 불만 사항들이 엑셀 텍스트로만 남아서 활용되지 못하고 썩고 있음.
그래서 결심했습니다. "이 흩어진 조각들을 하나로 모으자!"
단순한 엑셀 취합이 아니라, 살아있는 CRM 데이터베이스를 구축하는 '고객디비 조각모음' 프로젝트의 기록을 공유합니다.
🧠 설계 전략: 무작정 코딩하기 전에 (가장 중요!)
개발에 들어가기 앞서, "비용은 줄이고, 데이터 퀄리티는 높이기 위해" 4가지 핵심 원칙을 세웠습니다. 이 부분이 저의 노하우입니다.
0. "그냥 쌓는 건 창고, 써먹어야 무기고" (CRM DB 설계)
코드를 짜기 전에 가장 먼저 한 일은 "어떤 데이터를 남길 것인가?"를 정의하는 것이었습니다.
단순히 엑셀에 데이터를 쌓아두는 건 '창고'일 뿐입니다. 마케터가 필요할 때 바로 꺼내 쓸 수 있는 '무기고'를 만들기 위해, 고객DB의 각 열(Column) 하나하나에 CRM 마케팅 목적을 심어두었습니다.
이메일 (Unique Key):
목적: 중복 제거의 기준입니다. 구글 폼은 익명성이 강해서 닉네임이나 전화번호는 바뀔 수 있지만, 이메일은 잘 안 바뀝니다. 3년 동안 5번 응답한 고객 데이터를 5줄이 아닌 '1줄의 깊이 있는 히스토리'로 합치기 위함입니다.
응답수 (Loyalty Score):
목적: 우리 브랜드의 '찐팬' 식별기입니다. 한 번 스쳐 지나간 사람과, 매번 이벤트에 참여하는 사람은 다르게 대우해야죠. 이 숫자가 높은 분들은 따로 관리해서 신규 상품 런칭 시 가장 먼저 알립니다.
처음 & 마지막 활동일 (Customer Lifecycle):
목적: 고객의 수명주기를 파악합니다.
처음: "가입 1주년 축하" 같은 기념일 마케팅 용도.마지막: 마지막 응답일로부터 6개월이 지났다면? 이탈 위험군(Churn Risk)입니다. "잘 지내시나요?" 메일을 보내 잠든 고객을 깨우는 용도입니다.
관심사 (Hyper-Segmentation):
목적: 초개인화 마케팅의 핵심입니다. 모든 사람에게 똑같은 뉴스레터를 보내면 스팸 취급받습니다. Gemini가 분석해 준 "n8n" 태그가 있는 사람에게만 [n8n 세미나]를, "클로드코드" 태그가 있는 사람에게만 [바이브코딩 클래스] 정보를 보내 오픈율을 극대화합니다.
그리고 이 고객DB를 만들기 까지 자동화를 위한 시트 3장
1. "Human-in-the-loop" (수집 여부는 내가 정한다)
처음엔 모든 폼을 다 분석하게 할까 했습니다. 하지만 '오늘 점심 메뉴 조사' 같은 의미 없는 폼까지 Gemini API를 태우면 돈 낭비, 시간 낭비잖아요?
그래서 수집여부라는 열을 만들고 기본값은 비워뒀습니다.
스크립트가 리스트를 쫙 뽑아오면, 제가 눈으로 보고 "이건 분석 가치가 있다" 싶은 것만
1을 입력합니다.스크립트는 오직
1이 적힌 시트만 들어가서 데이터를 퍼옵니다. 자동화 속에 수동 검수를 딱 한 스푼 넣어서 효율을 잡았습니다.
2. "서술형(Paragraph)" 유무로 가치 판단
단답형이나 객관식만 있 는 폼은 굳이 AI가 분석할 필요가 없습니다.
스크립트가 폼을 1차로 훑을 때, 장문형(주관식) 질문이 포함되어 있는지 미리 파악해서 주관식여부 열에 자동으로 체크하게 했습니다. "주관식이 있다? = 고객의 진짜 속마음이 들어있다"는 뜻이니, 우선순위 판단에 큰 도움이 됩니다.
3. 관심사 키워드는 '별도 시트'로 통제
Gemini에게 "이 사람 관심사 뽑아줘"라고만 하면, 같은 뜻인데도 '살빼기', '체중감량', '다이어트'처럼 제각각인 태그를 뱉어냅니다. 이러면 나중에 필터링이 안 됩니다.
그래서 '관심사' 시트를 따로 만들고 우리 비즈니스에 중요한 표준 키워드(Standard Keywords)를 미리 정의했습니다.
Gemini에게 "다른 말 쓰지 말고, 꼭 이 리스트 안에 있는 단어로만 분류해!"라고 시키니 데이터가 아주 깔끔해졌습니다.
4. '고아 폼' 구출 작전
가장 골치 아픈 게 "응답은 받았는데 시트 연결을 안 해둔 폼"입니다. 이건 드라이브에서 '스프레드시트'만 검색하면 절대 안 나옵니다.
그래서 스크립트가 '구글 폼' 파일 자체를 전수 조사해서, 연결된 시트가 없으면 강제로 새 시트를 만들고 연결한 뒤 가져오도록 설계했습니다. 덕분에 죽어있던 데이터까지 살려냈습니다.
🛠️ 진행 방법: 도구와 코드
사용 도구
Google Apps Script (GAS): 전체 오케스트레이션
Gemini 2.5 Pro (API): 비정형 데이터 분석 & 헤더 매핑
Google Sheets와 Forms: DB 저장소
Gemini 3: 바이브코딩
Step 1. 흩어진 조각 모으기 (Listing)
먼저 3년 치 드라이브를 뒤져서 '고객조각'시트에 리스트를 만듭니다. 이때 폼과 시트를 크로스 체크해서 누락을 방지합니다.
모든 폼과 시트를 다 불러 올 때, 주관식, 서술형 문항이 있었는지도 파악하여 주관식 여부를 표시해주었습니다. 다음단계의 관심사 조사를 위해!
이제 저의 3년치 구글폼 중에서, 고객DB에 넣을 폼만 수집하도록 수집여부 열에 체크를 해 주었습니다.
네, 맞습니다!