Перейти к содержимому

Сохранённый граф кампании — это два массива: nodes, где каждый несёт тип и объект настройки, и edges, где каждый соединяет пронумерованный выход одного узла со входом другого. В графе больше ничего не хранится — имя кампании, её страница и активное состояние живут на кампании, а не в графе. Сохранение записывает новую версию обоих массивов.

ПолеТипОбязательноеОписание
idстрокадаИдентифицирует узел внутри этого графа, и именно на него указывают связи. Заменяется свежим идентификатором при сохранении графа, так что стабилен только в пределах одной версии.
typeстрокадаОдин из типов в Типы узлов, или один из типов только для рантайма, перечисленных ниже.
configобъектдаНастройки узла. Пустой объект допустим, и именно с ним начинает только что добавленный узел.
canvas_xчислодаГоризонтальная позиция узла на холсте. Восстанавливается при открытии графа.
canvas_yчислодаВертикальная позиция узла на холсте. Восстанавливается при открытии графа.
ПолеТипОбязательноеОписание
idстрокадаИдентифицирует связь внутри этого графа.
from_node_idстрокадаid узла, который связь покидает. Должен присутствовать в том же массиве nodes, иначе связь отбрасывается при сохранении.
to_node_idстрокадаid узла, в который связь входит. Должен присутствовать в том же массиве nodes, иначе связь отбрасывается при сохранении.
output_indexчислодаС какого выхода исходного узла уходит связь. 0 — выход по умолчанию; на condition 0 — это Match, а 1 — No Match; на random_split от 0 до N-1 — это ветви в настроенном порядке.
labelстроканетТекст, отображаемый на связи, взятый из имени исходного выхода — например, Match или No Match. Выполнения маршрутизируются по output_index, никогда по label.

Комментарий запускает кампанию, список ключевых слов решает, по какой ветке пойти, совпавшие люди получают личное сообщение и тег через час, а любое другое выполнение завершается немедленно.

trigger_commentconditionkeyword_listsend_dmdelay 3600sadd_tagstop Match (output 0) No Match (output 1)
{
"nodes": [
{
"id": "3f6c1a80-5d2b-4c11-9e64-7a0b8d43f215",
"type": "trigger_comment",
"config": { "post_scope": "all", "unique_per_user": false },
"canvas_x": 240,
"canvas_y": 40
},
{
"id": "9b1d47e2-08af-4d5c-bb37-2c6e5f90a4d1",
"type": "condition",
"config": {
"match_type": "keyword_list",
"keyword_list_id": 41,
"reverse_keywords": false,
"wait_for_reply": false
},
"canvas_x": 240,
"canvas_y": 200
},
{
"id": "c74a2f19-6e30-4b8d-8f52-19d7c3b6e084",
"type": "send_dm",
"config": {
"message_type": "text",
"text": "Thanks for commenting. The price list is on its way."
},
"canvas_x": 80,
"canvas_y": 380
},
{
"id": "1a58e63d-4c97-42f0-9b18-6d2f7ae5c390",
"type": "delay",
"config": { "delay_seconds": 3600, "only_if_no_reply": true },
"canvas_x": 80,
"canvas_y": 540
},
{
"id": "e2079b45-13cd-4a6e-8c71-5f83d0b29a6c",
"type": "add_tag",
"config": { "tag_ids": [12] },
"canvas_x": 80,
"canvas_y": 700
},
{
"id": "7d3fb0c6-92e1-4f57-a840-3b6c1d5e2087",
"type": "stop",
"config": {},
"canvas_x": 440,
"canvas_y": 380
}
],
"edges": [
{
"id": "5c8e1b73-2f40-4d19-9a6b-8e7d0c34f512",
"from_node_id": "3f6c1a80-5d2b-4c11-9e64-7a0b8d43f215",
"to_node_id": "9b1d47e2-08af-4d5c-bb37-2c6e5f90a4d1",
"output_index": 0,
"label": ""
},
{
"id": "b06d4a92-7e15-48c3-bf20-6a9c2d813e47",
"from_node_id": "9b1d47e2-08af-4d5c-bb37-2c6e5f90a4d1",
"to_node_id": "c74a2f19-6e30-4b8d-8f52-19d7c3b6e084",
"output_index": 0,
"label": "Match"
},
{
"id": "48f1c25e-3b7d-4096-8ea4-1c5b7f02d9a3",
"from_node_id": "9b1d47e2-08af-4d5c-bb37-2c6e5f90a4d1",
"to_node_id": "7d3fb0c6-92e1-4f57-a840-3b6c1d5e2087",
"output_index": 1,
"label": "No Match"
},
{
"id": "a91b7e04-6c58-4d2f-93a1-7e04b8c5f261",
"from_node_id": "c74a2f19-6e30-4b8d-8f52-19d7c3b6e084",
"to_node_id": "1a58e63d-4c97-42f0-9b18-6d2f7ae5c390",
"output_index": 0,
"label": ""
},
{
"id": "d5720af8-9134-4be6-8c07-2f6a5d18b3e9",
"from_node_id": "1a58e63d-4c97-42f0-9b18-6d2f7ae5c390",
"to_node_id": "e2079b45-13cd-4a6e-8c71-5f83d0b29a6c",
"output_index": 0,
"label": ""
}
]
}
Тип узлаКлючи в config
trigger_commentpost_scope (all или specific), post_id (обязателен, когда post_scopespecific), unique_per_user
trigger_dmunique_per_user
conditionmatch_type (any, contains, exact, keyword_list), text, keyword_list_id, reverse_keywords, wait_for_reply, filter_images, filter_gifs, filter_links
send_dmmessage_type (text, image, card, text_with_buttons), text, image_url, title, subtitle, buttons, buttons_text
reply_commenttext
send_commenttext, post_id
hide_comment, delete_commentalso_block_user (только Facebook)
delaydelay_seconds (от 1 до 31536000), only_if_no_reply
random_splitpaths — массив { "percent": number }, где каждый percent от 0 до 100, а сумма не больше 100
add_tag, remove_tagtag_ids — массив числовых идентификаторов тегов
stopнет

Типы узлов описывает, что делает каждый ключ и что делает каждый узел, когда до него доходит выполнение.

Холст применяет их, пока связь перетаскивается, так что недопустимая связь никогда не попадает в сохранённый граф.

  1. Триггер никогда не является целью связи.
  2. Узел никогда не подключается сам к себе.
  3. Связь, которая создала бы цикл, отклоняется.
  4. Узел принимает одну входящую связь.
  5. Каждый выход несёт одну исходящую связь.
  6. Триггер подключается только к condition.
  7. condition никогда не подключается к другому condition.
  8. Действия с комментарием недоступны, когда триггер — trigger_dm.
  9. После delete_comment reply_comment и hide_comment отклоняются.

На практике граф держит один триггер, хотя форма данных допускает больше одного. Граф, чьи узлы содержат ошибки настройки, вообще нельзя сохранить — вместо этого холст сообщает об ошибках. Построение кампании на холсте проводит через сборку графа, который удовлетворяет всему этому.

Рантайм распознаёт ещё восемь типов, у которых нет плитки в палитре и панели настроек. Граф, построенный на холсте, никогда их не содержит; они появляются только через путь, минующий редактор, так что считайте их типами только для рантайма, а не функциями.

Тип узлаЧто делает выполнение
switchПроверяет правила каждой ветви и следует по первой совпавшей, или по ветви по умолчанию, если она настроена. Без совпадения и без ветви по умолчанию выполнение завершается.
wait_untilЖдёт до настроенного времени, затем продолжает, запланировано так же, как delay.
block_userБлокирует человека и продолжает. Только Facebook; в Instagram ничего не делает и предупреждает.
unhide_comment, typing_indicator, mark_seen, set_field, noteВыполняемые, но у них нет панели настроек, и источники, стоящие за этой страницей, не фиксируют для них настроек.
  • Каждое сохранение записывает новую версию графа. Кампания указывает на самую новую версию, и только триггер этой версии запускает новые выполнения.
  • Каждый идентификатор узла перегенерируется при сохранении, и связи переназначаются на новые идентификаторы. Поэтому идентификаторы стабильны в пределах версии, но не между сохранениями.
  • Связь, чей from_node_id или to_node_id отсутствует в том же массиве nodes, отбрасывается, а остальная часть графа всё равно сохраняется.
  • Пустой граф — оба массива пусты — сохраняется успешно. Без триггера в нём ничто не запускает выполнение.
  • Выполнение, уже идущее, остаётся на версии, на которой оно началось, так что редактирование и сохранение кампании никогда не меняет выполнения, идущие в процессе.
  • Более старые версии удаляются, как только ни одно выполнение на них не ссылается.
  • Кнопка postback на узле send_dm получает собственный выход. При сохранении холст разворачивает каждую ветку кнопки в дополнительные узлы condition и подписывает связи идентификатором кнопки; открытие графа сворачивает их обратно в выходы кнопок.
  • Выполнение следует по связи, чей output_index совпадает с выходом, который выбрал узел. Когда ни одна связь не несёт этот индекс, выполнение завершается на этом узле.
  • Выполнение, которое достигает узла, уже посещённого, завершается ошибкой цикла, именно поэтому редактор в принципе отклоняет циклы.
  • Ключи настройки в этом справочнике — те, что нужно писать. Некоторые типы узлов также реагируют на более старые написания ключей, сохранённые для того, чтобы графы, сохранённые ранее, всё ещё работали.