UTM 생성기 구축 과정 | 3시간 만에 만든 URL 빌드·쇼트닝·관리 자동화 워크플로우

UTM 생성기 구축 과정 | 3시간 만에 만든 URL 빌드·쇼트닝·관리 자동화 워크플로우

그간 앱을 출시하기까지의 과정을 회고해 왔는데, 잠시 쉬어가는(?) 차원에서 요즘 잘 쓰고 있는 Recipesoup 전용 UTM 생성기와 관리 시트 구축 과정을 정리해 본다.


왜 UTM 생성기를 따로 만들었나

최근 Recipesoup 앱 출시 회고 블로그 글을 여러 채널에 공유하고 있다. 콘텐츠와 마케팅을 하면서 '숫자는 제대로 봐야 한다'는 감각이 몸에 배었었다. 큰 볼륨이 아니더라도 GA에서 정확한 지표를 보고 싶어 UTM을 붙였다. 그런데 링크드인, 앱스토어, 유튜브, 향후 예정된 SNS까지 채널이 늘어나면서 매번 스프레드시트를 열어 파라미터를 입력하고 GA4에서 값이 제대로 들어왔는지 확인하는 일이 점점 번거로워졌다. 단순 반복 작업을 좋아하지도 않고, 실무에서 알파벳 하나가 틀린 탓에 지표가 엉뚱하게 쌓인 사례도 직접 봤기에 자동화가 필요하다고 판단했다. 그래서 자동으로 UTM을 생성해주는 도구를 만들어보기로 했다.

"이 정도 작업을 자동화하는 것은 과한 투자인가?"라는 의문은 있었다. 하지만 한 번 틀을 만들어 두면 이후에는 입력 → 생성 → 기록이 자연스레 이어진다. 규칙을 매번 확인하지 않아도 되고 휴먼 에러를 시스템이 대신 막아준다. 요즘에는 AI와 다양한 기술 덕분에 간단한 툴 정도는 반나절이면 만들 수 있는 환경이 갖춰져 자유로움과 확장성을 자주 체감한다.


다섯 가지 UTM 파라미터 다시 정렬하기

UTM 필드를 혼동 없이 쓰기 위해 다섯 가지 파라미터의 역할을 다시 정리했다. 오랜만에 보면 헷갈릴 때가 있어 기준을 명확히 해 두었다.

  • utm_source: 사용자가 들어온 출처. linkedin, newsletter, naver처럼 플랫폼 이름을 적는다.
  • utm_medium: 전달 방식. social, organic , cpc등 매체 유형을 기록한다.
  • utm_campaign: 상위 캠페인 그룹. 보통 paid 광고 진행하면 autumn_discount_2025 등을 사용. 내 경우 앱 콘텐츠 시리즈로 묶었다.
  • utm_content: 동일 캠페인 안의 세부 콘텐츠 구분. focus_price vs focus_benefit 같은 A/B 테스트값. 나는 에피소드 구분용으로 사용했다.
  • utm_term: 검색 광고나 키워드 실험 값. 필요한 경우에만 입력한다.

역할을 명확히 나눠 두니 채널별로 어떤 값을 써야 할지 덜 고민하게 되었다. 그리고 이 내용을 각 필드 타이틀과 디스크립션에도 녹였다.

정책을 문서로 확정하기

혼자 쓰는 툴이라도 규칙이 없으면 자꾸 길을 잃는다. 그래서 utm-policy.md 문서를 만들어 필수·선택사항 파라미터를 표로 정리하고, 플랫폼별 UTM 추적 가능 여부와 GA4 실시간 확인 항목을 함께 적어 두었다. 이 문서가 UI 설계의 기준점이 되었다.

Recipesoup 톤을 살린 UI와 배포 방식

UTM 생성기 UI는 HTML/CSS/JavaScript로 구현했다. 디디자인은 모노톤으로도 충분하지만, Recipesoup 전용 툴이라는 느낌을 주고 싶어 앱의 토끼 로고와 크림색 팔레트를 그대로 사용했다. 기능 면에서는 아래와 같은 편의 요소를 넣었다.

  • https://를 생략해도 자동으로 보정한다.
  • 드롭다운에 자주 쓸 옵션을 미리 넣고 "직접 입력"을 선택하면 커스텀 필드가 열린다.
  • 생성된 링크는 버튼 한 번 클릭으로 복사, 토스트 메시지로 피드백을 준다.
  • 파비콘을 추가해 에러 페이지처럼 보이지 않게 했다.
  • 각 필드에 짧은 힌트를 붙여 입력 목적을 바로 이해할 수 있게 했다.

프론트엔드는 GitHub Pages로 배포했다. 저장소에 푸시하면 바로 반영되고 브랜치 기반으로 실험 버전을 따로 운영하기도 쉽다. 어디서든 동일한 URL을 열면 바로 작업을 시작할 수 있다.

여기서 자바스크립트는 HTML만으로 처리하기 어려운 입력 수집, UTM 조합, Apps Script와의 통신을 담당한다.

Apps Script와 Google Sheets로 자동화 완성

UTM 생성기에서 입력을 마치면 Google Apps Script 웹앱(WEB_APP_URL)에 JSON으로 아래 정보를 전달한다.

  • 원본 URL과 최종 UTM URL
  • 선택한 source/medium/campaign/content/term 값

Apps Script는 Google Sheets에 같은 데이터를 기록한다. 언제 어떤 링크를 만들었는지, 칼럼별 값까지 자동으로 쌓이고 분류되니 히스토리를 수기로 관리할 필요가 없어졌다.

"이미 Vercel 프록시를 쓰고 있다면, 모든 로직을 Vercel Serverless Function으로 옮겨서 한 번의 fetch 요청으로 처리하면 되지 않을까?"하는 생각도 들어 검토를 해봤다. 하지만 Google Sheets API를 직접 호출하려면 서비스 계정과 OAuth 인증을 세팅해야 하고 토큰 갱신과 권한 관리를 추가로 챙겨야 한다. 반면 Apps Script는 시트와 같은 계정 안에서 실행되기 때문에 인증을 손대지 않고도 빠르게 읽고 쓸 수 있다.

Supabase와 Edge Function 조합도 고려했다. 데이터가 늘어났을 때 SQL로 대시보드를 만들거나 다른 앱과 연동하기 좋은 선택지다. 다만 지금은 데이터가 적어서 스프레드시트가 합리적이다. 별도 DB를 운영하면 초기 마이그레이션과 백업까지 챙겨야 해서 우선순위를 낮췄다. Make·n8n·Zapier 같은 자동화 툴은 구축 속도와 확장성이 뛰어나지만 속도와 쿼터 제한을 살펴봐야 한다.

결론적으로 Apps Script는 무료로 간단하게 시작할 수 있는 데다, 나중에 다른 스택으로 옮겨가기에도 쉬워 가장 가벼운 출발점이었다.

기술을 조금씩 더 익힐수록 선택지는 계속 늘어난다. "이 조합 대신 다른 서비스를 쓰면?" 같은 질문이 매번 떠오르는데, 결국 지금 상황에서 적절한 균형점과 대안이 베스트인 것 같다. 자유도가 높아진 만큼 어떤 옵션을 선택할지에 대한 고민이 늘 따라다니는 요즘이다.

단축 URL 파이프라인 설계

UTM 구조가 그대로 노출되면 링크가 길어지고 캠페인 전략이 드러나기도 한다. 내 경우 너무 긴 UTM 처리가 목적이었다. 처음에는 Apps Script에서 바로 단축하려고 했지만 오히려 URL이 길어지는 문제가 생겼다. 그래서 Vercel 프록시를 사이에 두고 다음 순서로 처리하게 작업했다.

1. 생성기 → Apps Script: 캠페인 데이터를 전달

2. Apps Script → Vercel 프록시: 단축 URL 생성 요청

3. Vercel 프록시: 난수 코드 생성, 기존 코드와 중복 여부 확인

4. 중복이 없으면 링크 저장, 원본 URL과 매핑해 Apps Script로 응답

5. Apps Script는 단축 URL까지 포함해 시트에 기록

짧고 간단한 UTM 링크가 만들어졌다. 개인용이라 메인 도메인은 커스텀하지 않았고, Apps Script가 실패하면 에러 메시지를 띄우고 기본 UTM 링크를 먼저 보여주도록 예외 처리를 넣었다.

다만 처음에는 단축 링크를 눌러도 실제 캠페인 페이지가 아니라 Google Apps Script의 HTML 화면이 뜨면서 GA가 데이터를 못 받는 문제가 있었다. 단축 주소 → Apps Script → 캠페인 페이지 순서가 꼬여 있었던 것. 그래서 역할을 단순화했다. Apps Script는 시트에 기록만 남기고 '최종으로 보내야 하는 주소'만 돌려주도록 바꾸고, Vercel은 그 주소로 바로 넘겨주는 중간다리 역할만 하도록 정리했다. 이제는 단축 링크를 클릭하는 즉시 캠페인 페이지가 열리며 GA4에서도 의도한 소스·매체 값이 빠짐없이 쌓인다.

[최종 흐름] UTM 생성기 → Apps Script → Vercel → 블로그 페이지 → GA4 UTM 이벤트 수집

GA4 검증과 재사용 흐름 다듬기

툴을 만든 뒤에는 GA4 실시간 보고서로 파라미터가 정확히 기록되는지 확인했다. 테스트 결과 GA4 대시보드에 입력값이 정확히 들어왔다. 실시간 개요에서 direct로 표시되더라도 이벤트 매개변수를 열어 source, medium, campaign 값을 확인하면 의도한 대로 들어왔는지 바로 검증할 수 있다. utm-policy.md에 정리해둔 체크리스트와 나란히 비교해 QA 속도도 빨라졌다.


마무리하며

작은 도구지만 마케팅 자동화 사이클을 처음부터 끝까지 세팅했다. Recipesoup 회고 시리즈에서 자주 쓰는 옵션을 기본값으로 넣어두니 클릭 몇 번이면 링크가 만들어지고 입력값이 알아서 쌓인다. GA4에서는 소스·매체가 일관된 이름으로 묶여 채널별 비교가 간단해졌고, 시트 덕분에 히스토리를 따로 정리할 필요도 없다.

반복 작업을 줄이고 다시 체크하는 과정의 리소스를 덜 수 있다는 점이 특히 만족스러웠다. 짧은 시간 안에 필요한 것을 직접 구현한 경험도 의미있었다. 다음에는 협업자를 초대할 수 있는 접근 제어, 생성된 링크를 캠페인 요약 카드로 변환하는 기능처럼 주변 흐름을 확장해 볼 생각이다.

기술과 AI 덕분에 필요한 도구를 쉽게 만들어 실험할 수 있는 시대가 왔음을 다시 실감했다. 불편함과 문제를 빠르게 개선할 환경이 갖춰져 있으니 앞으로도 주저하지 않고 계속 테스트하고 만들어봐야겠다.