이 글은 온실 GreenHouse 시리즈의 1번째 기록입니다. (총 3개)

요약

내가 만든 앱들과 블로그가 서로를 홍보하는 자체 광고(하우스 광고) 시스템. 네이티브 앱의 빈 광고 자리에 외부 광고망 대신 내 앱·블로그 배너를 돌린다. 내부 코드명은 업계 표준 용어인 HouseAd, 사용자에게 보이는 브랜드는 온실이다 — 소리꽃(피아노)·강아지(습관)·모래(퍼즐)처럼 세계관이 제각각인 앱들을 억지로 통일하지 않고 한 유리온실에 담는다는 뜻이다.

구조는 단순하다. 광고 목록이 담긴 데이터 파일(ads.json)을 정적 사이트로 서빙하고, 앱은 실행할 때 그 파일을 받아 250×250 배너를 그린다. 광고 자체는 앱에 들어 있지 않아서, 파일만 고쳐 배포하면 이미 설치된 앱들의 배너가 다음 실행 때 바뀐다.

배너를 손으로 JSON 짜지 않고 만들 수 있게 폼 기반 편집기 페이지도 함께 둔다. 목록·편집 폼·실시간 미리보기로 배너를 다듬고 완성된 ads.json을 내보내는 방식이다.


제작 동기

카카오 애드핏은 승인된 웹 도메인에서만 광고를 준다. 그래서 웹은 광고가 돌지만, 네이티브 앱(데스크톱)의 WebView에서는 아예 뜨지 않아 광고 자리가 비어 있었다.

그 빈 자리가 아깝다는 데서 출발했다. 외부 광고망을 못 쓰는 자리라면 내 것을 홍보하면 된다. 블로그로, 다른 앱으로 트래픽이 순환하고, 외부 광고망을 안 거치니 약관 문제도 없다. 앱이 늘어날수록 서로가 서로의 광고판이 되는 구조다.

조건이 하나 있었다. 광고에 넣을 내용은 수시로 바뀔 텐데, 그때마다 앱을 재빌드·재배포하는 건 말이 안 된다. 그래서 광고 내용을 앱 밖(원격 데이터 파일)으로 빼는 게 이 프로젝트의 핵심 설계가 됐다.


목표 설정

  • 작업 기간: 2026.07.26. ~ 진행 중
  • 레벨 1 = 정적 ads.json + 배너 편집기 + CORS 설정. 파일 수정·배포만으로 모든 설치된 앱의 광고가 갱신되는 것까지
  • 배너 기본형 = 250×250 정사각형. 이미지가 있으면 이미지 카드, 없으면 텍스트 카드
  • 배포 주소는 계약 — 앱에 하드코딩되므로 한 번 정하면 바꾸지 않는다
  • 레벨 2(추후) = Cloudflare Worker + KV로 push 없이 실시간 반영 + 노출·클릭 통계. 편집기는 저장 대상만 바꾸면 승격되게 설계
  • 첫 소비자는 소리꽃 KeyBloom 네이티브 앱, 이후 다른 앱으로 확대

주요 작업

  1. 이름·구도 확정 — 내부 코드명 HouseAd / 브랜드 온실 GreenHouse ✅
  2. 블로그에서 분리해 독립 정적 사이트 프로젝트로 ✅
  3. 광고 데이터 규약(ads.json) — 제목/부제목/이미지/클릭 주소/노출 대상/가중치/기간 ✅
  4. 배너 편집기(admin.html) — 추가·수정·정렬, 검증, 내보내기, 250×250 미리보기, 초안 자동 저장 ✅
  5. CORS 설정(_headers) — 앱의 교차 출처 fetch 허용 ✅
  6. Cloudflare Pages 배포·URL 확정 ⏳
  7. 소리꽃 KeyBloom 연동 — fetch·배너 렌더·시스템 브라우저 열기 ⏳
  8. 광고 시드 확장 — 어떤 앱을 실을지 목록 확정 ⏳

결과

시작한 날 레벨 1이 repo에 갖춰졌다. 광고 데이터 규약과 첫 광고(블로그 홈 텍스트 카드), 배너 편집기, CORS 설정까지가 하루 분량이다. 아직 배포 전이라 편집기의 브라우저 확인과 Cloudflare Pages 프로젝트 생성이 다음 차례다.

배포 주소가 정해지면 첫 소비자인 소리꽃 KeyBloom부터 배너가 붙는다. 그 뒤로는 앱을 하나 낼 때마다 온실에 화분이 하나 늘어나는 셈이다.


Series: 온실 GreenHouse


Suggested Posts