프로젝트에 애널리틱스를 달아놨는데 팀원들이 확인하기에 번거로움이 있을 것 같아서 깃허브 알림처럼 디스코드로 알림을 받으면 좋을 것 같다는 생각이 들었다. 구글을 아무리 뒤져봐도 GA와 디스코드를 연동하는 것에 대한 글이 없었다.. 그래서 직접 만들어봤다
정확히 내가 만들고자 한 것은?
🤖 GA에 기록된 오늘의 방문자 수와 지금까지 누적 방문자 수를 매일 자정 discord에 알람을 보내는 봇!
그럼, 시작
웹훅을 추가하고 싶은 채널 → 채널 편집 → 연동 → 새 웹후크
여기서 새 웹훅을 만들어준다. 그리고 만들어진 URL을 복사해둔다.
API 및 서비스 → 라이브러리에서 Google Analytics Data API
를 활성화해준다
IAM 및 관리자 → 서비스 계정 → 서비스 계정 만들기
키 관리에 들어가서 키를 하나 만들어준다. 파일 형식으로 저장되는데 JSON 타입으로 선택해주자
이제 GCC에서 설정할 것은 끝났다!
이제 Google Analytics에 Google Analytics Data API 서비스 계정을 추가해줄 것이다
애널리틱스 관리 → 속성 설정 → 속성 → 속성 액세스 관리 → 사용자 추가
이메일주소에 키 발급 할 때 받은 json 파일에 적혀있는 client_email
을 넣어준다
이제 GA에서 데이터를 받아와 알림을 발생시킬 코드를 클라우드 함수로 설정하여 정기적으로 실행되도록 설정할 것이다
aws → Lambda → 함수 → 함수 생성
나는 js로 짤 것이라 node.js를 선택해줬다
넘어간 페이지에서 아래쪽 코드에 보면 처음에 기본 코드가 있다
export const handler = async(event) => {
// TODO implement
const response = {
statusCode: 200,
body: JSON.stringify('Hello from Lambda!'),
};
return response;
};
여기에 추가로 애널리틱스에서 받아올 코드와 디스코드 웹훅으로 보낼 코드를 추가해줄건데 서비스 계정 키 파일 설정을 함께 해줘야한다
서비스 계정 키 파일 설정 (이 부분은 gpt선생의 도움을 받았다)
GOOGLE_APPLICATION_CREDENTIALS
를 설정합니다. 이 값은 업로드된 서비스 계정 키 파일의 경로여야 합니다. AWS Lambda에서 로컬 파일 시스템의 /tmp/
디렉토리를 사용할 수 있으므로, 파일을 이 디렉토리에 저장하고 해당 경로를 환경 변수에 지정합니다./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!"),
};
};
만든 프로젝트와 키파일을 다 같이 압축한다.
그런 다음 코드 소스에서 zip파일로 업로드 해준다.
여기까지 완성했다면 테스트 섹션에서 테스트를 해 볼 수 있다. 성공적으로 코드가 동작한다면 디스코드 채널에 알람이 갔을 것이다
그런데 나는 시간초과 에러가 떠서 봤더니 처음엔 기본 구성으로 3초 제한이 걸려있다. 애널리틱스에서 받아오는데 시간이 좀 걸리는 것 같았다 (한 5초?) 그래서구성 → 일반구성에서 제한시간 을 넉넉히 1분으로 수정해줬다
잘 오는 구만 그래.
이제 마지막으로 매일 자정에 알림을 보낼 수 있도록 트리거 설정을 해준다!
트리거추가에서 EventBridge를 추가해준다
Amazon EventBridge 사용설명서를 참고하면 특정 시간에 실행되는 규칙은 cron 표현식을 사용하면 된다고 한다.
이 시간은 UTC기준이므로 변환하여 설정해주면 된다. 나는 매일 자정에 해줄거라서 cron(00 15 * * ? *)
으로 해주었다 (근데 이렇게 하면 12시부터 오늘기준이라 오늘 사용자가 0명으로 떠서 11시 59분 기준으로 해주었다)
이렇게 되면 완성이다! 자정에 맞춰 잘 작동했다.
멋지네용 저희 프로젝트에도 적용해 볼게요~ 감사합니다 :)