@adstage/web-sdk 1.3.1 → 1.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs.js +67 -86
- package/dist/index.d.ts +1 -9
- package/dist/index.esm.js +68 -86
- package/dist/index.standalone.js +68 -86
- package/package.json +1 -1
- package/src/index.ts +82 -32
- package/src/managers/event-tracker.ts +0 -48
- package/src/utils/sdk-standalone.ts +0 -20
package/dist/index.cjs.js
CHANGED
|
@@ -1546,46 +1546,6 @@ class EventTracker {
|
|
|
1546
1546
|
}
|
|
1547
1547
|
return 0; // 기본값
|
|
1548
1548
|
}
|
|
1549
|
-
/**
|
|
1550
|
-
* 커스텀 이벤트 추적
|
|
1551
|
-
*/
|
|
1552
|
-
async trackCustomEvent(eventName, params) {
|
|
1553
|
-
try {
|
|
1554
|
-
// 디바이스 정보 수집
|
|
1555
|
-
const deviceInfo = DeviceInfoCollector.collectDeviceInfo();
|
|
1556
|
-
// 커스텀 이벤트 데이터 구성
|
|
1557
|
-
const eventData = {
|
|
1558
|
-
eventName,
|
|
1559
|
-
params: params || {},
|
|
1560
|
-
// 기본 메타데이터
|
|
1561
|
-
userAgent: deviceInfo.userAgent,
|
|
1562
|
-
platform: deviceInfo.platform,
|
|
1563
|
-
screenWidth: deviceInfo.screenWidth,
|
|
1564
|
-
screenHeight: deviceInfo.screenHeight,
|
|
1565
|
-
deviceId: deviceInfo.deviceId,
|
|
1566
|
-
sessionId: deviceInfo.sessionId,
|
|
1567
|
-
timestamp: new Date().toISOString(),
|
|
1568
|
-
// SDK 정보
|
|
1569
|
-
sdkVersion: '1.3.1',
|
|
1570
|
-
eventTimestamp: Date.now(),
|
|
1571
|
-
};
|
|
1572
|
-
// 커스텀 이벤트 API 엔드포인트로 전송
|
|
1573
|
-
await fetch(`${this.baseUrl}/events/custom`, {
|
|
1574
|
-
method: 'POST',
|
|
1575
|
-
headers: {
|
|
1576
|
-
'x-api-key': this.apiKey,
|
|
1577
|
-
'Content-Type': 'application/json',
|
|
1578
|
-
},
|
|
1579
|
-
body: JSON.stringify(eventData),
|
|
1580
|
-
});
|
|
1581
|
-
if (this.debug) {
|
|
1582
|
-
console.log(`📊 커스텀 이벤트 추적: ${eventName}`, eventData);
|
|
1583
|
-
}
|
|
1584
|
-
}
|
|
1585
|
-
catch (error) {
|
|
1586
|
-
console.error('커스텀 이벤트 추적 실패:', error);
|
|
1587
|
-
}
|
|
1588
|
-
}
|
|
1589
1549
|
}
|
|
1590
1550
|
|
|
1591
1551
|
/**
|
|
@@ -1783,25 +1743,6 @@ async function createVideoAd(containerId, options) {
|
|
|
1783
1743
|
muted: options?.muted || true
|
|
1784
1744
|
});
|
|
1785
1745
|
}
|
|
1786
|
-
/**
|
|
1787
|
-
* 커스텀 이벤트 추적
|
|
1788
|
-
*/
|
|
1789
|
-
function trackEvent(eventName, params) {
|
|
1790
|
-
if (!globalSDKInstance) {
|
|
1791
|
-
console.warn('AdStage SDK가 초기화되지 않았습니다. 이벤트 추적을 건너뜁니다.');
|
|
1792
|
-
return;
|
|
1793
|
-
}
|
|
1794
|
-
try {
|
|
1795
|
-
globalSDKInstance.trackCustomEvent(eventName, {
|
|
1796
|
-
timestamp: new Date().toISOString(),
|
|
1797
|
-
...params
|
|
1798
|
-
});
|
|
1799
|
-
console.log(`📊 이벤트 추적: ${eventName}`, params);
|
|
1800
|
-
}
|
|
1801
|
-
catch (error) {
|
|
1802
|
-
console.error('이벤트 추적 실패:', error);
|
|
1803
|
-
}
|
|
1804
|
-
}
|
|
1805
1746
|
/**
|
|
1806
1747
|
* SDK 상태 확인
|
|
1807
1748
|
*/
|
|
@@ -1911,29 +1852,53 @@ class AdStageSDK {
|
|
|
1911
1852
|
...(options?.deviceType && { deviceType: options.deviceType }),
|
|
1912
1853
|
...(options?.country && { country: options.country }),
|
|
1913
1854
|
});
|
|
1914
|
-
const
|
|
1855
|
+
const requestUrl = `${this.baseUrl}/advertisements/list?${queryParams}`;
|
|
1856
|
+
if (this.config.debug) {
|
|
1857
|
+
console.log(`🌐 광고 API 요청 시작:`, {
|
|
1858
|
+
url: requestUrl,
|
|
1859
|
+
apiKey: this.config.apiKey.substring(0, 10) + '...',
|
|
1860
|
+
slot: slot.id
|
|
1861
|
+
});
|
|
1862
|
+
}
|
|
1863
|
+
const response = await fetch(requestUrl, {
|
|
1915
1864
|
headers: {
|
|
1916
1865
|
'x-api-key': this.config.apiKey,
|
|
1917
1866
|
'Content-Type': 'application/json',
|
|
1918
1867
|
},
|
|
1919
1868
|
});
|
|
1869
|
+
if (this.config.debug) {
|
|
1870
|
+
console.log(`📡 API 응답 상태:`, {
|
|
1871
|
+
status: response.status,
|
|
1872
|
+
statusText: response.statusText,
|
|
1873
|
+
ok: response.ok
|
|
1874
|
+
});
|
|
1875
|
+
}
|
|
1920
1876
|
if (!response.ok) {
|
|
1921
1877
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
1922
1878
|
}
|
|
1923
1879
|
const data = await response.json();
|
|
1880
|
+
if (this.config.debug) {
|
|
1881
|
+
console.log(`📊 API 응답 데이터:`, {
|
|
1882
|
+
data,
|
|
1883
|
+
advertisementsCount: data.advertisements ? data.advertisements.length : 0
|
|
1884
|
+
});
|
|
1885
|
+
}
|
|
1924
1886
|
const advertisements = data.advertisements || [];
|
|
1925
1887
|
if (advertisements.length > 0) {
|
|
1888
|
+
if (this.config.debug) {
|
|
1889
|
+
console.log(`✅ ${advertisements.length}개 광고 발견:`, advertisements);
|
|
1890
|
+
}
|
|
1926
1891
|
// 여러 광고가 있을 경우 슬라이드로 렌더링
|
|
1927
1892
|
this.renderSlotWithSlider(slot, advertisements, options);
|
|
1928
1893
|
// 첫 번째 광고에 대해서만 노출 이벤트 추적
|
|
1929
1894
|
await this.eventTracker.trackEvent(advertisements[0]._id, slot.id, exports.AdEventType.IMPRESSION);
|
|
1930
1895
|
}
|
|
1931
1896
|
else {
|
|
1932
|
-
console.warn(
|
|
1897
|
+
console.warn(`⚠️ 슬롯 ${slot.id}에 사용 가능한 광고가 없습니다. API 응답:`, data);
|
|
1933
1898
|
}
|
|
1934
1899
|
}
|
|
1935
1900
|
catch (error) {
|
|
1936
|
-
console.error(
|
|
1901
|
+
console.error(`❌ 슬롯 ${slot.id} 로드 실패:`, error);
|
|
1937
1902
|
}
|
|
1938
1903
|
}
|
|
1939
1904
|
/**
|
|
@@ -1941,8 +1906,18 @@ class AdStageSDK {
|
|
|
1941
1906
|
*/
|
|
1942
1907
|
renderSlotWithSlider(slot, advertisements, options) {
|
|
1943
1908
|
const container = DOMUtils.safeGetElementById(slot.containerId);
|
|
1944
|
-
if (!container)
|
|
1909
|
+
if (!container) {
|
|
1910
|
+
console.error(`❌ 컨테이너를 찾을 수 없습니다: ${slot.containerId}`);
|
|
1945
1911
|
return;
|
|
1912
|
+
}
|
|
1913
|
+
if (this.config.debug) {
|
|
1914
|
+
console.log(`🎨 광고 렌더링 시작:`, {
|
|
1915
|
+
slotId: slot.id,
|
|
1916
|
+
containerId: slot.containerId,
|
|
1917
|
+
advertisementCount: advertisements.length,
|
|
1918
|
+
container: container
|
|
1919
|
+
});
|
|
1920
|
+
}
|
|
1946
1921
|
if (advertisements.length === 1) {
|
|
1947
1922
|
// 광고가 하나뿐이면 기본 렌더링
|
|
1948
1923
|
this.renderSlot(slot, advertisements[0]);
|
|
@@ -1966,7 +1941,11 @@ class AdStageSDK {
|
|
|
1966
1941
|
slot.isLoaded = true;
|
|
1967
1942
|
if (this.config.debug) {
|
|
1968
1943
|
const sliderType = useFadeEffect ? 'fade slider' : 'slider';
|
|
1969
|
-
console.log(
|
|
1944
|
+
console.log(`✅ ${advertisements.length}개 광고를 ${sliderType}로 렌더링 완료:`, {
|
|
1945
|
+
slotId: slot.id,
|
|
1946
|
+
container: container,
|
|
1947
|
+
sliderContainer: sliderContainer
|
|
1948
|
+
});
|
|
1970
1949
|
}
|
|
1971
1950
|
}
|
|
1972
1951
|
/**
|
|
@@ -1974,15 +1953,36 @@ class AdStageSDK {
|
|
|
1974
1953
|
*/
|
|
1975
1954
|
renderSlot(slot, ad) {
|
|
1976
1955
|
const container = DOMUtils.safeGetElementById(slot.containerId);
|
|
1977
|
-
if (!container)
|
|
1956
|
+
if (!container) {
|
|
1957
|
+
console.error(`❌ 컨테이너를 찾을 수 없습니다: ${slot.containerId}`);
|
|
1978
1958
|
return;
|
|
1959
|
+
}
|
|
1960
|
+
if (this.config.debug) {
|
|
1961
|
+
console.log(`🎨 단일 광고 렌더링 시작:`, {
|
|
1962
|
+
slotId: slot.id,
|
|
1963
|
+
containerId: slot.containerId,
|
|
1964
|
+
ad: ad,
|
|
1965
|
+
container: container
|
|
1966
|
+
});
|
|
1967
|
+
}
|
|
1979
1968
|
// 팩토리를 사용해서 적절한 렌더러로 광고 생성
|
|
1980
1969
|
const adElement = AdRendererFactory.render(ad, slot, (adId, slotId, eventType) => this.eventTracker.trackEvent(adId, slotId, eventType));
|
|
1970
|
+
if (this.config.debug) {
|
|
1971
|
+
console.log(`🔧 광고 요소 생성됨:`, {
|
|
1972
|
+
adElement: adElement,
|
|
1973
|
+
tagName: adElement.tagName,
|
|
1974
|
+
innerHTML: adElement.innerHTML.substring(0, 200) + '...'
|
|
1975
|
+
});
|
|
1976
|
+
}
|
|
1981
1977
|
container.innerHTML = '';
|
|
1982
1978
|
container.appendChild(adElement);
|
|
1983
1979
|
slot.isLoaded = true;
|
|
1984
1980
|
if (this.config.debug) {
|
|
1985
|
-
console.log(
|
|
1981
|
+
console.log(`✅ 단일 광고 렌더링 완료:`, {
|
|
1982
|
+
slotId: slot.id,
|
|
1983
|
+
ad: ad,
|
|
1984
|
+
containerContent: container.innerHTML.substring(0, 200) + '...'
|
|
1985
|
+
});
|
|
1986
1986
|
}
|
|
1987
1987
|
}
|
|
1988
1988
|
/**
|
|
@@ -2060,23 +2060,6 @@ class AdStageSDK {
|
|
|
2060
2060
|
getAllSlots() {
|
|
2061
2061
|
return new Map(this.slots);
|
|
2062
2062
|
}
|
|
2063
|
-
/**
|
|
2064
|
-
* 커스텀 이벤트 추적
|
|
2065
|
-
*/
|
|
2066
|
-
trackCustomEvent(eventName, params) {
|
|
2067
|
-
try {
|
|
2068
|
-
this.eventTracker.trackCustomEvent(eventName, {
|
|
2069
|
-
timestamp: new Date().toISOString(),
|
|
2070
|
-
...params
|
|
2071
|
-
});
|
|
2072
|
-
if (this.config.debug) {
|
|
2073
|
-
console.log(`📊 커스텀 이벤트 추적: ${eventName}`, params);
|
|
2074
|
-
}
|
|
2075
|
-
}
|
|
2076
|
-
catch (error) {
|
|
2077
|
-
console.error('커스텀 이벤트 추적 실패:', error);
|
|
2078
|
-
}
|
|
2079
|
-
}
|
|
2080
2063
|
}
|
|
2081
2064
|
AdStageSDK.instance = null;
|
|
2082
2065
|
async function autoInit() {
|
|
@@ -2117,8 +2100,7 @@ var index = /*#__PURE__*/Object.freeze({
|
|
|
2117
2100
|
destroyAdStage: destroyAdStage,
|
|
2118
2101
|
getAdStageInstance: getAdStageInstance,
|
|
2119
2102
|
initAdStage: initAdStage,
|
|
2120
|
-
isAdStageReady: isAdStageReady
|
|
2121
|
-
trackEvent: trackEvent
|
|
2103
|
+
isAdStageReady: isAdStageReady
|
|
2122
2104
|
});
|
|
2123
2105
|
|
|
2124
2106
|
exports.AdStageSDK = AdStageSDK;
|
|
@@ -2130,4 +2112,3 @@ exports.destroyAdStage = destroyAdStage;
|
|
|
2130
2112
|
exports.getAdStageInstance = getAdStageInstance;
|
|
2131
2113
|
exports.initAdStage = initAdStage;
|
|
2132
2114
|
exports.isAdStageReady = isAdStageReady;
|
|
2133
|
-
exports.trackEvent = trackEvent;
|
package/dist/index.d.ts
CHANGED
|
@@ -190,10 +190,6 @@ declare function createVideoAd(containerId: string, options?: {
|
|
|
190
190
|
autoplay?: boolean;
|
|
191
191
|
muted?: boolean;
|
|
192
192
|
}): Promise<void>;
|
|
193
|
-
/**
|
|
194
|
-
* 커스텀 이벤트 추적
|
|
195
|
-
*/
|
|
196
|
-
declare function trackEvent(eventName: string, params?: Record<string, any>): void;
|
|
197
193
|
/**
|
|
198
194
|
* SDK 상태 확인
|
|
199
195
|
*/
|
|
@@ -292,10 +288,6 @@ declare class AdStageSDK {
|
|
|
292
288
|
* 모든 슬롯 정보 가져오기
|
|
293
289
|
*/
|
|
294
290
|
getAllSlots(): Map<string, AdSlot>;
|
|
295
|
-
/**
|
|
296
|
-
* 커스텀 이벤트 추적
|
|
297
|
-
*/
|
|
298
|
-
trackCustomEvent(eventName: string, params?: Record<string, any>): void;
|
|
299
291
|
}
|
|
300
292
|
|
|
301
|
-
export { AdEventType, AdSlot, AdStageConfig, AdStageSDK, AdType, Advertisement, SimpleAdStageConfig, createBanner, createTextAd, createVideoAd, AdStageSDK as default, destroyAdStage, getAdStageInstance, initAdStage, isAdStageReady
|
|
293
|
+
export { AdEventType, AdSlot, AdStageConfig, AdStageSDK, AdType, Advertisement, SimpleAdStageConfig, createBanner, createTextAd, createVideoAd, AdStageSDK as default, destroyAdStage, getAdStageInstance, initAdStage, isAdStageReady };
|
package/dist/index.esm.js
CHANGED
|
@@ -1542,46 +1542,6 @@ class EventTracker {
|
|
|
1542
1542
|
}
|
|
1543
1543
|
return 0; // 기본값
|
|
1544
1544
|
}
|
|
1545
|
-
/**
|
|
1546
|
-
* 커스텀 이벤트 추적
|
|
1547
|
-
*/
|
|
1548
|
-
async trackCustomEvent(eventName, params) {
|
|
1549
|
-
try {
|
|
1550
|
-
// 디바이스 정보 수집
|
|
1551
|
-
const deviceInfo = DeviceInfoCollector.collectDeviceInfo();
|
|
1552
|
-
// 커스텀 이벤트 데이터 구성
|
|
1553
|
-
const eventData = {
|
|
1554
|
-
eventName,
|
|
1555
|
-
params: params || {},
|
|
1556
|
-
// 기본 메타데이터
|
|
1557
|
-
userAgent: deviceInfo.userAgent,
|
|
1558
|
-
platform: deviceInfo.platform,
|
|
1559
|
-
screenWidth: deviceInfo.screenWidth,
|
|
1560
|
-
screenHeight: deviceInfo.screenHeight,
|
|
1561
|
-
deviceId: deviceInfo.deviceId,
|
|
1562
|
-
sessionId: deviceInfo.sessionId,
|
|
1563
|
-
timestamp: new Date().toISOString(),
|
|
1564
|
-
// SDK 정보
|
|
1565
|
-
sdkVersion: '1.3.1',
|
|
1566
|
-
eventTimestamp: Date.now(),
|
|
1567
|
-
};
|
|
1568
|
-
// 커스텀 이벤트 API 엔드포인트로 전송
|
|
1569
|
-
await fetch(`${this.baseUrl}/events/custom`, {
|
|
1570
|
-
method: 'POST',
|
|
1571
|
-
headers: {
|
|
1572
|
-
'x-api-key': this.apiKey,
|
|
1573
|
-
'Content-Type': 'application/json',
|
|
1574
|
-
},
|
|
1575
|
-
body: JSON.stringify(eventData),
|
|
1576
|
-
});
|
|
1577
|
-
if (this.debug) {
|
|
1578
|
-
console.log(`📊 커스텀 이벤트 추적: ${eventName}`, eventData);
|
|
1579
|
-
}
|
|
1580
|
-
}
|
|
1581
|
-
catch (error) {
|
|
1582
|
-
console.error('커스텀 이벤트 추적 실패:', error);
|
|
1583
|
-
}
|
|
1584
|
-
}
|
|
1585
1545
|
}
|
|
1586
1546
|
|
|
1587
1547
|
/**
|
|
@@ -1779,25 +1739,6 @@ async function createVideoAd(containerId, options) {
|
|
|
1779
1739
|
muted: options?.muted || true
|
|
1780
1740
|
});
|
|
1781
1741
|
}
|
|
1782
|
-
/**
|
|
1783
|
-
* 커스텀 이벤트 추적
|
|
1784
|
-
*/
|
|
1785
|
-
function trackEvent(eventName, params) {
|
|
1786
|
-
if (!globalSDKInstance) {
|
|
1787
|
-
console.warn('AdStage SDK가 초기화되지 않았습니다. 이벤트 추적을 건너뜁니다.');
|
|
1788
|
-
return;
|
|
1789
|
-
}
|
|
1790
|
-
try {
|
|
1791
|
-
globalSDKInstance.trackCustomEvent(eventName, {
|
|
1792
|
-
timestamp: new Date().toISOString(),
|
|
1793
|
-
...params
|
|
1794
|
-
});
|
|
1795
|
-
console.log(`📊 이벤트 추적: ${eventName}`, params);
|
|
1796
|
-
}
|
|
1797
|
-
catch (error) {
|
|
1798
|
-
console.error('이벤트 추적 실패:', error);
|
|
1799
|
-
}
|
|
1800
|
-
}
|
|
1801
1742
|
/**
|
|
1802
1743
|
* SDK 상태 확인
|
|
1803
1744
|
*/
|
|
@@ -1907,29 +1848,53 @@ class AdStageSDK {
|
|
|
1907
1848
|
...(options?.deviceType && { deviceType: options.deviceType }),
|
|
1908
1849
|
...(options?.country && { country: options.country }),
|
|
1909
1850
|
});
|
|
1910
|
-
const
|
|
1851
|
+
const requestUrl = `${this.baseUrl}/advertisements/list?${queryParams}`;
|
|
1852
|
+
if (this.config.debug) {
|
|
1853
|
+
console.log(`🌐 광고 API 요청 시작:`, {
|
|
1854
|
+
url: requestUrl,
|
|
1855
|
+
apiKey: this.config.apiKey.substring(0, 10) + '...',
|
|
1856
|
+
slot: slot.id
|
|
1857
|
+
});
|
|
1858
|
+
}
|
|
1859
|
+
const response = await fetch(requestUrl, {
|
|
1911
1860
|
headers: {
|
|
1912
1861
|
'x-api-key': this.config.apiKey,
|
|
1913
1862
|
'Content-Type': 'application/json',
|
|
1914
1863
|
},
|
|
1915
1864
|
});
|
|
1865
|
+
if (this.config.debug) {
|
|
1866
|
+
console.log(`📡 API 응답 상태:`, {
|
|
1867
|
+
status: response.status,
|
|
1868
|
+
statusText: response.statusText,
|
|
1869
|
+
ok: response.ok
|
|
1870
|
+
});
|
|
1871
|
+
}
|
|
1916
1872
|
if (!response.ok) {
|
|
1917
1873
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
1918
1874
|
}
|
|
1919
1875
|
const data = await response.json();
|
|
1876
|
+
if (this.config.debug) {
|
|
1877
|
+
console.log(`📊 API 응답 데이터:`, {
|
|
1878
|
+
data,
|
|
1879
|
+
advertisementsCount: data.advertisements ? data.advertisements.length : 0
|
|
1880
|
+
});
|
|
1881
|
+
}
|
|
1920
1882
|
const advertisements = data.advertisements || [];
|
|
1921
1883
|
if (advertisements.length > 0) {
|
|
1884
|
+
if (this.config.debug) {
|
|
1885
|
+
console.log(`✅ ${advertisements.length}개 광고 발견:`, advertisements);
|
|
1886
|
+
}
|
|
1922
1887
|
// 여러 광고가 있을 경우 슬라이드로 렌더링
|
|
1923
1888
|
this.renderSlotWithSlider(slot, advertisements, options);
|
|
1924
1889
|
// 첫 번째 광고에 대해서만 노출 이벤트 추적
|
|
1925
1890
|
await this.eventTracker.trackEvent(advertisements[0]._id, slot.id, AdEventType.IMPRESSION);
|
|
1926
1891
|
}
|
|
1927
1892
|
else {
|
|
1928
|
-
console.warn(
|
|
1893
|
+
console.warn(`⚠️ 슬롯 ${slot.id}에 사용 가능한 광고가 없습니다. API 응답:`, data);
|
|
1929
1894
|
}
|
|
1930
1895
|
}
|
|
1931
1896
|
catch (error) {
|
|
1932
|
-
console.error(
|
|
1897
|
+
console.error(`❌ 슬롯 ${slot.id} 로드 실패:`, error);
|
|
1933
1898
|
}
|
|
1934
1899
|
}
|
|
1935
1900
|
/**
|
|
@@ -1937,8 +1902,18 @@ class AdStageSDK {
|
|
|
1937
1902
|
*/
|
|
1938
1903
|
renderSlotWithSlider(slot, advertisements, options) {
|
|
1939
1904
|
const container = DOMUtils.safeGetElementById(slot.containerId);
|
|
1940
|
-
if (!container)
|
|
1905
|
+
if (!container) {
|
|
1906
|
+
console.error(`❌ 컨테이너를 찾을 수 없습니다: ${slot.containerId}`);
|
|
1941
1907
|
return;
|
|
1908
|
+
}
|
|
1909
|
+
if (this.config.debug) {
|
|
1910
|
+
console.log(`🎨 광고 렌더링 시작:`, {
|
|
1911
|
+
slotId: slot.id,
|
|
1912
|
+
containerId: slot.containerId,
|
|
1913
|
+
advertisementCount: advertisements.length,
|
|
1914
|
+
container: container
|
|
1915
|
+
});
|
|
1916
|
+
}
|
|
1942
1917
|
if (advertisements.length === 1) {
|
|
1943
1918
|
// 광고가 하나뿐이면 기본 렌더링
|
|
1944
1919
|
this.renderSlot(slot, advertisements[0]);
|
|
@@ -1962,7 +1937,11 @@ class AdStageSDK {
|
|
|
1962
1937
|
slot.isLoaded = true;
|
|
1963
1938
|
if (this.config.debug) {
|
|
1964
1939
|
const sliderType = useFadeEffect ? 'fade slider' : 'slider';
|
|
1965
|
-
console.log(
|
|
1940
|
+
console.log(`✅ ${advertisements.length}개 광고를 ${sliderType}로 렌더링 완료:`, {
|
|
1941
|
+
slotId: slot.id,
|
|
1942
|
+
container: container,
|
|
1943
|
+
sliderContainer: sliderContainer
|
|
1944
|
+
});
|
|
1966
1945
|
}
|
|
1967
1946
|
}
|
|
1968
1947
|
/**
|
|
@@ -1970,15 +1949,36 @@ class AdStageSDK {
|
|
|
1970
1949
|
*/
|
|
1971
1950
|
renderSlot(slot, ad) {
|
|
1972
1951
|
const container = DOMUtils.safeGetElementById(slot.containerId);
|
|
1973
|
-
if (!container)
|
|
1952
|
+
if (!container) {
|
|
1953
|
+
console.error(`❌ 컨테이너를 찾을 수 없습니다: ${slot.containerId}`);
|
|
1974
1954
|
return;
|
|
1955
|
+
}
|
|
1956
|
+
if (this.config.debug) {
|
|
1957
|
+
console.log(`🎨 단일 광고 렌더링 시작:`, {
|
|
1958
|
+
slotId: slot.id,
|
|
1959
|
+
containerId: slot.containerId,
|
|
1960
|
+
ad: ad,
|
|
1961
|
+
container: container
|
|
1962
|
+
});
|
|
1963
|
+
}
|
|
1975
1964
|
// 팩토리를 사용해서 적절한 렌더러로 광고 생성
|
|
1976
1965
|
const adElement = AdRendererFactory.render(ad, slot, (adId, slotId, eventType) => this.eventTracker.trackEvent(adId, slotId, eventType));
|
|
1966
|
+
if (this.config.debug) {
|
|
1967
|
+
console.log(`🔧 광고 요소 생성됨:`, {
|
|
1968
|
+
adElement: adElement,
|
|
1969
|
+
tagName: adElement.tagName,
|
|
1970
|
+
innerHTML: adElement.innerHTML.substring(0, 200) + '...'
|
|
1971
|
+
});
|
|
1972
|
+
}
|
|
1977
1973
|
container.innerHTML = '';
|
|
1978
1974
|
container.appendChild(adElement);
|
|
1979
1975
|
slot.isLoaded = true;
|
|
1980
1976
|
if (this.config.debug) {
|
|
1981
|
-
console.log(
|
|
1977
|
+
console.log(`✅ 단일 광고 렌더링 완료:`, {
|
|
1978
|
+
slotId: slot.id,
|
|
1979
|
+
ad: ad,
|
|
1980
|
+
containerContent: container.innerHTML.substring(0, 200) + '...'
|
|
1981
|
+
});
|
|
1982
1982
|
}
|
|
1983
1983
|
}
|
|
1984
1984
|
/**
|
|
@@ -2056,23 +2056,6 @@ class AdStageSDK {
|
|
|
2056
2056
|
getAllSlots() {
|
|
2057
2057
|
return new Map(this.slots);
|
|
2058
2058
|
}
|
|
2059
|
-
/**
|
|
2060
|
-
* 커스텀 이벤트 추적
|
|
2061
|
-
*/
|
|
2062
|
-
trackCustomEvent(eventName, params) {
|
|
2063
|
-
try {
|
|
2064
|
-
this.eventTracker.trackCustomEvent(eventName, {
|
|
2065
|
-
timestamp: new Date().toISOString(),
|
|
2066
|
-
...params
|
|
2067
|
-
});
|
|
2068
|
-
if (this.config.debug) {
|
|
2069
|
-
console.log(`📊 커스텀 이벤트 추적: ${eventName}`, params);
|
|
2070
|
-
}
|
|
2071
|
-
}
|
|
2072
|
-
catch (error) {
|
|
2073
|
-
console.error('커스텀 이벤트 추적 실패:', error);
|
|
2074
|
-
}
|
|
2075
|
-
}
|
|
2076
2059
|
}
|
|
2077
2060
|
AdStageSDK.instance = null;
|
|
2078
2061
|
async function autoInit() {
|
|
@@ -2113,8 +2096,7 @@ var index = /*#__PURE__*/Object.freeze({
|
|
|
2113
2096
|
destroyAdStage: destroyAdStage,
|
|
2114
2097
|
getAdStageInstance: getAdStageInstance,
|
|
2115
2098
|
initAdStage: initAdStage,
|
|
2116
|
-
isAdStageReady: isAdStageReady
|
|
2117
|
-
trackEvent: trackEvent
|
|
2099
|
+
isAdStageReady: isAdStageReady
|
|
2118
2100
|
});
|
|
2119
2101
|
|
|
2120
|
-
export { AdEventType, AdStageSDK, AdType, createBanner, createTextAd, createVideoAd, AdStageSDK as default, destroyAdStage, getAdStageInstance, initAdStage, isAdStageReady
|
|
2102
|
+
export { AdEventType, AdStageSDK, AdType, createBanner, createTextAd, createVideoAd, AdStageSDK as default, destroyAdStage, getAdStageInstance, initAdStage, isAdStageReady };
|
package/dist/index.standalone.js
CHANGED
|
@@ -1542,46 +1542,6 @@ class EventTracker {
|
|
|
1542
1542
|
}
|
|
1543
1543
|
return 0; // 기본값
|
|
1544
1544
|
}
|
|
1545
|
-
/**
|
|
1546
|
-
* 커스텀 이벤트 추적
|
|
1547
|
-
*/
|
|
1548
|
-
async trackCustomEvent(eventName, params) {
|
|
1549
|
-
try {
|
|
1550
|
-
// 디바이스 정보 수집
|
|
1551
|
-
const deviceInfo = DeviceInfoCollector.collectDeviceInfo();
|
|
1552
|
-
// 커스텀 이벤트 데이터 구성
|
|
1553
|
-
const eventData = {
|
|
1554
|
-
eventName,
|
|
1555
|
-
params: params || {},
|
|
1556
|
-
// 기본 메타데이터
|
|
1557
|
-
userAgent: deviceInfo.userAgent,
|
|
1558
|
-
platform: deviceInfo.platform,
|
|
1559
|
-
screenWidth: deviceInfo.screenWidth,
|
|
1560
|
-
screenHeight: deviceInfo.screenHeight,
|
|
1561
|
-
deviceId: deviceInfo.deviceId,
|
|
1562
|
-
sessionId: deviceInfo.sessionId,
|
|
1563
|
-
timestamp: new Date().toISOString(),
|
|
1564
|
-
// SDK 정보
|
|
1565
|
-
sdkVersion: '1.3.1',
|
|
1566
|
-
eventTimestamp: Date.now(),
|
|
1567
|
-
};
|
|
1568
|
-
// 커스텀 이벤트 API 엔드포인트로 전송
|
|
1569
|
-
await fetch(`${this.baseUrl}/events/custom`, {
|
|
1570
|
-
method: 'POST',
|
|
1571
|
-
headers: {
|
|
1572
|
-
'x-api-key': this.apiKey,
|
|
1573
|
-
'Content-Type': 'application/json',
|
|
1574
|
-
},
|
|
1575
|
-
body: JSON.stringify(eventData),
|
|
1576
|
-
});
|
|
1577
|
-
if (this.debug) {
|
|
1578
|
-
console.log(`📊 커스텀 이벤트 추적: ${eventName}`, eventData);
|
|
1579
|
-
}
|
|
1580
|
-
}
|
|
1581
|
-
catch (error) {
|
|
1582
|
-
console.error('커스텀 이벤트 추적 실패:', error);
|
|
1583
|
-
}
|
|
1584
|
-
}
|
|
1585
1545
|
}
|
|
1586
1546
|
|
|
1587
1547
|
/**
|
|
@@ -1779,25 +1739,6 @@ async function createVideoAd(containerId, options) {
|
|
|
1779
1739
|
muted: options?.muted || true
|
|
1780
1740
|
});
|
|
1781
1741
|
}
|
|
1782
|
-
/**
|
|
1783
|
-
* 커스텀 이벤트 추적
|
|
1784
|
-
*/
|
|
1785
|
-
function trackEvent(eventName, params) {
|
|
1786
|
-
if (!globalSDKInstance) {
|
|
1787
|
-
console.warn('AdStage SDK가 초기화되지 않았습니다. 이벤트 추적을 건너뜁니다.');
|
|
1788
|
-
return;
|
|
1789
|
-
}
|
|
1790
|
-
try {
|
|
1791
|
-
globalSDKInstance.trackCustomEvent(eventName, {
|
|
1792
|
-
timestamp: new Date().toISOString(),
|
|
1793
|
-
...params
|
|
1794
|
-
});
|
|
1795
|
-
console.log(`📊 이벤트 추적: ${eventName}`, params);
|
|
1796
|
-
}
|
|
1797
|
-
catch (error) {
|
|
1798
|
-
console.error('이벤트 추적 실패:', error);
|
|
1799
|
-
}
|
|
1800
|
-
}
|
|
1801
1742
|
/**
|
|
1802
1743
|
* SDK 상태 확인
|
|
1803
1744
|
*/
|
|
@@ -1907,29 +1848,53 @@ class AdStageSDK {
|
|
|
1907
1848
|
...(options?.deviceType && { deviceType: options.deviceType }),
|
|
1908
1849
|
...(options?.country && { country: options.country }),
|
|
1909
1850
|
});
|
|
1910
|
-
const
|
|
1851
|
+
const requestUrl = `${this.baseUrl}/advertisements/list?${queryParams}`;
|
|
1852
|
+
if (this.config.debug) {
|
|
1853
|
+
console.log(`🌐 광고 API 요청 시작:`, {
|
|
1854
|
+
url: requestUrl,
|
|
1855
|
+
apiKey: this.config.apiKey.substring(0, 10) + '...',
|
|
1856
|
+
slot: slot.id
|
|
1857
|
+
});
|
|
1858
|
+
}
|
|
1859
|
+
const response = await fetch(requestUrl, {
|
|
1911
1860
|
headers: {
|
|
1912
1861
|
'x-api-key': this.config.apiKey,
|
|
1913
1862
|
'Content-Type': 'application/json',
|
|
1914
1863
|
},
|
|
1915
1864
|
});
|
|
1865
|
+
if (this.config.debug) {
|
|
1866
|
+
console.log(`📡 API 응답 상태:`, {
|
|
1867
|
+
status: response.status,
|
|
1868
|
+
statusText: response.statusText,
|
|
1869
|
+
ok: response.ok
|
|
1870
|
+
});
|
|
1871
|
+
}
|
|
1916
1872
|
if (!response.ok) {
|
|
1917
1873
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
1918
1874
|
}
|
|
1919
1875
|
const data = await response.json();
|
|
1876
|
+
if (this.config.debug) {
|
|
1877
|
+
console.log(`📊 API 응답 데이터:`, {
|
|
1878
|
+
data,
|
|
1879
|
+
advertisementsCount: data.advertisements ? data.advertisements.length : 0
|
|
1880
|
+
});
|
|
1881
|
+
}
|
|
1920
1882
|
const advertisements = data.advertisements || [];
|
|
1921
1883
|
if (advertisements.length > 0) {
|
|
1884
|
+
if (this.config.debug) {
|
|
1885
|
+
console.log(`✅ ${advertisements.length}개 광고 발견:`, advertisements);
|
|
1886
|
+
}
|
|
1922
1887
|
// 여러 광고가 있을 경우 슬라이드로 렌더링
|
|
1923
1888
|
this.renderSlotWithSlider(slot, advertisements, options);
|
|
1924
1889
|
// 첫 번째 광고에 대해서만 노출 이벤트 추적
|
|
1925
1890
|
await this.eventTracker.trackEvent(advertisements[0]._id, slot.id, AdEventType.IMPRESSION);
|
|
1926
1891
|
}
|
|
1927
1892
|
else {
|
|
1928
|
-
console.warn(
|
|
1893
|
+
console.warn(`⚠️ 슬롯 ${slot.id}에 사용 가능한 광고가 없습니다. API 응답:`, data);
|
|
1929
1894
|
}
|
|
1930
1895
|
}
|
|
1931
1896
|
catch (error) {
|
|
1932
|
-
console.error(
|
|
1897
|
+
console.error(`❌ 슬롯 ${slot.id} 로드 실패:`, error);
|
|
1933
1898
|
}
|
|
1934
1899
|
}
|
|
1935
1900
|
/**
|
|
@@ -1937,8 +1902,18 @@ class AdStageSDK {
|
|
|
1937
1902
|
*/
|
|
1938
1903
|
renderSlotWithSlider(slot, advertisements, options) {
|
|
1939
1904
|
const container = DOMUtils.safeGetElementById(slot.containerId);
|
|
1940
|
-
if (!container)
|
|
1905
|
+
if (!container) {
|
|
1906
|
+
console.error(`❌ 컨테이너를 찾을 수 없습니다: ${slot.containerId}`);
|
|
1941
1907
|
return;
|
|
1908
|
+
}
|
|
1909
|
+
if (this.config.debug) {
|
|
1910
|
+
console.log(`🎨 광고 렌더링 시작:`, {
|
|
1911
|
+
slotId: slot.id,
|
|
1912
|
+
containerId: slot.containerId,
|
|
1913
|
+
advertisementCount: advertisements.length,
|
|
1914
|
+
container: container
|
|
1915
|
+
});
|
|
1916
|
+
}
|
|
1942
1917
|
if (advertisements.length === 1) {
|
|
1943
1918
|
// 광고가 하나뿐이면 기본 렌더링
|
|
1944
1919
|
this.renderSlot(slot, advertisements[0]);
|
|
@@ -1962,7 +1937,11 @@ class AdStageSDK {
|
|
|
1962
1937
|
slot.isLoaded = true;
|
|
1963
1938
|
if (this.config.debug) {
|
|
1964
1939
|
const sliderType = useFadeEffect ? 'fade slider' : 'slider';
|
|
1965
|
-
console.log(
|
|
1940
|
+
console.log(`✅ ${advertisements.length}개 광고를 ${sliderType}로 렌더링 완료:`, {
|
|
1941
|
+
slotId: slot.id,
|
|
1942
|
+
container: container,
|
|
1943
|
+
sliderContainer: sliderContainer
|
|
1944
|
+
});
|
|
1966
1945
|
}
|
|
1967
1946
|
}
|
|
1968
1947
|
/**
|
|
@@ -1970,15 +1949,36 @@ class AdStageSDK {
|
|
|
1970
1949
|
*/
|
|
1971
1950
|
renderSlot(slot, ad) {
|
|
1972
1951
|
const container = DOMUtils.safeGetElementById(slot.containerId);
|
|
1973
|
-
if (!container)
|
|
1952
|
+
if (!container) {
|
|
1953
|
+
console.error(`❌ 컨테이너를 찾을 수 없습니다: ${slot.containerId}`);
|
|
1974
1954
|
return;
|
|
1955
|
+
}
|
|
1956
|
+
if (this.config.debug) {
|
|
1957
|
+
console.log(`🎨 단일 광고 렌더링 시작:`, {
|
|
1958
|
+
slotId: slot.id,
|
|
1959
|
+
containerId: slot.containerId,
|
|
1960
|
+
ad: ad,
|
|
1961
|
+
container: container
|
|
1962
|
+
});
|
|
1963
|
+
}
|
|
1975
1964
|
// 팩토리를 사용해서 적절한 렌더러로 광고 생성
|
|
1976
1965
|
const adElement = AdRendererFactory.render(ad, slot, (adId, slotId, eventType) => this.eventTracker.trackEvent(adId, slotId, eventType));
|
|
1966
|
+
if (this.config.debug) {
|
|
1967
|
+
console.log(`🔧 광고 요소 생성됨:`, {
|
|
1968
|
+
adElement: adElement,
|
|
1969
|
+
tagName: adElement.tagName,
|
|
1970
|
+
innerHTML: adElement.innerHTML.substring(0, 200) + '...'
|
|
1971
|
+
});
|
|
1972
|
+
}
|
|
1977
1973
|
container.innerHTML = '';
|
|
1978
1974
|
container.appendChild(adElement);
|
|
1979
1975
|
slot.isLoaded = true;
|
|
1980
1976
|
if (this.config.debug) {
|
|
1981
|
-
console.log(
|
|
1977
|
+
console.log(`✅ 단일 광고 렌더링 완료:`, {
|
|
1978
|
+
slotId: slot.id,
|
|
1979
|
+
ad: ad,
|
|
1980
|
+
containerContent: container.innerHTML.substring(0, 200) + '...'
|
|
1981
|
+
});
|
|
1982
1982
|
}
|
|
1983
1983
|
}
|
|
1984
1984
|
/**
|
|
@@ -2056,23 +2056,6 @@ class AdStageSDK {
|
|
|
2056
2056
|
getAllSlots() {
|
|
2057
2057
|
return new Map(this.slots);
|
|
2058
2058
|
}
|
|
2059
|
-
/**
|
|
2060
|
-
* 커스텀 이벤트 추적
|
|
2061
|
-
*/
|
|
2062
|
-
trackCustomEvent(eventName, params) {
|
|
2063
|
-
try {
|
|
2064
|
-
this.eventTracker.trackCustomEvent(eventName, {
|
|
2065
|
-
timestamp: new Date().toISOString(),
|
|
2066
|
-
...params
|
|
2067
|
-
});
|
|
2068
|
-
if (this.config.debug) {
|
|
2069
|
-
console.log(`📊 커스텀 이벤트 추적: ${eventName}`, params);
|
|
2070
|
-
}
|
|
2071
|
-
}
|
|
2072
|
-
catch (error) {
|
|
2073
|
-
console.error('커스텀 이벤트 추적 실패:', error);
|
|
2074
|
-
}
|
|
2075
|
-
}
|
|
2076
2059
|
}
|
|
2077
2060
|
AdStageSDK.instance = null;
|
|
2078
2061
|
async function autoInit() {
|
|
@@ -2113,8 +2096,7 @@ var index = /*#__PURE__*/Object.freeze({
|
|
|
2113
2096
|
destroyAdStage: destroyAdStage,
|
|
2114
2097
|
getAdStageInstance: getAdStageInstance,
|
|
2115
2098
|
initAdStage: initAdStage,
|
|
2116
|
-
isAdStageReady: isAdStageReady
|
|
2117
|
-
trackEvent: trackEvent
|
|
2099
|
+
isAdStageReady: isAdStageReady
|
|
2118
2100
|
});
|
|
2119
2101
|
|
|
2120
|
-
export { AdEventType, AdStageSDK, AdType, createBanner, createTextAd, createVideoAd, AdStageSDK as default, destroyAdStage, getAdStageInstance, initAdStage, isAdStageReady
|
|
2102
|
+
export { AdEventType, AdStageSDK, AdType, createBanner, createTextAd, createVideoAd, AdStageSDK as default, destroyAdStage, getAdStageInstance, initAdStage, isAdStageReady };
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -127,34 +127,61 @@ export class AdStageSDK {
|
|
|
127
127
|
...(options?.country && { country: options.country }),
|
|
128
128
|
});
|
|
129
129
|
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
138
|
-
|
|
130
|
+
const requestUrl = `${this.baseUrl}/advertisements/list?${queryParams}`;
|
|
131
|
+
|
|
132
|
+
if (this.config.debug) {
|
|
133
|
+
console.log(`🌐 광고 API 요청 시작:`, {
|
|
134
|
+
url: requestUrl,
|
|
135
|
+
apiKey: this.config.apiKey.substring(0, 10) + '...',
|
|
136
|
+
slot: slot.id
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const response = await fetch(requestUrl, {
|
|
141
|
+
headers: {
|
|
142
|
+
'x-api-key': this.config.apiKey,
|
|
143
|
+
'Content-Type': 'application/json',
|
|
144
|
+
},
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
if (this.config.debug) {
|
|
148
|
+
console.log(`📡 API 응답 상태:`, {
|
|
149
|
+
status: response.status,
|
|
150
|
+
statusText: response.statusText,
|
|
151
|
+
ok: response.ok
|
|
152
|
+
});
|
|
153
|
+
}
|
|
139
154
|
|
|
140
155
|
if (!response.ok) {
|
|
141
156
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
142
157
|
}
|
|
143
158
|
|
|
144
159
|
const data = await response.json();
|
|
160
|
+
|
|
161
|
+
if (this.config.debug) {
|
|
162
|
+
console.log(`📊 API 응답 데이터:`, {
|
|
163
|
+
data,
|
|
164
|
+
advertisementsCount: data.advertisements ? data.advertisements.length : 0
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
|
|
145
168
|
const advertisements = data.advertisements || [];
|
|
146
169
|
|
|
147
170
|
if (advertisements.length > 0) {
|
|
171
|
+
if (this.config.debug) {
|
|
172
|
+
console.log(`✅ ${advertisements.length}개 광고 발견:`, advertisements);
|
|
173
|
+
}
|
|
174
|
+
|
|
148
175
|
// 여러 광고가 있을 경우 슬라이드로 렌더링
|
|
149
176
|
this.renderSlotWithSlider(slot, advertisements, options);
|
|
150
177
|
|
|
151
178
|
// 첫 번째 광고에 대해서만 노출 이벤트 추적
|
|
152
179
|
await this.eventTracker.trackEvent(advertisements[0]._id, slot.id, AdEventType.IMPRESSION);
|
|
153
180
|
} else {
|
|
154
|
-
console.warn(
|
|
181
|
+
console.warn(`⚠️ 슬롯 ${slot.id}에 사용 가능한 광고가 없습니다. API 응답:`, data);
|
|
155
182
|
}
|
|
156
183
|
} catch (error) {
|
|
157
|
-
console.error(
|
|
184
|
+
console.error(`❌ 슬롯 ${slot.id} 로드 실패:`, error);
|
|
158
185
|
}
|
|
159
186
|
}
|
|
160
187
|
|
|
@@ -163,7 +190,19 @@ export class AdStageSDK {
|
|
|
163
190
|
*/
|
|
164
191
|
private renderSlotWithSlider(slot: AdSlot, advertisements: Advertisement[], options?: any): void {
|
|
165
192
|
const container = DOMUtils.safeGetElementById(slot.containerId);
|
|
166
|
-
if (!container)
|
|
193
|
+
if (!container) {
|
|
194
|
+
console.error(`❌ 컨테이너를 찾을 수 없습니다: ${slot.containerId}`);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (this.config.debug) {
|
|
199
|
+
console.log(`🎨 광고 렌더링 시작:`, {
|
|
200
|
+
slotId: slot.id,
|
|
201
|
+
containerId: slot.containerId,
|
|
202
|
+
advertisementCount: advertisements.length,
|
|
203
|
+
container: container
|
|
204
|
+
});
|
|
205
|
+
}
|
|
167
206
|
|
|
168
207
|
if (advertisements.length === 1) {
|
|
169
208
|
// 광고가 하나뿐이면 기본 렌더링
|
|
@@ -202,7 +241,11 @@ export class AdStageSDK {
|
|
|
202
241
|
|
|
203
242
|
if (this.config.debug) {
|
|
204
243
|
const sliderType = useFadeEffect ? 'fade slider' : 'slider';
|
|
205
|
-
console.log(
|
|
244
|
+
console.log(`✅ ${advertisements.length}개 광고를 ${sliderType}로 렌더링 완료:`, {
|
|
245
|
+
slotId: slot.id,
|
|
246
|
+
container: container,
|
|
247
|
+
sliderContainer: sliderContainer
|
|
248
|
+
});
|
|
206
249
|
}
|
|
207
250
|
}
|
|
208
251
|
|
|
@@ -211,7 +254,19 @@ export class AdStageSDK {
|
|
|
211
254
|
*/
|
|
212
255
|
private renderSlot(slot: AdSlot, ad: Advertisement): void {
|
|
213
256
|
const container = DOMUtils.safeGetElementById(slot.containerId);
|
|
214
|
-
if (!container)
|
|
257
|
+
if (!container) {
|
|
258
|
+
console.error(`❌ 컨테이너를 찾을 수 없습니다: ${slot.containerId}`);
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (this.config.debug) {
|
|
263
|
+
console.log(`🎨 단일 광고 렌더링 시작:`, {
|
|
264
|
+
slotId: slot.id,
|
|
265
|
+
containerId: slot.containerId,
|
|
266
|
+
ad: ad,
|
|
267
|
+
container: container
|
|
268
|
+
});
|
|
269
|
+
}
|
|
215
270
|
|
|
216
271
|
// 팩토리를 사용해서 적절한 렌더러로 광고 생성
|
|
217
272
|
const adElement = AdRendererFactory.render(
|
|
@@ -220,12 +275,24 @@ export class AdStageSDK {
|
|
|
220
275
|
(adId, slotId, eventType) => this.eventTracker.trackEvent(adId, slotId, eventType)
|
|
221
276
|
);
|
|
222
277
|
|
|
278
|
+
if (this.config.debug) {
|
|
279
|
+
console.log(`🔧 광고 요소 생성됨:`, {
|
|
280
|
+
adElement: adElement,
|
|
281
|
+
tagName: adElement.tagName,
|
|
282
|
+
innerHTML: adElement.innerHTML.substring(0, 200) + '...'
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
|
|
223
286
|
container.innerHTML = '';
|
|
224
287
|
container.appendChild(adElement);
|
|
225
288
|
slot.isLoaded = true;
|
|
226
289
|
|
|
227
290
|
if (this.config.debug) {
|
|
228
|
-
console.log(
|
|
291
|
+
console.log(`✅ 단일 광고 렌더링 완료:`, {
|
|
292
|
+
slotId: slot.id,
|
|
293
|
+
ad: ad,
|
|
294
|
+
containerContent: container.innerHTML.substring(0, 200) + '...'
|
|
295
|
+
});
|
|
229
296
|
}
|
|
230
297
|
}
|
|
231
298
|
|
|
@@ -314,23 +381,6 @@ export class AdStageSDK {
|
|
|
314
381
|
getAllSlots(): Map<string, AdSlot> {
|
|
315
382
|
return new Map(this.slots);
|
|
316
383
|
}
|
|
317
|
-
|
|
318
|
-
/**
|
|
319
|
-
* 커스텀 이벤트 추적
|
|
320
|
-
*/
|
|
321
|
-
trackCustomEvent(eventName: string, params?: Record<string, any>): void {
|
|
322
|
-
try {
|
|
323
|
-
this.eventTracker.trackCustomEvent(eventName, {
|
|
324
|
-
timestamp: new Date().toISOString(),
|
|
325
|
-
...params
|
|
326
|
-
});
|
|
327
|
-
if (this.config.debug) {
|
|
328
|
-
console.log(`📊 커스텀 이벤트 추적: ${eventName}`, params);
|
|
329
|
-
}
|
|
330
|
-
} catch (error) {
|
|
331
|
-
console.error('커스텀 이벤트 추적 실패:', error);
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
384
|
}
|
|
335
385
|
|
|
336
386
|
async function autoInit() {
|
|
@@ -128,52 +128,4 @@ export class EventTracker {
|
|
|
128
128
|
|
|
129
129
|
return 0; // 기본값
|
|
130
130
|
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* 커스텀 이벤트 추적
|
|
134
|
-
*/
|
|
135
|
-
async trackCustomEvent(eventName: string, params?: Record<string, any>): Promise<void> {
|
|
136
|
-
try {
|
|
137
|
-
// 디바이스 정보 수집
|
|
138
|
-
const deviceInfo = DeviceInfoCollector.collectDeviceInfo();
|
|
139
|
-
|
|
140
|
-
// 커스텀 이벤트 데이터 구성
|
|
141
|
-
const eventData = {
|
|
142
|
-
eventName,
|
|
143
|
-
params: params || {},
|
|
144
|
-
|
|
145
|
-
// 기본 메타데이터
|
|
146
|
-
userAgent: deviceInfo.userAgent,
|
|
147
|
-
platform: deviceInfo.platform,
|
|
148
|
-
screenWidth: deviceInfo.screenWidth,
|
|
149
|
-
screenHeight: deviceInfo.screenHeight,
|
|
150
|
-
deviceId: deviceInfo.deviceId,
|
|
151
|
-
sessionId: deviceInfo.sessionId,
|
|
152
|
-
timestamp: new Date().toISOString(),
|
|
153
|
-
|
|
154
|
-
// SDK 정보
|
|
155
|
-
sdkVersion: '1.3.1',
|
|
156
|
-
eventTimestamp: Date.now(),
|
|
157
|
-
};
|
|
158
|
-
|
|
159
|
-
// 커스텀 이벤트 API 엔드포인트로 전송
|
|
160
|
-
await fetch(
|
|
161
|
-
`${this.baseUrl}/events/custom`,
|
|
162
|
-
{
|
|
163
|
-
method: 'POST',
|
|
164
|
-
headers: {
|
|
165
|
-
'x-api-key': this.apiKey,
|
|
166
|
-
'Content-Type': 'application/json',
|
|
167
|
-
},
|
|
168
|
-
body: JSON.stringify(eventData),
|
|
169
|
-
}
|
|
170
|
-
);
|
|
171
|
-
|
|
172
|
-
if (this.debug) {
|
|
173
|
-
console.log(`📊 커스텀 이벤트 추적: ${eventName}`, eventData);
|
|
174
|
-
}
|
|
175
|
-
} catch (error) {
|
|
176
|
-
console.error('커스텀 이벤트 추적 실패:', error);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
131
|
}
|
|
@@ -121,26 +121,6 @@ export async function createVideoAd(
|
|
|
121
121
|
});
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
/**
|
|
125
|
-
* 커스텀 이벤트 추적
|
|
126
|
-
*/
|
|
127
|
-
export function trackEvent(eventName: string, params?: Record<string, any>): void {
|
|
128
|
-
if (!globalSDKInstance) {
|
|
129
|
-
console.warn('AdStage SDK가 초기화되지 않았습니다. 이벤트 추적을 건너뜁니다.');
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
try {
|
|
134
|
-
globalSDKInstance.trackCustomEvent(eventName, {
|
|
135
|
-
timestamp: new Date().toISOString(),
|
|
136
|
-
...params
|
|
137
|
-
});
|
|
138
|
-
console.log(`📊 이벤트 추적: ${eventName}`, params);
|
|
139
|
-
} catch (error) {
|
|
140
|
-
console.error('이벤트 추적 실패:', error);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
124
|
/**
|
|
145
125
|
* SDK 상태 확인
|
|
146
126
|
*/
|