GitHub 커넥터
GitHub 리포지토리를 Brevo에 연결하여 Tajo를 통해 개발자 인게이지먼트 추적, 릴리스 알림 워크플로우, 커뮤니티 활동 모니터링을 구현하세요.
개요
| 속성 | 값 |
|---|---|
| 플랫폼 | GitHub |
| 카테고리 | Custom |
| 설정 난이도 | 보통 |
| 공식 통합 | 아니오 |
| 동기화되는 데이터 | 이벤트, 사용자, 리포지토리 |
| API 유형 | REST API, GraphQL API |
| 인증 | GitHub App / Personal Access Token / OAuth 2.0 |
| Base URL | https://api.github.com |
| API 버전 | 2022-11-28 (헤더 기반 버전 관리) |
주요 기능
- 이슈 및 PR 추적 - 이슈와 Pull Request 이벤트를 Brevo 연락처 타임라인으로 동기화합니다
- 릴리스 알림 - 새 리포지토리 릴리스에서 Brevo 캠페인을 트리거합니다
- 컨트리뷰터 동기화 - 커뮤니티 인게이지먼트를 위해 GitHub 컨트리뷰터를 Brevo 연락처에 매핑합니다
- 스타 및 포크 추적 - 리포지토리 인기 지표를 모니터링합니다
- 웹훅 이벤트 전달 - GitHub 이벤트를 Brevo 자동화로 전달합니다
- 리포지토리 카탈로그 - 리포지토리 메타데이터를 Brevo 카탈로그 항목으로 동기화합니다
사전 준비 사항
시작하기 전에 다음 사항이 준비되어 있어야 합니다.
- 대상 리포지토리에 액세스할 수 있는 GitHub 계정
- GitHub App 또는 Personal Access Token (fine-grained 권장)
- 웹훅 구성을 위한 리포지토리 관리자 액세스 권한
- API 액세스가 활성화된 Brevo 계정
- 활성 구독이 있는 Tajo 계정
인증
GitHub는 여러 인증 방식을 지원합니다. Tajo는 조직 수준 액세스에 GitHub App 사용을 권장합니다.
옵션 1: GitHub App (권장)
- Settings > Developer settings > GitHub Apps로 이동합니다
- New GitHub App을 클릭합니다
- 다음 권한으로 앱을 구성합니다.
Repository permissions: Issues: Read Pull requests: Read Contents: Read Metadata: Read
Organization permissions: Members: Read
Subscribe to events: Issues Pull request Push Release Star Fork옵션 2: Fine-Grained Personal Access Token
- Settings > Developer settings > Personal access tokens > Fine-grained tokens로 이동합니다
- Generate new token을 클릭합니다
- 대상 리포지토리를 선택합니다
- 다음 권한을 부여합니다.
Repository access: Selected repositoriesPermissions: Issues: Read-only Pull requests: Read-only Contents: Read-only Metadata: Read-only토큰 보안
Fine-grained 토큰은 만료일이 있습니다. 만료 전에 토큰 순환을 설정하세요. GitHub App 설치 토큰은 자동으로 갱신되며 프로덕션 용도로 선호됩니다.
Tajo에 연결
# Using GitHub Apptajo connectors install github \ --app-id $GITHUB_APP_ID \ --private-key-path ./github-app-key.pem \ --installation-id $GITHUB_INSTALLATION_ID
# Using Personal Access Tokentajo connectors install github \ --token $GITHUB_TOKEN설정
기본 설정
connectors: github: enabled: true auth_type: "github_app" # or "token"
repositories: - owner/repo-1 - owner/repo-2
sync: issues: true pull_requests: true releases: true contributors: true stars: true
lists: contributors: 20 stargazers: 21필드 매핑
GitHub 사용자 데이터를 Brevo 연락처 속성에 매핑합니다.
field_mapping: # Standard fields login: GITHUB_USERNAME email: email name: FIRSTNAME
# Developer metrics contributions: GITHUB_CONTRIBUTIONS repositories_count: GITHUB_REPOS followers: GITHUB_FOLLOWERS created_at: GITHUB_JOINED
# Custom attributes company: COMPANY location: LOCATION bio: GITHUB_BIOAPI 엔드포인트
Tajo는 다음 GitHub REST API 엔드포인트와 통합됩니다.
| 엔드포인트 | Method | 용도 |
|---|---|---|
/repos/{owner}/{repo}/issues | GET | 리포지토리 이슈 목록 |
/repos/{owner}/{repo}/pulls | GET | Pull Request 목록 |
/repos/{owner}/{repo}/releases | GET | 릴리스 목록 |
/repos/{owner}/{repo}/contributors | GET | 컨트리뷰터 목록 |
/repos/{owner}/{repo}/stargazers | GET | 스타가져 목록 |
/repos/{owner}/{repo}/forks | GET | 포크 목록 |
/repos/{owner}/{repo}/events | GET | 리포지토리 이벤트 목록 |
/users/{username} | GET | 사용자 프로필 조회 |
/orgs/{org}/members | GET | 조직 멤버 목록 |
/repos/{owner}/{repo}/hooks | POST | 웹훅 생성 |
코드 예제
커넥터 초기화
import { TajoClient } from '@tajo/sdk';
const tajo = new TajoClient({ apiKey: process.env.TAJO_API_KEY, brevoApiKey: process.env.BREVO_API_KEY});
await tajo.connectors.connect('github', { appId: process.env.GITHUB_APP_ID, privateKey: process.env.GITHUB_PRIVATE_KEY, installationId: process.env.GITHUB_INSTALLATION_ID});컨트리뷰터를 Brevo로 동기화
await tajo.connectors.sync('github', { type: 'full', resources: ['contributors'], repositories: ['owner/repo-1', 'owner/repo-2']});
const status = await tajo.connectors.status('github');console.log(status);// {// connected: true,// lastSync: '2024-03-15T11:00:00Z',// contributorsCount: 245,// issuesTracked: 1890,// releasesTracked: 34// }웹훅 이벤트 처리
app.post('/webhooks/github', async (req, res) => { const signature = req.get('X-Hub-Signature-256'); const event = req.get('X-GitHub-Event');
// Verify webhook signature if (!verifyGitHubSignature(req.body, signature)) { return res.status(401).send('Unauthorized'); }
await tajo.connectors.handleWebhook('github', { event, payload: req.body });
res.status(200).send('OK');});릴리스 캠페인 트리거
// Listen for new releases and trigger Brevo campaigntajo.connectors.on('github', 'release.published', async (event) => { await tajo.campaigns.trigger('release-announcement', { listId: 21, params: { version: event.release.tag_name, release_notes: event.release.body, download_url: event.release.html_url } });});요청 제한
GitHub는 인증 방식에 따라 요청 제한을 적용합니다.
| 인증 | 기본 요청 제한 | Search API |
|---|---|---|
| 미인증 | 시간당 60회 | 분당 10회 |
| Personal Access Token | 시간당 5,000회 | 분당 30회 |
| GitHub App (installation) | 시간당 5,000회 | 분당 30회 |
| GitHub App (user-to-server) | 시간당 5,000회 | 분당 30회 |
조건부 요청
Tajo는 API 소비를 줄이기 위해 조건부 요청(If-None-Match / If-Modified-Since 헤더)을 사용합니다. 304 Not Modified 응답은 요청 제한에 포함되지 않습니다.
추가 제한:
- 보조 요청 제한: 동시 요청 100회 이하. REST API 엔드포인트의 경우 분당 900 포인트 이하.
- GraphQL: 시간당 5,000 포인트 (쿼리 비용은 복잡도에 따라 다름).
문제 해결
일반적인 문제
| 문제 | 원인 | 해결 방법 |
|---|---|---|
| 401 Unauthorized | 토큰 만료 또는 잘못된 자격 증명 | 토큰을 재생성하거나 GitHub App을 재설치하세요 |
| 403 Forbidden | 권한 부족 | 토큰 스코프 또는 앱 권한을 확인하세요 |
| 404 Not Found | 액세스 권한이 없는 비공개 리포지토리 | 토큰 또는 앱에 리포지토리 액세스를 부여하세요 |
| Rate limit exceeded | API 호출이 너무 많음 | 조건부 요청을 활성화하고 동기화 빈도를 줄이세요 |
| 웹훅 수신 안 됨 | 잘못된 URL 또는 방화벽 | 웹훅 URL이 공개적으로 접근 가능한지 확인하세요 |
디버그 모드
connectors: github: debug: true log_level: verbose log_webhooks: true연결 테스트
tajo connectors test github# ✓ API authentication successful# ✓ Repository access verified# ✓ Issue data readable# ✓ Webhook delivery active# ✓ Rate limit healthy (4,850/5,000 remaining)모범 사례
- PAT보다 GitHub App 사용 - GitHub App은 세분화된 권한과 자동 갱신 토큰을 제공합니다
- 웹훅 시크릿 활성화 - 항상 HMAC-SHA256으로 웹훅 서명을 검증하세요
- 조건부 요청 사용 - ETag를 활용해 요청 제한 할당량 낭비를 방지하세요
- 대용량 응답 페이지네이션 - GitHub는 페이지당 최대 100개 항목을 반환합니다.
Link헤더로 순회하세요 - 저활동 시간대에 동기화 - 개발 피크 시간 외에 전체 동기화를 예약하세요
- 요청 제한 헤더 모니터링 - 사전적 제한을 위해
X-RateLimit-Remaining을 확인하세요
보안
- GitHub App 인증 - 짧은 수명의 설치 토큰이 적용된 RSA 키 기반 JWT
- 웹훅 서명 - 모든 웹훅 페이로드에 대한 HMAC-SHA256 서명 검증
- Fine-Grained 토큰 - 특정 리포지토리 및 권한으로 스코프 제한
- HTTPS 전용 - 모든 API 통신은 TLS 1.2+를 통해 암호화됩니다
- 암호화된 저장소 - Tajo의 프라이빗 키와 토큰은 저장 시 암호화됩니다
- 토큰 만료 - Fine-grained 토큰은 자동으로 만료됩니다. 순환 알림을 설정하세요