전체 글로 돌아가기

[운영] GA4 Data API로 주간 서비스 운영 보고서 자동 생성하기

AWS Lambda와 GA4 Data API를 연동하여 서비스의 핵심 트래픽 및 전환 지표를 매일 0.4초 만에 자동 수집하고 저장하는 자동화 노하우입니다.

fruit.nxnl.appGoodFruit
GA4DataAPIAWSLambdaSecretsManager

[운영] GA4 Data API로 주간 서비스 운영 보고서 자동 생성하기

한 줄 요약: 매일/매주 GA4 콘솔에 수동으로 로그인하여 데이터를 추출하는 번거로움을 없애기 위해, AWS Lambda 및 @google-analytics/data SDK를 활용하여 주요 전환 지표 및 트래픽 유입 경로를 자동 조회하고 S3에 지표 보고서 JSON/HTML로 저장하는 파이프라인을 연동했습니다.

1. 서비스와 분석 목적

GoodFruit 서비스를 운영하면서 매일 아침 "어제 방문자는 몇 명이었지?", "사진 분석은 몇 번이나 완료되었지?", "어떤 과일 가이드 페이지로 오가닉 유입이 많이 들어왔지?"를 확인하는 일은 필수적입니다.

하지만 구글 애널리틱스(GA4) 웹 콘솔은 로딩이 매우 느리고, 원하는 이벤트 비율을 보려면 매번 탐색(Exploration) 보고서를 복잡하게 클릭해야 했습니다.

이 과정을 자동화하여 매일 아침 전날 데이터를 자동 수집하고, 주간 전환 리포트를 한눈에 파악할 수 있는 자동화 보고서 파이프라인을 만들고자 했습니다.

2. 데이터 집계 기간

  • **자동화 실행 주기**: 매일 새벽 01:00 UTC (EventBridge Cron 트리거)
  • **집계 범위**: 최근 1일(Yesterday) 및 최근 7일(Weekly) 누적 데이터

3. 핵심 수집 지표 (Automated GA4 Data API Dimensions & Metrics)

infra/report-api/index.mjs에서 GA4 Data API를 통해 자동으로 조회하는 5대 지표군:

  • **개요 지표**: `sessions` (세션), `activeUsers` (활성 사용자), `screenPageViews` (페이지뷰)
  • **트래픽 유입 경로**: `sessionSourceMedium` (유입 소스/매체 Top 10), `sessionDefaultChannelGroup` (채널 그룹)
  • **디바이스 및 브라우저**: `deviceCategory` (모바일/데스크톱), `operatingSystem` (iOS/Android), `browser`

4. 핵심 커스텀 이벤트: analysis_start, analysis_complete, share_click, coupang_copy

5. 인기 페이지 Top 10: pagePath별 세션 수 및 체류 시간

4. 데이터 신뢰도와 표본 크기

구글 서비스 계정(Service Account) 전용 IAM 인증 키를 AWS Secrets Manager에 보관하고 사용하므로, 데이터 탈취 위험 없이 100% 실시간 GA4 서버 데이터와 정확히 일치합니다.

5. 발견한 문제 및 해결책

기존 수동 관리의 한계:

  • 주말이나 바쁜 일정 중에 GA4 콘솔 확인을 거르면 지표의 흐름을 놓침.
  • API 호출 시 구글 비공개 키(`private_key`) 관리가 소스코드에 포함되면 보안 위협 발생.

해결 방안:

  • **AWS Secrets Manager (`goodfruit/ga4-credentials`) 연동**: GA4 Client Email과 Private Key를 암호화 보관.
  • **Lambda 자동 수집 및 S3 정적 캐싱**: 수집된 JSON 리포트를 S3 버킷 `reports/YYYY-MM-DD.json` 파일로 보관하여 0.01초 만에 렌더링.

6. 핵심 연동 코드

`infra/report-api/index.mjs` (GA4 Data API 호출 및 보고서 산출 Lambda)

import { BetaAnalyticsDataClient } from "@google-analytics/data";
import { GetSecretValueCommand, SecretsManagerClient } from "@aws-sdk/client-secrets-manager";
import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3";

const secretsClient = new SecretsManagerClient({});
const s3Client = new S3Client({});

// 1. Secrets Manager에서 GA4 비공개 인증서 동적 인출
async function getCredentials() {
  const command = new GetSecretValueCommand({ SecretId: "goodfruit/ga4-credentials" });
  const response = await secretsClient.send(command);
  return JSON.parse(response.SecretString);
}

// 2. GA4 Data API 리포트 실행
export async function handler(event) {
  const creds = await getCredentials();
  const analyticsClient = new BetaAnalyticsDataClient({
    credentials: {
      client_email: creds.clientEmail,
      private_key: creds.privateKey.replace(/\\n/g, "\n"),
    },
  });

  const property = `properties/${creds.propertyId}`;

  // 전날(yesterday) 메트릭 자동 조회
  const [overviewRes] = await analyticsClient.runReport({
    property,
    dateRanges: [{ startDate: "yesterday", endDate: "yesterday" }],
    metrics: [
      { name: "sessions" },
      { name: "activeUsers" },
      { name: "screenPageViews" },
    ],
  });

  const reportData = {
    date: new Date().toISOString().slice(0, 10),
    sessions: overviewRes.rows[0]?.metricValues[0]?.value || 0,
    activeUsers: overviewRes.rows[0]?.metricValues[1]?.value || 0,
    pageViews: overviewRes.rows[0]?.metricValues[2]?.value || 0,
  };

  // S3 버킷에 일별 지표 JSON 저장
  await s3Client.send(new PutObjectCommand({
    Bucket: "fruit.nxnl.app",
    Key: `reports/${reportData.date}.json`,
    Body: JSON.stringify(reportData, null, 2),
    ContentType: "application/json",
  }));

  return { statusCode: 200, body: JSON.stringify(reportData) };
}

7. 실제 운영 수치 및 이점

  • **보고서 수집 소요 시간**: GA4 웹 로그인 후 클릭 5분 -> **자동화 API 실행 0.4초**.
  • **지표 가시성**: 매일 아침 전날의 과일 사진 분석 건수와 유입 소스를 슬랙/이메일 또는 정적 JSON 보고서로 즉시 확인 가능.

8. 다른 환경에서 주의할 점

  • GA4 Data API 서비스 계정 이메일을 만든 후, **구글 애널리틱스 속성 관리자 메뉴에서 해당 서비스 계정에 "뷰어(Viewer)" 권한을 반드시 부여**해야 API 호출 시 `PERMISSION_DENIED` 에러가 나지 않습니다.
  • `private_key`에 들어있는 줄바꿈 문자는 `.replace(/\\n/g, "\n")`로 정확히 이스케이프 처리해야 PEM 파싱 실패를 막을 수 있습니다.

9. 정리

GA4 Data API와 AWS Lambda를 결합하면 매번 애널리틱스 화면을 열어보지 않고도 서비스의 핵심 성장 수치를 100% 자동화하여 수집하고 정량적 의사결정을 내릴 수 있습니다.

10. 관련 글

  • [전날 데이터를 하루 한 번 조회하고 캐시하는 방법](file:///Users/uram/dev/goodfruit/posts/09-daily-data-fetch-and-cloudfront-cache.md)
  • [GA4 커스텀 이벤트로 분석 완료율 측정하기](file:///Users/uram/dev/goodfruit/posts/07-ga4-custom-events-completion-rate.md)
  • [AI 서비스의 광고수익과 API 비용을 함께 계산하기](file:///Users/uram/dev/goodfruit/posts/10-ai-service-adsense-vs-api-cost.md)

실제 적용 서비스

자동화된 수치 집계 시스템 기반으로 성장하고 있는 GoodFruit 서비스를 직접 체험해 보세요!

👉 [GoodFruit 서비스 방문하기](https://fruit.nxnl.app/?utm_source=tistory&utm_medium=content&utm_campaign=goodfruit&utm_content=08_ga4_data_api_weekly_report)

내부 원문 복사