Работа с капчей Редактировано: 28.08.2020 в 04:45
При работе с API ВКонтакте очень часто может возникнуть непредвиденная ошибка "картинки смерти". Это - капча. Когда Ваш скрипт отправляет по одному access_token'у слишком много запросов секунду, то сервер ВКонтакте приостанавливает его активность до тех пор, пока Вы не докажете, что Вы - не бот. Такая ошибка возникнет только при работе с токеном пользователя, в других ситуациях сервер ВКонтакте попросту временно заморозит Ваш токен.
После того, как сервер ВКонтакте "замораживает" токен пользователя, на любой его запрос будет возвращаться ошибка капчи. В этой ошибке имеются данные для решения капчи, основное - это SID
капчи (ID капчи, прикрепленный к текущей сессии, токену), и URL
капчи (URL адрес картинки капчи, переходя по которому скрипт сервера ВКонтакте автоматически сгенерирует изображение капчи с буквами)
Чтобы решить капчу, необходимо просто в любом следующем запросе отправить такие параметры, как captcha_sid
, captcha_key
(текст с картинки). Если все верно, то запрос будет выполнен.
Я знаю, что это достаточно неудобно - контролировать все запросы на наличие этих параметров, ведь бывает так, что сразу два запроса выполняются асинхронно. Именно поэтому в EasyVK с недавних пор существует новая настройка - captchaHandler, которая помогает ловить капчу и автоматически ее решать
# captchaHandler
Так как все запросы при работе с Easy VK происходят через метод vk.call()
, то внутри него имеется основной хендлер - он отвечает за обработку всех ошибок внутри запроса. Это он распознает, какая именно произошла ошибка. И, если произошла ошибка капчи, он попробует запустить captchaHandler для ее решения.
captchaHandler - это просто функция, которая вызывается каждый раз, когда происходит ошибка капчи. В нее передается одним параметром следующий объект
{
captcha_sid, // SID текущей капчи
captcha_img, // URL адрес капчи
resolve, // Callback функция для решения капчи resolve(key){...}
vk // Объект EasyVK для работы в разной области видимости
}
Чтобы задать captchaHandler
, необходимо добавить эту настройку в объект настройки Easy VK.
function captchaHandler ({captcha_sid, captcha_img:url, resolve:solve}) {
// В этой функции Вы решаете капчу любым удобным Вам способом
console.log(`Ой.. Надо решить капчу, URL = ${url}`)
/*
ПСЕВДОКОД:
getCaptcha(url).then(key => {
// Получили текст с картинки с помощью Вашего алгоритма
solve(key).then(() => {
console.log('Капча решена')
}).catch(({err, reCall}) => {
// Капча не решена, пробуем снова
reCall()
});
})
*/
}
easyvk({
captchaHandler: captchaHandler
}).then((vk) => {
//...
}).catch(console.error)
Когда вы получите текст с картинки каким-либо способом, запустите callback функцию resolve
(из основных параметров captchaHandler), которая возвращает объект <Promise>. Если капча не решена, в reject
функцию этого Promis'а вернется следующий объект
{
err, // Ошибка и ее описание
reCall, // Функция для повторного запуска captchaHandler
vk // Объект EasyVK
}
Ниже я привел пример рабочего кода, когда капча ловится автоматически и скрипт запрашивает ввести код капчи в консоль.
const readline = require('readline')
const easyvk = require('easyvk')
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
const captchaHandler = ({captcha_sid, captcha_img, resolve:solve, vk}) => {
rl.question(`Введите капчу для картинки ${captcha_img} `, (key) => {
// Когда вводится капча в консоль, пробуем решить капчу
solve(key).then(() => {
console.log('Капча решена корректно!')
}).catch(({err, reCall: tryNewCall}) => {
// Иначе капча не решена, стоит попробовать снова
console.log('Капче не решена!!!\nПробуем занова')
tryNewCall() // Пробуем снова, занова запускаем наш captchaHandler, по факту...
// Не стоит самостоятельно перезапускать функцию captchaHandler, так как в EasyVK
// для этого имеется функция reCall, которая точно запустит все как нужно
})
})
}
easyvk({
captchaHandler: captchaHandler
}).then(vk => {
// пример: vk.call('messages.send', ...)
}).catch(console.error)
С версии 2.6.0 captchaHandler
работает также с HTTP Клиентом