Перейти к содержанию

Интеграция Linear и n8n: issues, webhooks и безопасный routing

Обновлено: 2026-05-30

AI summary: Problem/Solution-гайд по Linear и n8n: как отправлять продуктовые и инженерные события в Linear issues без дублей, неверных teams и потери контекста.
Готовый blueprint для внедрения

Импортируйте JSON в n8n, замените credentials, URL API, project/list IDs, поля и лимиты под вашу инфраструктуру.

Проблема: Linear удобен для инженерной команды, но не любит “сырые” события из форм, CRM и мониторинга: без team mapping, labels и дедупликации issues быстро становятся мусором.

Решение: Используйте n8n как issue router для Linear: валидируйте team и project, собирайте GraphQL mutation, ищите existing issue по external_id и обновляйте comment/labels вместо создания дубля.

Схема интеграции Linear и n8n для issues без дублей
Схема показывает валидацию mapping, поиск дубля и GraphQL mutation для Linear.

Проблема: почему простая интеграция создаёт дубли и ручной хаос

Linear обычно внедряют там, где команде важна скорость: баги из поддержки, feature request из CRM, инциденты из мониторинга, product feedback из формы. Если каждый источник создаёт issue напрямую, backlog загрязняется задачами без owner, priority и воспроизводимого контекста.

Надёжная настройка Linear и n8n должна решать не только “создать issue”. Нужно контролировать team_id, project_id, priority, labels, source_url, actor, environment и повторные события. Это снижает ручной triage и помогает инженерной команде доверять автоматизации.

Архитектура workflow для n8n

БлокЗадачаProduction-проверка
Webhook product eventпринимает bug, feature request или incidentsource, entity_id, event_type
Validate Linear mappingпроверяет team_id, project_id и priorityallowlist команд и проектов
Build GraphQL payloadсобирает mutation для Linear APItitle, description, labels, assignee
Find existing issueищет issue по external_idдо создания нового issue
Create/update issueсоздаёт issue или добавляет commentбез потери labels и priority
Respond / notifyвозвращает issue identifieralert на API-ошибки

Для Linear важно заранее договориться, какие внешние события становятся issue, а какие только комментарием к существующему issue. Иначе backlog заполняется повторными “сигналами”, а не задачами.

Контракт входных данных

{
  "source": "support",
  "event_type": "bug_report",
  "entity_id": "case-9102",
  "title": "Ошибка оплаты при повторной попытке",
  "description": "Пользователь получает 500 после retry платежа",
  "team_key": "PAY",
  "project_key": "checkout-stability",
  "priority": "urgent",
  "labels": [
    "bug",
    "payment",
    "customer-report"
  ],
  "source_url": "https://support.example.ru/cases/9102",
  "customer_impact": "Платёж не завершается у 12 клиентов"
}

team_key и priority должны проходить allowlist. Нельзя отдавать пользователю формы право создавать задачи в любой engineering team.

Code Node: нормализация, mapping и guard-условия

const src = $json.body ?? $json;
const teams = { PAY: 'linear-team-payments', WEB: 'linear-team-web' };
const priorities = { urgent: 1, high: 2, medium: 3, low: 4 };
const teamKey = String(src.team_key ?? 'WEB').trim().toUpperCase();
if (!teams[teamKey]) throw new Error(`Linear team is not allowed: ${teamKey}`);
const entityId = String(src.entity_id ?? '').trim();
if (!entityId) throw new Error('No entity_id for Linear issue');
const priorityKey = String(src.priority ?? 'medium').toLowerCase();
const externalId = `linear-router:${src.source ?? 'external'}:${entityId}`;
const labels = Array.isArray(src.labels) ? src.labels.map(String).slice(0, 8) : [];
const title = String(src.title ?? 'External issue').trim().slice(0, 180);
const description = [String(src.description ?? '').trim(), '', `External ID: ${externalId}`, `Source: ${src.source ?? 'external'}`, `Impact: ${src.customer_impact ?? 'n/a'}`, `URL: ${src.source_url ?? ''}`].join('
');
return [{ json: {
  external_id: externalId,
  find_query: externalId,
  mutation: {
    teamId: teams[teamKey],
    title,
    description,
    priority: priorities[priorityKey] ?? 3,
    labels,
    projectKey: src.project_key ?? null
  },
  comment: `Повторное событие для ${externalId}`
}}];
Почему Linear GraphQL лучше закрывать шаблоном

GraphQL mutation гибкая, но ломкая для ручных правок. Шаблон в Code Node фиксирует обязательные поля, mapping команд и формат description, чтобы разные источники не создавали разные структуры issues.

Готовый workflow JSON: скачать и импортировать

Скачать готовый workflow JSON Скачать тестовый payload

{
  "name": "Nodbot - Linear issue router with GraphQL dedupe",
  "nodes": [
    {
      "name": "Webhook Linear event",
      "type": "n8n-nodes-base.webhook",
      "purpose": "Принять событие"
    },
    {
      "name": "Validate Linear mapping",
      "type": "n8n-nodes-base.code",
      "purpose": "Проверить team/project/priority"
    },
    {
      "name": "Find existing Linear issue",
      "type": "n8n-nodes-base.httpRequest",
      "purpose": "Найти issue по external_id"
    },
    {
      "name": "Create or update Linear issue",
      "type": "n8n-nodes-base.httpRequest",
      "purpose": "Создать issue или comment"
    },
    {
      "name": "Notify owner",
      "type": "n8n-nodes-base.httpRequest",
      "purpose": "Сообщить ссылку на issue"
    },
    {
      "name": "Respond",
      "type": "n8n-nodes-base.respondToWebhook",
      "purpose": "Вернуть identifier"
    }
  ],
  "connections": "Webhook Linear event → Validate Linear mapping → Find existing Linear issue → Create or update Linear issue → Notify owner → Respond"
}

Пошаговая настройка связки

  1. Опишите mapping team_key → Linear team ID и project_key → project.
  2. Создайте labels для источников и severity.
  3. Импортируйте workflow JSON и замените Linear API token.
  4. Настройте поиск existing issue по external_id до create mutation.
  5. Проверьте тестовые события с разным priority и повторным entity_id.

Тесты перед production

curl -X POST "https://YOUR-N8N-DOMAIN/webhook/integration-linear-n8n-issue-router" \
  -H "Content-Type: application/json" \
  --data @integration-linear-n8n-issue-router-payload.json
  1. Повторный payload не создаёт дубль и возвращает тот же output key.
  2. Некорректный mapping останавливается до запроса к внешнему API.
  3. Пустые необязательные поля не ломают workflow.
  4. Ошибка API уходит в alert или DLQ с безопасным payload.
  5. Execution data не содержит секретов, токенов и лишних персональных данных.

Production-риски

  • team_id задаётся из внешнего payload. Событие может попасть в неправильную команду.
  • Каждый alert создаёт issue. Инцидент размазывается по backlog вместо одного issue с комментариями.
  • Priority не нормализован. Срочные клиентские ошибки становятся обычными задачами.
  • GraphQL error игнорируется. Workflow отвечает 200, но issue не создан.
  • Нет ссылки на источник. Инженер не может открыть case, alert или CRM-сущность.
Карточка результата Linear issue router с team, priority и external_id
Пример результата: один Linear issue содержит приоритет, источник и историю повторов.

Критерии готовности

  1. team_key и project_key проходят allowlist.
  2. external_id сохраняется в issue description или custom workflow-поле.
  3. Повтор entity_id добавляет comment, а не создаёт duplicate issue.
  4. GraphQL errors попадают в alert и не маскируются под successful run.
  5. Issue содержит source_url, impact и понятный priority.
Нужен Linear-router без backlog-мусора?

Nodbot настроит Linear + n8n: GraphQL mutation, team mapping, дедупликацию, labels, source links и алерты для engineering workflow.

Обсудить Linear-интеграцию