Discord Бот
Введение
Стандартным способом использования API является использование ключа API с предоставленным SDK для конкретного сервиса. Однако иногда мы хотим получить доступ к "закрытым конечным точкам API", которые недоступны. Вот почему возникает необходимость в обратном инжиниринге официального клиента, который может быть приложением или веб-сайтом, чтобы найти конечные точки API и повторить запросы, как если бы мы были клиентом.
Discord
Недавно я подписался на канал Discord и хотел бы получать уведомления в Telegram, когда появляется новое сообщение. Причина для проксирования с Discord в Telegram заключается в том, что я чаще проверяю Telegram. Кроме того, канал Discord доступен только для подписчиков, и я хотел бы автоматически делиться сообщениями, которые я получаю, в Telegram-группе.
Я начал с чтения документации на веб-сайте https://discord.com/developers/docs/resources/channel. Документация была предназначена только для Discord Ботов. Проблема заключалась в том, что я не мог добавить своего бота в канал Discord, который я хотел скрэпить. Это оставило мне только один вариант - использовать свою собственную учетную запись, хотя есть риск ее блокировки (https://support.discord.com/hc/en-us/articles/115002192352-Automated-user-accounts-self-bots-).
С чего начать: веб-приложение или приложение для настольного компьютера?
Я вспомнил, что у Discord есть веб-приложение, и с использованием Google Chrome всегда легче отслеживать вкладку "Сеть" с помощью встроенных инструментов разработчика. После входа в систему я перешел в канал, который хотел спарсить. Во вкладке "Сеть" отображаются следующие запросы. Запрос messages?limit=50
кажется немного интересным. При нажатии на него отображается ответ в формате JSON, отправленный сервером.
Кажется, это то, что мы ищем! Если мы сможем повторить этот эндпоинт и получить ответ, то можем быть достаточно уверены, что парсинг будет работать.
Для этого нам нужно посмотреть, что отправляется на сервер Discord при отправке запроса. Мы видим, что эндпоинт /api/v8/channels/<channelID>/messages?limit=50
запрашивается с некоторыми дополнительными заголовками. Authorization: mfa._Xf1ZjwM31....
похоже на то, что обычно используется веб-серверами для аутентификации пользователя.
Создадим простую команду curl, чтобы попробовать ее протестировать. И действительно, мы получаем ответ, содержащий объект JSON с последними сообщениями!
curl https://discord.com/api/v8/channels/<channelID>/messages?limit=50 -H "Authorization: mfa._Xf1ZjwM3l..."
Следующим шагом будет настройка планировщика, который будет запускаться каждую минуту или около того, чтобы опрашивать эндпоинт. Логика для получения последнего сообщения проста. Мы сохраняем локальную переменную с последним идентификатором latestId
. Сравнивая первый элемент в ответе JSON response[0].id
, если есть несоответствие, мы знаем, что сообщение новое. Затем мы обновляем latestId
на response[0].id
и продолжаем опрос.
Ограничения
Хотя у меня не возникло никаких проблем с этим методом после недели использования, токен может истечь через определенное время. Но я думаю, что Discord продлит срок действия токена, если он будет активен. Таким образом, обычный пользователь не будет выходить из системы, если он постоянно находится в сети.
API-точка доступа также может измениться в будущем, но на данный момент я очень доволен этим простым подходом.