middle
Как обрабатывать события в Jira Cloud?
Обработка событий в Jira Cloud основана на Forge Triggers (рекомендуемый подход) и Connect Webhooks, в отличие от синхронных Event Listener в DC.
Forge Triggers
Пример
# manifest.yml
modules:
trigger:
- key: on-issue-created
function: issueCreatedHandler
events:
- avi:jira:created:issue
- key: on-issue-updated
function: issueUpdatedHandler
events:
- avi:jira:updated:issue
- key: scheduled-task
function: scheduledHandler
interval: hour # minute, hour, day, week
Код обработчиков событий
export async function onIssueCreated(event: any, context: any) {
const { issue } = event;
console.log(`Issue created: ${issue.key}`);
if (issue.fields.issuetype.name === 'Bug'
&& issue.fields.priority.name === 'Critical') {
await api.asApp().requestJira(
route`/rest/api/3/issue/${issue.key}`,
{
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
update: { labels: [{ add: 'critical-auto' }] }
})
}
);
}
}
export async function onIssueUpdated(event: any, context: any) {
const { issue, changelog } = event;
if (!changelog?.items) return;
for (const change of changelog.items) {
if (change.field === 'status' && change.toString === 'Done') {
await fetch('https://api.example.com/tasks/completed', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
issueKey: issue.key,
completedAt: new Date().toISOString()
})
});
}
}
}
export async function onScheduled(event: any) {
const response = await api.asApp().requestJira(route`/rest/api/3/search`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
jql: 'duedate < now() AND status != Done',
maxResults: 50
})
});
const data = await response.json();
console.log(`Просроченных задач: ${data.total}`);
}
Различия обработки событий DC vs Cloud
| Аспект | DC (Event Listener) | Cloud (Forge Trigger) | Cloud (Connect Webhook) |
|---|---|---|---|
| Вызов | Синхронно в JVM | Async (serverless) | HTTP POST |
| Доставка | Гарантированная | At-least-once | At-least-once |
| Порядок | Гарантированный | Не гарантированный | Не гарантированный |
| Timeout | Нет (в JVM) | 25 секунд | Зависит от сервера |
| Retry | Нет (свой) | Автоматический (3x) | Ограниченный |
Частые ошибки
- Синхронная тяжёлая обработка в Forge trigger — превышение 25-секундного лимита
- Предположение о порядке событий — issue_updated может прийти раньше issue_created
- Не обрабатывать дубликаты — проверяйте, было ли событие уже обработано
- Неиспользование фильтров в Connect webhooks — получение всех событий перегружает сервер
Как используется в 2026
- Forge Triggers стали основным механизмом для Cloud-приложений
- Atlassian улучшил гарантии доставки и добавил dead-letter queue для failed triggers
- Async Events в Forge — для цепочек обработки (trigger -> async function -> async function)
- Scheduled triggers ограничены: minute, hour, day, week — нет cron-выражений
На собеседовании: сравните три подхода: DC Event Listener (синхронный, в JVM), Forge Trigger (async, serverless, 25s лимит), Connect Webhook (HTTP POST, свой сервер). Ключевое: idempotent-обработка обязательна — события at-least-once, порядок не гарантирован.