크롬 웹스토어에 확장 프로그램 배포하기 — 심사 통과까지
확장을 다 만들고 나면 마지막 단계가 남습니다. 스토어에 올리기. 개발자 모드로 로컬에서 쓸 때는 폴더만 있으면 되지만, 다른 사람에게 주려면 매번 zip을 보내고 "개발자 모드 켜세요"를 설명해야 합니다. 그리고 크롬은 개발자 모드로 로드한 확장에 브라우저를 켤 때마다 경고 배너를 띄웁니다.
이 글은 앞의 두 글에서 만든 매매 봇 컨트롤 패널을 실제로 크롬 웹스토어에 올리고 심사를 통과한 기록입니다. 절차 자체보다 어디서 걸리는지에 무게를 뒀습니다.
먼저 알아야 할 두 가지 숫자
개발자 등록비 5달러. 계정당 한 번 내는 일회성 비용이고, 확장 개수와 무관합니다. 이걸 내야 대시보드에 아이템을 만들 수 있습니다. 결제 후 계정 활성화까지 잠깐 걸릴 수 있습니다.
심사 기간은 며칠 단위. 빠르면 하루 안, 보통은 며칠입니다. 여기서 중요한 건 평균이 아니라 편차입니다. 권한을 많이 요구하거나 설명이 모호하면 수동 검토로 넘어가면서 눈에 띄게 길어집니다. "언제 통과되는지"는 대체로 내가 만든 manifest가 결정합니다.
권한 최소화가 곧 심사 속도다
앞 글에서 manifest 권한을 최소로 유지한 이야기를 했는데, 그 효과가 가장 크게 나타나는 곳이 여기입니다. 이 확장의 권한은 이렇습니다.
"permissions": [
"windows"
],
"host_permissions": [
"https://script.google.com/*"
]
심사에서 문제가 되는 것은 대체로 다음 셋입니다.
<all_urls>또는 넓은 host_permissions — "모든 사이트의 데이터를 읽고 변경" 경고가 뜨고, 왜 필요한지 소명해야 합니다content_scripts— 남의 페이지에 코드를 주입한다는 뜻이라 검토 강도가 올라갑니다- 원격 코드 실행 — MV3에서는 아예 금지입니다. 외부 스크립트를
eval하거나 CDN에서 받아 실행하면 거절됩니다
이 확장은 셋 다 해당하지 않습니다. content_scripts가 없고, 접근 도메인이 자기 백엔드 하나이며, 모든 코드가 패키지 안에 있습니다. 제출 폼에서 각 권한의 사유를 적는 칸이 있는데, 권한이 하나면 이 칸도 한 줄로 끝납니다.
실제로 적은 사유는 이런 식입니다.
windows — 확장 팝업에서 외부 매뉴얼 링크를 새 창으로 여는 데 사용합니다.
https://script.google.com/* — 이 확장의 백엔드(Google Apps Script 웹앱)를
호출하기 위해 필요합니다. 이 도메인 외에는 어떤 네트워크 요청도 하지 않습니다.
핵심은 "무엇을 하지 않는지"까지 쓰는 것입니다. 검토자가 확인해야 할 범위를 좁혀 주면 그만큼 빨리 끝납니다.
제출 전에 한 번은 깨지는 것들
업로드 자체에서 걸리는 실수는 대개 정해져 있습니다.
- zip 안에 폴더가 한 겹 더 있다.
manifest.json이 zip 루트에 있어야 합니다. 폴더째 압축하면 거부됩니다 - 버전을 안 올렸다. 같은
version으로는 다시 못 올립니다. 재제출할 때마다 올려야 합니다 - 안 쓰는 파일이 남아 있다. 개발 중 만든 샘플 HTML, 쓰지 않는 CSS, 캡처용 임시 파일이 그대로 들어갑니다. 용량 문제라기보다 검토 대상이 늘어납니다
- 아이콘 크기 누락. 16/48/128 세 벌을
icons와action.default_icon양쪽에 넣어 둡니다
배포용 zip은 소스 폴더를 그대로 압축하지 말고, 필요한 파일만 따로 모아 만드는 편이 안전합니다.
dist/
manifest.json
popup.html
popup.js
api.js
icons/
icon16.png
icon48.png
icon128.png
스토어 이미지 1280x800
스토어 등록 페이지에는 스크린샷이 최소 1장 필요합니다. 규격은 1280x800(또는 640x400)이고, 여기가 은근히 시간을 잡아먹습니다. 확장 팝업은 폭이 400px이라 그대로 캡처하면 1280x800을 채울 수 없습니다. 남는 공간을 어떻게 할 것인가 하는 문제가 생깁니다.
해결한 방법은 이렇습니다. 팝업과 같은 마크업·같은 CSS를 쓰는 캡처 전용 HTML을 하나 만들고, 배경 위에 팝업을 얹어 1280x800으로 렌더링했습니다.
<!-- store-shot.html : 캡처 전용. 배포 zip 에는 넣지 않는다 -->
<body style="width:1280px;height:800px;display:flex;
align-items:center;justify-content:center;
background:linear-gradient(135deg,#0e1116,#1b2430);">
<div style="width:400px;box-shadow:0 20px 60px rgba(0,0,0,.5);
border-radius:12px;overflow:hidden;">
<!-- popup.html 과 동일한 마크업을 그대로 삽입 -->
</div>
</body>
이러면 두 가지가 좋습니다. 실제 화면과 어긋나지 않고(같은 CSS를 쓰니까), UI를 고칠 때 캡처만 다시 뜨면 됩니다. 스크린샷을 포토샵으로 합성해 두면 다음 버전에서 반드시 실제 화면과 달라집니다.
다크·라이트 두 벌을 준비한 것도 의도적입니다. 스토어 목록에서 테마 전환이 된다는 사실 자체가 정보가 되고, 스크린샷 여러 장으로 기능을 설명하는 것보다 이쪽이 직관적입니다.
실제 제출한 스토어 이미지. 400px 팝업을 1280x800 배경 위에 얹어 렌더링했습니다.
같은 화면의 라이트 테마. 테마 지원 자체를 스토어에서 보여 주는 역할을 합니다.
개인정보처리방침 — 대부분 여기서 막힌다
제출 과정에서 가장 자주 반려되는 항목이 개인정보 관련 신고입니다. 대시보드에는 이런 것들을 적는 칸이 있습니다.
- 어떤 사용자 데이터를 수집하는가 (개인 식별 정보, 인증 정보, 위치, 활동 기록 등 항목별 체크)
- 수집한다면 왜 필요한가
- 제3자에게 판매·양도하지 않는다는 확인
- 공개된 개인정보처리방침 URL
여기서 정직해야 합니다. 이 확장은 API 키와 계좌번호를 입력받습니다. 확장 자체가 서버로 수집해 보관하는 것은 아니고 사용자 본인의 백엔드에 저장되지만, "인증 정보를 다룬다"는 사실은 그대로 신고해야 합니다. 여기서 "수집 안 함"으로 체크하고 화면에 API 키 입력란이 보이면 반려됩니다 — 검토자가 스크린샷과 대조합니다.
개인정보처리방침은 접근 가능한 공개 URL이어야 합니다. 블로그 페이지 하나로도 충분하고, 최소한 다음이 들어가야 합니다.
- 무엇을 입력받는가 (API 키, 계좌번호, 매매 파라미터)
- 어디에 저장되는가 (사용자 본인의 Apps Script 프로퍼티)
- 개발자가 그 값에 접근하는가 (접근하지 않는다면 그렇게 명시)
- 제3자 전송 여부
- 문의 연락처
덧붙여, 확장이 하는 일과 스토어 설명이 일치해야 합니다. 설명에 없는 기능이 화면에 있거나 그 반대면 "기능 설명 불일치"로 반려됩니다.
금융 관련 확장이라서 추가로 신경 쓴 것
매매 봇 컨트롤 패널은 금융 카테고리에 가까운 물건이라 몇 가지를 더 조심했습니다.
- 수익을 약속하는 문구를 쓰지 않는다. 설명은 "자동 매매 시스템의 컨트롤 패널"이라는 기능 서술로만 씁니다
- 증권사와 무관함을 분명히 한다. 이 확장은 공개 REST API를 쓰는 서드파티 도구이고, 증권사가 만들거나 보증한 것이 아닙니다. 브랜드·로고를 쓰지 않고, 이름에도 공식처럼 보이는 표기를 피합니다
- 위험 고지를 설명에 넣는다. 자동매매로 손실이 날 수 있다는 문장을 스토어 설명과 매뉴얼 양쪽에 둡니다
첫 번째와 두 번째는 스토어 정책 문제이고, 세 번째는 정책 이전에 쓰는 사람에 대한 의무에 가깝습니다.
통과 후
승인되면 스토어 URL이 나오고, 그때부터는 zip을 보내는 대신 링크 하나면 됩니다. 실제로 등록된 결과물은 여기 있습니다 — Stock Trading Bot.
업데이트도 같은 흐름입니다. version을 올려 새 zip을 올리면 다시 심사를 거칩니다. 권한을 추가하는 업데이트는 처음 제출만큼 오래 걸린다고 보는 편이 안전합니다. 권한이 그대로면 대체로 빠릅니다 — 이것도 처음에 권한을 좁게 잡아 둔 값입니다.
참고로 크롬은 기존 사용자에게 자동 업데이트를 밀어 줍니다. 편하지만 되돌릴 수 없다는 뜻이기도 합니다. 매매를 조작하는 확장이라면, 로컬에서 개발자 모드로 한 번 검증하고 올리는 절차를 생략하지 않는 편이 좋습니다.
정리
- 일회성 5달러, 심사는 며칠 — 편차는 대부분 내 manifest가 만든다
- 심사를 빠르게 하는 것은 넓은 host_permissions·content_scripts·원격 코드가 없는 것
- 권한 사유에는 "무엇을 하지 않는지"까지 적어 검토 범위를 좁힌다
- zip은 manifest가 루트에, 재제출마다 version 올리기, 안 쓰는 파일 빼기
- 1280x800 이미지는 같은 CSS를 쓰는 캡처 전용 HTML로 만들면 화면과 어긋나지 않는다
- 개인정보 신고는 정직하게 — 화면에 API 키 입력란이 있으면 "수집 안 함"은 통하지 않는다
- 금융 도구는 수익 약속 금지 · 증권사와 무관함 명시 · 위험 고지
서버 없는 백엔드(1편) → 크롬 확장 컨트롤 패널(2편) → 스토어 배포(3편)로 한 바퀴가 끝났습니다. 전체를 관통하는 교훈은 하나입니다. 제약을 먼저 받아들이면 설계가 단순해진다. GAS의 1분 트리거가 전략을 골라 줬고, 팝업의 400px가 기능을 골라 줬고, 스토어의 권한 심사가 manifest를 깎아 줬습니다.
※ 이 글은 개발·배포 기록이며 투자 권유가 아닙니다. 자동매매는 시스템 오류·네트워크 장애·예상치 못한 시장 상황으로 손실이 발생할 수 있으며, 투자 판단과 그 결과는 전적으로 본인 책임입니다. 스토어 정책과 심사 기준은 수시로 바뀌므로 제출 전 최신 공식 문서를 확인하시기 바랍니다.
댓글
댓글 쓰기