Интерактивные диалоги
Интеграции открывают диалоговые окна путем отправки HTTP POST
запроса, содержащего данные в теле запроса, на эндпоинт сервера Time. Интеграции могут использовать этот эндпоинт для открытия диалоговых окон, когда пользователи нажимают кнопки в сообщении или выбирают опцию в выпадающих списках, или используют быстрые команды.
Пример того, как выглядит диалоговое окно для создания бота в пользовательском интерфейсе Time:
Открыть диалоговое окно
Для того чтобы открыть диалоговое окно, ваша интеграция должна сначала получить HTTP-запрос от сервера Time. Этот запрос может быть инициирован slash-командой или интерактивным сообщением. Запрос будет включать идентификатор триггера (далее триггер).
Вы можете использовать полученный триггер, чтобы открыть диалоговое окно у пользователя. Для этого необходимо отправить HTTP POST
запрос на адрес https://<time-url>/api/v4/actions/dialogs/open
. См. раздел ниже, чтобы узнать детали.
Параметры
Параметры интерактивных диалоговых окон:
Параметр | Тип | Описание |
---|---|---|
title | String | Заголовок диалога. Максимум 24 символа. |
introduction_text | String | Текст в формате Markdown, который отображается перед элементами формы (elements ). |
elements | Array | Если массив элементов пустой, то окно действует как простое подтверждение. Какими именно могу быть элементы — описано ниже. |
url | String | URL-адрес, на который будет отправлен запрос с результатами заполнения формы. Должен возвращать код 200. Любой другой код будет считаться ошибкой. |
icon_url | String | (Необязательно) URL-адрес иконки, используемой для вашего диалога. Отображается перед заголовком. Если не заполнено — не отображается. |
submit_label | String | (Необязательно) Текст на кнопке отправки формы. Значение по умолчанию — Submit . |
notify_on_cancel | Boolean | (Необязательно) Если указано true — Time отправит событие в интеграцию при закрытии диалога пользователем. Никакие другие данные с событием обратно не отправляются. Значение по умолчанию — false . |
state | String | (Необязательно) Строка, предоставленная интеграцией, при открытии диалогового окна. По умолчанию используется пустая строка. Может содержать любые данные, которые интеграция хочет получить обратно в момент отправки формы. |
Ниже приведен пример JSON. Заполненные формы отправляются на URL, указанный интеграцией. Обязательно указывать триггер, полученный из slash-команды или интерактивного сообщения.
{
"trigger_id": "<unique ID generated by the server>",
"url": "<URL to send the submitted request to>",
"dialog": {
"callback_id": "<ID specified by the integration to identify the request>",
"title": "<title of the dialog>",
"introduction_text": "<Text describing the dialog box content>",
"elements": [
"<Array of UI elements to display in the dialog>"
],
"submit_label": "<label of the button to complete the dialog>",
"notify_on_cancel": false,
"state": "<string provided by the integration that will be echoed back with dialog submission>"
}
}
Элементы
Каждое диалоговое окно поддерживает элементы ввода из списка ниже.
text
: Однострочное текстовое поле. Используйте его для ввода таких данных, как имена, адреса электронной почты или номера телефонов.textarea
: Многострочное текстовое поле. Используйте это поле, если ожидается, что ответ будет длиннее 150 символов.select
: Выпадающий список. Позволяет выбирать из заранее известных вариантов. Может содержать статический список, либо динамические списки (пользователи или публичные каналы). Для получения дополнительной информации — см. Интерактивные сообщения.bool
: Опция элемента выбора (checkbox). Используется для бинарного выбора.radio
: Опция переключателя (radio button). Используется для выбора одного из нескольких доступных вариантов.
Каждый элемент является обязательным по умолчанию, в противном случае клиент вернет ошибку. Обратите внимание, что сообщение об ошибке появится под пояснением к полю, если оно указано. Чтобы сделать элемент необязательным, установите поле "optional": "true"
.
Элементы text
Текстовые элементы представляют собой однострочные текстовые поля. Ниже приведен пример элемента с типом text
, запрашивающего адрес электронной почты.
{
"display_name": "Email",
"name": "email",
"type": "text",
"subtype": "email",
"placeholder": "placeholder@example.com"
}
В приведенном выше примере есть необязательное поле "subtype": "email"
, которое определяет раскладку клавиатуры, используемую на мобильных устройствах. В этом примере пользователю отображается клавиатура электронной почты, если для подтипа задано значение email.
Полный список поддерживаемых полей:
Поле | Тип | Описание |
---|---|---|
display_name | String | Отображаемое название поля, показываемого пользователю в диалоговом окне. Максимум 24 символа. |
name | String | Имя элемента, используемого интеграцией. Максимум 300 символов. В рамках одного окна все элементы должны иметь уникальное значение name . |
type | String | Укажите text. |
subtype | String | (Необязательно) Одно из значений: text , email , number , password , tel или url . Значение по умолчанию - text . Используйте поле, чтобы указать, какая клавиатура будет отображаться пользователям на мобильных устройствах при вводе значения поля. |
min_length | Integer | (Необязательно) Минимальная допустимая длина ввода для элемента. Значение по умолчанию равно 0 . |
max_length | Integer | (Необязательно) Максимальная допустимая длина ввода для элемента. Значение по умолчанию равно 150 . Необходимо использовать тип textarea , если ожидаемая длина ввода больше 150 символов. |
optional | Boolean | (Необязательно) Установите значение true , если этот элемент формы не требуется. Значение по умолчанию — false . |
help_text | String | (Необязательно) Задаёт текст пояснения для этого элемента формы. Максимум 150 символов. |
default | String | (Необязательно) Установите значение по умолчанию для этого элемента формы. Максимум 150 символов. |
placeholder | String | (Необязательно) Строка-подсказка, отображаемая для помощи пользователям в заполнении элемента. Максимум 150 символов. |
Элементы textarea
Элементы с типом textarea
представляют собой многострочные текстовые поля. Ниже приведен пример JSON:
{
"display_name": "Ticket Description",
"name": "ticket_description",
"type": "textarea",
"help_text": "Provide description for your ticket."
}
Максимальная длина для textarea
составляет 3000 символов.
Список поддерживаемых полей такой же, как и для элемента с типом text
.
Поле | Тип | Описание |
---|---|---|
display_name | String | Отображаемое название поля, показываемого пользователю в диалоговом окне. Максимум 24 символа. |
name | String | Имя элемента, используемого интеграцией. Максимум 300 символов. В рамках одного окна все элементы должны иметь уникальное значение name . |
type | String | Укажите textarea . |
subtype | String | (Необязательно) Одно из значений: text , email , number , password , tel или url . Значение по умолчанию -text . Используйте поле, чтобы указать, какая клавиатура будет отображаться пользователям на мобильных устройствах при вводе значения поля. |
min_length | Integer | (Необязательно) Минимальная допустимая длина ввода для элемента. Значение по умолчанию равно 0 . |
max_length | Integer | (Необязательно) Максимальная допустимая длина ввода для элемента. По умолчанию — 3000 . |
optional | Boolean | (Необязательно) Установите значение true , если этот элемент формы не требуется. Значение по умолчанию — false . |
help_text | String | (Необязательно) Задаёт текст пояснения для этого элемента формы. Максимум 150 символов. |
default | String | (Необязательно) Установите значение по умолчанию для этого элемента формы. Максимум 3000 символов. |
placeholder | String | (Необязательно) Строка-подсказка, отображаемая для помощи пользователям в заполнении элемента. Максимум 3000 символов. |
Элементы select
Элементы с типом select
— это выпадающее списки, которые позволяют пользователям выбирать одну предопределенную опцию из списка. Ниже приведен пример элемента с типом select
, который запрашивает одну из двух опций:
{
"display_name": "Option Selector",
"name": "options",
"type": "select",
"options": [
{
"text": "Option1",
"value": "opt1"
},
{
"text": "Option2",
"value": "opt2"
},
{
"text": "Option3",
"value": "opt3"
}
]
}
JSON описание для элементов c типом select
соответствует интерактивным меню сообщений.
Элемент select
также может быть сгенерирован динамически пользователями и каналами.
Для пользователей используйте:
{
"display_name": "Assignee",
"name": "assignee",
"type": "select",
"data_source": "users"
}
Для общедоступных каналов используйте:
{
"display_name": "Post this message to",
"name": "channel",
"type": "select",
"data_source": "channels"
}
Полный список поддерживаемых полей:
Поле | Тип | Описание |
---|---|---|
display_name | String | Отображаемое название поля, показываемого пользователю в диалоговом окне. Максимум 24 символа. |
name | String | Имя элемента, используемого интеграцией. Максимум 300 символов. В рамках одного окна все элементы должны иметь уникальное значение name . |
type | String | Укажите select . |
data_source | String | (Необязательно) Одно из значений: users , channels . Если ничего не указано, предполагается, что интеграцияпредоставляет свой список опций. |
optional | Boolean | (Необязательно) Установите значение true , если этот элемент формы не требуется. Значение по умолчанию — false . |
options | Array | (Необязательно) Набор параметров для элемента с типом select . Не применимо для users или channels источников данных. |
help_text | String | (Необязательно) Задаёт текст пояснения для этого элемента формы. Максимум 150 символов. |
default | String | (Необязательно) Установите значение по умолчанию для этого элемента формы. Максимум 3000 символов. |
placeholder | String | (Необязательно) Строка-подсказка, отображаемая для помощи пользователям в заполнении элемента. Максимум 3000 символов. |
Элемент checkbox
Элементы с типом checkbox
выглядят как обычный текст с отметкой для выбора.
{
"display_name": "Can you please select below",
"placeholder": "The meeting was helpful.",
"name": "meeting_input",
"type": "bool"
}
Полный список поддерживаемых полей:
Поле | Тип | Описание |
---|---|---|
display_name | String | Отображаемое название поля, показываемого пользователю в диалоговом окне. Максимум 24 символа. |
name | String | Имя элемента, используемого интеграцией. Максимум 300 символов. В рамках одного окна все элементы должны иметь уникальное значение name . |
type | String | Укажите bool . |
optional | Boolean | (Необязательно) Установите значение true , если этот элемент формы не требуется. Значение по умолчанию — false . |
help_text | String | (Необязательно) Задаёт текст пояснения для этого элемента формы. Максимум 150 символов. |
default | String | (Необязательно) Установите значение по умолчанию для этого элемента формы. Варианты: true или false . |
placeholder | String | (Необязательно) Строка-подсказка, отображаемая для помощи пользователям в заполнении элемента. Максимум 150 символов. |
Элемент radio
Элементы с типом radio
выглядят как обычное текст с переключателем для выбора.
{
"display_name": "Which department do you work in?",
"name": "department",
"type": "radio",
"options": [
{
"text": "Engineering",
"value": "engineering"
},
{
"text": "Sales",
"value": "sales"
},
{
"text": "Administration",
"value": "administration"
}
],
"help_text": "Please indicate your department as of January 1.",
"default": "engineering"
}
Полный список поддерживаемых полей:
Поле | Тип | Описание |
---|---|---|
display_name | String | Отображаемое название поля, показываемого пользователю в диалоговом окне. Максимум 24 символа. |
name | String | Имя элемента, используемого интеграцией. Максимум 300 символов. В рамках одного окна все элементы должны иметь уникальное значение name . |
type | String | Укажите radio . |
options | Array | (Необязательно) Массив с вариантами для элемента с типом radio . |
help_text | String | (Необязательно) Задаёт текст пояснения для этого элемента формы. Максимум 150 символов. |
default | Строка | (Необязательно) Установите значение по умолчанию для этого элемента формы. |
Отправка данных интерактивных диалогов
Когда пользователь отправляет данные через диалоговое окно, Time выполняет проверку входных данных на стороне клиента, чтобы убедиться:
- Все обязательные поля заполнены.
- Все форматы верны (например, адрес электронной почты, номер телефона и т.д.).
Time отправляет POST
запрос в интеграцию, вызвавшую отображение диалогово окна. В теле запроса содержится JSON описание. Пример:
{
"type": "dialog_submission",
"callback_id": "<callback ID provided by the integration>",
"state": "<state provided by the integration>",
"user_id": "<user ID of the user who submitted the dialog>",
"channel_id": "<channel ID the user was in when submitting the dialog>",
"team_id": "<team ID the user was on when submitting the dialog>",
"submission": {
"some_element_name": "<value of that element>",
"some_other_element": "<value of some other element>"
},
"cancelled": false
}
Если для параметра notify_on_cancel
установлено в значение true
, то Time отправит запрос в интеграцию. Поле cancelled
будет установлено в значение true
и поле submission
будет пустым.
Time также позволяет самой интеграции выполнять проверку входных данных. Для этого необходимо в ответе на запрос отправки данных диалогового окна заполнить словарь ошибок errors
. Поле errors
— объект, сопоставляющий имена полей ввода со строковыми сообщениями об ошибках, которые вы хотели бы показать пользователю. Например, если у вас есть поле с именем num_between_0_and_10
, вы можете заставить пользователя ввести число от 0 до 10, вернув следующее тело ответа, если условие не выполнено:
{
"errors": {
"num_between_0_and_10": "Enter a number between 0 and 10."
}
}
Интеграция может возвращать пользователю общее сообщение об ошибке, которое не привязано к определенному полю. Это можно сделать заполнив поле error
. Поле error
— строка с сообщением об ошибке, которая будет показана пользователю.
Например, при возникновении ошибки на стороне сервера вы можете вернуть сообщение с её объяснением:
{
"error": "Failed to fetch additional data. Please try again."
}
После отправки запроса мы рекомендуем, чтобы интеграция ответила системным (system) или эфемерным (ephemeral) сообщением, подтверждающим отправку. Это должен быть отдельный запрос обратно в Time. Это можно сделать либо через "REST API" → "Create a ephemeral post", либо через Plugin API, если вы разрабатываете плагин.
Если диалоговое окно закрыто нажатием кнопки Отмена ("Cancel") или ✖, данные не будут отправляться.
Если пользователь нажимает не на диалоговое окно, тогда диалоговое окно не закрывается. Это сделано для предотвращения случайной потери любых ответов, которые были даны в неподтвержденном диалоге.
Пример
Ниже приведен полный пример создания интерактивного диалога в Time:
Пример тела запроса
{
"trigger_id": "nbt1dxzqwpn6by14sfs66ganhc",
"url": "http://localhost:5000/dialog_submit",
"dialog": {
"callback_id": "somecallbackid",
"title": "Test Title",
"icon_url": "https://<time-url>.com/images/icon.png",
"elements": [
{
"display_name": "Display Name",
"name": "realname",
"type": "text",
"subtype": "",
"default": "default text",
"placeholder": "placeholder",
"help_text": "This a regular input in an interactive dialog triggered by a test integration.",
"optional": false,
"min_length": 0,
"max_length": 0,
"data_source": "",
"options": null
},
{
"display_name": "Email",
"name": "someemail",
"type": "text",
"subtype": "email",
"default": "",
"placeholder": "placeholder@bladekick.com",
"help_text": "This a regular email input in an interactive dialog triggered by a test integration.",
"optional": false,
"min_length": 0,
"max_length": 0,
"data_source": "",
"options": null
},
{
"display_name": "Number",
"name": "somenumber",
"type": "text",
"subtype": "number",
"default": "",
"placeholder": "",
"help_text": "",
"optional": false,
"min_length": 0,
"max_length": 0,
"data_source": "",
"options": null
},
{
"display_name": "Display Name Long Text Area",
"name": "realnametextarea",
"type": "textarea",
"subtype": "",
"default": "",
"placeholder": "placeholder",
"help_text": "",
"optional": true,
"min_length": 5,
"max_length": 100,
"data_source": "",
"options": null
},
{
"display_name": "User Selector",
"name": "someuserselector",
"type": "select",
"subtype": "",
"default": "",
"placeholder": "Select a user...",
"help_text": "",
"optional": false,
"min_length": 0,
"max_length": 0,
"data_source": "users",
"options": null
},
{
"display_name": "Channel Selector",
"name": "somechannelselector",
"type": "select",
"subtype": "",
"default": "",
"placeholder": "Select a channel...",
"help_text": "Choose a channel from the list.",
"optional": true,
"min_length": 0,
"max_length": 0,
"data_source": "channels",
"options": null
},
{
"display_name": "Option Selector",
"name": "someoptionselector",
"type": "select",
"subtype": "",
"default": "",
"placeholder": "Select an option...",
"help_text": "",
"optional": false,
"min_length": 0,
"max_length": 0,
"data_source": "",
"options": [
{
"text": "Option1",
"value": "opt1"
},
{
"text": "Option2",
"value": "opt2"
},
{
"text": "Option3",
"value": "opt3"
}
]
}
],
"submit_label": "Submit",
"notify_on_cancel": true,
"state": "somestate"
}
}