개요
현재 팀에서는 GA(Google Analytics4) 를 사용하여 플랫폼 데이터를 분석을 하고 있었다.
조금 더 세부적인 내용에 관한 분석 필요성이 있었고, 현재는 앱단에서만 GA 이벤트 메세지를 수집하고 있었으므로, ‘사용자의 포인트 총액’ 과 같이 백엔드의 DB 조회가 필요한 내용에 대해서는 수집하지 못하고 있었다.
따라서, 백엔드 서버에서도 GA4 연동 작업의 필요가 있었기에, 해당 작업을 하게 되었다.
GA 데이터
GA에는 두 가지 주요 유형 데이터가 있다.
이벤트(Event) 는 사용자의 어떤 액션들이다. 예를 들어, ‘상품 구매’ , ‘포인트 사용/충전’ 등 플랫폼에서의 특정 활동이 이벤트에 해당한다.
사용자 속성(User Properties) 은 사용자의 종속된 특성이나 상태이다. 예를 들어, 사용자의 ‘포인트 총액’, ‘상품 구매 개수’ 등 해당 사용자의 정보들이 사용자 속성에 해당한다. 또한 사용자를 특정할 수 있는 데이터이다.
사용자 속성
처음엔 사용자 별, 사용자 속성의 개념을 Key - Value 로 이해하여, 사용자 속성 데이터가 GA 로 전달 되었을 때, 덮어 씌워지는 것인 줄 알았으나, 새로운 데이터가 계속적으로 누적 되는 것이었다.
즉, 예를 들어 ‘x월 x일에는 특정 그룹의 사용자의 포인트가 N개 였으나, x월 x일에는 특정 그룹의 사용자의 포인트가 N개이다.’ 와 같이 데이터를 추적, 통계 낼 수 있는 것이다.
또한, GA는 기본적으로 사용자의 브라우저, 기기 정보, IP 주소를 기반으로 한 지역 정보 등을 사용자 속성으로 수집한다.
하나의 사용자. 서로 다른 디바이스 & 서버에서의 사용자 식별 (user_id)
플랫폼에서 GA를 사용할 때 주의할 점이 있다. 각 디바이스 및 서버에서 추적한 사용자가 서로 다르게 집계될 수 있다는 것이다.
GA가 적용 된 사이트에 사용자가 접속하면 브라우저에 GA 쿠키가 생성되고 클라이언트 ID가 생성된다. 이 때, 사용자가 기존엔 Chrome 브라우저로 접속 하였으나, Safari 브라우저로 사이트에 했을 경우, 이 두 브라우저는 서로 다른 사용자로 식별된다.
위 상황은 사용자가 모바일 앱으로 접속할 때와, 데스크톱 브라우저로 접속할 때 등 디바이스, 브라우저가 달라지는 여러 상황에서 동일하게 발생할 수 있는 문제이다.
당연히 이를 위해 특정 사용자를 식별하기 위한 user_id 를 사용할 수 있다. 플랫폼에서 제공하는 모든 디바이스 앱, 사이트에서 GA에 사용자 이벤트를 전송할 때, 동일한 user_id 를 사용하여 전달하는 것이다.
user_id, 혹은 그 외 사용자 속성 데이터들은 사용자를 개별적으로 식별할 수 있는 정보가 될 수 있으므로, 사용자 개인 정보를 특정할 수 있는 민감 정보나, 개인정보 보호에 관한 내용을 준수하는 것이 중요하다.
감사하게도, 아래 블로그에 잘 정리된 내용이 있다.
GA4가 사용자를 식별하는 방법과 사용자 ID(User ID) 수집하기
백엔드 서버에서 GA4로 데이터 전송. Measurement Protocol
GA는 페이지 뷰 , 방문 경로 와 같이, 일반적으로 Client 단에서 데이터를 수집 데에 사용하나,
상황에 따라, 유저의 총 상품 구매 수, 유저의 특정 상품 구매로 인한 포인트 사용량 과 같이, 백엔드 단에서 DB 데이터의 조합으로 수집해야 하는 데이터들이 있을 수 있다.
이러한 경우, GA에서 제공하는 Measurement Protocol 을 사용할 수 있다.
Measurement Protocol 은 GA의 Collection Endpoint 에 직접 Http 요청을 보내, 데이터를 수집할 수 있게 해준다.
측정 프로토콜(Google 애널리틱스 4) | Google 애널리틱스 4용 측정 프로토콜 | Google for Developers
코드상의 사용법은 단순하다.
// statistics.utils.ts
import axios from 'axios';
import { GA_API_KEY, GA_MEASUREMENT_ID } from './statistics.env';
import { GaPayload } from './statistics';
export const measurementProtocolUrl = `https://www.google-analytics.com/mp/collect?measurement_id=${GA_MEASUREMENT_ID}&api_secret=${GA_API_KEY}`;
export const sendGaCollect = async (payload: GaPayload) => {
const result = await axios.post(measurementProtocolUrl, payload);
return result.data;
};
위와 같이, GA의 Collection Endpoint 에 수집 하고자 하는 payload와 함께, 요청을 보내기만 하면 된다.
아래와 같이 추가적인 로직을 구현하고 싶을 경우, utils의 function 을 wrapping 하여 사용할 수도 있다.
import { sendGaCollect as _sendGaCollect } from './statistics.utils';
@Injectable()
export class StatisticsService {
constructor() {}
async sendGaCollect(userId: string, payload: GaPayload) {
try {
// todo: 조금 더 상세한 Validation 체크와, 필요 로직을 구현
if (!userId || !payload) throw new BadRequestException('userId or payload badRequest');
payload.client_id = userId;
payload.user_id = userId;
await _sendGaCollect(payload);
} catch (e) {
throw e;
}
}
}
데이터 스트림 추가
간단한 코드 사용법은 위에서 살펴 보았고, 이제 GA Collection Endpoint 에서 우리의 애널리틱스 보드에 데이터를 보낼 것을 특정해 줘야 한다.
이를 위해, GA 보드에서 데이터 스트림 을 추가할 수 있다. 데이터 스트림은 GA4의 구성 요소 중 하나로, 사용자 상호 작용을 추적하고 수집하는 데 사용된다.
GA 관리 탭에서 데이터 스트림을 추가할 수 있다.
해당 작업을 위해, 사전에 추가해 둔 웹 데이터 스트림이다.
세부정보에서 API KEY 와 MEASUREMENT ID 를 확인할 수 있다.
<https://www.google-analytics.com/mp/collect?measurement_id=${GA_MEASUREMENT_ID}&api_secret=${GA_API_KEY}>
이제, Collection Endpoint 쿼리에 measurement_id 와 api_secret 을 설정해 주면 우리의 애널리틱스 보드에 데이터를 수집하도록 특정해 줄 수 있다.
위 작업 절차는 Google Codelab 에서도 잘 설명해 주고 있다.
측정 프로토콜을 사용하여 GA4에 앱 이벤트 보내기 | Firebase
Payload의 검증
작업하며 한 가지 유의할 점은, Measurement Protocol 로 보내는 요청이 실제로 GA 상에 잘 적재되고 있는 지 여부이다.
Client 단에선, DebugView 메뉴에서 실제로 이벤트 & 사용자 속성이 잘 보내지고 있는 지 검증할 수 있지만,
[GA4] DebugView에서 이벤트 모니터링하기 - 애널리틱스 고객센터
백엔드 단에선 실시간 보고서 메뉴에서, 실시간 이벤트를 확인해 검증해야 한다.
이를 위해, 첫째로 데이터 스트림이 잘 설정 되었는 지를 확인해야 한다.
https://ga-dev-tools.google/ga4/event-builder/
위 사이트에서 api_secret, measurement_id, event_name 등을 설정한 후, 설정 된 Payload 값들을 검증할 수 있고, 어떤 포맷으로 Payload 데이터를 정의해야 하는 지 확인할 수 있다.
그 후 하단의 Sent 버튼을 눌러 GA 실시간 리포트에서 테스트를 위해 임시로 설정한 이벤트가 잘 들어오는 지 확인한다.
설정한 이벤트가 잘 들어오는 것을 확인 하였다면, 이제 데이터 스트림의 설정 검증은 완료 하였으니,
백엔드 서버에서 위 사이트에서 테스트에 사용한 Payload 를 보내봐도 되고, 그 외 확인할 수 있는 데이터를 보내, Measurement Protocol 이 잘 동작함을 확인할 수 있다.
'개발' 카테고리의 다른 글
Node 프로젝트 패키지 최적화 (bundle analyzer) (0) | 2024.03.04 |
---|---|
EKS환경의 NestJS에서 원본 IP를 제대로 가져오지 못하던 문제 (X-Forwarded-For 헤더) (1) | 2024.03.02 |
백그라운드 프로세스 시스템 구축하기 (NestJS, CronJob 스케줄러) (0) | 2024.02.19 |
인프라 환경을 개선하여 서비스에 기여하기. (AWS 인프라 이전 & Docker) (1) | 2024.02.18 |
Google Play 인앱 구독 상품, 실시간 상태 추적 시스템 구축. RTDN (Real-Time Develop Notification) (1) | 2024.02.17 |