Kommo + Jira: задачи команды разработки из выигранных сделок
Jira — основная система управления задачами для dev- и CS-команд в большинстве B2B SaaS. Без интеграции с Kommo менеджер после Won вручную создаёт Jira-тикет, указывает тип клиента, план, технический контекст. При переходе тикета в Done Kommo не знает. Связка через Jira REST API замыкает этот цикл: Won -> Jira Task -> Done -> Note в сделку.
Почему нативная интеграция не закрывает задачу
Kommo Marketplace предлагает несколько Jira-виджетов, но большинство из них — просто ссылка на Jira из карточки сделки. Двусторонней синхронизации нет: изменение статуса задачи в Jira не обновляет сделку в Kommo. Создание тикета с данными из кастомных полей сделки (тариф, технический стек, онбординг-требования) через эти виджеты невозможно.
Zapier поддерживает создание Jira-задачи при смене статуса в Kommo, но не умеет: заполнять описание тикета из нескольких кастомных полей, обрабатывать обратный вебхук от Jira, работать с custom field’ами Jira (Story Points, priority, epic).
Jira REST API v3 даёт полный контроль: создание задачи с любой структурой данных, управление переходами, чтение комментариев — всё через один API-ключ.
Что синхронизируется
Kommo -> Jira:
— Название сделки -> Summary задачи
— Тариф и план -> labels или custom field
— Имя и email контакта -> Description задачи
— Технический стек из кастомного поля -> Components
— ID сделки -> custom field kommo_deal_id для трассировки
Jira -> Kommo:
— Задача перешла в Done -> Note в Kommo: «Онбординг завершён»
— Jira-комментарий от техкоманды -> Note в сделке
— Задача заблокирована (blocked) -> задача менеджеру: уточнить у клиента
Архитектура
Kommo Webhook: сделка перешла в Won
↓ Backend
1. GET /api/v4/leads/{id} + contacts
-> имя клиента, email, тариф, технический стек
2. Jira: POST /rest/api/3/issue
-> project: {key: 'OB'}, issuetype: {name: 'Task'}
-> summary, description с данными клиента
-> labels: ['onboarding', plan]
-> customfield_10001: deal_id (Kommo Deal ID)
-> получить issue_key (OB-123)
3. Kommo: PATCH /leads/{deal_id}
-> jira_ticket = 'OB-123'
-> jira_ticket_url = 'https://company.atlassian.net/browse/OB-123'
4. Kommo: POST /leads/{deal_id}/notes
-> «Создан Jira-тикет OB-123: https://...»
Jira Webhook: issue_updated (transition to Done)
↓ Backend
1. Из payload: issue.key, changelog.items (status change)
2. Проверить: to.name == 'Done'
3. Найти deal_id по customfield_10001 (kommo_deal_id)
4. Kommo: POST /leads/{deal_id}/notes
-> «Jira OB-123: задача закрыта. Онбординг завершён.»
5. Опционально: PATCH /leads/{deal_id} -> jira_status = done
Jira REST API v3: ключевые запросы
Base URL: https://{site}.atlassian.net/rest/api/3/. Аутентификация: Basic Auth, username = email, password = api_token (создать в atlassian.com/manage-profile/security/api-tokens).
Создать задачу:
import requests
from requests.auth import HTTPBasicAuth
JIRA_URL = 'https://yourcompany.atlassian.net'
JIRA_EMAIL = 'bot@yourcompany.com'
JIRA_TOKEN = 'your_api_token'
JIRA_AUTH = HTTPBasicAuth(JIRA_EMAIL, JIRA_TOKEN)
def create_jira_issue(summary: str, description: str,
project_key: str, labels: list,
kommo_deal_id: int) -> str:
payload = {
'fields': {
'project': {'key': project_key},
'issuetype': {'name': 'Task'},
'summary': summary,
'description': {
'type': 'doc',
'version': 1,
'content': [{
'type': 'paragraph',
'content': [{'type': 'text', 'text': description}]
}]
},
'labels': labels,
'priority': {'name': 'Medium'},
# Кастомное поле - ID узнать через GET /rest/api/3/field
'customfield_10200': str(kommo_deal_id) # Kommo Deal ID
}
}
resp = requests.post(
f'{JIRA_URL}/rest/api/3/issue',
auth=JIRA_AUTH,
json=payload
)
resp.raise_for_status()
return resp.json()['key'] # 'OB-123'
Описание задачи из данных Kommo:
def build_issue_description(lead: dict, contact: dict) -> str:
plan = get_custom_field(lead, PLAN_FIELD_ID)
tech_stack = get_custom_field(lead, TECH_STACK_FIELD_ID)
deal_amount = lead.get('price', 0)
return (
f'Клиент: {contact.get("name")}\n'
f'Email: {get_contact_email(contact)}\n'
f'Тариф: {plan}\n'
f'Сумма сделки: ${deal_amount}\n'
f'Технический стек: {tech_stack}\n'
f'Kommo Deal ID: {lead["id"]}'
)
Обработка Jira Webhook:
from flask import Flask, request
app = Flask(__name__)
@app.route('/webhooks/jira', methods=['POST'])
def jira_webhook():
payload = request.json
event = payload.get('webhookEvent')
if event != 'jira:issue_updated':
return '', 200
issue = payload.get('issue', {})
issue_key = issue.get('key')
changelog = payload.get('changelog', {})
# Ищем смену статуса в changelog
status_change = None
for item in changelog.get('items', []):
if item.get('field') == 'status':
status_change = item
break
if not status_change:
return '', 200
to_status = status_change.get('toString', '')
if to_status != 'Done':
return '', 200
# Получить kommo_deal_id из кастомного поля Jira
custom_fields = issue.get('fields', {})
kommo_deal_id = custom_fields.get('customfield_10200')
if kommo_deal_id:
deal_id = int(kommo_deal_id)
create_kommo_note(
deal_id,
f'Jira {issue_key}: задача закрыта (Done). Онбординг завершён.'
)
return '', 200
Получить список ID кастомных полей Jira:
def get_jira_fields():
resp = requests.get(
f'{JIRA_URL}/rest/api/3/field',
auth=JIRA_AUTH
)
return {f['name']: f['id'] for f in resp.json()}
# Запустить один раз для поиска нужных field ID:
# fields = get_jira_fields()
# print(fields) # {'Story Points': 'customfield_10016', ...}
Регистрация Jira Webhook:
Jira Cloud позволяет регистрировать webhooks через Admin: Settings -> System -> Webhooks -> Create a WebHook. Указать URL и выбрать события. Для Issue Updated выбрать: Issue updated с фильтром project = OB AND status = Done.
Также доступна регистрация через API: POST /rest/webhooks/1.0/webhook (требует Jira Admin права).
Маппинг тарифов Kommo -> Jira labels
PLAN_TO_LABELS = {
'Starter': ['onboarding', 'tier-starter'],
'Pro': ['onboarding', 'tier-pro'],
'Enterprise': ['onboarding', 'tier-enterprise', 'priority-high'],
}
def get_jira_labels(kommo_plan: str) -> list:
return PLAN_TO_LABELS.get(kommo_plan, ['onboarding'])
Enterprise-клиенты получают priority-high лейбл — CS-команда видит их в отдельном фильтре Jira.
Реальный кейс
B2B SaaS (EU, 30–40 новых клиентов в квартал, Kommo + Jira + Notion, команда онбординга 4 человека):
- До: менеджер после Won тратил 15–20 минут на создание Jira-тикета. Нередко забывал указать тариф или технический стек — CS узнавал это уже в процессе онбординга. При закрытии тикета в Jira сделка в Kommo оставалась без обновления.
- После: Won -> Jira Task за 40 секунд с полным описанием из CRM. CS-команда видит в тикете всё что нужно. При Done -> автоматический Note в Kommo. Sales Director видит статус онбординга прямо в сделке.
- Дополнительно: если тикет висит без движения 7 дней — Jira-автоматизация (или scheduled webhook) -> задача менеджеру проверить.
Для кого актуально
- B2B SaaS с отдельной командой онбординга / Customer Success / Implementation
- После Won продажи передают клиента CS через Jira-задачи
- CS-команда не работает в CRM, Sales-команда не работает в Jira
- 15+ передач клиентов в месяц — ручное создание тикетов нерентабельно
Часто задаваемые вопросы
Jira API — OAuth или Basic Auth?
Для серверных интеграций без участия пользователя — Basic Auth с email и API Token. API Token создаётся в профиле Atlassian (atlassian.com/manage-profile/security/api-tokens), не в Jira. OAuth 2.0 нужен для приложений, где пользователь сам авторизует доступ.
Как Jira Webhook проверяет что запрос подлинный?
Jira Cloud не поддерживает HMAC-подпись webhooks по умолчанию. Защита — IP-whitelist (если у вас статический IP) или secret параметр в URL (Jira добавляет его к запросу). Дополнительно: проверяйте что payload содержит ожидаемый project key.
Как найти ID кастомного поля Jira для API?
Через GET /rest/api/3/field — возвращает все поля с их ID. Кастомные поля имеют ID вида customfield_XXXXX. Также ID виден в URL при редактировании поля в Jira: Settings -> Issues -> Custom Fields -> Edit field.
Что если один клиент имеет несколько сделок в Kommo?
В Jira-тикете храните kommo_deal_id конкретной сделки Won. При обратном вебхуке используете этот ID для обновления нужной сделки. Если сделок несколько — создавайте отдельный тикет для каждой Won.
Jira Server vs Jira Cloud — разные API?
Jira Cloud использует REST API v3 (atlassian.net). Jira Server/Data Center — REST API v2 (ваш домен). Основная разница: описание задачи в Cloud требует Atlassian Document Format (JSON-дерево), в Server — обычный текст или wiki-разметку.
Итого
- Jira REST API v3: Basic Auth (email:api_token), Base URL
https://{site}.atlassian.net/rest/api/3/ - Создание задачи:
POST /issueс полями из Kommo (summary, description, labels, custom fields) - Webhook при Done -> Note в Kommo через
kommo_deal_idиз Jira custom field - Описание задачи: Atlassian Document Format (ADF) для Jira Cloud
- Типовой срок разработки — 1–2 недели
Если у вас Kommo и Jira и передача клиентов происходит вручную — опишите вашу структуру проектов и статусов. Exceltic.dev настроит создание тикетов и обратную синхронизацию статусов онбординга.