티스토리 뷰
GitHub Webhook을 활용한 NestJS 서버 구축 및 이벤트 처리
이전 글에서 GitHub Webhook의 개념과 활용 사례를 살펴보았습니다.
이번 글에서는 NestJS를 사용하여 Webhook 서버를 구축하고, GitHub에서 발생하는 이벤트를 처리하는 방법을 설명합니다.
1. 프로젝트 환경 설정 (NestJS + Webhook 서버 구축)
🔹 1-1. NestJS 프로젝트 생성
npm install -g @nestjs/cli
nest new github-webhook-server
cd github-webhook-server
🔹 1-2. Webhook을 수신할 컨트롤러 생성
nest generate controller webhook
src/webhook/webhook.controller.ts 파일이 생성됩니다.
2. Webhook 요청을 처리하는 API 구현
GitHub Webhook 요청을 수신하는 POST 엔드포인트를 구현합니다.
🔹 2-1. Webhook 컨트롤러 코드 작성
import { Controller, Post, Headers, Body } from '@nestjs/common';
@Controller('webhook')
export class WebhookController {
@Post()
handleWebhook(
@Headers('x-github-event') event: string,
@Headers('x-hub-signature-256') signature: string,
@Body() payload: any,
) {
console.log(`📌 GitHub Event: ${event}`);
console.log(`🔹 Payload:`, JSON.stringify(payload, null, 2));
return { message: 'Webhook received' };
}
}
🚀 x-github-event 헤더를 이용해 이벤트 종류를 식별할 수 있습니다.
🔹 2-2. 서버 실행
npm run start
이제 http://localhost:3000/webhook 엔드포인트에서 Webhook을 받을 준비가 되었습니다.
3. GitHub Webhook 등록 및 테스트
🔹 3-1. GitHub Webhook 설정 방법
- GitHub Repository → Settings → Webhooks로 이동
- "Add webhook" 버튼 클릭
- Payload URL: http://your-server/webhook 입력
- Content type: application/json 선택
- Secret: 랜덤한 시크릿 키 설정 (보안용)
- Events: Push, Pull Request, Issue 등 원하는 이벤트 선택
- "Add webhook" 클릭하여 저장
이제 Webhook이 설정되었으며, GitHub에서 이벤트가 발생하면 서버로 자동 요청이 전송됩니다.
4. Webhook 보안 강화 (Signature 검증)
GitHub Webhook 요청이 **정상적인 요청인지 검증하기 위해 X-Hub-Signature-256**을 활용한 HMAC 검증을 추가해야 합니다.
🔹 4-1. HMAC 검증 함수 추가
src/utils/verifySignature.ts 파일을 생성하고, 다음과 같이 구현합니다.
import * as crypto from 'crypto';
export function verifySignature(payload: string, signature: string, secret: string): boolean {
const hmac = crypto.createHmac('sha256', secret);
hmac.update(payload, 'utf-8');
const expectedSignature = `sha256=${hmac.digest('hex')}`;
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expectedSignature));
}
🔹 4-2. 컨트롤러에서 검증 로직 추가
import { Controller, Post, Headers, Body, BadRequestException } from '@nestjs/common';
import { verifySignature } from '../utils/verifySignature';
const GITHUB_SECRET = process.env.GITHUB_SECRET || 'your_secret_key';
@Controller('webhook')
export class WebhookController {
@Post()
handleWebhook(
@Headers('x-github-event') event: string,
@Headers('x-hub-signature-256') signature: string,
@Body() payload: any,
) {
const payloadString = JSON.stringify(payload);
if (!verifySignature(payloadString, signature, GITHUB_SECRET)) {
throw new BadRequestException('Invalid signature');
}
console.log(`📌 Valid Webhook Event: ${event}`);
return { message: 'Webhook processed successfully' };
}
}
💡 verifySignature()를 사용하여 Webhook 요청이 유효한지 검증합니다.
잘못된 Webhook 요청은 400 Bad Request 오류를 반환합니다.
5. GitHub Webhook 이벤트 처리 (Push, PR, Issue)
🔹 5-1. 이벤트별 처리 로직 추가
Webhook 이벤트에 따라 Push, PR, Issue 이벤트를 다르게 처리합니다.
import { Controller, Post, Headers, Body } from '@nestjs/common';
@Controller('webhook')
export class WebhookController {
@Post()
handleWebhook(@Headers('x-github-event') event: string, @Body() payload: any) {
switch (event) {
case 'push':
console.log(`📌 Push Event: ${payload.ref}에 커밋 발생`);
break;
case 'pull_request':
console.log(`📌 Pull Request ${payload.action}: #${payload.number}`);
break;
case 'issues':
console.log(`📌 Issue ${payload.action}: #${payload.issue.number}`);
break;
default:
console.log(`📌 Unknown Event: ${event}`);
}
return { message: `Processed ${event} event` };
}
}
🚀 Push, Pull Request, Issue 이벤트 발생 시 각각 다른 메시지가 출력됩니다.
6. Webhook 로그 저장 및 데이터베이스 연동
🔹 6-1. PostgreSQL 설정 (Prisma ORM 사용)
npm install @prisma/client @nestjs/prisma
🔹 6-2. Prisma 모델 정의 (prisma/schema.prisma)
model WebhookEvent {
id String @id @default(uuid())
eventType String
payload Json
createdAt DateTime @default(now())
}
🔹 6-3. Webhook 로그 저장 코드 추가
import { Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
@Injectable()
export class WebhookService {
constructor(private readonly prisma: PrismaService) {}
async saveWebhookEvent(eventType: string, payload: any) {
return this.prisma.webhookEvent.create({
data: { eventType, payload },
});
}
}
🔹 6-4. 컨트롤러에서 DB 저장 로직 적용
@Controller('webhook')
export class WebhookController {
constructor(private readonly webhookService: WebhookService) {}
@Post()
async handleWebhook(@Headers('x-github-event') event: string, @Body() payload: any) {
await this.webhookService.saveWebhookEvent(event, payload);
console.log(`✅ Event Saved: ${event}`);
return { message: 'Webhook processed and saved' };
}
}
💡 이제 Webhook 이벤트가 발생하면 PostgreSQL에 자동 저장됩니다.
7. 마무리 및 다음 글 예고
이번 글에서는 GitHub Webhook을 수신하는 NestJS 서버를 구축하고, 이벤트 처리 및 로그 저장 기능을 구현했습니다.
다음 글에서는 Webhook을 활용한 CI/CD 자동화 및 배포 트리거를 다뤄보겠습니다! 🚀
'모음집 > git' 카테고리의 다른 글
GitHub Webhook을 활용한 Issue 및 Pull Request 자동 관리 시스템 구축 (0) | 2025.03.19 |
---|---|
GitHub Webhook을 활용한 CI/CD 자동화 시스템 구축 (0) | 2025.03.18 |
GitHub Webhook 개념과 자동화 시스템 구축의 필요성 (2) | 2025.03.18 |
[Github] vscode에서 git을 사용 해보자 (0) | 2022.05.23 |
[Github] Repository 만들기 (0) | 2022.05.23 |
- Total
- Today
- Yesterday
- 웹개발
- REACT
- App Router
- 파이썬알고리즘
- NestJS
- 딥러닝
- Ktor
- SEO최적화
- llm
- Next.js
- AI챗봇
- kotlin
- 백엔드개발
- 프론트엔드
- gatsbyjs
- CI/CD
- seo 최적화 10개
- nextJS
- rag
- flax
- Docker
- SEO 최적화
- fastapi
- 프론트엔드면접
- PostgreSQL
- nodejs
- JAX
- Python
- 개발블로그
- Prisma
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |