Друзья, приветствую!
Сегодня я подготовил небольшую, расслабляющую статью, особенно в сравнении с предыдущими. Недавно я разрабатывал FullStack-приложение для небольшого лендинга, где одной из задач было привязать форму с сайта к Telegram-боту.
Суть задачи:
Пользователь вводит данные в форму на сайте, после чего эта информация отправляется заказчику через Telegram-бота. Данные отправляются в формате HTML, с полным набором информации. Всё это нужно было реализовать на чистом JavaScript + HTML + CSS. Из этой задачи родилась идея для данной статьи.
Чем мы займёмся?
Мы зарегистрируем Telegram-бота через BotFather, создадим приятную страницу с формой для сбора данных с использованием бесплатного сервиса WebSim.ai, а затем настроим отправку сообщений с формы в Telegram-бота, используя только JavaScript, HTML и CSS.
После завершения проекта, я покажу, как запустить его удалённо, чтобы каждый мог воспользоваться нашей формой. Для этого мы будем использовать хостинг Amvera Cloud, потому что это быстро и удобно за счет встроенного CI/CD. Для развертывания достаточно выполнить три команды в IDE или просто перетянуть файлы проекта в интерфейсе.
Кратко о процессе деплоя
Процесс деплоя сводится к следующему:
Подготовить файлы страницы.
Создать файл инструкций (его я предоставлю).
Доставить файлы на Amvera через GIT или встроенный интерфейс.
После простых манипуляций наш сайт станет доступен по бесплатному HTTPS-домену, который предоставит Amvera.
Подготовка Telegram для приёма сообщений
На этом этапе мы создадим Telegram-бота, получим свой Telegram ID, чтобы бот знал, кому отправлять сообщения, и позволим боту отправлять нам сообщения, «познакомившись» с ним.
Шаги для создания Telegram-бота:
Перейдите в BotFather.
Введите команду
/newbot
(или выберите её в меню).Придумайте имя бота — любое, на любом языке.
Присвойте уникальный username на английском, оканчивающийся на "bot", "BOT" или "Bot" (без пробелов).
Сохраните токен, который выдаст BotFather.

Для того чтоб позволить боту отправлять вам сообщения, перейдите в чат с ботом и нажмите кнопку «СТАРТ».

Получение Telegram ID:
Чтобы бот мог отправлять вам сообщения, нужно получить ваш Telegram ID. Один из способов — воспользоваться ботом IDBot Finder Pro:
Перейдите в бота.
Нажмите «Старт».
Выберите «My info».
Кликните на свой ID, и он скопируется в буфер обмена.

Подготовка страницы с формой
Страницу можно сделать самостоятельно или с помощью сервиса WebSim.ai, который сгенерирует нужную форму. Я воспользуюсь WebSim.ai.
Подробно про данный сервис я писал в этой статье: «WebSim AI: Бесплатный ИИ-помощник для быстрой веб-разработки – время фронтендерам напрячься».
Хочу чтоб в моей форме были следующие поля:
Имя (обязательно)
Фамилия (обязательно)
Дата рождения (обязательно)
Пол (чекбоксы, обязательно)
Хобби (выпадающий список, обязательно минимум одно)
Примечание (необязательно)
После отправки формы пользователь увидит сообщение: «Ваша анкета отправлена».
Задача для нейросети WebSim
Скрытый текст
Необходимо создать страницу с формой, которая будет содержать следующие поля:
Имя (input type="text")
Поле обязательно для заполнения.
Фамилия (input type="text")
Поле обязательно для заполнения.
Дата рождения (input type="date")
Обязательное поле для выбора даты через календарь.
Пол (input type="checkbox")
Чекбоксы для выбора пола. Обязательно должно быть выбрано одно значение.
Примеры значений: мужской, женский.
Хобби (select multiple)
Выпадающий список с возможностью выбора нескольких значений.
Обязательно должно быть выбрано как минимум одно хобби.
Пример хобби: чтение, спорт, музыка, путешествия.
Примечание (textarea)
Поле для ввода произвольного текста. Заполнение не обязательно.
Под формой необходимо разместить кнопку «Отправить».
После успешной отправки формы, отобразить всплывающее сообщение (popup) с текстом:
«Ваша анкета отправлена».
Требования:
Форма должна быть валидирована перед отправкой (проверка обязательных полей).
Для реализации можно использовать HTML5 и JavaScript.
Можно писать и проще, но я за то чтоб моя задача была максимально понятна.
Перейдем на сайт WebSim, выполним авторизацию и в поле ввода запроса вставим наш промт.

Посмотрим на результат

Попросим добавить больше стилей. Кроме того, пусть он подправит нам блок с хобби, добавив возможность отмечать чекбоксами и работать в формате выпадающего списка.
Новая задача для нейросети WebSim
Скрытый текст
Добавить стилизацию формы и её элементов:
Придать форме более современный вид с использованием CSS (flexbox/grid для организации элементов).
Все обязательные поля должны иметь специальную визуальную индикацию (например, красную звёздочку рядом с меткой поля).
Стилизация кнопки «Отправить» — сделать её заметной, с эффектом при наведении.
Добавить отступы, границы, и тени для полей ввода, чтобы они выглядели аккуратно и легко читались.
Всплывающее сообщение «Ваша анкета отправлена» стилизовать как модальное окно с затемнением фона.
Изменить блок с хобби:
Реализовать выпадающий список с возможностью выбора нескольких опций, где каждое хобби отмечается через чекбоксы.
Для этого добавить кастомный dropdown (например, с использованием select + checkbox для выбора нескольких вариантов).
В выпадающем списке пользователь должен видеть доступные варианты хобби и иметь возможность отмечать одно или несколько.
Добавить проверку, что как минимум одно хобби выбрано.
Примерные стили:
Сделать выпадающий список с хобби похожим на мультивыборные списки с чекбоксами внутри, который открывается при нажатии (можно использовать популярные решения с JavaScript для кастомного мультиселекта).
Валидация формы:
Проверить обязательность заполнения всех полей перед отправкой.
Подсветить ошибку, если какое-либо обязательное поле не заполнено или не выбрано.
Итоговое требование:
Форма должна выглядеть стильно, быть удобной для пользователей и работать корректно, включая валидацию и отправку данных с подтверждением в виде модального окна.
Смотрим на результат

Теперь нам остается привязать отправку этой формы в наше телеграмм. Попросим об этом сервис, так как WebSim прекрасно работает с JavaScript. После, при необходимости, подправим JS под себя.
Я бы хотел, чтоб сообщение в бота отправлялось с HTML форматированием, поэтому, задачу поставим так:
Скрытый текст
Отправка данных через чистый JavaScript
После того как форма будет валидирована и отправлена, данные должны отправляться на указанный Telegram-бот (ID бота: 7840688347:AAFsSq0EAцуU42lEnXFueфR8RtVtTа37N9BQ
).
Сообщение должно отправляться пользователю с ID: 5120841744
.
Формат сообщения:
Сообщение должно быть в формате ParseMode HTML.
Начало сообщения: «📩 Вам новая заявка:».
После этого перечислить данные из формы:
Имя
Фамилия
Дата рождения
Пол
Выбранные хобби
Примечание (если заполнено)
Примерная структура сообщения:
📩 Вам новая заявка:
<b>Имя:</b> Иван
<b>Фамилия:</b> Иванов
<b>Дата рождения:</b> 01.01.1990
<b>Пол:</b> Мужской
<b>Хобби:</b> Чтение, Путешествия
<b>Примечание:</b> Люблю кодить!
Инструкция по отправке данных в Telegram:
Использовать метод Telegram API sendMessage
для отправки сообщения.
Заполним анкету

Отправим анкету

Смотрим сообщение

Отлично, все у нас работает.
Теперь давайте скачаем полученный результат и подготовим его к деплою.
Для загрузки кликаем на три точки в правом верхнем углу и нажимаем на «Загрузить».

Сохраненный файл назовем index.html

Теперь у нас в руках полный готовый код проекта , в чем можем убедиться нажав на CTRL + U.
Подготовка проекта к деплою
Сейчас, в целом, мы готовы к деплою, но мне бы хотелось навести порядок в коде. Поэтому, я разобью данный файл на шаблон HTML и на статические файлы (JS и CSS). Кроме того, перед деплоем нам нужно будет создать небольшой файл с инструкциями для корректного запуска нашей странички с формой в облаке.
Структура у меня получилась следующая.
В корневой директории проекта расположен файл index.html, а также папка static, содержащая два файла:
script.js — файл с кодом на JavaScript.
style.css — файл, содержащий стили для оформления.
Стили и JS-код я просто перенес из тех, что мне предоставил WebSim.
HTML-шаблон
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Личная анкета</title>
<!-- Импорт стилей -->
<link rel="stylesheet" href="static/style.css">
</head>
<body>
<div class="container">
<h1>Личная анкета</h1>
<form id="personalForm">
<div class="form-group">
<label for="firstName" class="required">Имя:</label>
<input type="text" id="firstName" name="firstName" required>
<div class="error" id="firstNameError"></div>
</div>
<div class="form-group">
<label for="lastName" class="required">Фамилия:</label>
<input type="text" id="lastName" name="lastName" required>
<div class="error" id="lastNameError"></div>
</div>
<div class="form-group">
<label for="birthDate" class="required">Дата рождения:</label>
<input type="date" id="birthDate" name="birthDate" required>
<div class="error" id="birthDateError"></div>
</div>
<div class="form-group">
<label class="required">Пол:</label>
<div class="radio-group">
<label>
<input type="radio" name="gender" value="male" required> Мужской
</label>
<label>
<input type="radio" name="gender" value="female" required> Женский
</label>
</div>
<div class="error" id="genderError"></div>
</div>
<div class="form-group">
<label for="hobbies" class="required">Хобби:</label>
<div class="multiselect">
<button type="button" class="multiselect-btn" id="hobbiesBtn">Выберите хобби</button>
<div class="multiselect-dropdown" id="hobbiesDropdown">
<div class="multiselect-option">
<input type="checkbox" id="hobby-reading" value="reading">
<label for="hobby-reading">Чтение</label>
</div>
<div class="multiselect-option">
<input type="checkbox" id="hobby-sports" value="sports">
<label for="hobby-sports">Спорт</label>
</div>
<div class="multiselect-option">
<input type="checkbox" id="hobby-music" value="music">
<label for="hobby-music">Музыка</label>
</div>
<div class="multiselect-option">
<input type="checkbox" id="hobby-travel" value="travel">
<label for="hobby-travel">Путешествия</label>
</div>
</div>
</div>
<div class="error" id="hobbiesError"></div>
</div>
<div class="form-group">
<label for="notes">Примечание:</label>
<textarea id="notes" name="notes"></textarea>
</div>
<button type="submit">Отправить</button>
</form>
</div>
<div id="modal" class="modal">
<div class="modal-content">
<p>Ваша анкета отправлена</p>
</div>
</div>
<!-- Импорт JavaScript -->
<script src="static/script.js"></script>
</body>
</html>
Здесь представлена стандартная HTML-форма. Особое внимание стоит уделить импорту стилей и JavaScript-файлов. Весь код был записан в одном файле.
Импорт стилей:
<link rel="stylesheet" href="static/style.css">
Импорт JavaScript:
<script src="static/script.js"></script>
Код стилей приводить тут не буду, так как демонстрация стилей не является самоцелью данной статьи. Код JS продемонстрирую частично, а именно блок с отправкой данных с формы в телеграмм бота.
Вот фрагмент кода, который отвечает за отправку собранных данных в Telegram-бота, с комментариями:
// Функция для отправки данных в Telegram
function sendDataToTelegram(formData) {
const botToken = '6845698347:AAFsSq0EAlU42lEапfue7R8RtVtT397N9BQ'; // Токен вашего бота
const chatId = '5120801744'; // ID получателя (пользователя)
const apiUrl = `https://api.telegram.org/bot${botToken}/sendMessage`; // URL для отправки сообщения
// Формируем сообщение в формате HTML
const message = `
📩 Вам новая заявка:
<b>Имя:</b> ${formData.firstName}
<b>Фамилия:</b> ${formData.lastName}
<b>Дата рождения:</b> ${formData.birthDate}
<b>Пол:</b> ${formData.gender === 'male' ? 'Мужской' : 'Женский'}
<b>Хобби:</b> ${formData.hobbies.join(', ')}
<b>Примечание:</b> ${formData.notes || 'Не указано'}
`;
// Параметры, которые будем отправлять
const params = {
chat_id: chatId, // ID чата
text: message, // Текст сообщения
parse_mode: 'HTML' // Режим парсинга HTML
};
// Отправляем данные с помощью fetch API
return fetch(apiUrl, {
method: 'POST', // Метод отправки
headers: {
'Content-Type': 'application/json', // Указываем тип содержимого
},
body: JSON.stringify(params) // Преобразуем параметры в JSON
}).then(response => response.json()); // Возвращаем ответ в формате JSON
}
// Обработчик события отправки формы
form.addEventListener('submit', (e) => {
e.preventDefault(); // Отменяем стандартное поведение формы
if (validateForm()) { // Проверяем форму на валидность
const formData = { // Собираем данные из формы
firstName: document.getElementById('firstName').value,
lastName: document.getElementById('lastName').value,
birthDate: document.getElementById('birthDate').value,
gender: document.querySelector('input[name="gender"]:checked').value,
hobbies: Array.from(hobbiesCheckboxes)
.filter(checkbox => checkbox.checked)
.map(checkbox => checkbox.nextElementSibling.textContent),
notes: document.getElementById('notes').value
};
// Показать состояние загрузки
modal.innerHTML = '<div class="modal-content"><p>Отправка данных...</p></div>';
modal.style.display = 'block';
// Отправляем данные в Telegram
sendDataToTelegram(formData)
.then(result => {
if (result.ok) {
// Если данные успешно отправлены
modal.innerHTML = '<div class="modal-content"><p>Ваша анкета успешно отправлена</p></div>';
} else {
// Если произошла ошибка при отправке
modal.innerHTML = '<div class="modal-content"><p>Ошибка при отправке анкеты. Пожалуйста, попробуйте еще раз.</p></div>';
}
})
.catch(error => {
console.error('Error:', error);
// Обработка ошибки
modal.innerHTML = '<div class="modal-content"><p>Произошла ошибка. Пожалуйста, попробуйте позже.</p></div>';
})
.finally(() => {
// Закрываем модальное окно и сбрасываем форму через 3 секунды
setTimeout(() => {
modal.style.display = 'none';
form.reset(); // Сброс формы
updateHobbiesButton(); // Обновляем текст кнопки хобби
}, 3000);
});
}
});
Комментарии к коду
sendDataToTelegram: Функция, отправляющая данные формы в Telegram.
botToken и chatId: Переменные, содержащие токен бота и ID чата, куда будет отправлено сообщение.
message: Форматирование сообщения с использованием HTML для выделения данных.
fetch: Используется для отправки данных на сервер Telegram. Ответ преобразуется в JSON.
Обработчик события отправки формы: Отменяет стандартное поведение формы, собирает данные и вызывает функцию отправки данных в Telegram.
Модальное окно: Показ состояния отправки и сообщение об успехе или ошибке отправки данных.
Этот код обеспечивает отправку данных формы в Telegram с необходимой валидацией и обработкой состояния.
Полный код этого проекта, как и другой эксклюзивный контент, который я не публикую на Хабре, вы найдете в моем телеграмм канале «Легкий путь в Python».
Деплой проекта
И, в завершении этого небольшого гайда, развернем наш проект удаленно. В качестве посадки я буду использовать сервис Amvera Cloud. И, прежде чем мы приступим к деплою, давайте подготовим небольшой файл с инструкциями для запуска проекта.
Мы будем создавать Dockerfile и, если вы совсем в этом не понимаете, то не страшно. Просто вставляйте мой код и все будет работать.
Файл Dockerfile необходимо разместить на одном уровне с файлом index.html. Вот содержимое:
# Используем официальный образ NGINX в качестве базового
FROM nginx:alpine
# Удаляем дефолтный файл конфигурации NGINX
RUN rm /usr/share/nginx/html/index.html
# Копируем наш index.html в папку с HTML файлами NGINX
COPY index.html /usr/share/nginx/html/
# Копируем статические файлы из папки static в NGINX
COPY static /usr/share/nginx/html/static
# Экспонируем порт 80
EXPOSE 80
# Запускаем NGINX
CMD ["nginx", "-g", "daemon off;"]
Этот Dockerfile создает контейнер с веб-сервером NGINX, который будет обслуживать ваш собственный HTML-файл (index.html) на порту 80. Он обеспечивает корректный запуск вашей веб-страницы в сервисе Amvera и позволяет привязать к ней бесплатное доменное имя с поддержкой HTTPS, что нас интересует.

Приступаем к деплою
Регистрируемся на сайте Amvera Cloud если не было регистрации. За регистрацию вы получите 111 рублей в подарок на основной счет.
Переходим в раздел проектов
Кликаем на «Создать». Далее даем название проекту и выбираем тарифный план. Мне подойдет «Пробный». Затем жмем на «Далее».

Теперь нужно определиться с форматом доставки файлов в проект. Есть вариант «Через GIT» и «Через интерфейс». Так как проект не большой я воспользуюсь вторым вариантом. Далее достаточно будет загрузить все файлы проекта в специальное окно загрузки.

После жмем «Далее» и на новом экране «Завершить», так как все необходимые настройки мы уже подготовили.
Теперь осталось активировать доменное имя. Для этого входим в проект и открываем вкладку «Настройки». Далее нажимаем на «Добавить домен» и активируем его.

После нажмем на кнопку «Пересобрать», чтоб доменное имя точно корректно привязалось к нашему проекту.

Этого достаточно. Теперь остается подождать пару минут и при переходе по доменному имени будет доступен наш сайт с возможностью сделать отправку.
У меня получилась такая ссылка: https://formahabr-yakvenalex.amvera.io/. Перейдем по ссылки и выполним тесты.

Решаем проблему с безопасностью
В текущей реализации, хотя приложение и работает, существует существенная уязвимость в области безопасности — это токен бота. Любой, кто откроет панель разработчика в браузере, сможет перехватить этот токен. В рабочих проектах это недопустимо. Чтобы устранить проблему, предлагаю использовать FastAPI для создания простого бэкенда, который будет надежно скрывать токен бота.
Новый подход
Мы создадим серверное приложение на FastAPI с двумя основными функциями:
Рендеринг главной страницы (index.html).
Обработка POST-запросов с формой.
Теперь данные с формы будут отправляться не напрямую в Telegram, а через серверный эндпоинт. Это повысит безопасность, скрыв критические данные (например, токен бота).
Новая структура проекта
FastAPI гибкий, но рекомендуется придерживаться стандартной структуры:
Создаем папку
templates
и помещаем в нее файлindex.html
.Изменяем пути к статическим файлам в HTML-шаблоне:
Было:
<link rel="stylesheet" href="static/style.css">
Стало:
<link rel="stylesheet" href="/static/style.css">
Было:
<script src="static/script.js"></script>
Стало:
<script src="/static/script.js"></script>
JavaScript-код для отправки данных теперь будет выглядеть так:
form.addEventListener('submit', async (e) => {
e.preventDefault();
if (validateForm()) {
const formData = {
firstName: document.getElementById('firstName').value,
lastName: document.getElementById('lastName').value,
birthDate: document.getElementById('birthDate').value,
gender: document.querySelector('input[name="gender"]:checked').value,
hobbies: Array.from(hobbiesCheckboxes)
.filter(checkbox => checkbox.checked)
.map(checkbox => checkbox.nextElementSibling.textContent),
notes: document.getElementById('notes').value
};
// Показать состояние загрузки
modal.innerHTML = '<div class="modal-content"><p>Отправка данных...</p></div>';
modal.style.display = 'block';
// Отправка данных на сервер FastAPI
try {
const response = await fetch('/send-data/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formData)
});
const result = await response.json();
if (result.ok) {
modal.innerHTML = '<div class="modal-content"><p>Ваша анкета успешно отправлена</p></div>';
} else {
const errorMessage = result.error || 'Ошибка при отправке анкеты. Пожалуйста, попробуйте еще раз.';
modal.innerHTML = `<div class="modal-content"><p>${errorMessage}</p></div>`;
}
} catch (error) {
console.error('Error:', error);
modal.innerHTML = '<div class="modal-content"><p>Произошла ошибка. Пожалуйста, попробуйте позже.</p></div>';
} finally {
setTimeout(() => {
modal.style.display = 'none';
form.reset();
updateHobbiesButton();
}, 3000);
}
}
});
Файл requirements.txt
Для Python-кода создадим файл requirements.txt
со следующими зависимостями:
fastapi==0.115.0
uvicorn==0.31.0
python-decouple==3.8
httpx==1.0.0b0
jinja2==3.1.4
FastAPI — основной бэкенд фреймворк.
Uvicorn — сервер для запуска приложения.
python-decouple — для безопасного хранения токена в
.env
.httpx — для асинхронного общения с Telegram API.
Jinja2 — для рендеринга HTML-шаблонов.
Команда установки зависимостей:
pip install -r requirements.txt
Файл .env
Создаем файл .env
для хранения конфиденциальных данных:
BOT_TOKEN=тут_ваш_токен
CHAT_ID=тут_id_чата
Логика бэкенда
Вся логика приложения будет находиться в файле main.py
:
from decouple import config
from fastapi import FastAPI, Request
from fastapi.staticfiles import StaticFiles
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
import httpx
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
# Разрешаем CORS
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # Разрешить запросы с любых источников
allow_credentials=True,
allow_methods=["*"], # Разрешить все методы
allow_headers=["*"], # Разрешить все заголовки
)
# Настройка статических файлов
app.mount("/static", StaticFiles(directory="static"), name="static")
# Настройка шаблонов
templates = Jinja2Templates(directory="templates")
@app.get("/", response_class=HTMLResponse)
async def read_index(request: Request):
return templates.TemplateResponse("index.html", {"request": request})
@app.post("/send-data/")
async def send_data(form_data: dict):
bot_token = config('BOT_TOKEN')
chat_id = config('CHAT_ID')
api_url = f'https://api.telegram.org/bot{bot_token}/sendMessage'
message = f"""
📩 Вам новая заявка:
<b>Имя:</b> {form_data['firstName']}
<b>Фамилия:</b> {form_data['lastName']}
<b>Дата рождения:</b> {form_data['birthDate']}
<b>Пол:</b> {'Мужской' if form_data['gender'] == 'male' else 'Женский'}
<b>Хобби:</b> {', '.join(form_data['hobbies'])}
<b>Примечание:</b> {form_data.get('notes', 'Не указано')}
"""
params = {
"chat_id": chat_id,
"text": message,
"parse_mode": "HTML"
}
async with httpx.AsyncClient() as client:
response = await client.post(api_url, json=params)
return {"ok": response.status_code == 200}
Комментарии к коду
CORS: Мы добавили
CORSMiddleware
, чтобы разрешить запросы с любых источников. Для повышения безопасности можно ограничить допустимые домены.Статические файлы: FastAPI монтирует папку
/static
для работы с CSS и JavaScript.Асинхронный запрос: Мы используем
httpx.AsyncClient
для выполнения асинхронного запроса к Telegram API.Шаблоны: Для рендеринга HTML-страниц используем Jinja2.
Теперь проект защищен, и критические данные, такие как токен бота, надежно скрыты на сервере. Токен больше не виден в исходном коде фронтенда, что предотвращает его компрометацию.
Деплой нового формата
Так как наша проектная логика теперь изменилась, нам нужно обновить файл с инструкциями для деплоя на Amvera Cloud. Конечно, можно снова использовать Dockerfile, но я хочу продемонстрировать вам другой подход.
Давайте теперь создадим файл amvera.yml с таким содержимым
meta:
environment: python
toolchain:
name: pip
version: 3.12
build:
requirementsPath: requirements.txt
run:
persistenceMount: /data
containerPort: 8000
command: uvicorn main:app --host 0.0.0.0 --port 8000
В этом файле мы прописали стандартные инструкции для запуска FastApi приложения.
Теперь нам остается доставить файлы проекта на сервер Amvera, чтоб там получилась такая структура:

То есть, Dockerfile нам больше не нужен. После доставки не забудьте пересобрать проект.
Заключение
В этой статье я не стремился убедить вас, что создание сайтов с помощью нейронных сетей — это единственный путь. Моя цель была показать, как можно быстро и просто создать фронтенд для своих приложений без лишних сложностей.
Кроме того, я продемонстрировал, как интегрировать формы захвата данных в Telegram-ботов, не используя языки бэкенда, такие как Python или PHP, и наглядно рассказал, почему лучше так не делать.
Надеюсь, что эта информация была для вас полезной и интересной. Если это так, ставьте лайки и оставляйте комментарии — это мотивирует меня создавать больше полезного и обучающего контента для вас.
До скорого.