333 lines
9.4 KiB
TypeScript
333 lines
9.4 KiB
TypeScript
import * as amplitude from '@amplitude/analytics-browser'
|
|
import type {
|
|
AnalyticsDetailType,
|
|
AnalyticsLogDataTracking,
|
|
} from '../types/AnalyticsType'
|
|
import type { PageDataResourceGroup } from '#layers/types/api/pageData'
|
|
import type { IdentityInfo, ActionInfo, MarketingInfo } from '../types/Stove'
|
|
|
|
declare const svcLog: any
|
|
declare const twq: any
|
|
declare const ttq: any
|
|
|
|
/**
|
|
* 페이지 데이터와 템플릿 정보를 기반으로 분석용 로그 데이터를 생성하는 composable
|
|
* @param resourcesData 페이지 리소스 데이터
|
|
* @param pageVerTmplSeq 템플릿 시퀀스 번호
|
|
* @returns 분석용 로그 데이터 객체
|
|
*/
|
|
export const useAnalyticsLogData = (
|
|
resourcesData: PageDataResourceGroup,
|
|
pageVerTmplSeq: number
|
|
) => {
|
|
const store = usePageDataStore()
|
|
const pageData = store.pageData
|
|
|
|
if (!pageData) {
|
|
return ref({} as AnalyticsDetailType)
|
|
}
|
|
|
|
const pageDataTrack = (
|
|
typeof resourcesData.tracking === 'object' ? resourcesData.tracking : {}
|
|
) as AnalyticsLogDataTracking
|
|
console.log('🚀 ~ useAnalyticsLogData ~ pageDataTrack:', pageData)
|
|
|
|
const logData = ref({
|
|
actionType: pageDataTrack?.action_type,
|
|
// logSourceType:pageDataTrack.logSourceType,
|
|
// viewArea:pageDataTrack.viewArea,
|
|
// viewType:pageDataTrack.viewType,
|
|
clickArea: pageData.page_name_en,
|
|
clickSarea: pageData.templates[pageVerTmplSeq].page_ver_tmpl_name_en,
|
|
clickItem: `${pageData.templates[pageVerTmplSeq].page_ver_tmpl_name}_${pageDataTrack?.click_item}`,
|
|
event: pageData.page_name,
|
|
eventCategory: `${pageData.page_name}_${pageDataTrack?.click_item}`,
|
|
template_code: pageData.templates[pageVerTmplSeq].template_code,
|
|
page_ver_tmpl_name: pageData.templates[pageVerTmplSeq].page_ver_tmpl_name,
|
|
page_ver_tmpl_name_en:
|
|
pageData.templates[pageVerTmplSeq].page_ver_tmpl_name_en,
|
|
} as unknown as AnalyticsDetailType)
|
|
|
|
return logData
|
|
}
|
|
|
|
// target에 {XX1, XX2}와 같은 형태가 포함되어 있을 경우 options.clickItem으로부터 값 추출하여 세팅
|
|
const findValueFromOption = (target: string, { options = {} }: any) => {
|
|
if (target.includes('{') && target.includes('}')) {
|
|
const strTargetClickItem = target.substring(
|
|
target.indexOf('{') + 1,
|
|
target.indexOf('}')
|
|
)
|
|
|
|
const arrTargetClickItem = strTargetClickItem.split(',')
|
|
const arrTargetClickItemValue = []
|
|
|
|
for (let targetClickItem of arrTargetClickItem) {
|
|
targetClickItem = targetClickItem.trim()
|
|
arrTargetClickItemValue.push(options.clickItem[targetClickItem])
|
|
}
|
|
target = target.replaceAll(
|
|
`{${strTargetClickItem}}`,
|
|
arrTargetClickItemValue.join(',')
|
|
)
|
|
}
|
|
return target
|
|
}
|
|
|
|
/**
|
|
* Google Analytics 전송
|
|
*
|
|
* @param {AnalyticsDetailType} analytics
|
|
* @param {object} options
|
|
*/
|
|
const sendGA = (analytics: AnalyticsDetailType, { options = {} }: any) => {
|
|
console.log('🚀 ~ 1111 sendGA ~ analytics:', analytics)
|
|
try {
|
|
const { gtag } = useGtag()
|
|
|
|
const eventName = analytics.event || ''
|
|
const eventLocale = analytics.eventLocale || ''
|
|
const eventCategory = `${analytics.eventCategory}`
|
|
|
|
// GA 클릭 이벤트 명 뒤에 언어 값 추가 노출되도록 개발. ex) GNB_자유게시판_KO
|
|
const eventLabel = `${eventCategory}_${eventLocale}`
|
|
|
|
gtag('set', 'cookie_domain', `${window?.location?.hostname || ''}`) // env 값으로 설정 시 쿠키 생성 안 돼서 window.location.hostname으로 설정
|
|
gtag('set', 'cookie_expires', '0') // 0으로 설정 시 쿠키가 Session 기반 쿠키로 전환
|
|
gtag('event', `${eventName}`, {
|
|
event_category: eventLabel,
|
|
})
|
|
} catch (e) {
|
|
console.error('[Exception] useAnalytics.sendGA: ', e)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Stove Analytics(81 Plug) 전송
|
|
*
|
|
* @param {AnalyticsDetailType} analytics
|
|
* @param {string} mcode
|
|
* @param {object} options
|
|
*/
|
|
const sendSA = (
|
|
analytics: AnalyticsDetailType,
|
|
{ mcode = '', options = {} }: any
|
|
) => {
|
|
const gameDataStore = useGameDataStore()
|
|
const { gameData } = storeToRefs(gameDataStore)
|
|
|
|
try {
|
|
const gameNo = gameData.value.game_code
|
|
|
|
const device = useDevice()
|
|
const deviceType = device.isDesktop ? 'pcweb' : 'mobileweb'
|
|
|
|
const country = `${csrGetCountry()}`
|
|
const memberNo = `${csrGetStoveMemberNo()}`
|
|
|
|
const actionType = analytics.actionType || ''
|
|
const logSourceType = analytics.logSourceType || ''
|
|
const viewArea = analytics.viewArea || ''
|
|
const viewType = analytics.viewType || ''
|
|
const clickArea = analytics.clickArea || ''
|
|
const clickSarea = findValueFromOption(analytics.clickSarea || '', {
|
|
options,
|
|
})
|
|
const eventLocale = analytics.eventLocale || ''
|
|
|
|
const identityInfo: IdentityInfo = {
|
|
app_id: 'stove',
|
|
log_source_type: logSourceType,
|
|
country,
|
|
locale: eventLocale,
|
|
lang_cd: eventLocale,
|
|
member_no: memberNo,
|
|
channeling_cd: 'SO',
|
|
}
|
|
|
|
const marketingInfo: MarketingInfo = {
|
|
marketing_code: mcode || '',
|
|
device_type: deviceType,
|
|
media_type: '',
|
|
media_page: '',
|
|
}
|
|
|
|
let actionParam = {}
|
|
|
|
if (actionType === 'view') {
|
|
actionParam = {
|
|
view_area: viewArea,
|
|
view_type: viewType,
|
|
view_info: {
|
|
game_no: gameNo,
|
|
lang_cd: eventLocale,
|
|
...options?.viewInfo,
|
|
},
|
|
}
|
|
} else if (actionType === 'click') {
|
|
actionParam = {
|
|
click_area: clickArea,
|
|
click_sarea: clickSarea,
|
|
click_item: {
|
|
click_item: analytics.clickItem,
|
|
game_no: gameNo,
|
|
lang_cd: eventLocale,
|
|
...options?.clickItem,
|
|
},
|
|
}
|
|
}
|
|
|
|
const actionInfo: ActionInfo = {
|
|
action_type: actionType,
|
|
action_param: actionParam,
|
|
marketing_info: marketingInfo,
|
|
}
|
|
|
|
const amplitudeActionInfo = {
|
|
...actionInfo,
|
|
url: `${location?.href || ''}`,
|
|
agent: `${navigator?.userAgent || ''}`,
|
|
}
|
|
|
|
const amplitudeActionParams: {
|
|
event_type: string
|
|
event_properties: ActionInfo & { url: string; agent: string }
|
|
} = {
|
|
event_type: actionType,
|
|
event_properties: amplitudeActionInfo,
|
|
}
|
|
|
|
svcLog.identity(identityInfo)
|
|
svcLog.action(actionInfo, {}, {}) // 81plug warning log 제거를 위해 2번째 인자부터 빈 객체 세팅
|
|
amplitude.track(amplitudeActionParams)
|
|
} catch (e) {
|
|
console.error('[Exception] useAnalytics.sendSA: ', e)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 기본 로그 일괄 전송
|
|
*
|
|
* @param {string} locale
|
|
* @param {AnalyticsDetailType} analytics
|
|
*/
|
|
const sendLog = (locale: string, analytics: AnalyticsDetailType) => {
|
|
console.log('🚀 ~ sendLog ~ analytics:', analytics)
|
|
|
|
// 언어 코드 대문자 변환
|
|
analytics.eventLocale = locale.toUpperCase()
|
|
|
|
if (analytics) {
|
|
// GA 전송 : eventCategory 유무로 판별
|
|
sendGA(analytics, { options: analytics.options })
|
|
// SA 전송 : actionType, logSourceType 유무로 판별
|
|
if (
|
|
analytics.actionType &&
|
|
analytics.actionType !== ''
|
|
// analytics.logSourceType &&
|
|
// analytics.logSourceType !== ''
|
|
) {
|
|
sendSA(analytics, { mcode: analytics.mcode, options: analytics.options })
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Google Analytics 전송 (기본 이벤트만 전송)
|
|
*
|
|
* @param {string} gaEventName
|
|
*/
|
|
const sendGAEventOnly = (gaEventName: string) => {
|
|
try {
|
|
const { gtag } = useGtag()
|
|
|
|
gtag('set', 'cookie_domain', `${window?.location?.hostname || ''}`) // env 값으로 설정 시 쿠키 생성 안 돼서 window.location.hostname으로 설정
|
|
gtag('set', 'cookie_expires', '0') // 0으로 설정 시 쿠키가 Session 기반 쿠키로 전환
|
|
gtag('event', `${gaEventName}`)
|
|
} catch (e) {
|
|
console.error('[Exception] useAnalytics.sendGAEventOnly: ', e)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 메타 픽셀 전송
|
|
*
|
|
* @param {string} fbEventName
|
|
* @description 수집 대상 페이지에 useHead({ meta: [loadMetaPixelMeta()] }) 선언
|
|
*/
|
|
const sendMetaPixel = (fbEventName: string) => {
|
|
try {
|
|
const { $fbq } = useNuxtApp()
|
|
if (typeof $fbq === 'function') {
|
|
$fbq('trackCustom', fbEventName)
|
|
}
|
|
} catch (e) {
|
|
console.error('[Exception] useAnalytics.sendMetaPixel: ', e)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* X(트위터) 픽셀 전송
|
|
*
|
|
* @param {string} twEventName
|
|
* @description 수집 대상 페이지에 useHead({ script: [loadTwitterPixelScript()] }) 선언
|
|
*/
|
|
const sendTwitterPixel = (twEventName: string) => {
|
|
try {
|
|
twq('event', twEventName, {})
|
|
} catch (e) {
|
|
console.error('[Exception] useAnalytics.sendTwitterPixel: ', e)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 틱톡 픽셀 전송
|
|
*
|
|
* @param {string} ttEventName
|
|
* @description 수집 대상 페이지에 onMounted(() => { loadTikTokPixelScript() }) 선언
|
|
*/
|
|
const sendTiktokPixel = (ttEventName: string) => {
|
|
try {
|
|
ttq.track(ttEventName)
|
|
} catch (e) {
|
|
console.error('[Exception] useAnalytics.sendTiktokPixel: ', e)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 마케팅 인텔리전스 팀 요청 마케팅 스크립트 일괄 전송
|
|
*
|
|
* @param {string} gaEventName
|
|
* @param {string} fbEventName
|
|
* @param {string} twEventName
|
|
* @param {string} ttEventName
|
|
*/
|
|
const sendMarketingScript = ({
|
|
gaEventName,
|
|
fbEventName,
|
|
twEventName,
|
|
ttEventName,
|
|
}: {
|
|
gaEventName?: string
|
|
fbEventName?: string
|
|
twEventName?: string
|
|
ttEventName?: string
|
|
}) => {
|
|
if (gaEventName) {
|
|
sendGAEventOnly(gaEventName)
|
|
}
|
|
if (fbEventName) {
|
|
sendMetaPixel(fbEventName)
|
|
}
|
|
if (twEventName) {
|
|
sendTwitterPixel(twEventName)
|
|
}
|
|
if (ttEventName) {
|
|
sendTiktokPixel(ttEventName)
|
|
}
|
|
}
|
|
|
|
export default () => {
|
|
return { sendGA, sendSA, sendLog, sendMarketingScript, useAnalyticsLogData }
|
|
}
|