generated from ttipo/project-base
59c84dcac5
- 관리자 화면 '업체 링크' 메뉴: 업체 추가, 링크 발급·복사·중지, 기간별 클릭·신청·구매, 링크별 실적 회원 목록, 상품 불러오기·구매 집계 새로고침 - partner-ref.html (Header Code): 클릭 ID 를 30일 보관하고 로그인 회원과 잇는다 - imweb-free-apply.html: 신청 기록(클릭 ID 포함)과 오픈카톡 클릭 기록 전송 추가 - README 에 귀속 규칙·한계·처음 켤 때 순서 정리 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
653 lines
28 KiB
HTML
653 lines
28 KiB
HTML
<!-- ===== 아임웹 HTML 위젯 삽입용 코드 (본문 스니펫) - 무료 신청 완료 ===== -->
|
|
<!-- ※ 신청 위젯(course-enroll.html)과 같은 페이지에 배치하세요. 신청 완료 시 자동으로 표시됩니다. -->
|
|
<div class="moneyguider-complete">
|
|
<div class="moneyguider-complete__card">
|
|
|
|
<div class="moneyguider-complete__icon" aria-hidden="true">
|
|
<svg width="34" height="34" viewBox="0 0 24 24" fill="none" stroke="#1a1200" stroke-width="3"
|
|
stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg">
|
|
<path d="M20 6L9 17l-5-5" />
|
|
</svg>
|
|
</div>
|
|
|
|
<h2 class="moneyguider-complete__title">신청이 완료되었습니다.</h2>
|
|
|
|
<hr class="moneyguider-complete__divider" />
|
|
|
|
<div class="moneyguider-complete__info">
|
|
<div class="moneyguider-complete__row">
|
|
<span class="moneyguider-complete__label">신청강의</span>
|
|
<span class="moneyguider-complete__value">[무료한정 😳] 하루 2시간 월1000 버는 AI 효자 상품 찾기</span>
|
|
</div>
|
|
</div>
|
|
|
|
<p class="moneyguider-complete__guide">
|
|
무료 라이브 단톡방에 입장하셔서<br />
|
|
<strong>전자책, 무료강의 등 다양한 혜택</strong>을 받아가세요!
|
|
</p>
|
|
|
|
<a class="moneyguider-complete__kakao" href="https://open.kakao.com/o/gWNuX9Eh" target="_blank"
|
|
rel="noopener noreferrer">
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="#1a1200" xmlns="http://www.w3.org/2000/svg">
|
|
<path
|
|
d="M12 3C6.5 3 2 6.6 2 11c0 2.8 1.9 5.3 4.7 6.7-.2.7-.7 2.6-.8 3-.1.5.2.5.4.4.2-.1 2.6-1.8 3.7-2.5.7.1 1.4.2 2 .2 5.5 0 10-3.6 10-8S17.5 3 12 3z" />
|
|
</svg>
|
|
오픈카톡 입장하기
|
|
</a>
|
|
|
|
<a class="moneyguider-complete__secondary" href="/home">메인 페이지로 이동</a>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<style>
|
|
/* moneyguider 신청 완료 위젯 전용 스코프 스타일 (사이트 전역에 영향 없음) */
|
|
.moneyguider-complete {
|
|
box-sizing: border-box;
|
|
width: 100%;
|
|
font-family: "Pretendard", "Apple SD Gothic Neo", "Malgun Gothic", sans-serif;
|
|
-webkit-font-smoothing: antialiased;
|
|
/* 기본 숨김: 신청 완료 시 JS가 .is-shown 클래스를 추가해 표시 */
|
|
display: none;
|
|
}
|
|
|
|
.moneyguider-complete.is-shown {
|
|
display: block;
|
|
}
|
|
|
|
.moneyguider-complete * {
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.moneyguider-complete__card {
|
|
width: 100%;
|
|
max-width: 560px;
|
|
margin: 0 auto;
|
|
padding: 44px 36px 36px;
|
|
background-color: #141414;
|
|
border: 1px solid rgba(255, 255, 255, 0.07);
|
|
border-radius: 24px;
|
|
text-align: center;
|
|
}
|
|
|
|
/* 체크 아이콘 */
|
|
.moneyguider-complete__icon {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 72px;
|
|
height: 72px;
|
|
margin: 0 auto 22px;
|
|
background-color: #f5b727;
|
|
border-radius: 50%;
|
|
}
|
|
|
|
.moneyguider-complete .moneyguider-complete__title {
|
|
margin: 0;
|
|
font-size: 26px;
|
|
font-weight: 800;
|
|
line-height: 1.35;
|
|
color: #ffffff;
|
|
letter-spacing: -0.02em;
|
|
text-indent: 0;
|
|
font-style: normal;
|
|
}
|
|
|
|
.moneyguider-complete__divider {
|
|
height: 1px;
|
|
margin: 26px 0;
|
|
border: 0;
|
|
background-color: rgba(255, 255, 255, 0.08);
|
|
}
|
|
|
|
/* 신청 정보 박스 */
|
|
.moneyguider-complete__info {
|
|
padding: 22px 24px;
|
|
background-color: #1a1a1a;
|
|
border-radius: 14px;
|
|
text-align: left;
|
|
}
|
|
|
|
.moneyguider-complete__row {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
justify-content: space-between;
|
|
gap: 16px;
|
|
}
|
|
|
|
.moneyguider-complete__label {
|
|
flex: 0 0 auto;
|
|
font-size: 15px;
|
|
font-weight: 700;
|
|
color: #cfcfcf;
|
|
}
|
|
|
|
.moneyguider-complete__value {
|
|
font-size: 15px;
|
|
line-height: 1.5;
|
|
color: #ffffff;
|
|
text-align: right;
|
|
}
|
|
|
|
/* 안내 문구 */
|
|
.moneyguider-complete__guide {
|
|
margin: 26px 0 22px;
|
|
font-size: 15px;
|
|
line-height: 1.6;
|
|
color: #9a9a9a;
|
|
}
|
|
|
|
.moneyguider-complete__guide strong {
|
|
font-weight: 700;
|
|
color: #f5b727;
|
|
}
|
|
|
|
/* 버튼 */
|
|
.moneyguider-complete__kakao {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 8px;
|
|
width: 100%;
|
|
padding: 17px;
|
|
margin-bottom: 12px;
|
|
background-color: #fee500;
|
|
border-radius: 12px;
|
|
font-size: 16px;
|
|
font-weight: 700;
|
|
color: #1a1200 !important;
|
|
text-decoration: none;
|
|
transition: filter 0.2s ease, transform 0.2s ease;
|
|
}
|
|
|
|
.moneyguider-complete__kakao:hover {
|
|
filter: brightness(0.96);
|
|
transform: translateY(-2px);
|
|
}
|
|
|
|
.moneyguider-complete__secondary {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 100%;
|
|
padding: 17px;
|
|
background-color: transparent;
|
|
border: 1px solid rgba(255, 255, 255, 0.18);
|
|
border-radius: 12px;
|
|
font-size: 16px;
|
|
font-weight: 700;
|
|
color: #ffffff !important;
|
|
text-decoration: none;
|
|
transition: background-color 0.2s ease, border-color 0.2s ease;
|
|
}
|
|
|
|
.moneyguider-complete__secondary:hover {
|
|
background-color: rgba(255, 255, 255, 0.05);
|
|
border-color: rgba(255, 255, 255, 0.3);
|
|
}
|
|
|
|
/* 반응형 */
|
|
@media (max-width: 520px) {
|
|
.moneyguider-complete__card {
|
|
padding: 36px 22px 26px;
|
|
border-radius: 20px;
|
|
}
|
|
|
|
.moneyguider-complete .moneyguider-complete__title {
|
|
font-size: 22px;
|
|
}
|
|
|
|
.moneyguider-complete__row {
|
|
flex-direction: column;
|
|
gap: 4px;
|
|
}
|
|
|
|
.moneyguider-complete__value {
|
|
text-align: left;
|
|
}
|
|
}
|
|
</style>
|
|
|
|
<script>
|
|
(function () {
|
|
'use strict';
|
|
|
|
/* ========================================================
|
|
▼▼▼ 여기만 수정하시면 됩니다 ▼▼▼
|
|
======================================================== */
|
|
|
|
/* 1) 비로그인 사용자를 이 화면에서 튕겨낼지.
|
|
주소창에 /apply 를 직접 쳐서 들어오는 것을 막습니다. */
|
|
var REQUIRE_LOGIN = true;
|
|
|
|
/* 2) 튕겨낼 때 어디로 보낼지
|
|
'join' 아임웹 회원가입 페이지로 보냅니다. 가입이 끝나면
|
|
지금 주소(/apply?...)로 그대로 돌아와 완료 화면이
|
|
보입니다. 신청 흐름이 끊기지 않습니다.
|
|
주소 그 주소로 이동시킵니다.
|
|
예) '/free-shop/?idx=52' '/home' */
|
|
var REDIRECT_TO = 'join';
|
|
|
|
/* 3) 회원가입 페이지 주소 ('가입 방식 선택' 화면).
|
|
back_url 파라미터는 자동으로 붙습니다.
|
|
detail-buy-btn.html 의 JOIN_PAGE 와 같은 값이어야 합니다.
|
|
|
|
※ SITE_MEMBER.openJoinTypeChoice() 를 부르면 같은 화면이
|
|
현재 페이지 위에 '모달' 로 뜹니다. 이 페이지는 내용을
|
|
감춰 둔 상태라 모달 뒤가 텅 비어 보이고, 사용자가 모달을
|
|
닫으면 빈 화면에 갇힙니다. 전체 페이지로 보냅니다. */
|
|
var JOIN_PAGE = '/site_join_type_choice';
|
|
|
|
/* 4) 광고 픽셀 이벤트
|
|
------------------------------------------------------
|
|
※ '오픈카톡방에 실제로 입장했는지' 는 우리 쪽에서 알 수
|
|
없습니다. open.kakao.com 은 카카오 도메인이고, 입장
|
|
결과를 사이트로 알려주는 콜백이 없습니다.
|
|
그래서 '입장하기 버튼 클릭' 을 전환으로 잡습니다.
|
|
실제 입장률만큼 과대 집계되는 점을 감안하세요. */
|
|
var PIXEL = {
|
|
/* 켜고 끄기 */
|
|
ON: true,
|
|
|
|
/* (1) 오픈카톡 버튼 클릭 → 이것을 광고 전환으로 잡으시면 됩니다.
|
|
메타 광고 관리자에는 '구독' 으로 표시됩니다.
|
|
|
|
Subscribe 를 고른 이유
|
|
- 캠페인 목표가 '판매' 면 전환 이벤트 목록에 커머스
|
|
계열만 나옵니다. Contact / Lead 는 '잠재 고객' 목표
|
|
전용이라 목록에 아예 안 뜹니다.
|
|
- Subscribe 는 그 목록 안에 있으면서 아직 아무도
|
|
쓰지 않는 이벤트입니다. (결제 시작·콘텐츠 조회·
|
|
장바구니·구매는 아임웹 쇼핑 연동이 이미 사용 중,
|
|
등록 완료는 아래 가입 전환이 사용 중)
|
|
- 의미도 '채널 입장 = 구독' 으로 가장 가깝습니다.
|
|
|
|
※ 주의 : 상품 타입이 subscribe 로 잡혀 있어
|
|
(data-bs-prod-type="subscribe"), 정규강의 결제가
|
|
완료되면 아임웹이 Purchase 대신 Subscribe 를 쏠
|
|
가능성이 있습니다. 그때는 이벤트 관리자에서 '구독'
|
|
이벤트의 소스 URL 을 확인해 /apply 외의 주소가
|
|
섞이는지 보세요. 섞인다면 URL 조건을 건 맞춤 전환으로
|
|
분리하시면 됩니다.
|
|
|
|
맞춤 전환으로 따로 관리하시려면 KAKAO_CUSTOM 을 true 로
|
|
두세요. 그러면 trackCustom 으로 보냅니다. */
|
|
KAKAO_EVENT: 'Subscribe',
|
|
KAKAO_CUSTOM: false,
|
|
|
|
/* (2) 회원가입 완료 → CompleteRegistration ('등록 완료')
|
|
지금은 꺼져 있습니다. 위 (1) 구독 추적만 동작합니다.
|
|
|
|
true 로 바꾸면 가입 전환도 함께 집계됩니다. 그때 필요한
|
|
표식은 detail-buy-btn.html 이 이미 남기고 있으므로
|
|
여기 값만 바꾸면 되고, 다른 파일은 손대지 않아도 됩니다.
|
|
|
|
켤 경우의 동작 : 가입 페이지를 거쳐 돌아온 사람만 셉니다.
|
|
이미 회원인 사람이 완료 화면에 다시 들른 경우는
|
|
세지 않습니다. */
|
|
REGISTRATION: false,
|
|
|
|
/* (3) 구글 광고 전환 — 전환 액션 '회원가입 (광섭)'
|
|
구글은 메타처럼 이벤트 이름으로 구분하지 않고,
|
|
전환 액션마다 발급되는 send_to 값으로 구분합니다.
|
|
구글 애즈 > 목표 > 해당 전환 액션 > 태그 설정 에서
|
|
'AW-계정ID/라벨' 형태로 확인할 수 있습니다.
|
|
|
|
비워두면 구글 쪽으로는 아무것도 보내지 않습니다. */
|
|
GOOGLE_KAKAO: 'AW-17296567556/95baCOj7ze0aEITa0rdA',
|
|
|
|
/* 가입 완료 시점에 보낼 구글 전환. 지금은 비워 두었습니다.
|
|
(아래 REGISTRATION 이 false 라 어차피 동작하지 않습니다)
|
|
가입 시점으로 옮기시려면 위 값을 여기로 옮기고
|
|
REGISTRATION 을 true 로 바꾸세요. */
|
|
GOOGLE_SIGNUP: '',
|
|
|
|
/* (4) GA4 이벤트도 함께 보낼지.
|
|
※ 현재 이 사이트에는 GA4(G-) 속성이 없고 구글 광고
|
|
태그(AW-)만 설치돼 있습니다. 그래서 켜 두어도 지금은
|
|
실질적인 효과가 없습니다. 나중에 GA4 를 붙이면
|
|
그때부터 동작합니다. */
|
|
GA4: true
|
|
};
|
|
|
|
/* detail-buy-btn.html 이 남기는 표식의 이름. 양쪽이 같아야 합니다. */
|
|
var JOIN_FLAG = 'mg-join-started';
|
|
|
|
/* 6) 상품별 오픈카톡 링크
|
|
키 : 상품번호 — 주소의 ?idx= 값입니다.
|
|
detail-buy-btn.html 이 신청 버튼에서 함께 넘겨줍니다.
|
|
값 : 그 상품 전용 오픈채팅방 주소
|
|
|
|
여기에 없는 상품은 아래 KAKAO_DEFAULT 로 갑니다. */
|
|
var KAKAO_LINKS = {
|
|
'52': 'https://open.kakao.com/o/gWNuX9Eh'
|
|
// '10': 'https://open.kakao.com/o/XXXXXXXX',
|
|
};
|
|
|
|
/* 등록되지 않은 상품이거나 상품번호 없이 들어온 경우에 쓸 링크.
|
|
비워두면('') 오픈카톡 버튼 자체를 숨깁니다.
|
|
엉뚱한 방으로 보내느니 안 보여주는 편이 낫다면 비우세요. */
|
|
var KAKAO_DEFAULT = '';
|
|
|
|
/* 5) 로그인 여부를 판별하는 데 기다릴 최대 시간.
|
|
아임웹 전역(MEMBER_UID)이 늦게 실행되는 경우 대비입니다.
|
|
이 시간이 지나도 판별이 안 되면 '통과' 시킵니다. */
|
|
var WAIT_MS = 2000;
|
|
var POLL_MS = 100;
|
|
|
|
/* 7) 신청 기록을 보낼 백엔드 주소
|
|
신청 완료 화면이 뜰 때 회원·상품번호·유입정보·업체 링크 클릭을
|
|
보내 관리자 화면 '신청 내역'과 '업체 링크' 실적에 남깁니다.
|
|
비워두면('') 아무것도 보내지 않습니다. */
|
|
var API_BASE = 'https://moneyguide.wandergo.net/api';
|
|
|
|
/* ========================================================
|
|
▲▲▲ 여기까지 ▲▲▲ 아래는 수정할 필요 없습니다.
|
|
======================================================== */
|
|
|
|
var el = document.querySelector('.moneyguider-complete');
|
|
if (!el) return;
|
|
|
|
var params = new URLSearchParams(window.location.search);
|
|
var name = params.get('name');
|
|
/* 상품번호 — detail-buy-btn.html 이 붙여 보냅니다.
|
|
오픈카톡 링크를 고르고, 픽셀에도 함께 실어 보냅니다. */
|
|
var idx = params.get('idx') || '';
|
|
var isApplyPage = window.location.pathname.indexOf('apply') !== -1;
|
|
|
|
// /apply 페이지도 아니고 name 파라미터도 없으면 아무것도 하지 않습니다
|
|
if (!isApplyPage && !name) return;
|
|
|
|
/* ── 픽셀 전송 ────────────────────────────────────────
|
|
픽셀이 아직 안 떴거나 광고차단기에 막혀도 페이지가 죽지
|
|
않도록 전부 방어합니다. 완료 화면 표시가 픽셀보다 우선입니다. */
|
|
function meta(name, custom, params) {
|
|
if (!PIXEL.ON || typeof window.fbq !== 'function') return;
|
|
try { window.fbq(custom ? 'trackCustom' : 'track', name, params || {}); }
|
|
catch (e) { }
|
|
}
|
|
|
|
function ga(name, params) {
|
|
if (!PIXEL.ON || !PIXEL.GA4 || typeof window.gtag !== 'function') return;
|
|
try { window.gtag('event', name, params || {}); } catch (e) { }
|
|
}
|
|
|
|
/* 구글 광고 전환.
|
|
|
|
구글이 안내하는 스니펫은 gtag_report_conversion(url) 형태로,
|
|
전환을 보낸 뒤 window.location 으로 이동시키는 구조입니다.
|
|
그건 '같은 탭에서 이동하는 링크' 를 위한 것입니다.
|
|
우리 카톡 버튼은 target="_blank" 라 현재 페이지가 그대로
|
|
남으므로 이동을 가로챌 이유가 없습니다. 그 방식을 쓰면
|
|
새 탭이 열리면서 현재 탭까지 카톡으로 넘어가 버립니다.
|
|
→ 전환만 보내고 링크는 건드리지 않습니다. */
|
|
function gads(sendTo) {
|
|
if (!PIXEL.ON || !sendTo || typeof window.gtag !== 'function') return;
|
|
try { window.gtag('event', 'conversion', { 'send_to': sendTo }); }
|
|
catch (e) { }
|
|
}
|
|
|
|
function ssGet(key) {
|
|
try { return window.sessionStorage.getItem(key); }
|
|
catch (e) { return null; }
|
|
}
|
|
|
|
function ssDrop(key) {
|
|
try { window.sessionStorage.removeItem(key); } catch (e) { }
|
|
}
|
|
|
|
/* 픽셀 스크립트는 비동기로 뜹니다. 페이지 로드 직후에는 아직
|
|
window.fbq 가 없을 수 있어 잠깐 기다립니다.
|
|
|
|
이게 필요한 이유 : 가입 전환은 '표식을 지우고 → 보낸다' 인데,
|
|
픽셀이 안 뜬 상태에서 표식부터 지워버리면 그 가입은 영영
|
|
집계되지 않습니다. 표식은 실제로 보낸 뒤에만 지웁니다. */
|
|
var PIXEL_WAIT_MS = 4000;
|
|
|
|
function whenPixelReady(cb) {
|
|
var waited = 0;
|
|
(function poll() {
|
|
var ready = (typeof window.fbq === 'function');
|
|
if (ready || waited >= PIXEL_WAIT_MS) { cb(ready); return; }
|
|
waited += 100;
|
|
window.setTimeout(poll, 100);
|
|
})();
|
|
}
|
|
|
|
/* ── 신청 기록 전송 ──────────────────────────────────────
|
|
실패해도 완료 화면·픽셀에는 영향을 주지 않습니다 (전부 조용히 무시).
|
|
같은 회원·상품은 서버가 한 건만 남기므로 새로고침해도 안전합니다. */
|
|
var PRODUCT_IDX_PATTERN = /^\d{1,20}$/;
|
|
var PRODUCT_NAME_MAX = 200;
|
|
var INFLOW_MAX = 1000;
|
|
var applicationRequest = null; /* 신청 기록 ID 를 돌려주는 Promise */
|
|
|
|
/* 아임웹 전역(MEMBER_UID)이 늦게 생기는 경우를 잠깐 기다립니다 */
|
|
function whenMemberUid(cb) {
|
|
var waited = 0;
|
|
(function poll() {
|
|
var uid = window.MEMBER_UID;
|
|
if (uid) { cb(String(uid)); return; }
|
|
if (typeof uid === 'string' || waited >= WAIT_MS) return;
|
|
waited += POLL_MS;
|
|
window.setTimeout(poll, POLL_MS);
|
|
})();
|
|
}
|
|
|
|
/* header-top.html(UTM 스크립트)이 보관한 유입정보 — 없으면 빈 값 */
|
|
function readInflow() {
|
|
try {
|
|
var value = window.MG_UTM && typeof window.MG_UTM.peek === 'function'
|
|
? window.MG_UTM.peek() : '';
|
|
return typeof value === 'string' ? value.slice(0, INFLOW_MAX) : '';
|
|
} catch (e) { return ''; }
|
|
}
|
|
|
|
/* partner-ref.html(업체 링크 스크립트)이 보관한 클릭 ID — 없으면 빈 배열 */
|
|
function readPartnerRefs() {
|
|
try {
|
|
var refs = window.MG_PARTNER && typeof window.MG_PARTNER.refs === 'function'
|
|
? window.MG_PARTNER.refs() : [];
|
|
return Array.isArray(refs) ? refs : [];
|
|
} catch (e) { return []; }
|
|
}
|
|
|
|
function recordApplication() {
|
|
if (!API_BASE || !PRODUCT_IDX_PATTERN.test(idx) ||
|
|
typeof window.fetch !== 'function') return;
|
|
|
|
applicationRequest = new Promise(function (resolve) {
|
|
whenMemberUid(function (memberUid) {
|
|
var body = { memberUid: memberUid, productIdx: idx };
|
|
if (name) body.productName = name.slice(0, PRODUCT_NAME_MAX);
|
|
var inflow = readInflow();
|
|
if (inflow) body.inflow = inflow;
|
|
var refs = readPartnerRefs();
|
|
if (refs.length) body.partnerRefs = refs;
|
|
|
|
window.fetch(API_BASE + '/applications', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
credentials: 'omit',
|
|
body: JSON.stringify(body)
|
|
}).then(function (res) {
|
|
return res.ok ? res.json() : null;
|
|
}).then(function (json) {
|
|
resolve(json && json.success && json.data ? json.data.id : null);
|
|
}).catch(function () { resolve(null); });
|
|
});
|
|
});
|
|
}
|
|
|
|
/* 오픈카톡 버튼 클릭 기록 — 서버는 처음 한 번만 남깁니다 */
|
|
function recordKakaoClick() {
|
|
if (!applicationRequest) return;
|
|
applicationRequest.then(function (id) {
|
|
if (!id) return;
|
|
window.fetch(API_BASE + '/applications/' + encodeURIComponent(id) +
|
|
'/kakao-clicks', { method: 'POST', credentials: 'omit' })
|
|
.catch(function () { });
|
|
});
|
|
}
|
|
|
|
function show() {
|
|
el.classList.add('is-shown');
|
|
|
|
// URL로 전달된 상품명을 '신청강의' 값에 채움
|
|
if (name) {
|
|
var valueEl = el.querySelector('.moneyguider-complete__value');
|
|
if (valueEl) valueEl.textContent = name;
|
|
}
|
|
|
|
/* 신청 기록 — 아래 카톡 버튼 처리가 중간에 끝날 수 있어 먼저 보냅니다 */
|
|
recordApplication();
|
|
|
|
/* (2) 방금 가입을 마치고 돌아온 경우에만 가입 전환 */
|
|
if (PIXEL.REGISTRATION && PIXEL.ON && ssGet(JOIN_FLAG)) {
|
|
whenPixelReady(function (ready) {
|
|
/* 끝내 안 뜨면(광고차단기 등) 표식을 남겨 둡니다.
|
|
어차피 못 보낼 상황이고, 지워봐야 손해만 봅니다. */
|
|
if (!ready) return;
|
|
|
|
ssDrop(JOIN_FLAG); /* 보내기 직전에 지웁니다 */
|
|
meta('CompleteRegistration', false, {
|
|
content_name: name || '', status: true
|
|
});
|
|
gads(PIXEL.GOOGLE_SIGNUP);
|
|
ga('sign_up', { method: 'imweb', content_name: name || '' });
|
|
});
|
|
}
|
|
|
|
/* (1) 오픈카톡 입장 버튼 클릭 → 광고 전환으로 쓸 이벤트
|
|
|
|
버튼이 target="_blank" 라 이 페이지가 그대로 남습니다.
|
|
덕분에 이벤트가 전송될 시간이 확보됩니다. 같은 탭에서
|
|
열도록 바꾸시면 전송 전에 페이지가 떠나 유실될 수 있습니다.
|
|
|
|
preventDefault 를 하지 않습니다. 링크는 평소대로 열립니다. */
|
|
var kakao = el.querySelector('.moneyguider-complete__kakao');
|
|
if (kakao) {
|
|
/* 상품번호로 오픈채팅방 주소를 고릅니다.
|
|
등록된 게 없으면 KAKAO_DEFAULT, 그것도 비어 있으면
|
|
버튼을 숨깁니다. */
|
|
var link = (Object.prototype.hasOwnProperty.call(KAKAO_LINKS, idx)
|
|
? KAKAO_LINKS[idx] : '') || KAKAO_DEFAULT;
|
|
|
|
if (!link) {
|
|
kakao.style.display = 'none';
|
|
return;
|
|
}
|
|
kakao.setAttribute('href', link);
|
|
|
|
var sent = false;
|
|
|
|
function onKakao() {
|
|
/* 한 화면에서 여러 번 눌러도 한 번만 집계합니다.
|
|
target="_blank" 라 페이지가 그대로 남아 있어서
|
|
두세 번 누르는 일이 실제로 생깁니다. 그대로 두면
|
|
한 사람이 전환 여러 건으로 잡힙니다. */
|
|
if (sent) return;
|
|
sent = true;
|
|
|
|
recordKakaoClick();
|
|
|
|
/* content_ids 를 함께 보내면 나중에 광고 관리자에서
|
|
상품별로 전환을 쪼개 볼 수 있습니다. */
|
|
var p = { content_name: name || '', content_category: 'kakao_openchat' };
|
|
if (idx) p.content_ids = [idx];
|
|
meta(PIXEL.KAKAO_EVENT, PIXEL.KAKAO_CUSTOM, p);
|
|
gads(PIXEL.GOOGLE_KAKAO);
|
|
ga('kakao_openchat_join', { content_name: name || '' });
|
|
}
|
|
|
|
kakao.addEventListener('click', onKakao);
|
|
|
|
/* 가운데 버튼 클릭은 click 이 아니라 auxclick 으로 옵니다.
|
|
새 탭에서 열리는 건 똑같으므로 함께 집계합니다.
|
|
(Ctrl+클릭은 button 0 의 click 이라 위에서 이미 잡힙니다) */
|
|
kakao.addEventListener('auxclick', function (e) {
|
|
if (e.button === 1) onKakao();
|
|
});
|
|
}
|
|
}
|
|
|
|
if (!REQUIRE_LOGIN) { show(); return; }
|
|
|
|
/* ── 로그인 판별 ──────────────────────────────────────
|
|
detail-buy-btn.html 과 같은 방식입니다.
|
|
window.MEMBER_UID 로그인 회원의 식별자 (비로그인이면 빈 값)
|
|
_imweb_login_state 로그인 상태 쿠키 ('Y')
|
|
|
|
반환값 : 'in' | 'out' | 'unknown'
|
|
|
|
※ '확실히 로그아웃(out)' 일 때만 튕겨냅니다. 판별이 안 되면
|
|
(unknown) 화면을 보여줍니다. 반대로 하면 아임웹 스크립트가
|
|
늦게 뜬 순간 정상적으로 가입을 마친 사람까지 완료 화면을
|
|
못 보게 됩니다. */
|
|
function loginState() {
|
|
var uid = window.MEMBER_UID;
|
|
var m = /(?:^|;\s*)_imweb_login_state=([^;]*)/.exec(document.cookie || '');
|
|
|
|
if (uid || (m && m[1] === 'Y')) return 'in';
|
|
if (typeof uid === 'string') return 'out';
|
|
return 'unknown';
|
|
}
|
|
|
|
/* 가입 직후 돌아왔는데 판별이 한 박자 늦어 다시 튕겨내는
|
|
무한 왕복을 막습니다. 세션당 한 번만 튕겨냅니다. */
|
|
var ONCE_KEY = 'mg-apply-bounced';
|
|
|
|
function bouncedBefore() {
|
|
try { return window.sessionStorage.getItem(ONCE_KEY) === '1'; }
|
|
catch (e) { return false; } /* 시크릿 모드 등 - 막지 않습니다 */
|
|
}
|
|
|
|
function markBounced() {
|
|
try { window.sessionStorage.setItem(ONCE_KEY, '1'); } catch (e) { }
|
|
}
|
|
|
|
/* 아임웹 복귀 주소 형식 : encodeURIComponent(btoa(주소)) */
|
|
function backUrl(url) {
|
|
try { return encodeURIComponent(window.btoa(url)); }
|
|
catch (e) { return ''; }
|
|
}
|
|
|
|
/* 튕겨냅니다. 성공하면 true (= 완료 화면을 보여주지 않음) */
|
|
function bounce() {
|
|
if (bouncedBefore()) return false;
|
|
markBounced();
|
|
|
|
if (REDIRECT_TO !== 'join') {
|
|
/* replace 를 쓰는 이유 : 뒤로가기로 다시 /apply 에
|
|
들어와 또 튕기는 일이 없게 합니다. */
|
|
window.location.replace(REDIRECT_TO);
|
|
return true;
|
|
}
|
|
|
|
var back = backUrl(window.location.href);
|
|
if (!back) return false;
|
|
|
|
window.location.replace(JOIN_PAGE +
|
|
(JOIN_PAGE.indexOf('?') === -1 ? '?' : '&') +
|
|
'back_url=' + back);
|
|
return true;
|
|
}
|
|
|
|
/* 판별될 때까지 잠깐 기다립니다. 그동안 완료 화면은 숨은 채로
|
|
둡니다. 먼저 보여줬다가 튕겨내면 내용이 한 번 번쩍입니다. */
|
|
var waited = 0;
|
|
(function check() {
|
|
var state = loginState();
|
|
|
|
if (state === 'unknown' && waited < WAIT_MS) {
|
|
waited += POLL_MS;
|
|
window.setTimeout(check, POLL_MS);
|
|
return;
|
|
}
|
|
|
|
if (state === 'out' && bounce()) return;
|
|
show();
|
|
})();
|
|
})();
|
|
</script>
|
|
<!-- ===== 코드 끝 ===== --> |