Перейти до вмісту
NimbusNexus

Конвеєри

Конвеєр — це JSON-документ, а ця сторінка описує його мову. Webhooks і Request Bins виконують ту саму мову на тому самому рушії, тож усе, про що ви дізнаєтеся тут, діє й там — у межах правил кожного продукту щодо заголовків. Щоб спробувати будь-що з цього без акаунта, скористайтеся playground.

Документ

Цей конвеєр залишає оплачені рахунки на суму від $1,000, вилучає email клієнта й будь-які номери телефону, додає два поля й заголовок і вказує, що до запиту додається bearer-токен:

JSON
{
  "version": 1,
  "steps": [
    { "filter": { "type": "invoice.paid", "data": { "amount": { "$gte": 100000 } } }, "note": "Paid invoices of $1,000 or more" },
    { "drop": ["data.customer.email", "**.phone"] },
    { "set": { "event_type": "{{ type }}", "amount_display": "{{ data.amount | money(data.currency) }}" } },
    { "headers": { "set": { "X-Event-Type": "{{ type }}" } } },
    { "auth": { "type": "bearer", "secret": "sec_…" } }
  ]
}

version — це формат документа, завжди 1, а не версія конвеєра. Кроки виконуються в тому порядку, у якому записані. Кожен — це обʼєкт з одним ключем кроку й, за бажання, note до 200 символів: консоль показує її на кроці, а коли запит відкинуто, її повертає відповідь. filter також може мати action.

Запуск бачить один запит: body — будь-яке значення JSON, headers і meta, доступне лише для читання. В API запуску усі три — це те, що ви надсилаєте. Кожен крок бачить тіло таким, яким його залишив попередній. В API й текстах помилок кроки нумеруються з 0, а в редакторі консолі — з 1.

КрокУ консоліЩо робить
filterFilterЗалишає запит, лише якщо він збігається, або, з "action": "drop", відкидає його, якщо збігається.
dropRemove fieldsВилучає поля з тіла.
setSet fieldsДодає або перезаписує поля.
mapReshape the bodyЗамінює тіло тим, яке будуєте ви.
headersHeadersЗадає, вилучає або перейменовує заголовки.
authCredentialВказує, що до запиту додається bearer-токен, Basic-автентифікація чи API-ключ, і називає слот, з якого вони беруться.

filter

Залишає запит, лише якщо він збігається; інакше запуск відповідає dropped. З "action": "drop" усе навпаки: відкидається те, що збігається.

JSON
{ "filter": { "data": { "status": "paid", "amount": { "$gte": 100000 } } }, "note": "Paid, $1,000 or more" }
  • Кожен ключ — це умова, і виконуватися мають усі. Вкладений обʼєкт перевіряється за формою, як тут data.
  • Просте значення збігається за рівністю JSON: 1 дорівнює 1.0.
  • Масив збігається, коли він дорівнює значенню або коли збігається один з його елементів: {"data": {"tags": "urgent"}} виконується для ["billing", "urgent"], а {"data": {"items": {"sku": "A-1", "qty": 2}}} потребує одного елемента, у якому є обидва.
  • Поле, якого в запиті немає, збігається лише з {"$exists": false} і запереченнями, як-от $neq.
  • Оператори: $eq, $neq, $gt, $gte, $lt, $lte (числа з числами, текст із текстом; мітки часу ISO порівнюються за часом), $in, $nin, $exists, $startsWith, $endsWith, $contains (текст або масив, що містить значення), а також $and, $or і $not, щоб поєднувати фільтри.
  • $headers, $meta і $body перевіряють відповідну частину запиту: {"$headers": {"x-github-event": "push"}}.

drop

Вилучає поля з тіла: список від 1 до 50 шляхів. * відповідає будь-якому одному рівню, а ** — будь-якій глибині, тож **.email вилучає кожне поле email, хоч би де воно було. Шлях, який нічому не відповідає, не є помилкою.

JSON
{ "drop": ["data.customer.email", "data.cards[*].number", "**.phone"] }

set

Додає або перезаписує поля: від 1 до 50 пар зі шляху й значення. Відсутні обʼєкти дорогою створюються, і кожне значення читає тіло таким, яким його застав крок. Шлях, що натрапляє на значення, яке не є обʼєктом, провалює запуск з set_conflict.

JSON
{ "set": { "event_type": "{{ type }}", "data.total_cents": { "$ref": "data.amount" } } }

map

Замінює тіло значенням, яке пишете ви, — зазвичай обʼєктом.

JSON
{ "map": {
    "invoice_id": "{{ data.id }}",
    "amount": { "$ref": "data.amount" },
    "amount_display": "{{ data.amount | money(data.currency) }}",
    "event": "{{ type }}"
} }

Для запиту invoice.paid, у якого data — це {"id": "in_42", "amount": 150000, "currency": "usd"}, тіло стає таким:

JSON
{ "invoice_id": "in_42", "amount": 150000, "amount_display": "1,500.00 USD", "event": "invoice.paid" }

headers

Задає заголовки через set, вилучає їх через remove і перейменовує через rename — у порядку remove, rename, set. Назви збігаються незалежно від регістру, а задана назва замінює всі її написання.

JSON
{ "headers": { "set": { "X-Event-Type": "{{ type }}", "Content-Type": "application/json" } } }

Крок headers не може задати заголовок, що належить зʼєднанню, як-от Host чи Content-Length, а також Set-Cookie. Не може він задати й Authorization, Cookie чи X-Api-Key, бо значення лежало б у документі, який повертає кожне читання: облікові дані додаються кроком auth. Продукт, який виконує конвеєр за посиланням, також застосовує до нього власні правила щодо заголовків.

auth

Вказує, що до запиту додаються облікові дані, і називає слот, з якого вони беруться:

typeЩо додає
bearerAuthorization: Bearer і облікові дані.
basicAuthorization: Basic з username і облікових даних як пароля.
api_key, "in": "header"Облікові дані в заголовку з назвою name, після необовʼязкового prefix, як-от "Token ".
api_key, "in": "query"Облікові дані як параметр запиту name в URL отримувача.
JSON
{ "auth": { "type": "api_key", "in": "header", "name": "X-Api-Key", "secret": "sec_…" } }

secret — це ідентифікатор слота, який є в робочому просторі. Це ніколи не значення: вставлене туди значення відхиляється з invalid_secret, і відмова його не повторює. Продукт, який виконує конвеєр за посиланням, зіставляє слот із власним секретом (Облікові дані). Тестування й API запуску показують заголовок чи параметр із замаскованим значенням.

Кроки auth стоять після всіх інших кроків, тож жоден крок не може прочитати, скопіювати чи перевірити облікові дані.

Шляхи та значення

Шлях указує на поле тіла:

ШляхУказує на
data.customer.emailПоле.
data.items[0].skuЕлемент списку.
data['first name']Ключ, у якому є пробіл, крапка чи дужка.
data.items[*].skuКожен елемент; у значенні — їхній список.
**.emailemail на будь-якій глибині; лише в drop.
$meta.source, $headers.x-name, $body.dataМетадані запиту, один із його заголовків або його тіло; лише в значенні.

set приймає прості шляхи, drop — * і **, а значення читає з *, але не з **.

Значення в set, map чи заголовку — це JSON, який копіюється так, як записаний, за двома винятками:

  • {{ path }} у рядку вставляє значення як текст. Відсутнє значення чи null нічого не вставляє, а обʼєкт або список вставляється як JSON. {{ 'text' }} і {{ 42 }} — літерали, тож буквальне {{ записується як {{ '{{' }}.
  • {"$ref": "path"} вставляє саме значення й зберігає його тип: число лишається числом, список — списком. Додайте "default" на випадок, коли шляху немає.

Вираз може пропустити своє значення через фільтри, зліва направо: {{ data.amount | money(data.currency) }} дає 1,500.00 USD для суми 150000 у usd.

ФільтрДає
upper, lowerТекст великими чи малими літерами.
default(x)x, коли значення немає, воно null або порожнє.
truncate(n)Щонайбільше n символів, а далі ….
join(sep)Список як текст, зʼєднаний через ", ", якщо не вказати sep.
lengthКількість елементів, ключів чи символів.
json, json(indent)Значення як компактний JSON або з відступом від 1 до 8 пробілів.
number(digits)Число з такою кількістю знаків після коми.
money(currency)Суму в мінімальних одиницях валюти, відформатовану; валюти без дробової частини й із трьома знаками теж.
date(format)Час у форматі ISO 8601 або в секундах epoch, в UTC, з %Y, %m, %d, %H, %M, %S тощо.
escape(target)Текст, який не може форматувати повідомлення в чаті: slack (за замовчуванням), discord або markdown.
code(target, max, language)Текст як блок коду в розмітці slack, discord чи markdown, який текст не може завершити передчасно, обрізаний до max символів.

Циклів, умов і обчислень немає: умова — це крок filter, а список стає текстом через [*] і join.

Шаблони

У галереї є готові конвеєри, з яких можна почати. У консолі вони під Start from a template. Через API GET /v1/pipelines/templates повертає кожен шаблон із його pipeline. Після збереження шаблону ви отримуєте власний конвеєр: змінюйте його, як будь-який інший; із шаблоном він більше нічим не повʼязаний.

idШаблонЩо надсилає
slackSlack messageДля вхідного вебхука Slack: тип події як заголовок повідомлення, її ідентифікатор і час, а дані — блоком коду.
discordDiscord messageДля вебхука каналу Discord: embed із типом події, її даними блоком коду, ідентифікатором і часом. Нікого не згадує.
teamsMicrosoft Teams cardДля вебхука робочого процесу Teams: Adaptive Card із типом події, її ідентифікатором і часом, а дані — моноширинним шрифтом.
keep_fieldsKeep only these fieldsid, type, created_at і version події та лише ті поля data, які перелічує його map, починаючи з data.id. Перелічене поле, якого в події немає, надсилається як null.
drop_personalDrop personal dataПодію без email, phone, first_name, last_name, address, billing_address, shipping_address, date_of_birth і ip_address на будь-якій глибині. Звичайне name лишається, бо воно часто називає план чи продукт.

Кожен шаблон для чату — це крок map і крок headers, що задає Content-Type: application/json, і працює він з будь-якою подією. Відсутній тип показується як «Event», а відсутній ідентифікатор чи час — як «—», дані обрізаються під обмеження застосунку, і ніщо в події не може відформатувати повідомлення, когось згадати чи передчасно завершити блок коду.

Ліміти

Конвеєр не має циклів, годинника й мережі, а фіксовані межі обмежують кожен запуск. Якщо межу перевищено, запуск відповідає failed із причиною, а документ, що її перевищує, відхиляється під час збереження.

ЩоЛімітВідхиляється як
Документ як компактний JSON64 KiBtoo_large
Кроки20too_many_steps
Шляхи в drop, поля в set, назви в кожній частині кроку headers50invalid_value
Налаштування кроку як компактний JSON16 KiBtoo_large
Примітка кроку200 символівinvalid_value
Вкладеність у кроці й у тілі32 рівніtoo_deep, input_too_deep
Тіло, яке читає крок256 KiBinput_too_large
Тіло, яким відповідає запуск256 KiBoutput_too_large
Одне значення, яке формує крок64 KiBvalue_too_large
Робота за один запуск100,000 прочитаних чи скопійованих значень; текст — одне на 128 символівtoo_many_nodes
Заголовки після кожного кроку50 або стільки, скільки було в запиті, якщо їх більшеtoo_many_headers
Значення одного заголовка8 KiBheader_too_large під час запуску, для значення з виразом; invalid_header під час збереження, для значення без нього

У playground менші межі: документ на 16 KiB, тіло на 32 KiB, 16 KiB на одне значення, яке формує крок, 20 заголовків, 1 KiB на значення одного заголовка і 10,000 прочитаних чи скопійованих значень за один запуск.

Що далі