Google Analytics와 Discord 연동해서 알람받기

황수콩·2024년 1월 26일
0
post-thumbnail

프로젝트에 애널리틱스를 달아놨는데 팀원들이 확인하기에 번거로움이 있을 것 같아서 깃허브 알림처럼 디스코드로 알림을 받으면 좋을 것 같다는 생각이 들었다. 구글을 아무리 뒤져봐도 GA와 디스코드를 연동하는 것에 대한 글이 없었다.. 그래서 직접 만들어봤다

정확히 내가 만들고자 한 것은?

🤖 GA에 기록된 오늘의 방문자 수와 지금까지 누적 방문자 수매일 자정 discord에 알람을 보내는 봇!

그럼, 시작

👾 디스코드 웹훅 만들기

웹훅을 추가하고 싶은 채널채널 편집연동새 웹후크

여기서 새 웹훅을 만들어준다. 그리고 만들어진 URL을 복사해둔다.

🎮 Google Cloud Console 설정하기

1. 새 프로젝트를 생성

2. Google Analytics Data API 활성화

API 및 서비스 → 라이브러리에서 Google Analytics Data API를 활성화해준다

3. 서비스 계정 생성

IAM 및 관리자 → 서비스 계정 → 서비스 계정 만들기

4. 키 생성

키 관리에 들어가서 키를 하나 만들어준다. 파일 형식으로 저장되는데 JSON 타입으로 선택해주자

이제 GCC에서 설정할 것은 끝났다!

📈 GA에 API 서비스 계정 추가하기

이제 Google Analytics에 Google Analytics Data API 서비스 계정을 추가해줄 것이다

애널리틱스 관리속성 설정속성속성 액세스 관리사용자 추가

이메일주소에 키 발급 할 때 받은 json 파일에 적혀있는 client_email을 넣어준다

📡 AWS Lambda(람다) 연동하기

이제 GA에서 데이터를 받아와 알림을 발생시킬 코드를 클라우드 함수로 설정하여 정기적으로 실행되도록 설정할 것이다

1. 함수 생성

awsLambda함수함수 생성

나는 js로 짤 것이라 node.js를 선택해줬다

2. 코드 작성

넘어간 페이지에서 아래쪽 코드에 보면 처음에 기본 코드가 있다

 export const handler = async(event) => {
     // TODO implement
     const response = {
         statusCode: 200,
         body: JSON.stringify('Hello from Lambda!'),
     };
     return response;
 };

여기에 추가로 애널리틱스에서 받아올 코드와 디스코드 웹훅으로 보낼 코드를 추가해줄건데 서비스 계정 키 파일 설정을 함께 해줘야한다

서비스 계정 키 파일 설정 (이 부분은 gpt선생의 도움을 받았다)

  1. 서비스 계정 키 파일 업로드: Google Cloud에서 생성한 서비스 계정 키 파일(JSON 형식)을 Lambda 함수와 함께 업로드해야 합니다. 이 파일은 Google Cloud API에 액세스하기 위한 인증 정보를 포함하고 있습니다.
  2. 환경 변수 설정: Lambda 함수의 환경 변수에서 GOOGLE_APPLICATION_CREDENTIALS를 설정합니다. 이 값은 업로드된 서비스 계정 키 파일의 경로여야 합니다. AWS Lambda에서 로컬 파일 시스템의 /tmp/ 디렉토리를 사용할 수 있으므로, 파일을 이 디렉토리에 저장하고 해당 경로를 환경 변수에 지정합니다.
  3. Lambda 함수에서 파일 복사: Lambda 함수가 실행될 때마다 서비스 계정 키 파일을 /tmp/ 디렉토리로 복사하는 로직을 추가합니다. 이는 Lambda 함수가 매 호출마다 새 실행 환경을 생성하기 때문입니다.
     const __filename = fileURLToPath(import.meta.url);
     const __dirname = path.dirname(__filename);
     
     function copyCredentialsFile() {
       const sourcePath = path.join(__dirname, credentialsFilePath);
       fs.copyFileSync(sourcePath, tmpCredentialsPath);
       process.env.GOOGLE_APPLICATION_CREDENTIALS = tmpCredentialsPath;
     }

그런 다음 함수구성환경 변수 에 다음과 같이 설정해둔다

그 다음으로 Analytics Data API 를 통해 데이터를 가져와야한다

Method: properties.runReport를 이용하여 필요한 데이터를 요청하면 된다!

지원하는 측정기준 이름 목록은 API 측정기준을 참고하면된다

request도 어떻게 보내야하는지 상세하게 나와있고 옆에 try this method에서 먼저 시도해볼 수 있으니 그대로 작성하면된다

전체 코드

    import axios from "axios";
    import { BetaAnalyticsDataClient } from "@google-analytics/data";
    import fs from "fs";
    import path from "path";
    import { fileURLToPath } from "url";
    
    const START_DATE = "2024-01-18";
    
    const propertyId = "";
    const webhookUrl = "";
    const credentialsFilePath = "credentials.json";
    const tmpCredentialsPath = "/tmp/credentials.json";
    
    const analyticsDataClient = new BetaAnalyticsDataClient();
    
    const __filename = fileURLToPath(import.meta.url);
    const __dirname = path.dirname(__filename);
    
    function copyCredentialsFile() {
      const sourcePath = path.join(__dirname, credentialsFilePath);
      fs.copyFileSync(sourcePath, tmpCredentialsPath);
      process.env.GOOGLE_APPLICATION_CREDENTIALS = tmpCredentialsPath;
    }
    
    async function runAnalyticsReport(startDate, endDate, metricName) {
      try {
        const [response] = await analyticsDataClient.runReport({
          property: `properties/${propertyId}`,
          dateRanges: [{ startDate, endDate }],
          metrics: [{ name: metricName }],
        });
        return response.rows?.[0]?.metricValues?.[0]?.value || 0;
      } catch (error) {
        console.error(`Error fetching ${metricName}:`, error);
        throw error;
      }
    }
    
    export const handler = async (event) => {
      copyCredentialsFile();
    
      try {
        const totalUsers = await runAnalyticsReport(START_DATE, "today", "totalUsers");
        const todayUsers = await runAnalyticsReport("today", "today", "totalUsers");
    
        await axios.post(webhookUrl, {
          content: `🎉 오늘은 ${todayUsers}명이 모디를 사용했어요, 총 사용자 ${totalUsers}명에 달성했습니다!`,
        });
      } catch (error) {
        console.error("에러 발생:", error);
      }
    
      return {
        statusCode: 200,
        body: JSON.stringify("Hello from Lambda!"),
      };
    };

3. 코드 업로드

만든 프로젝트와 키파일을 다 같이 압축한다.
그런 다음 코드 소스에서 zip파일로 업로드 해준다.

여기까지 완성했다면 테스트 섹션에서 테스트를 해 볼 수 있다. 성공적으로 코드가 동작한다면 디스코드 채널에 알람이 갔을 것이다

그런데 나는 시간초과 에러가 떠서 봤더니 처음엔 기본 구성으로 3초 제한이 걸려있다. 애널리틱스에서 받아오는데 시간이 좀 걸리는 것 같았다 (한 5초?) 그래서구성 → 일반구성에서 제한시간 을 넉넉히 1분으로 수정해줬다

잘 오는 구만 그래.

4. 트리거 설정

이제 마지막으로 매일 자정에 알림을 보낼 수 있도록 트리거 설정을 해준다!

트리거추가에서 EventBridge를 추가해준다

Amazon EventBridge 사용설명서를 참고하면 특정 시간에 실행되는 규칙은 cron 표현식을 사용하면 된다고 한다.

이 시간은 UTC기준이므로 변환하여 설정해주면 된다. 나는 매일 자정에 해줄거라서 cron(00 15 * * ? *) 으로 해주었다 (근데 이렇게 하면 12시부터 오늘기준이라 오늘 사용자가 0명으로 떠서 11시 59분 기준으로 해주었다)

이렇게 되면 완성이다! 자정에 맞춰 잘 작동했다.

profile
@binllionaire

2개의 댓글

comment-user-thumbnail
2024년 1월 28일

멋지네용 저희 프로젝트에도 적용해 볼게요~ 감사합니다 :)

답글 달기
comment-user-thumbnail
2024년 1월 30일

스스로가 느낀 필요성에 따라서 웹훅을 커스텀하는 모습이 너무 멋있네요 !!

답글 달기