Linear 커넥터
Linear 워크스페이스를 Brevo에 연결하여 고객 대상 이슈 추적, 제품 업데이트 알림, Tajo를 통한 개발 마일스톤 캠페인을 구현하세요.
개요
| 속성 | 값 |
|---|---|
| 플랫폼 | Linear |
| 카테고리 | Custom |
| 설정 난이도 | 쉬움 |
| 공식 통합 | 아니오 |
| 동기화되는 데이터 | 이슈, 프로젝트, 사용자, 이벤트 |
| API 유형 | GraphQL API |
| 인증 | OAuth 2.0 / Personal API Key |
| Base URL | https://api.linear.app/graphql |
주요 기능
- 이슈 이벤트 동기화 - 이슈 생성, 업데이트, 완료 이벤트를 Brevo 연락처 타임라인으로 전달합니다
- 프로젝트 마일스톤 추적 - 프로젝트가 주요 마일스톤에 도달하면 Brevo 캠페인을 트리거합니다
- 고객 이슈 연결 - 지원 가시성을 위해 Linear 이슈를 Brevo 연락처와 연결합니다
- 라벨 기반 세분화 - Linear 라벨을 Brevo 연락처 속성에 매핑합니다
- 사이클 분석 - 팀 성과 리포팅을 위해 스프린트/사이클 완료 데이터를 동기화합니다
- 웹훅 기반 자동화 - Linear 웹훅을 통한 실시간 이벤트 전달
사전 준비 사항
시작하기 전에 다음 사항이 준비되어 있어야 합니다.
- 관리자 액세스 권한이 있는 Linear 워크스페이스
- 구성된 Personal API key 또는 OAuth 애플리케이션
- API 액세스가 활성화된 Brevo 계정
- 활성 구독이 있는 Tajo 계정
인증
Linear는 Personal API key와 OAuth 2.0을 지원합니다.
옵션 1: Personal API Key
- Linear > Settings > API > Personal API keys로 이동합니다
- Create key를 클릭합니다
- 이름을 “Tajo Integration”으로 지정합니다
- 생성된 키(
lin_api_로 시작)를 복사합니다
curl -X POST https://api.linear.app/graphql \ -H "Authorization: $LINEAR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"query": "{ viewer { id name email } }"}'옵션 2: OAuth 2.0
여러 워크스페이스를 지원하는 통합의 경우 다음과 같이 진행합니다.
- linear.app/settings/api/applications에서 OAuth 애플리케이션을 생성합니다
- 리디렉션 URI를 구성합니다:
https://app.tajo.io/callbacks/linear - 스코프를 요청합니다:
read,write,issues:create,comments:create
GraphQL API
Linear는 GraphQL API만 사용합니다. 모든 쿼리와 뮤테이션은 단일 엔드포인트(https://api.linear.app/graphql)를 통해 이루어집니다. Tajo는 모든 GraphQL 쿼리 구성을 자동으로 처리합니다.
Tajo에 연결
# Using Personal API Keytajo connectors install linear \ --api-key $LINEAR_API_KEY
# Using OAuthtajo connectors install linear \ --client-id $LINEAR_CLIENT_ID \ --client-secret $LINEAR_CLIENT_SECRET설정
기본 설정
connectors: linear: enabled: true
sync: issues: true projects: true cycles: true users: true
teams: - key: "ENG" sync_to_list: 38 - key: "SUPPORT" sync_to_list: 39
issue_states: - Backlog - Todo - "In Progress" - Done - Canceled필드 매핑
Linear 사용자 및 이슈 데이터를 Brevo 속성에 매핑합니다.
field_mapping: # User fields id: LINEAR_USER_ID email: email name: FIRSTNAME
# Issue metrics mapped to contact events last_issue_identifier: LAST_LINEAR_ISSUE last_issue_state: LAST_ISSUE_STATUS last_issue_priority: LAST_ISSUE_PRIORITY total_issues: LINEAR_ISSUE_COUNT
# Project data current_project: ACTIVE_PROJECT team_key: LINEAR_TEAM이벤트 매핑
event_mapping: Issue.create: ISSUE_CREATED Issue.update: ISSUE_UPDATED Issue.remove: ISSUE_DELETED Comment.create: COMMENT_ADDED Project.update: PROJECT_UPDATED Cycle.update: CYCLE_UPDATEDAPI 엔드포인트
Linear는 단일 GraphQL 엔드포인트를 사용합니다. Tajo가 사용하는 주요 쿼리와 뮤테이션은 다음과 같습니다.
| 작업 | 타입 | 용도 |
|---|---|---|
issues | Query | 이슈 목록 조회 및 필터링 |
issue | Query | ID로 단일 이슈 조회 |
projects | Query | 전체 프로젝트 목록 |
cycles | Query | 사이클(스프린트) 목록 |
teams | Query | 워크스페이스 팀 목록 |
users | Query | 워크스페이스 멤버 목록 |
viewer | Query | 인증된 사용자 정보 조회 |
issueCreate | Mutation | 새 이슈 생성 |
issueUpdate | Mutation | 기존 이슈 업데이트 |
commentCreate | Mutation | 이슈에 코멘트 추가 |
webhookCreate | Mutation | 웹훅 등록 |
GraphQL 쿼리 예제
query GetIssues($filter: IssueFilter, $first: Int, $after: String) { issues(filter: $filter, first: $first, after: $after) { nodes { id identifier title state { name } priority assignee { email name } labels { nodes { name } } createdAt updatedAt } pageInfo { hasNextPage endCursor } }}코드 예제
커넥터 초기화
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('linear', { apiKey: process.env.LINEAR_API_KEY});이슈 동기화
await tajo.connectors.sync('linear', { type: 'incremental', resources: ['issues'], teams: ['ENG', 'SUPPORT'], since: '2024-01-01'});
const status = await tajo.connectors.status('linear');console.log(status);// {// connected: true,// lastSync: '2024-03-15T18:00:00Z',// issuesTracked: 3200,// projectsMonitored: 8,// usersLinked: 45// }Linear 웹훅 처리
app.post('/webhooks/linear', async (req, res) => { const event = req.body;
// Verify webhook signature const signature = req.get('Linear-Signature'); if (!verifyLinearSignature(req.body, signature)) { return res.status(401).send('Unauthorized'); }
await tajo.connectors.handleWebhook('linear', { type: event.type, action: event.action, payload: { issueId: event.data?.id, identifier: event.data?.identifier, title: event.data?.title, state: event.data?.state?.name, assigneeEmail: event.data?.assignee?.email } });
res.status(200).send('OK');});Brevo 이벤트에서 이슈 생성
// Create a Linear issue when a Brevo contact submits a requesttajo.events.on('contact.event', async (event) => { if (event.name === 'FEATURE_REQUEST') { await tajo.connectors.create('linear', { teamId: 'ENG', title: `Feature Request: ${event.data.subject}`, description: event.data.description, priority: 3, labelIds: ['feature-request'] }); }});요청 제한
Linear는 GraphQL API에 요청 제한을 적용합니다.
| 제한 유형 | 값 |
|---|---|
| 요청 속도 | API key당 시간당 1,500회 |
| 쿼리 복잡도 | 요청당 10,000 complexity points |
| 페이지네이션 | 페이지당 최대 250개 노드 (기본 50개) |
| 웹훅 | 들어오는 이벤트 무제한 |
복잡도 예산
Linear는 복잡도 기반 요청 제한 시스템을 사용합니다. 간단한 쿼리는 더 적은 포인트를 소모합니다. Tajo는 필요한 필드만 요청하고 효율적인 페이지네이션을 사용하여 복잡도를 최소화하도록 쿼리를 최적화합니다.
제한을 초과하면 Linear는 Retry-After 헤더와 함께 429 Too Many Requests를 반환합니다.
문제 해결
일반적인 문제
| 문제 | 원인 | 해결 방법 |
|---|---|---|
| 401 Unauthorized | 유효하지 않거나 취소된 API key | Linear Settings에서 새 API key를 생성하세요 |
| Query errors | 유효하지 않은 GraphQL 구문 | Linear의 API 탐색기를 사용해 쿼리를 검증하세요 |
| 이슈 누락 | 팀 액세스 제한 | API key 소유자가 대상 팀에 액세스 권한이 있는지 확인하세요 |
| 웹훅이 동작하지 않음 | 잘못된 URL 또는 비활성화됨 | Linear Settings > API > Webhooks에서 웹훅 상태를 확인하세요 |
| 페이지네이션 불완전 | after 커서 누락 | hasNextPage가 false가 될 때까지 페이지네이션 루프를 유지하세요 |
디버그 모드
connectors: linear: debug: true log_level: verbose log_queries: true연결 테스트
tajo connectors test linear# ✓ GraphQL API connection successful# ✓ Workspace access verified# ✓ Team list readable# ✓ Issue query operational# ✓ Webhook registration available모범 사례
- 실시간 처리를 위해 웹훅 사용 - 이슈 변경을 폴링하는 대신 웹훅을 등록하세요
- 팀별 필터링 - API 사용량을 줄이기 위해 관련 팀의 이슈만 동기화하세요
- GraphQL 쿼리 최적화 - 복잡도 제한 내에서 유지하려면 필요한 필드만 요청하세요
- 라벨을 세그먼트에 매핑 - Linear 라벨을 활용해 Brevo 연락처 세분화를 구동하세요
- 페이지네이션 처리 - 항상
hasNextPage를 확인하고 완전한 데이터를 위해endCursor를 사용하세요 - 웹훅 서명 검증 - 항상
Linear-Signature헤더를 검증하세요
보안
- API Key 인증 - 워크스페이스로 스코프 제한된 Personal keys
- OAuth 2.0 - 여러 워크스페이스 통합을 위한 안전한 인증 플로우
- HTTPS 전용 - 모든 API 통신은 TLS 1.2+를 통해 암호화됩니다
- 웹훅 서명 - HMAC 기반 서명 검증
- 암호화된 저장소 - API key는 Tajo에 저장 시 암호화됩니다
- SOC 2 준수 - Linear 플랫폼은 SOC 2 Type II 인증을 받았습니다