Это мой первый опыт в разработке публичных модулей для Laravel, поэтому прошу не судить строго!
Данный модуль позволяет легко и быстро настроить отправку логов и сообщений об ошибках в Telegram сообщество, где под каждый тип события вы можете выбрать отдельный топик. Таким образом вы можете отправлять сообщения о кастомных событиях, исключения и системные ошибки.
Конечно, есть более продвинутые решения для логирования, но они требуют более глубокую настройку. Я же хотел создать модуль, который будет быстро настраиваться и хорошо подойдёт для мелких и средних проектов.
Настройка модуля
Для начала вам нужно создать Telegram бота который будет отвечать за отправку оповещений. После этого создаём группу, включаем в ней «Темы» и добавляем созданного бота в группу (обязательно с правами администратора).
После установки модуля, вам необходимо создать конфигурационный файл config/tg-logger.php и прописать в нём параметры для работы модуля.
Вы можете создать файл вручную или перенести заготовленную версию конфигурации, которая находится внутри модуля, прописал следующую команду.
php artisan vendor:publish --tag=config
После настройки tg-logger.php, вам необходимо запустить команду которая создаст темы в группе.
php artisan tglogger:create-topics
*После запуска данной команды, файл tg-logger.php будет перезаписан и в нём будут указаны id тем
На этом настройка модуля закончена, ниже рассмотрим как работать с модулем TgLogger.
Работа с модулем TgLogger
Отлов системных ошибок
Для отлова всех типов ошибок вам необходимо изменить базовый обработчик логов в конфигурационном файле config/logging.php, указав в качестве обработчиков классы модуля.
Вы также можете отправлять оповещения, напрямую, используя класс TgLogger и статический метод sendLog().
TgLogger::sendLog('Your message', 'level');
Большое спасибо тем кто дочитать данную статью до конца! Буду очень рад если вы поддержите данное решение на GitHub и напишете свой комментарий под данным постом.
Год с небольшим назад начал торговать кое-каким товаром на Wildberries, а поставщик требовал удерживать РРЦ- очень очень. Иначе штрафы и другие проблемы. Поэтому начал искать, сначала один программист, сделал сыроватый продукт, потом другой сделал как надо.. В итоге, стал сам пользоваться, и другим продавцам у нашего продавца тоже предоставил такую возможность.
В итоге, спустя полгода доработок- в неспешном тормозном стиле ( мне вообще-то 48 лет, и последний раз программировал в институте на турбо-паскале и бейсике в школе), получилось то что получилось, ниже это просто своего рода памятки. Рекламные статьи будут совсем на других ресурсах.
А тут пост для мотивации, что можно натворить не будучи программистом ( вру вру, в душе то я программист, мысленно программировал, писал тех.задания программистам, но кроме include в php ничего не знаю, при том что по логике пытаюсь код читать, который писал нейросети, они ведь иногда ошибаются, что-то иногда понимаю..)
Так что думаю совсем с нуля такое не получится написать, надо хотя бы немного уметь читать документацию и задавать чёткие запросы нейросетям, тем не менее, как говорится, не верю своим глазам!
Если бы учился программированию на php, думаю пришлось бы года два на это убить и то не факт, поскольку нет у меня необходимой для программирования усидчивости, и основные то интересы в жизни это психология (по последнему образованию клинический психолог), кое-какие сайты делал для продажи тех же товаров ( но опять же, без программирования, на конструкторе), написал книгу в конце июля вообще на абсолютно другие темы, не связанные никак с техническим программированием, больше на тему психологии, но тоже не совсем, сейчас планирую вторую книгу, и третья это книга стихов. Чтобы вы понимали, что я не очень то фанат компьютеров:-) Но видимо была детская мечта стать программистом, в своё время не хватило баллов для поступления на автоматизацию металлургических процессов в Красноярске ( цветмет), и поступил просто на металлурга.. Это к тому, что некоторое вдохновение имеется, к тому же меня немножко подпинывали и давали идеи, что можно сделать ( сам то как человек ленивый наверное ограничился бы обычным репрайсером, как он был изначально написан супер-программистом)
Итак, что мы имеем в сухом остатке:
Было изначально:
Репрайсер, удерживающий РРЦ (рекомендованную розничную цену), с проверкой раз в 7 минут ( задается в настройках планировщика хостинг-панели), хранение данных в файловой бд sqlite. Контроль СПП и WB кошелька. ( первоначальные затраты 50 000 р, оплата программистам, первый создал неудачный костыльный вариант ( блин комом), второй создал очень хорошую основу с удачной архитектурой для обновления и для обучения на примере)
Также репрайсер изначально содержит возможность телеграм уведомления при ошибках обновления цен ( в основном это говорит о том, что на WB неполадки того или иного рода)
Что было далее сделано мной с помощью DeepSeek и Le Chat, вначале использовался Copilot, но быстро отправился в утиль..:
В самом репрайсере:
1) Изменение цен в заданных диапазонах времени ( свой прайс- под каждый диапазон времени)
2) Таблица репрайсера показывает остатки товара ( можно выгрузить в CSV, или Excel, с остальными параметрами, чтобы отфильтровать по заданным диапазонам)
3) Загрузка цен до СПП ( изначально репрайсер создан для удержания РРЦ)
4) Загрузка цен до WB кошелька.
5) Юнит-калькулятор ( расчет прибыльности и маржи в %, выгрузка в виде Excel-отчета, быстрая проверка рекламных расходов)
6) Полуавтоматическое обновление цен поставщика при условии заданного артикула поставщика в первой колонке Excel прайса.
7) Реализация создания отчета для отправки поставщику, при выполнении условия из п.6
8) Установка в прайсе товаров, которые не нужно менять
9) Горячая замена цен ( клик мышкой, открывается окно, вписывается цена). В основном цены задавались только напрямую через excel прайс, и приходилось каждый раз загружать новый прайс с измененной ценой.
10) Быстрый вывод товаров с нулевым СПП.
11) Вывод логов действий репрайсера за последние два дня- в модальном окне, либо скачивание файлов отчетов ( до этого только я мог сам посмотреть по FTP)
12) Выводится дата годности токена на видном месте ( ранее информации не было).
Внешние доработки, для себя, не используются другими клиентами, но можем сделать и вам😊
1) Выдача пропусков по расписанию ( актуально для FBS)
2) Синхронизация цен с OZON ( можно ставить в WB такие же цены как в Ozon, при условии доступа к api ozon, либо к сторонним json выгрузкам с прайсом в Ozon.
3) Слежение за конкурентами и создание таблиц с отчетами, проверка цены раз в час, выгружаются таблицы за последние 10 дней, а также в режиме реального времени,с уведомлением о нарушении в телеграм.
4) Слежение за конкурентами и следование ценовым стратегиям ( держать цену на 1р ниже, или такую же как у конкурента, но не ниже заданного предела). В процессе тестирования, проверялось на малом количестве товаров, планируется интеграция в репрайсер
5) Суммирование возвратов ( упрощение процесса работы с возвратами), актуально если очень много товаров.
Для удобства работы с клиентами
1) Обновитель-updater ( эдакая замена GIT по простому), на основе WinSCP ( да, голь на выдумки хитра, и до сих пор не научился пользоваться git, контроль версий проводится кустарно ( в этой папке старое, в этой новое, тестирую, смотрю). При нажатии одной кнопки происходит обновление на разных ftp-серверах, в разных папках, всех установленных репрайсеров, когда была сделана доработка.
2) Панель для контроля оплат, интегрирована с платёжной системой Prodamus через API ( автоматическое продление подписок), в целом реализована система автоматического выключения при неоплате, но пока достаточно всё видно и по таблице оплат.
3) Инсталлятор, то есть клиент вводит в заданной форме емайл, телефон, название организации, логин и пароль, репрайсер устанавливается автоматически по заданному адресу, настройки выдаются на экране установщика и отправляются на почту. Ранее всё делалось вручную, пароли задавались также, файлы копировались через FTP вручную.
Roadmap. Что будет сделано ( в процессе, или в планах):
Для себя: Уведомление об остатках ( если товара мало- приходит уведомление на почту и в телеграм), уже работает, но с колебаниями, в процессе доработки
Для клиентов: Whatsapp-уведомление для желающих ( выбор в настройках), если WB-кошелек сменился ( ранее работало автоматическое обновление WB-кошелька, сейчас задаётся вручную, ввиду изменений WB, возможно это обновление и не понадобится. если WB вернет доступ к настройкам). Также будет сделано уведомление о времени завершения работы токена ( за неделю).
Для клиентов: Задание диапазона обновления/проверки цен в админ/панели, от 7 до 60 минут ( сейчас в основном задаю вручную 1 раз в 7 минут, 1 раз в 10-15 минут, кому этого достаточно и не нужно очень быстро). Отключение/Включение обновления через админ/панель.
Для клиентов: Возможное добавление юнит-калькулятора для учёта % возвратов ( актуально для одежды, где много возвратов, и существующий юнит-калькулятор показывает тогда далеко не точные цифры). Также в общем будет сделана доработка юнит-калькулятора для удобства использования ( цветовые диапазоны для разных уровней прибыльности), сейчас выводится красным если ниже 0, а также другие доработки для горячего анализа прибыльности, сейчас таблица с параметрами добавляется через Excel.
Возможно создание PWA приложения, но это если хватит знаний и если так можно по архитектуре проекта ( до конца не проверено), в этом случае будет возможен запуск на любом мобильном с ярлыка, по аналогии с приложением в телефоне. ( пока это на последнем месте по приоритету)
Возможны другие доработки в меру сил, по пожеланиям клиентов.
Доработки с пометкой для себя чаще всего не внедряются в репрайсер, чтобы его не загромождать ( да и не всем клиентам это нужно), внедряются в первую очередь полезные доработки.
Ежели будут любые вопросы спрашивайте, авось отвечу:-)
Интеграция оборудования с веб-системами часто становится непростой задачей, особенно когда дело касается специфических устройств, таких как кассы. В одном из наших проектов потребовалось настроить взаимодействие кассы АТОЛ 30Ф с веб-приложением, работающим на PHP. Этот кейс стал для нас важным шагом в изучении возможностей автоматизации и оптимизации бизнес-процессов.
Как все начиналось
Касса АТОЛ 30Ф — это популярное решение для ритейла, но её работа традиционно рассчитана на использование с локальными системами, такими как 1С. Нам же нужно было подключить её к веб-приложению, чтобы обеспечить удалённое управление операциями.
Проблема заключалась в том, что драйверы кассы были написаны на языке C и не имели нативной поддержки PHP. Задача заключалась в том, чтобы связать веб-приложение с физическим устройством напрямую, сохранив его функциональность и производительность. Решение мы нашли в технологии FFI (Foreign Function Interface), позволяющей PHP взаимодействовать с библиотеками на других языках.
FFI: как PHP взаимодействует с C
FFI — это расширение PHP, которое открывает доступ к библиотекам на C. С его помощью можно описать функции библиотеки и вызывать их из PHP-кода, как если бы они были встроенными.
Работа началась с изучения заголовочного файла библиотеки Драйвер контрольно-кассовой техники v.10. Этот файл содержал описание ключевых функций, включая команды для управления устройством, передачи данных и получения ответов. Благодаря FFI мы смогли подключить библиотеку и использовать её функции прямо из веб-приложения.
Например, команда для печати чека выглядела следующим образом:
Для упрощения взаимодействия с функциями и переменными из кода на C мы создали PHP-классы-заглушки. Они полностью повторяли структуру заголовочного файла библиотеки, предоставляя описание необходимых функций и переменных на уровне PHP.
Этот подход значительно упростил работу: разработчики могли удобно вызывать методы, а также быстро просматривать их сигнатуры и параметры прямо в IDE, без необходимости заглядывать в исходные файлы на C.
PHP вызывал функцию драйвера, которая напрямую передавала команды кассе.
Стек технологий
Для реализации проекта мы использовали следующий стек технологий:
PHP 8.0: основной язык разработки веб-системы.
FFI: для связи с библиотекой на C.
MySQL: для хранения данных о транзакциях и конфигурациях касс.
Nginx: в качестве веб-сервера.
Docker: для упрощения тестирования и развёртывания.
Linux: серверная операционная система, обеспечивающая поддержку необходимых драйверов.
Особенностью проекта стало сочетание гибкости PHP для веб-разработки и производительности библиотек на C.
С какими трудностями мы столкнулись
Этот проект не обошёлся без сложностей, которые потребовали нестандартного подхода. Одной из основных проблем стало различие в форматах данных: PHP использует строки в кодировке UTF-8, тогда как драйвер кассы ожидал 32-битные данные.
Ещё одной сложностью стало управление памятью. В PHP оно происходит автоматически, тогда как в C за это отвечает разработчик. Чтобы избежать утечек и сохранить стабильность работы, мы реализовали дополнительные меры для корректного освобождения памяти. Кроме того, нам нужно было обеспечить поддержку разных способов подключения кассы — USB, Bluetooth и IP. Мы адаптировали систему так, чтобы она могла работать с любым из этих интерфейсов, обеспечивая гибкость использования в зависимости от сценария.
Как это работает в веб-системе
На финальном этапе наша команда завершила настройку интеграции. Теперь взаимодействие с кассой выглядит просто и интуитивно. Например, чтобы напечатать чек, достаточно вызвать PHP-функцию, а всё остальное — от преобразования данных до отправки команды — происходит под капотом.
Это позволило клиенту управлять кассовыми операциями удалённо, что особенно полезно в ситуациях, когда устройство подключено через IP. При необходимости веб-система также поддерживает работу с кассой через локальные интерфейсы, такие как USB или Bluetooth.
Что мы вынесли из этого проекта
Опыт, полученный в процессе реализации задачи, показал, насколько мощным инструментом может быть FFI. Он позволяет интегрировать устройства и системы на разных языках, что открывает широкие возможности для автоматизации и оптимизации бизнес-процессов.
Этот подход оказался универсальным и может быть применён для работы не только с кассами, но и с другими устройствами: от драйверов видеокарт до сетевых адаптеров.
Работа с FFI и драйверами на C расширила наши представления о возможностях PHP и показал, что грамотное использование технологий позволяет находить простые и эффективные решения для сложных задач.
Чаще всего под шаблонами проектирования понимают некую часть программы, которая должна выполнить часто повторяющуюся задачу. Для таких частых, стандартных задач были написаны алгоритмы и, даже, специальная книга "Design Patterns".
Вот об этих шаблонах или паттернах, описанных в книге, и поговорим.
В статье на Википедии предлагают следующую классификацию шаблонов:
Мне кажется, что самый простой и популярный шаблон, который можно разобрать в первой статье - это Порождающий шаблон "Фабричный метод". Основная идея его в том, что наша программа будет создавать разные классы в зависимости от некоторых условий. Причем, во время разработки программы, мы не будем знать какой класс нам будет необходим. И программа должна будет определить и создать класс сама. Да, объяснить без примеров это не просто, поэтому посмотрим на код.
Фреймворк
Для того, чтобы написать программу использующую паттерны, я решил создать небольшой проект и попробовать внедрить шаблоны так, чтобы практическая польза от них была как-то заметна. Проект - это элементарный телеграм бот. В который можно написать любое сообщение и получить ответ от бота. Для реализации бота я использовал простой php фреймворк с сайта code.mu на котором есть много полезных уроков и заданий.
Код проекта можно найти на гитхабе, ведь редактор текста на Пикабу не позволяет форматировать код для удобного чтения.
А бот можно найти в телеграме, написать ему сообщение и проверить работу нашего Фабричного метода.
Код проекта
Идея программы очень простая - вы пишите сообщение телеграм боту. Бот отправляет callback сообщение на бекэнд нашего приложения. И в зависимости от текста этого сообщения, код на бекэнде определяет какое сообщение отправить боту обратно, чтобы вывести его в телеграм клиенте.
Сообщение от телеграма приходит на роут, который мы указали при создании бота в BotFather. А во фреймворке создали этот роут в "\project\config\routes.php"
use \Core\Route;
return [
new Route('/telegram/:var1/', 'telegram', 'index'), // роут для telegram bot
];
Роут находит Telegram Controller и выполняет метод index. В этом методе мы выполняем ряд проверок. И если сообщение пришло от нашего телеграм бота, передаем сообщение в Фабричный метод, чтобы создать нужный объект и получить обратное сообщение для бота.
$ms = new MessageFactory($params);
$msObject = $ms->create();
В классе MessageFactory есть два метода. В конструкторе мы разбираем параметры сообщения и пытаемся получить текст сообщения от телеграма и id чата от которого сообщение пришло.
А в методе create мы проверяем существует ли класс для конкретного сообщения и если существует создаем объект этого класса и возвращаем его в контроллер. Если же класса нет, значит мы должны создать дефолтный класс.
Для каждого конкретного сообщения, которое мы хотим обработать на бекэнде по уникальному сценарию, мы должны создать класс реализации. Например, класс "\project\classes\messagefactory\messages\MessageTest.php"
Этот класс расширяет абстрактный класс MessageAbstract и реализует интерфейс IMessage. class MessageTest extends MessageAbstract implements IMessage {}
У него есть только конструктор, в котором мы вызываем конструктор родителя и заполняем свойство $message = 'Test Message'. Соответственно, если мы напишем в телеграм бот сообщение 'test', то наш Фактори метод создаст класс MessageTest, в свойстве $message у него будет строка 'Test Message' и контроллер отправит эту строку обратно в телеграм бот.
Telegram Bot
Что если
Что если бы мы не использовали все эти модные паттерны, классы и ооп. Конечно, такую программу можно реализовать и без ооп, возможно это даже проще. Но тогда описать обработку каждого сообщения придется в блоках if/else или switch/case. На первом этапе это будет не трудно. Просто напишем нужную строку для каждого case. Но, что если логика реакции на каждое сообщение будет сложной. Если при сообщении '/start' мы захотим зарегистрировать пользователя в системе и добавить его в базу данных. А при дефолтном сообщении создать еще несколько вариантов сценариев. Тогда наш контроллер будет огромного размера и поддерживать такую программу станет слишком сложно.
С другой стороны, если создать фабрику сообщений, то нам нужно только добавить отдельный файл сообщения в соответствующую директорию и все остальное сделает наш Фактори метод.
Вместо заключения. Это первый шаблон проектирования ПО который мы рассмотрели. Впереди еще много работы и полезных штук, поэтому... Спасибо всем, кто смог дочитать этот пост до конца несмотря на ужасное оформление, примеры на php и общую безграмотность. Отдельное спасибо всем, кто заходит и подписывается на ютуб канал. Я начинаю готовить видео на тему Шаблонов проектирования. Может быть примеры кода на видео будут более понятны.
// Укажите ID чата, куда бот будет отправлять сообщения $chat_id = "ВАШ_CHAT_ID";
// Получение данных из формы $name = htmlspecialchars($_POST['name']); $email = htmlspecialchars($_POST['email']); $message = htmlspecialchars($_POST['message']);
// Формирование текста сообщения для Telegram $txt = "Новое сообщение с сайта:\n"; $txt .= "Имя: $name\n"; $txt .= "Email: $email\n"; $txt .= "Сообщение: $message\n"; $txt .= "IP: $ip_address";
// Выполнение запроса $response = curl_exec($ch); curl_close($ch);
// Проверка успешности отправки if ($response) { echo "Сообщение успешно отправлено."; } else { echo "Ошибка при отправке сообщения."; } ?>
Инструкции:
Замените ВАШ_TELEGRAM_TOKEN на токен вашего бота (получить можно у BotFather).
Замените ВАШ_CHAT_ID на ID вашего чата или пользователя, куда бот будет отправлять сообщения. Узнать ваш ID можно, отправив /start вашему боту и проверив ответ от Telegram API.
Разместите оба файла (form.html и send_to_telegram.php) на сервере.
AppWrite, SupaBase, Directus, Strapi - не понравились
AppWrite
Есть всё, кроме массового импорта. Мощнейшая вещь.
Но настройка его сложна для новичка, и жрет о 2-4гб оперативки на сервере.
SupaBase
Крутая штука, не допёр как сделать авторизацию 🤣
И тоже с настройкой были траблы.
Плюс мне не нравится HTTP Basic Авторизация по захардкоженным credentials в конфиге прокси сервера.
За то импорт и экспорт нормальный есть
Directus
Очень крутая штука, особенно его Flows.
Стал сильно продуманнее за прошедшие полгода с моей встречи с ним.
Но все так же документация меня вымораживает. Много не раскрытых тем, и скрытых, не упомянутых ограничений.
Например условная нода логики в тех же Flow - не поддерживает тупую проверку входных данных на их наличие... Не уверен что мне когда-либо понравится это. И так же во flows много других ограничений, хотя задумка улетная.
В остальном это комбайн для супер быстрого старта, толком даже без настроек, всё мышкой можно сделать.
Ограничения так же можно обойти, сделав простое расширение, я так пол логики в прошлом проекте сделал, но теряется весь шарм легкости и наглядности. 🥲
Думаю ребята в нужном направлении двигаются, и их время просто ещё не настало, держу звезду на гитзабе за них.
Strapi
HeadlessCMS, да. Крутая, да. Популярная? А вот хз-хз.
Вроде раньше много где встречал про неё статьи, и на гитхабе звезд куча насыпано.
НО КАК? Как может не быть у такой популярной CMS функционала для импорта/экспорта, хотя бы банального!?
Он справделивости ради есть в официальном маркете расширений, но... На прошлую версию 😖 Не без обратной совместимости 😩
Ну я его тоже оставил откисать.
FilamentPHP
Тяжелая артилерия из TALL Stack компонентов и не то что целой системы, а уже целой ЭКОсистемы для любого рода панелей, да еще и на базе Laravel 😤
Ну это козырь был.
Я пытался, честно, вот даже описал что меня останавило, и на каждый из вариантов я потратил минимум 4 часа времени.
Думал ребята допили свои проекты, обещающие супер быстрый старт, но везде какие-то проблемы...
В итоге я все же снова взял в работу этот стэк для бэка. Нельзя на нем не сделать бэк. Ну нет ограничений, сколько бы я не придумывал.
Меня просто удивляет продуманность этого Filament. Баги есть, не без них, конечно. Как оказалось без ошибок ни то, что люди, роботы не справятся 🙃 (Отсылка к нейросетям)
Тут я за пару дней уложился извернуться и не сорвать сроки, а сделано:
Админка
Бизнес логика
Token Based Авторизация по API (пришлось потратить полдня, чтобы разобраться в этой теме, так как я её намеренно игнорировал последние 3 года)
API c аутентификацией по токену
Расширение для хрома на WXT + React (TanStack Router, Query, Store)
Для расширения хромовского - я вообще только с WXT работал и голым React, чисто для верстки.
К сожалению - опять не пригодился Background скрипт, так что всё ещё познать вполне не удастся разработку расширений...
Но с TanStack я не работал. Как-то раз для крипто проекта пытался его настроить и за целый день - так и не вышло. Сейчас же скажу - это мастхэв! Очень крутая штука!
Ну и отказался от Tailwind и SCSS в пользу CSS Modules в паре с clsx. И я не сказал бы, что стили писать долго. В моем случае я заказы беру вообще без дизайна и предпочтений, так что 50-80% от них пишет нейросеть, а я просто не претендую на произведение искусства 😆
Кто работал с этими комбайнами, опишите свой опыт, мб я чего не догоняю... Конкретно с AppWrite - разбираться не стал в силу ограничения по срокам, а supabase по инерции последним выбыл.