Недавно я написал статью о разработке бота на php с использование laravel+botman для telegram. Самое первое, что написали, цитирую, “стрельба из пушки по воробьям”. Я согласен с этим, даже осознавал это во время разработки, но мне был интересен laravel.
Сейчас же я разрабатывал бота на чистом php(без обвязок) и API telegram, а так как статей на подобную тему очень много, то плюсом немного затронем API google(api youtube). Надеюсь, вам будет интересно и полезно узнать о API youtube.
Небольшое отступление. На данный момент я работаю frontend программистом и с php работаю лишь в свое удовольствие(хотя какое здесь удовольствие). Возможны глупейшие ошибки на стороне сервера, но это работает и мне на момент обучения этого достаточно.
Постановка задачи
Однажды вечером мне пришла идея связать бота и youtube, на тот момент я даже не подозревал о существовании api google. Требуется бот, который при выходе нового видео на youtube канале будет делать пуш уведомление в моего бота.
В принципе, функционал довольно простой, но как работать с youtube? Оказывается решение этой задачи есть у самого google и имя ему google API. Он позволяет работать со всеми приложениями от компании, но меня интересовал лишь youtube.
Настройка и разработка
Так получилось, что во время изучения api youtube было найдено куда элегантное решение моей задачи, его предложила сама документация по api. Но сначала о api. Чтобы начать работать с ним вам необходимо перейти в google console и выбрать нужный вам вариант api. После чего путь лежит лишь в документацию или на stackoverflow. Сразу скажу, русского варианта документации нет, уроков тоже нет. Желательно иметь минимальные знания английского языка или действовать методом тыка.
Выглядит это так. Вы заходите в google console, создаете свой проект и выбираете нужный API.
А теперь к решению проблемы. Во время чтения документации я нашел(google сам показал) сервис pubsubhubbub.appspot.com/subscribe он позволяет связать youtube и ваше приложение. Как работает? Работает по принципу webhook. Вы вставляете youtube канала, который хотите прослушать и каждый раз при каких либо действиях на канале(добавление видео, удаление, изменение) будите получать данные на свой скрипт.
Callback URL — скрипт, который будет принимать данные от google.
Topic URL — канал, который вы хотите прослушивать.
Ну и поле Mode позволяет выбрать, что вы хотите, подписаться или отписаться от прослушивания.
Приступим к написанию кода, для начала давайте настроим наш скрипт для работы с youtube. Я писал все в одном файле т.к. это был тест + кода там действительно мало. После того, как вы отправите запрос на подписку его нужно подтвердить. Погуглив, можно найти ответ на всеми любимом сайте, один из комментариев на stackoverflow подсказывает.
$video = "null";
if (isset($_GET['hub_challenge'])) { echo $_REQUEST['hub_challenge']; }
else { $video = parseYoutubeUpdate(file_get_contents('php://input')); }
function parseYoutubeUpdate($data) {
$xml = simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA);
$video_id = substr((string)$xml->entry->id, 9);
$channel_id = substr((string)$xml->entry->author->uri, 32);
$published = (string)$xml->entry->published;
return array(
'video_id'=>$video_id,
'channel_id'=>$channel_id,
'published'=>$published
);
}
Здесь мы создаем для удобства переменную в которой будет нужная нам инфа о видео. Две последующие строки, позволяют определить, есть ли возможность подтвердить запрос от pubsubhubbub, если да, то подтверждаем, если нет, то значит, что пришли данные от youtube и нам нужно их обработать. В функции parseYoutubeUpdate мы обрабатывает ответ, получаем всю нам нужную инфу.
Здесь стоит сделать отступление и рассказать о особом(на мой взгляд, могу ошибаться) виде данных, которым пользуется youtube(для ответов) он называется, как я понял, atom(не путать с IDE или это обычный xml… опыта с ним было мало). Выглядит он как-то так(небольшой кусок ответа от youtube):
<id>yt:video:eE5mpblYpdY</id>
<yt:videoId>eE5mpblYpdY</yt:videoId>
<yt:channelId>UCGqKr3O5ub-O7zEKx_qeHUQ</yt:channelId>
<title>20b3560a49 1080</title>
<link rel="alternate" href="https://www.youtube.com/watch?v=hgCQ378xNus"/>
<author>
<name>not Epic</name>
<uri>https://www.youtube.com/channel/UCGqKr3O5ub-O7zEKx_qeHUQ</uri>
</author>
<published>2019-07-14T05:10:49+00:00</published>
<updated>2019-07-14T05:11:07.600177664+00:00</updated>
Вернемся к parseYoutubeUpdate().
В функции мы преобразуем ответ в xml формат.
Записываем в переменные нужные нам данные.
А после возвращаем массив с этими данными.
Переходим к telegram. Для начала хочется сказать, это ****** как легче работать нежели с botman. Если вы хотите разрабатывать ботов только под telegram, то не пользуйтесь библиотеками, которые позволяют разрабатывать ботов под разные платформ…. в этом нет смысла… больше проблем будет. API telegram'a очень понятное и простое даже для новичка, который только познакомился с php и имеет минимальные знания ООП.
Так, ближе к делу, ближе к коду. Нам нужно создать бота и привязать его к нашему скрипту. Надеюсь, бота вы создать в состоянии. Записываем токен от бота и создаем запрос
const TOKEN = "6826815*******Yme99*****9kjzgVi*****3S******";
$url = 'https://api.telegram.org/bot' . TOKEN . '/sendMessage';
Теперь нам необходимо лишь отправить запрос на сервера telegram.
$params = [
'chat_id' =>712531723,
"text" => $linkVideo,
];
$url = $url . '?' . http_build_query($params);
Создаем необходимые параметры, для меня это id чата(если выводит на продакшен бота, то необходимо сохранять все id в БД чтобы спамить) и текстовое сообщение.
Как вы могли заметить, я передаю ссылку как простое сообщение, а не видео. Как я понял, телеграм передает видео лишь в том случае, если оно загружено на сервер, а иначе нет… + Мне необходимо видеть превью картинку для видео.
Теперь наш бот будет получать уведомления о выходе/редактирование видео. Выглядит это как-то так:
Game over. У меня все на этом. Самый большой недостаток этого кода в том, что он находится в одном файле, но кода на 10 строк для меня не имела смысла разделять.
Исходники — github.
Комментарии (13)
BogdanH
12.08.2019 10:36Чего вас так задевает, для написания скрипта в личном проекте автор может писать, КАК ЕМУ УГОДНО. Хабр — не коммисия по чистому коду, логика показана, подход показан, можете взять пример и написать по своему.
Автор, а API предостовляет доступ к комментам под видео?EpicLegend_gg Автор
12.08.2019 10:38API возможно, а вот сервис pubsubhubbub нет. Из API можно получить все данные о видео(как в админ панели youtube канала), но вот про комменты я не уверен.
dron88
12.08.2019 10:38Уважаемые коллеги, а может кто подобное на Python делал или встречал. Задача 1 в 1, написать смогу сам, но мало ли есть готовое решение, тем более я только учу Python.
P.S. Автору спасибо за идею.EpicLegend_gg Автор
12.08.2019 10:40Если только учишь, то лучше сам напиши, встретишь много нового. Если юзать библиотеку, то много упустишь. Работать будет, но не понятно как. =)
Сам так laravel изучал.
kruslan
Жесть какая… Лет 10 такого не видел.
EpicLegend_gg Автор
В каком плане?
demonarxs1
Он про качество кода… Уделите внимание мелочам… У Вас результат вызова функции передается в аргумент функции… Это можно вынести, и будет лучше. Затем, можно вынести условие… и сделать не однострочный if/else…
Уделите внимание мелочам. Наверно это подразумевалось.
Dromok
Ну это же вам не движок сайта. А для прикладных задач (боты, парсеры и т.д.) как раз такой подход и используется обычно.
vn_sten
Если для вас это «обычный подход», то вы сильно отстали от современного php.
Такой пример кода сойдёт показать другу, но не выкидывать на хабр
EpicLegend_gg Автор
В плане производительности есть разница? Если нет, то здесь вопрос лишь в читаемости, а эти споры никогда не закончатся.
Rastishka
А как сейчас принято писать условия?
Vitaly48
Для PHP так www.php-fig.org/psr/psr-2/#51-if-elseif-else
Rastishka
А, тогда согласен.
А то я думал эта дурь medium.com/edge-coders/coding-tip-try-to-code-without-if-statements-d06799eed231 добралась и до PHP.