PostHog 커넥터
Tajo를 통해 PostHog를 Brevo에 연결하여 제품 분석 데이터, 사용자 행동 이벤트, 코호트 멤버십을 동기화하고 데이터 기반 마케팅 캠페인 및 맞춤형 고객 참여를 실현하십시오.
개요
| 속성 | 값 |
|---|---|
| 플랫폼 | PostHog |
| 카테고리 | 제품 분석 (Custom) |
| 설정 복잡도 | 중간 |
| 공식 통합 | 아니오 |
| 동기화 데이터 | 이벤트, 개인, 기능 플래그, 코호트 |
| 인증 방법 | 개인 API 키 / 프로젝트 토큰 |
기능
- 이벤트 동기화 - 행동 타겟팅을 위해 PostHog 분석 이벤트를 Brevo로 전달
- 개인 프로필 동기화 - PostHog 개인 속성을 Brevo 연락처 속성으로 동기화
- 코호트 기반 세그먼테이션 - PostHog 코호트를 Brevo 연락처 목록에 매핑
- 기능 플래그 동기화 - 활성화된 기능 플래그별로 연락처 세그먼트화
- 퍼널 데이터 - 타겟 재참여에 전환 퍼널 데이터 사용
- 세션 리플레이 메타데이터 - 세션 참여 지표로 연락처 보강
사전 요구 사항
시작하기 전에 다음이 준비되어 있는지 확인하십시오.
- PostHog 계정 (클라우드 또는 자체 호스팅)
- PostHog 설정의 개인 API 키
- 프로젝트 설정의 프로젝트 API 키(토큰)
- API 접근이 가능한 Brevo 계정
- 커넥터 권한이 있는 Tajo 계정
인증
개인 API 키 (비공개 엔드포인트)
# https://app.posthog.com/settings/user-api-keys 에서 생성export POSTHOG_PERSONAL_API_KEY=phx_your_personal_api_keyexport POSTHOG_PROJECT_TOKEN=phc_your_project_tokenexport POSTHOG_HOST=https://us.posthog.com # 또는 https://eu.posthog.comexport TAJO_API_KEY=your_tajo_api_keyexport BREVO_API_KEY=your_brevo_api_key// 비공개 API 엔드포인트는 Bearer 인증 사용const headers = { 'Authorization': `Bearer ${process.env.POSTHOG_PERSONAL_API_KEY}`, 'Content-Type': 'application/json'};
// 공개 엔드포인트는 프로젝트 토큰 사용const publicHeaders = { 'Content-Type': 'application/json'};// 공개 엔드포인트의 경우 토큰은 요청 본문에 전달됨API 키 보안
개인 API 키는 전체 계정 접근을 제공합니다. 클라이언트 측 코드에 절대 노출하지 마십시오. 이벤트 캡처 및 기능 플래그 평가와 같은 공개 엔드포인트에는 프로젝트 API 키(토큰)를 사용하십시오.
구성
기본 설정
connectors: posthog: enabled: true host: "${POSTHOG_HOST}" personal_api_key: "${POSTHOG_PERSONAL_API_KEY}" project_token: "${POSTHOG_PROJECT_TOKEN}" project_id: "12345"
sync: persons: true events: true cohorts: true feature_flags: true schedule: "0 */3 * * *" # 3시간마다
event_filters: - "$pageview" - "purchase_completed" - "signup_completed" - "feature_used"
lists: all_users: 25 active_users: 26 power_users: 27필드 매핑
field_mapping: email: email $name: FIRSTNAME $browser: BROWSER $os: OS $initial_referrer: REFERRAL_SOURCE total_events: EVENT_COUNT last_seen: LAST_ACTIVE_DATE signup_date: SIGNUP_DATE plan: SUBSCRIPTION_PLAN company: COMPANY cohort_names: POSTHOG_COHORTSAPI 엔드포인트
| 엔드포인트 | 메서드 | 설명 |
|---|---|---|
{host}/api/projects/{id}/persons/ | GET | 개인 목록 |
{host}/api/projects/{id}/events/ | GET | 이벤트 목록 |
{host}/api/projects/{id}/cohorts/ | GET | 코호트 목록 |
{host}/api/projects/{id}/feature_flags/ | GET | 기능 플래그 목록 |
{host}/api/projects/{id}/feature_flags/evaluation/ | POST | 플래그 평가 |
{host}/api/projects/{id}/insights/ | GET | 저장된 인사이트 목록 |
{host}/api/projects/{id}/query/ | POST | HogQL 쿼리 실행 |
{host}/i/v0/e | POST | 이벤트 캡처 (공개) |
{host}/decide/?v=3 | 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('posthog', { host: process.env.POSTHOG_HOST, personalApiKey: process.env.POSTHOG_PERSONAL_API_KEY, projectToken: process.env.POSTHOG_PROJECT_TOKEN, projectId: '12345'});개인을 Brevo로 동기화
// PostHog 개인을 페이지네이션으로 순회let nextUrl = `${posthogHost}/api/projects/${projectId}/persons/?` + new URLSearchParams({ limit: '100' });
while (nextUrl) { const response = await fetch(nextUrl, { headers: { 'Authorization': `Bearer ${process.env.POSTHOG_PERSONAL_API_KEY}` } });
const data = await response.json();
for (const person of data.results) { const email = person.properties.$email || person.properties.email; if (!email) continue;
await tajo.contacts.sync({ email, attributes: { FIRSTNAME: person.properties.$name || person.properties.name, LAST_ACTIVE_DATE: person.properties.$last_seen, SIGNUP_DATE: person.created_at, EVENT_COUNT: person.properties.$event_count, BROWSER: person.properties.$browser, OS: person.properties.$os, REFERRAL_SOURCE: person.properties.$initial_referrer }, listIds: [25] }); }
nextUrl = data.next;}코호트를 Brevo 목록으로 동기화
// PostHog 코호트를 가져와서 멤버를 Brevo 목록으로 동기화const cohortsResponse = await fetch( `${posthogHost}/api/projects/${projectId}/cohorts/`, { headers: { 'Authorization': `Bearer ${process.env.POSTHOG_PERSONAL_API_KEY}` } });
const { results: cohorts } = await cohortsResponse.json();
for (const cohort of cohorts) { // 이 코호트에 속한 개인 가져오기 const personsResponse = await fetch( `${posthogHost}/api/projects/${projectId}/cohorts/${cohort.id}/persons/`, { headers: { 'Authorization': `Bearer ${process.env.POSTHOG_PERSONAL_API_KEY}` } } );
const { results: persons } = await personsResponse.json();
for (const person of persons) { const email = person.properties.$email || person.properties.email; if (email) { await tajo.contacts.update(email, { attributes: { POSTHOG_COHORTS: cohort.name } }); } }}분석을 위한 HogQL 쿼리 실행
// HogQL을 사용하여 분석 데이터 쿼리const queryResponse = await fetch( `${posthogHost}/api/projects/${projectId}/query/`, { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.POSTHOG_PERSONAL_API_KEY}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ query: { kind: 'HogQLQuery', query: ` SELECT properties.$email AS email, count() AS event_count, max(timestamp) AS last_event FROM events WHERE event = 'purchase_completed' AND timestamp > now() - interval 30 day GROUP BY email HAVING event_count > 3 ORDER BY event_count DESC LIMIT 1000 ` } }) });
const queryResult = await queryResponse.json();
for (const row of queryResult.results) { await tajo.contacts.update(row[0], { attributes: { PURCHASE_COUNT_30D: row[1], LAST_PURCHASE: row[2] } });}속도 제한
| 엔드포인트 카테고리 | 제한 | 참고 |
|---|---|---|
| 분석 엔드포인트 | 240/분, 1,200/시간 | GET 개인, 이벤트, 인사이트 |
| 쿼리 엔드포인트 | 2,400/시간 | HogQL 및 맞춤 쿼리 |
| 기능 플래그 평가 | 600/분 | 로컬 평가 엔드포인트 |
| CRUD 엔드포인트 | 480/분, 4,800/시간 | 생성, 업데이트, 삭제 작업 |
| 공개 엔드포인트 (캡처) | 무제한 | 이벤트 캡처, 플래그 결정 |
배치 내보내기
대규모 이벤트 데이터 내보내기의 경우 API 대신 PostHog의 배치 내보내기 기능을 사용하십시오. 배치 내보내기는 S3, BigQuery, Snowflake 및 기타 대상을 지원합니다.
문제 해결
| 문제 | 원인 | 해결 방법 |
|---|---|---|
| 401 Unauthorized | 잘못된 API 키 | 설정에서 개인 API 키 확인 |
| 400 잘못된 프로젝트 | 잘못된 프로젝트 ID | PostHog URL에서 프로젝트 ID 확인 |
| 개인 목록이 비어 있음 | 식별된 사용자 없음 | posthog.identify()가 호출되는지 확인 |
| 속성 누락 | 속성이 설정되지 않음 | 클라이언트 SDK에서 $set 호출 확인 |
| 속도 제한 429 | 너무 많은 요청 | 백오프 구현, 속도 제한 헤더 확인 |
디버그 모드
connectors: posthog: debug: true log_level: verbose log_queries: true log_sync: true모범 사례
- 사용자 식별 - 개인 동기화를 활성화하려면 항상 이메일로
posthog.identify()호출 - 세그먼테이션에 코호트 사용 - Brevo 목록을 위해 PostHog의 행동 코호트 활용
- API 요청 배치 처리 - 대용량 데이터 세트에는 페이지네이션과 배치 처리 사용
- 복잡한 쿼리에 HogQL 사용 - SQL과 유사한 쿼리로 맞춤 분석 추출
- 배치 내보내기 설정 - 대량 데이터 볼륨의 경우 API 폴링보다 배치 내보내기 선호
- 관련 이벤트 필터링 - 노이즈를 줄이기 위해 마케팅 관련 이벤트만 동기화
보안
- 개인 API 키 - 범위 지정된 Bearer 토큰 인증
- 프로젝트 토큰 - 클라이언트 측 작업 전용 공개 토큰
- HTTPS 전용 - 모든 엔드포인트에 TLS 암호화 필요
- IP 허용 목록 - 자체 호스팅 인스턴스에서 사용 가능
- 키 범위 지정 - 특정 권한 범위로 API 키 생성
- GitHub 시크릿 스캐닝 - PostHog는 키 유출 탐지를 위해 GitHub와 파트너십