integration-examples/dialog-sequence/index.js

179 lines
5.8 KiB
JavaScript
Raw Normal View History

2024-06-17 20:01:33 +00:00
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());
// Адрес сервера данного приложения (для доступа из Интернета)
const SERVER_URL = '';
// Адрес сервера Loop
const LOOP_URL = '';
// Порт на котором будет слушать наш сервер
const PORT = 4000;
// Описание первой формы
const form1 = {
title: 'Первая форма',
icon: 'icon.png', // Иконку для каждой формы можно задать свою
fields: [
{
type: 'text',
name: 'message',
modal_label: 'Тут какое-то поле',
position: 1,
is_required: true,
},
],
submit: {
// Куда отправлять запрос после нажатия кнопки "Отправить"
path: '/second_modal',
// Контекст для запроса
expand: {
// Запрашиваем данные пользователя который вызвал действие
acting_user: "all",
// запрашиваем канал в котором было вызвано действие
channel: "all",
}
},
}
// Описание второй формы
const form2 = {
title: 'Вторая форма',
icon: 'icon.png',
fields: [
{
type: 'text',
name: 'message2',
modal_label: 'Еще одно поле',
position: 1,
},
],
submit: {
// Куда отправлять запрос после нажатия кнопки "Отправить"
path: '/second_result',
expand: {
// Запрашиваем данные пользователя который вызвал действие
acting_user: "all",
// запрашиваем канал в котором было вызвано действие
channel: "all",
}
},
}
// Отправка сообщения в канал Loop
const createPost = async (bot_access_token, channel_id, message) => {
try {
await fetch(`${LOOP_URL}/api/v4/posts`, {
method: 'POST',
headers: {
Authorization: 'Bearer ' + bot_access_token,
},
body: JSON.stringify({
channel_id,
message,
})
});
} catch (e) {
console.error('Error when create post', e);
}
}
// Обработчик результата первой формы
app.post('/second_modal', (req, res) => {
const context = req.body.context;
// Отправляем данные формы в канал
createPost(
context.bot_access_token,
context.channel.id,
'### Заполнена форма 1\n```json\n' + JSON.stringify(req.body.values, null, 2) + '\n```',
);
// Отвечаем второй формой. Обязательно статус 200 (не 201 и тд)
res.status(200).json({
type: 'form',
form: form2,
})
});
// Обработчик результата второй формы
app.post('/second_result', (req, res) => {
const context = req.body.context;
// Отправляем результат в канал
createPost(
context.bot_access_token,
context.channel.id,
'### Заполнена форма 2\n```json\n' + JSON.stringify(req.body.values, null, 2) + '\n```',
);
// Отвечаем что все хорошо. Обязательно статус 200 (не 201 и тд)
res.status(200).json({
type: 'ok',
});
})
// Данный метод будет вызываться при открытии любого канала, любым пользователем
// Отвечает за отрисовку кнопки в сайдбаре
app.post('/bindings', (req, res) => {
res.status(200).json({
type: 'ok',
data: [
{
// Место где показать кнопку
location: '/channel_header',
// Описание кнопки
bindings: [
{
// идентификатор, который будет отправлен в запросе
location: 'send-button',
// Иконка кнопки
icon: 'icon.png',
// Подпись для кнопки
label: 'Открыть форму',
// Первая форма
form: form1,
}
]
},
]
})
})
// Манифест для установки приложения
app.get('/manifest.json', (req, res) => {
res.json({
app_id: 'ru.loop.dialog-sequence-example',
version: '0.1.0',
display_name: 'Loop Dialog Sequence Example',
description: 'An app that opens modal dialogs sequentially',
icon: 'icon.png',
homepage_url: 'https://git.wilix.dev/loop/integration-examples',
// Разрешения для приложения
requested_permissions: [
// разрешение, чтобы приложение могло писать от имени бота
'act_as_bot',
// разрешение, чтобы получать данные пользователя, который вызывает действия
'act_as_user'
],
// Разрешения для установки кнопок или команд
requested_locations: [
// Устанавливает кнопку во всех каналах в сайдбаре или в заголовке канала
// (расположение завит от того, включен ли сайдбар)
'/channel_header'
],
app_type: 'http',
http: {
root_url: SERVER_URL
}
})
})
// Сервим иконки из папки. Все иконки всегда будут искаться по пути /static
app.use('/static', express.static('./static'));
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});