Всем привет! В этой статье расскажу свой путь по написанию bot-а(скрипта) для репоста постов из VK на другие платформы.
Ознакомиться с проектом можете на Github, по ссылке.
Если кратко (цель проекта)
Файли - Index.php - при публикации предложенной записи в VK - записывать запись в БД.
Файлы - toTG.php\toFB.php\toOK.php - проверяют в БД наличие неопубликованных записей и если записи есть - публикуют их в соответствующей соц.сети\меседжере.
Предыстория
Все началось лет 10 назад, когда студентом пытался на найти квартиру через VK. Но паблика недвижимости для моего города - не нашлось. Я подумал - это ниша и создал группу для поиска недвижимости. На текущий момент в группе около 10.000 подписчиков.
Прошло много времени, я начал работать в IT как QA, постиг много азов и решил, пора расширятся на другие платформы, но было лень (а лень двигатель прогресса) публиковать все новости в других соц.сетях и меседжерах вручную и я решил это немного автоматизировать. Что вышло - читайте ниже.
В этой статье мы рассмотрим пример для публикации записей из VK на различных платформах, таких как Telegram, Facebook и Одноклассники. Мы будем использовать Docker, официальные SDK и API.
Пройдемся по файлам .php в проекте:
index.php
Этот PHP код представляет собой скрипт для обработки входящих данных от VK (ВКонтакте) и сохранения их в базу данных. Давайте разберем, что делает этот код в этом файле:
В начале кода происходит чтение конфигурационного файла
config.ini
, в котором хранятся параметры, такие как токены для доступа к VK API и настройки базы данных (далее об этом будет рассказано подробнее)Дальше код проверяет наличие запроса от VK, декодирует пришедший JSON и выполняет несколько проверок и действий в зависимости от типа запроса:
Если запрос содержит тип
confirmation
, скрипт возвращаетconfirmation_token
для подтверждения сервера VK.Если тип записи (
post_type
) не соответствует заданному типу, скрипт просто выводит "ok" и завершает работу.Если тип записи -
wall_post_new
, скрипт вызывает функциюCheckIdWallinDB(connection(), $data)
, чтобы проверить уникальность записи в базе данных. Если запись уникальна, она сохраняется в базе данных с помощью функцииAddWallPostinDB($connection, $data)
.
Функция
connection()
- устанавливает соединение с базой данных MySQL, используя данные из конфигурации.Функция
CheckIdWallinDB($connection, $data)
проверяет, есть ли запись с такимid
в базе данных. Если запись с такимid
уже существует, выводится сообщение "ok". В противном случае, вызывается функцияAddWallPostinDB($connection, $data)
, которая добавляет новую запись в базу данных.Функция
AddWallPostinDB($connection, $data)
добавляет новую запись в базу данныхfromvk
с полямиid
,text
, иsigner_id
.Функция
GetImageUrlFromPost($data)
проходится по входящим данным и извлекает URL фотографий из вложений в записи, затем возвращает массив с URL фотографий.Функция
AddWallPhotoDB($connection, $parsedArray, $postIdFromVk)
обновляет запись в базе данных, добавляя в нее URL фотографий.
toTG.php
Данный код представляет собой скрипт на PHP, который выполняет автоматический репост контента из БД(куда мы записываем записи фалом index.php) в Telegram. Предполагается, что скрипт будет запускаться периодически, например, через крон (планировщик задач) для регулярной проверки наличия нового контента в базе данных и его репоста.
Подключение необходимых библиотек и файлов:
В начале кода происходит подключение внешних зависимостей через
autoload.php
, что обеспечивает загрузку необходимых классов для работы с Telegram API и базой данных. Также из файлаconfig.ini
читаются конфигурационные данные, такие как ключ API Telegram и данные для подключения к базе данных.Установка соединения с базой данных:
После чтения данных из
config.ini
, происходит установка соединения с базой данных MySQL с использованием полученных параметров (сервер, имя пользователя, пароль, имя базы данных). Если соединение не установлено успешно, скрипт завершается с выводом ошибки.Выборка новой записи из базы данных:
Затем скрипт выполняет SQL-запрос для выборки одной записи из таблицы
fromvk
, где полеIsRepostToTelegram
равно 0. Это служит для того, чтобы получить только те записи, которые еще не были репостнуты в Telegram.Репост контента в Telegram:
Если в результате запроса была получена хотя бы одна запись, то выполняется репост контента в Telegram.
Сначала данные из выбранной записи (id, фотографии, текст, идентификатор автора) сохраняются в соответствующие переменные.
При необходимости, идентификатор автора добавляется в текст сообщения.
Фотографии, полученные в виде строки с разделителем пробела, разбиваются на отдельные URL.
Затем формируется массив с объектами фотографий и их подписями (caption).
Если в базе данных есть фотографии, то осуществляется репост сообщения с медиа-группой (фотографиями). Если фотографий нет, то осуществляется репост сообщения без медиа-группы.
После успешной отправки сообщения в Telegram, поле
IsRepostToTelegram
для выбранной записи обновляется в базе данных, устанавливая значение 1, чтобы пометить, что контент был репостнут.
Логирование запуска по крону:
В конце скрипта выводится лог, содержащий текущую дату и время запуска (в формате "Год-Месяц-День Час:Минута:Секунда") и количество обработанных записей (
$result->num_rows
) из базы данных. Это позволяет контролировать работу скрипта и его активность при запуске через крон.
Важно отметить, что в данном коде используется сторонняя библиотека для работы с Telegram API, а также соединение с базой данных осуществляется напрямую через расширение mysqli
. При использовании в реальных проектах рекомендуется обеспечить безопасное взаимодействие с базой данных, используя подготовленные запросы или ORM (Object-Relational Mapping) для уменьшения уязвимостей и повышения безопасности.
toFB.php
Код, представленный в этом файле, выполняет автоматическую публикацию записей из базы данных на странице Facebook, используя Facebook Graph API. Давайте разберем шаги и функционал этого кода:
В начале кода происходит подключение файлов необходимых для работы с Facebook SDK, а также чтение конфигурационного файла
config.ini
, где хранятся настройки приложения Facebook и параметры для доступа к базе данных.Затем код устанавливает соединение с базой данных MySQL.
Следующий шаг - получение одной записи из таблицы
fromvk
, где значение поляIsRepostToFacebook
равно 0 (то есть запись еще не была отправлена на Facebook).Если найдена хотя бы одна такая запись, инициализируется Facebook SDK с помощью полученных ранее данных (App ID, App Secret из
config.ini
).Затем происходит обработка полученной записи из базы данных: извлекаются значения полей
id
,photo
,text
, иsigner_id
.Если
signer_id
не пустой, то он добавляется к тексту сообщения.Создается массив параметров
$post_data
, который содержит текст сообщения для публикации на странице Facebook.Проверяется наличие фотографий в записи (
$photo
). Если они есть, то URL фотографий разделяются на отдельные элементы массива$photo_urls
, и для каждой фотографии выполняется следующее:a. Фотография загружается на Facebook с помощью метода
post
и получается ID загруженной фотографии ($media_id
).b. ID фотографии добавляется в массив
$attached_media
.Если есть либо фотографии (
$attached_media
), либо текст сообщения ($text
), то выполняется публикация на странице Facebook с помощью методаpost
и параметров$post_data
, передавая токен пользователя ($facebookUserAccessToken
).Если публикация прошла успешно (
$graphNode['id']
не пустой), обновляется флагIsRepostToFacebook
в базе данных, устанавливая его значение на 1, чтобы пометить запись как опубликованную.Если при публикации возникли ошибки, они обрабатываются через исключения классов
FacebookResponseException
иFacebookSDKException
.Если в записи отсутствуют и текст, и фотографии, выводится сообщение "No photo or text found."
В конце кода закрывается соединение с базой данных.
toOK.php
Данный код представляет собой скрипт для автоматической публикации контента из базы данных на платформе Одноклассники (ОК). Давайте разберем, что делает этот код:
На первом этапе происходит чтение конфигурационного файла
config.ini
, в котором хранятся настройки для доступа к платформе Одноклассники и настройки базы данных.Устанавливается соединение с базой данных MySQL.
Выполняется выборка из таблицы
fromvk
одной записи, где значение поляIsRepostToOK
равно 0 (запись еще не была опубликована на Одноклассниках).Если найдена хотя бы одна такая запись, код извлекает из нее данные, такие как фотографии (
$photo
), текст сообщения ($text
) и идентификатор автора ($signer_id
).Формируется текст сообщения для публикации, который будет содержать оригинальный текст из записи и информацию об авторе.
Если в записи имеются фотографии, они загружаются на сервер Одноклассники. Каждая фотография получает уникальное имя и временно сохраняется на сервере, указанном в
$path
.Функция
ok_wall_post()
выполняет публикацию на странице Одноклассники с помощью методаmediatopic.post
, передавая текст сообщения и список загруженных фотографий.После успешной публикации обновляется значение поля
IsRepostToOK
в базе данных, устанавливая его значение на 1, чтобы пометить запись как опубликованную на Одноклассники.Загруженные фотографии удаляются с сервера.
В случае отсутствия текста сообщения и фотографий для загрузки, выводится сообщение "Отсутствуют текст сообщения и изображения для загрузки."
Ниже определена функция
ok_wall_post()
, которая отвечает за публикацию сообщения и фотографий на странице Одноклассники. В ней выполняется создание массивов с фотографиями и их загрузка, а также формирование параметров для публикации и создания подписи для запроса.
Установка на сервер:
Подключаемся к серверу по SSH
Обновляем все на сервере
sudo apt update
sudo apt upgrade
Устанавливаем Docker
Установите необходимые пакеты для поддержки HTTPS:
sudo apt install apt-transport-https ca-certificates curl software-properties-common
Добавляем официальный ключ Docker GPG:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
Добавляем официальный репозиторий Docker:
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Обновляем индексы пакетов еще раз:
sudo apt update
И наконец ставим Docker:
sudo apt install docker-ce docker-ce-cli containerd.io
Проверяем, что Docker успешно установлен, запустив простую команду:
sudo docker run hello-world
Устанавливаем Git
sudo apt install git
После завершения установки проверяем, что Git установлен правильно, выполнив команду:
git --version
Копируем проект к себе на сервер
Git clone git@github.com:Antoha-94/flat_polotsk_novopolotsk
Выполняем инструкцию из файла README.md
Краткая выдержка:
Редактируем под себя файл .env(делаем его из примера: .env.example )
Редактируем файлы конфига nginx
Выполняем:
docker compose exec php bash
Ставим в контейнере PHP - composer, выполнив
composer install
Билдуем контейнеры Docker
docker-compose up -d --build
Настраиваем соц.сети\меседжеры
Из файла config.example.ini делаем свой файл config.ini - это файл с подключениями к БД и нашими токенами от VK, Telegram, Facebook и odnoklassniki
Нам нужно настроить доступ к API каждой социальной сети\меседжера\БД. Для этого нам понадобится указать в файлике config.ini следующие данные:
[Database] - указываем подключения к БД
servername - ip по которому подключаемся в базе
username - имя пользователя
password - пароль
dbname - название БД
[VK] - переходим в настройки группы(управление) -> работа с API -> Callback API и заполняем инфу о сервере, секретный ключ и берем значение " Строка, которую должен вернуть сервер". Все записываем в config.ini файл.
confirmation_token: значение указанное в "Строка, которую должен вернуть сервер"
token: значение указанное в " Секретный ключ:"
post_type: в моем случае "post"
[Telegram] - создает своего бота через BotFather, добавляем его в канал(предполагается что он уже создан) telegram куда будем репостить посты из ВК. Вносим в config.ini следущее:
api_key: Ключ бота Telegram.
chat_id: Идентификатор чата или канала, куда мы будем отправлять сообщения.
[Facebook] - регистрируемся в кабинете разработчика Facebook: https://developers.facebook.com/async/registration и создаем приложение на странице: https://developers.facebook.com/apps
В config.ini вносим:
app_id: Идентификатор приложения Facebook.
app_secret: Секретный ключ приложения Facebook.
page_id: Идентификатор страницы Facebook, на которую мы будем репостить записи.
user_access_token: Токен доступа пользователя с необходимыми разрешениями.
[OK] (Одноклассники) - создаем группу куда будем репостить посты из ВК. Регистрируемся в https://ok.ru/devaccess и создаем своем приложение (подробнее здесь: https://apiok.ru/dev/app/create)
В config.ini вносим:
access_token: Вечный access_token в приложении
private_key: Закрытый ключ приложения.
public_key: Публичный ключ приложения.
session_key: Сессионный ключ в приложении.
group_id: Идентификатор группы Одноклассники, на которую мы будем репостить записи.
7. Размечаем таблицу fromvk в БД, выполнив в PHPmyAdmin SQL:
CREATE TABLE fromvk ( id int(11) NOT NULL, text text DEFAULT NULL, photo text DEFAULT NULL, signer_id text DEFAULT NULL, IsRepostToTelegram tinyint(1) NOT NULL DEFAULT 0, IsRepostToInstagram tinyint(1) NOT NULL DEFAULT 0, IsRepostToFacebook tinyint(1) NOT NULL DEFAULT 0, IsRepostToViber tinyint(1) DEFAULT 0, IsRepostToOK tinyint(1) DEFAULT 0 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
Настраиваем расписание в Сrone
Открываем файл Crone c расписанием:
crontab -e
Настраиваем как часто будет происходить проверка в БД на наличие неперерепощеных записей в telegram, facebook, ok. Рекомендую ставить одинаковое расписание для всех 3 фалов. В примере ниже - проверка каждую минуту + логирование в файл cron.log
* * * * * cd /root/simple-docker-php-main && docker compose exec php php toTG.php >> /root/simple-docker-php-main/cron.log 2>&1
* * * * * cd /root/simple-docker-php-main && docker compose exec php php toFB.php >> /root/simple-docker-php-main/cron.log 2>&1
* * * * * cd /root/simple-docker-php-main && docker compose exec php php toOK.php >> /root/simple-docker-php-main/cron.log 2>&1
Тестируем, что все работает
Публикуем запись в группе ВК.
Ждем не более минуты, пока отработает расписание Crone
Проверяем, что записи появились в соц.сетях\меседжерах
Жду ваших пул реквестов с улучшениями, код пока что сыроват, но мои требования выполняет.