Linear 连接器

通过 Tajo 将您的 Linear 工作区连接到 Brevo,实现面向客户的 Issue 跟踪、产品更新通知和开发里程碑活动。

概览

属性
平台Linear
类别自定义
设置复杂度简单
官方集成
同步数据Issue、项目、用户、事件
API 类型GraphQL API
认证方式OAuth 2.0 / 个人 API 密钥
基础 URLhttps://api.linear.app/graphql

功能

  • Issue 事件同步 - 将 Issue 创建、更新和完成事件转发到 Brevo 联系人时间线
  • 项目里程碑跟踪 - 当项目达到关键里程碑时触发 Brevo 活动
  • 客户 Issue 关联 - 将 Linear Issue 与 Brevo 联系人关联,提供支持可见性
  • 基于标签的细分 - 将 Linear 标签映射到 Brevo 联系人属性
  • 周期分析 - 同步冲刺/周期完成数据,用于团队绩效报告
  • Webhook 驱动自动化 - 通过 Linear Webhook 实现实时事件转发

前提条件

开始之前,请确保您已具备:

  1. 具有管理员权限的 Linear 工作区
  2. 已配置个人 API 密钥或 OAuth 应用
  3. 具有 API 访问权限的 Brevo 账户
  4. 具有有效订阅的 Tajo 账户

认证

Linear 支持个人 API 密钥和 OAuth 2.0。

选项 1:个人 API 密钥

  1. 前往 Linear > 设置 > API > 个人 API 密钥
  2. 点击创建密钥
  3. 命名为”Tajo Integration”
  4. 复制生成的密钥(以 lin_api_ 开头)
Terminal window
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

适用于服务多个工作区的集成:

  1. linear.app/settings/api/applications 创建 OAuth 应用
  2. 配置重定向 URI:https://app.tajo.io/callbacks/linear
  3. 请求范围:readwriteissues:createcomments:create

GraphQL API

Linear 专用 GraphQL API。所有查询和变更均通过单一端点进行:https://api.linear.app/graphql。Tajo 自动处理所有 GraphQL 查询构建。

连接到 Tajo

Terminal window
# Using Personal API Key
tajo connectors install linear \
--api-key $LINEAR_API_KEY
# Using OAuth
tajo 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 用户和 Issue 数据映射到 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_UPDATED

API 端点

Linear 使用单一 GraphQL 端点。Tajo 使用的主要查询和变更:

操作类型用途
issues查询列出和过滤 Issue
issue查询按 ID 获取单个 Issue
projects查询列出所有项目
cycles查询列出周期(冲刺)
teams查询列出工作区团队
users查询列出工作区成员
viewer查询获取已认证用户信息
issueCreate变更创建新 Issue
issueUpdate变更更新现有 Issue
commentCreate变更向 Issue 添加评论
webhookCreate变更注册 Webhook

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
});

同步 Issue

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 Webhook

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 事件创建 Issue

// Create a Linear issue when a Brevo contact submits a request
tajo.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 密钥每小时 1,500 个请求
查询复杂度每请求 10,000 复杂度点
分页每页最多 250 个节点(默认 50)
Webhook无限制传入事件

复杂度预算

Linear 使用基于复杂度的速率限制系统。简单查询消耗的点数更少。Tajo 通过只请求必要字段和使用高效分页来优化查询以最小化复杂度。

超出限制时,Linear 返回 429 Too Many Requests 并附带 Retry-After 头部。

故障排除

常见问题

问题原因解决方案
401 UnauthorizedAPI 密钥无效或已撤销在 Linear 设置中生成新 API 密钥
查询错误GraphQL 语法无效使用 Linear 的 API 资源管理器验证查询
Issue 缺失团队访问受限确保 API 密钥所有者有访问目标团队的权限
Webhook 未触发URL 不正确或已禁用在 Linear 设置 > API > Webhooks 中检查 Webhook 状态
分页不完整缺少 after 游标确保分页循环直到 hasNextPage 为 false

调试模式

connectors:
linear:
debug: true
log_level: verbose
log_queries: true

测试连接

Terminal window
tajo connectors test linear
# ✓ GraphQL API connection successful
# ✓ Workspace access verified
# ✓ Team list readable
# ✓ Issue query operational
# ✓ Webhook registration available

最佳实践

  1. 使用 Webhook 实现实时 - 注册 Webhook 而非轮询 Issue 变更
  2. 按团队过滤 - 只同步相关团队的 Issue 以减少 API 使用
  3. 优化 GraphQL 查询 - 只请求所需字段以保持在复杂度限制内
  4. 将标签映射到细分 - 使用 Linear 标签驱动 Brevo 联系人细分
  5. 处理分页 - 始终检查 hasNextPage 并使用 endCursor 获取完整数据
  6. 验证 Webhook 签名 - 始终验证 Linear-Signature 头部

安全

  • API 密钥认证 - 限定到工作区的个人密钥
  • OAuth 2.0 - 多工作区集成的安全授权流程
  • 仅 HTTPS - 所有 API 通信通过 TLS 1.2+ 加密
  • Webhook 签名 - 基于 HMAC 的签名验证
  • 加密存储 - API 密钥在 Tajo 中静态加密
  • SOC 2 合规 - Linear 平台通过 SOC 2 Type II 认证

相关资源

Subscribe to updates

developer-docs

Drop your email or phone number — we'll send you what matters next.

auto-detect
AI 助手

你好!关于文档有任何问题都可以问我。