Не мало людей удивятся «А что так можно было?». Да – хорошие боты можно писать на PHP. Да – WordPress хорошо подходит в качестве фреймворка. Далее поделюсь своим опытом. Речь пойдет о веб-хуках из Телеграм, но и на апдейтах применимо.

Погодите хейтить за нагрузку и тяжесть.

Почему WordPress? На нем же сайты делают!

Аргументов несколько:

  1. WordPress имеет хуки, функции, которые ускоряют написание кода.

  2. Есть понятная БД, со своей определенной логикой.

  3. Можно ставить плагины, которые тоже могут помогать в написании Телеграм-бота. В частности, постоянно использую Cyr-to-lat, ACF, что-то для сжатия фото.

  4. Бота можно интегрировать в действующий сайт или же со временем развить бота в сайт.

  5. Пользователь в боте – это пользователь в WordPress. Аналогично про записи в WP - это посты в ТГ.

  6. При правильной организации к WordPress можно добавить бота из ВК, Дискорда и т.д. При этом можно синхронизировать пользователей из разных соцсетей (сам запараллелил бота ТГ + ВК, и ТГ + Дискорд + почту в рамках двух проектов).

  7. У владельца бота есть готовая и, часто уже знакомая, админ-панель.

  8. Безопасность. CMS разрабатывается десятками специалистов и имеет большое количество фидбеков от пользователей. Это лучше, чем создать свою систему, пусть даже командой, и забыть что-то предусмотреть. Тут можно поспорить с аргументом «чем больше система, тем больше дыр».

  9. Много программистов уже знают, как устроен WordPress и им будет легче войти, а владельцу - легче сменить разработчика.

  10. WordPress обновляется. Плагины обновляются. Маленькая команда не сможет так часто обновлять свою систему.

  11. Не нужно настраивать дебаг – включил в wp-config.php define("DEBUG", true) и все ошибки фиксируются даже из неродного кода.

Итого: WordPress – хороший фреймворк для разработки Телеграм и прочих ботов.

Минусы (добавьте свои в комментах):

  1. В режиме «как есть» и «веб-хуки» на виртуальном хостинге не подходит для работы с большим количеством пользователей бота. Я бы сформулировал так: если бот в большинстве своем текстовый, то обработка каждого запроса на стороне WordPress займет 0.1-0.3 секунды (замерял). Также проводил эксперимент – нормально работает с 2-3 запросами в секунду. Однако, в некоторых случаях можно дропать ожидание ответа и тогда будет создано несколько потоков, а значит на 10 потоках можно обрабатывать до 20-30 запросов в секунду (эту провокацию вписал для комментов).

  2. Из-за веса CMS, без кэширования, при большом (см. п.1) количестве запросов пользователей производится серьезная нагрузка на процессор.

К минусам отношусь философски.

Если у тебя есть даже 1 запрос в секунду, значит у тебя аудитория большая, значит ты можешь и свою систему написать. Если же не хочешь писать систему, можно проапгрейдить код бота и переписать работу с WordPress под режим SHORTINIT и увеличить скорость его работы до 0.04-0.07 секунды (тоже замерял) на каждый запрос с кратным снижением нагрузки на процессор хостера.

Здесь мы, как мне кажется, больше упремся в то, сколько через веб-хук может пропускать сам Телеграм. На отправку до бота и обратно в ТГ тоже время уходит, а это добавляет где-то 0.03 секунды.

Главное – структура файлов и кода бота.

Изо дня в день, создавая ботов я совершенствовал свой код. Для себя лично определил оптимальной такую структуру:

Организация файлов:

  1. В корне WordPress создаем директорию bots

  2. В директории bots создаем tg и/или vk и т.д.

  3. В каждой поддиректории типа tg создаем, скажем, constructor, loyality, что позволит нам на одном WordPress иметь несколько разных Телеграм-ботов (да-да). В этой директории и будет лежать код бота.

  4. Ну, а далее кидаем .htaccess и перенаправляем все запросы на index.php

В общем случае, структура выглядит так:

  • site_root_dir/subfolder?

    • bots/

      • vendor/ (из композера)

      • tg/

        • bot_name/

          • index.php (все запросы сюда и тут же загружаем WordPress)

          • Senders/ (отправляторы в АПИ)

            • TG.php

            • VK.php

            • GPT.php

          • Common/ (для общих классов)

            • Screen.php (создает экраны)

            • Button.php (создает кнопки)

            • Uploads.php (загрузка файлов в WP)

          • General/

            • Config.php

            • Parser.php (распарсит и хранит у себя данные из запроса)

            • Errors.php

            • Router.php (определяет обработчик и направляет к нему запрос)

          • Handlers/ (обработчик действий из ТГ)

            • Callback/ (обработчики нажатий кнопок)

              • button_data__private.php

            • Command/ (обработчики команд)

              • command_name.php

            • Text/ (обработчики текстовых сообщений)

              • action_name__private.php

            • Photo/ (и так далее: Video, Sticker…)

              • action_name__private.php

Аналогичную структуру построил и для бота ВК, хотя под него пришлось (ну, а как) переписать Parser.php, Router.php и вместо Callback/ создал Payload/, а в остальном, можно сказать, просто скопировал из Телеграм-бота файлы.

Вот как выглядит код стартового экрана бота ВК по нажатию кнопки:

Вот как выглядит код стартового экрана бота ТГ по нажатию кнопки:

Эти скриншоты из одного и того же WordPress. Да, на ТГ-скриншоте немного другая структура, давным давно положил все в Classes - и больше нет отличий, но это будет переписано в скором времени. Суть в том, что сам WP и код организован таким образом, что получается однообразная структура, одинаковые запросы к БД, хуки и одинаковые ответы и обработка.

П.С.

На счет button_data__private.php или action_name__private.php .

Варианта подгрузки обработчика 3:

  1. Имя команды является названием файла: post__private.php с одноименной функцией внутри function post__private() {}

  2. Имя команды обобщенное, а обработчик конкретный подключается внутри на switch/case: base__private.php >> new Class{}

  3. Имя команды является базовым классом, а дальше пошло либо описание обработчиков методами внутри класса, либо ветвление с подключением наследников.

Все из перечисленного делал и вариант на switch/case показался наиболее оптимальным.

Что за __private в конце? Это определяется в Parser.php тип чата: частный, супергруппа и так далее. То есть можно организовать base__private.php или base__public.php или base__supergroup.php и обрабатывать одинаковые команды из разных чатов.

Как формирую запросы

Интересно то, как можно формировать обращение к файлу-обработчику.

Допустим, мы нажали в боте на кнопку, у которой в data записано такое значение: post?action=change&id=777&scope=title. Это условно написано, но ведь правда напоминает GET-запрос из УРЛ? У меня настроено так: класс Queries разбирает строку и Router обращается к файлу Callback/post__private.php.

Вся строка из data сохраняется в "последних действиях" и через Callback/post__private.php отдаем пользователю ответ на нажатие кнопки. Теперь мы находимся в ожидании ввода текста. После ввода текста пользователем, запрос доходит до Router, который смотрит "последние действия" (там - post), понимает что в данном случае нужен обработчик из Text, обращается к Text/post__private.php, внутри которого, согласно команде с кнопки, происходит работа: какая запись (id) из WP должна быть запрошена и что (action/scope) с ней надо сделать. Происходит выполнение поставленной задачи, и введенный текст попадает в заголовок записи WP, который собственно и меняется.

Аналогично и с командой. Можно написать что-то вроде /post?action=change&id=777&scope=title и бот также запишет это в действия пользователя. Всего, по сути, из Телеграма приходит два призыва к действию: это Callback и Command.

Почему решил опубликовать эту запись?

Дело в том, что иногда обращаются клиенты за доработкой ТГ-ботов. Ни разу не встретилась единообразная структура кода. Также просят бота на Laravel, Yii, а я сижу и не понимаю, зачем тебе, заказчику с фриланса поставляющему запчасти из Японии или владеющему кадровым агентством с 2-5К клиентов нужна отдельная система за ХХ ХХХ рублей, которую потом еще нужно интегрировать в твой сайт, который часто как раз на WP и сделан. Бывают запросы и на бота для друзей, на бота корпоративного, других мелко-средних ботов.

Нет, все-таки дело в том, что писать даже микро-бота не хочется без админки и без упорядоченного кода.

Особенно мне нравится использовать ACF Pro из плагинов WP. В него поместил все настройки бота, чтобы заказчик сам мог менять не из кода, чтобы тексты мог прописывать сам. Да, что греха таить – я конструктор ботов на ACF Pro сделал, чтобы заказчик сам экраны заполнял, кнопки расставлял, тексты прописывал, фотки и документы отправлял. И все в рамках той же структуры.

Чуть топорно - нет перетаскивающихся экранов, красивостей, но это "твоё", с этим можно работать, добавлять текст, кнопки, делать неограниченно экраны. Клиентам нравится, это не дорого и легко усовершенствовать.
Чуть топорно - нет перетаскивающихся экранов, красивостей, но это "твоё", с этим можно работать, добавлять текст, кнопки, делать неограниченно экраны. Клиентам нравится, это не дорого и легко усовершенствовать.
Так выглядит набор экранов из конструктора бота. Это вариант годовой давности. Другие клиенты делают более невероятные и удобные вещи.
Так выглядит набор экранов из конструктора бота. Это вариант годовой давности. Другие клиенты делают более невероятные и удобные вещи.

Примерный набросок структуры сделал, наспех (не ругайте) вычистив код, выложил на гитхаб: https://github.com/Feelosov/wp_base_bot

Примеры о связке с WordPress

Скажем, регистрация пользователя происходит у меня сразу в Parser. Из наброска на гитхабе можно увидеть. Создается пользователь через wp_insert_user и через мета-поля связывается пользователь из Телеграм и пользователь в WordPress. При этом в БД сразу попадает и имя и никнейм, которые видны в админке в разделе "Пользователи". Через этот же Parser.php код узнает с каким пользователем в WP связан пользователь из ТГ.

Как я сделал доску объявлений на WP + TG? Не вдаваясь в детали: создал кастомный тип записи "advs", настроил мета-поля для него и каждое объявление из ТГ становится отдельной записью в WP, которую можно опубликовать, отмодерировать на сайте и оформить в соответствии с темой сайта. Тут же настроил права пользователей, которым разрешено модерировать - это вообще можно через админку сделать без кода. При этом, чтобы дать пользователю ссылку на объявление есть встроенная функция, которая помогает сформировать УРЛ, указав всего лишь ID.

Также сделал систему тикетов с поддержкой GPT. Через ТГ задается вопрос, попадает в записи по условию 1 пользователь = 1 запись. В том же Parser.php закодил так, чтобы тикет создавался сразу при создании пользователя в БД. Оператор открывает тикет, видит нативное поле для ввода ответа, видит переписку, имеет кнопку "Спросить GPT", забанить и прочие.

Пара скриншотов из тикет-системы:

Список тикетов
Список тикетов

Тикет-система на WordPress настолько получилась удачная, что на одной бирже мой код тупо перепродают, как бы смешно ни было, дороже, чем я. Увы, сделать я навряд ли что-то могу.

В основе выбора WP лежат хуки, мета-поля, готовая админка, возможность укороченной загрузки, поддержка global $wpdb, возможность вырастить из бота сайт, использовать плагины, которые как бы станут дополнением сторонних разработчиков к боту.

Самые часто используемые функции, разумеется, это get_post_meta, update_post_meta, get_user_meta, update_user_meta, а также разные встроенные проверки, вроде очистка строки, проверка на мейлность, проверка прав доступа, готовый дебаг, если использовать ACF, то еще get_field из любой записи или опций.

Комментарии (9)


  1. makapohmgn
    14.09.2023 14:32
    +3

    А ещё можно телескопом гвозди забивать)

    Cyr-to-lat это два массива и str_replace

    Работа с изображениями есть в документации, можно прям оттуда готовый код взять)

    Если прям уж очень хочется видеть какие-то таблицы прям в wp, положи данные в таблицы, тоже ничего сверхсложного)

    Неужели wp-программисты не могут 3 строчки кода самостоятельно написать, чтобы не подтягивать целый фреймворк с кучей плагинов?)


  1. Pinchoalex
    14.09.2023 14:32

    Это больно(


  1. SidVisceos
    14.09.2023 14:32
    +1

    Извините, но это шок - контент. Для чего там нужен фреймворк - непонятно. Для работы с апи телеграм в принципе не нужно ничего.


  1. sasmoney
    14.09.2023 14:32

    Лиж бы не изучать самописную разработку, любую дичь придумают


  1. IvanTheCrazy
    14.09.2023 14:32

    WP это прям образчик того, как делать не надо, кладезь антипаттернов. Хуже только битрикс


  1. init0
    14.09.2023 14:32

    Хороший пример того как не нужно писать под Wordpress.

    В корне WordPress создаем директорию bots

    Не осилили создание плагина? Только там и место для любого кастомного кода.

    Код на гитхабе - ад.


  1. CodeMaster125
    14.09.2023 14:32

    Автор красавчик - тянуть огромный оверхед в виде Wordpress для создания телеграм-бота?

    Я представляю автор удивится, когда узнает про DRY, KISS, SOLID, YAGNI, PSR и зачем всё это придумали)


  1. bO_oblik
    14.09.2023 14:32

    Что-то какой-то безосновательный хейт WP в комментариях. К примеру если сравнить laravel nova и wp, а так же уровень вопросов и проблем от комьюнити этих cms - то увы, nova не выдержит никакой критики, попробуйте переспорить :)


    1. init0
      14.09.2023 14:32

      Ну я бы вам посоветовал не тригериться на это, т.к. все эти хейтеры прибегают с нарративом но без аргументов.