Уже достаточно долгое время Яндекс предоставляет бесплатный сервис обнаружения спама в сообщениях под названием «Яндекс.Чистый Веб», однако до сих пор он остаётся малопопулярным.
В этом посте я продемонстрирую основные методы работы с API «Яндекс.Чистый Веб» на примере PHP-класса.
Итак, сервис поддерживает четыре метода — обнаружение спама, получение CAPTCHA, проверка введённой CAPTCHA и обжалование решения детектора спама. Мы рассмотрим работу с первыми тремя методами.
Для удобства оформим всё это в виде простого статического класса.
- class YandexCW
- {
- public static $api_key = '12345';
- /* URL-адреса */
- const check_data_url = 'http://cleanweb-api.yandex.ru/1.0/check-spam';
- const get_captcha_url = 'http://cleanweb-api.yandex.ru/1.0/get-captcha';
- const check_captcha_url = 'http://cleanweb-api.yandex.ru/1.0/check-captcha';
- }
Приступим к реализации методов класса. API «Чистого Веба» принимает GET и POST запросы в зависимости от необходимого метода, и отдаёт результат в формате XML. Поэтому сперва мы напишем в нашем классе несложный приватный метод для отправки запросов и чтения ответов. Будем использовать SimpleXML для чтения ответов, а вот CURL применять не станем — благо, стандартная функция file_get_contents позволяет совершать и GET- и POST-запросы с помощью контекстов.
- /* Отправка запроса сервису */
- private function xml_query($url, $parameters = array(), $post = false)
- {
- if (!isset($parameters['key'])) $parameters['key'] = self::$api_key;
- $parameters_query = http_build_query($parameters);
- if ($post)
- {
- $http_options = array(
- 'http' => array (
- 'method' => 'POST',
- 'content' => $parameters_query
- )
- );
- $context = stream_context_create($http_options);
- $contents = file_get_contents($url, false, $context);
- } else $contents = file_get_contents($url.'?'.$parameters_query);
- if (!$contents) return false;
- $xml_data = new SimpleXMLElement($contents);
- return $xml_data;
- }
Этот метод существенно упростит нам работу с API — он автоматически подставляет ключ, формирует контекст для file_get_contents, если нам понадобится сделать POST-запрос, а также возвращает ответ уже в виде объекта SimpleXML. Думаю, код не нуждается в более подробном комментировании. Так что перейдём непосредственно к методам для работы с API.
Проверка сообщения на спам
В первую очередь реализуем метод для отправки содержимого сообщения Яндексу и последующей проверки его на спам. Однако перед тем, как просто привести код, следует кое-что уточнить. Согласно описанию метода check-spam, он может принимать следующие параметры, касающиеся содержимого сообщения:
- ip — IP-адрес отправителя.
- email — Адрес электронной почты отправителя.
- name — Имя отправителя, отображаемое в подписях к сообщениям.
- login — Имя учетной записи пользователя на ресурсе.
- realname — ФИО пользователя взятые, например, из его регистрационных данных.
- subject-plain — Тема поста в формате text/plain.
- subject-html — Тема поста в формате text/html.
- subject-bbcode — Тема поста в формате BBCode.
- body-plain — Содержимое (тело) комментария или поста в формате text/plain.
- body-html — Содержимое (тело) комментария или поста в формате text/html.
- body-bbcode — Содержимое (тело) комментария или поста в формате BBCode.
Набор отправляемых на проверку данных может быть произвольным, за исключением того, что из семейства параметров body и subject может быть указан лишь один тип — или plain, или html, или bbcode. Обязательных параметров также нет. Поэтому передавать все эти данные нашему методу мы будем не идущими последовательно параметрами, а одним массивом с произвольным набором данных.
- /* Проверка на спам */
- public function is_spam($message_data, $return_full_data = false)
- {
- if (!isset($message_data['ip'])) $ip = $_SERVER['REMOTE_ADDR'];
- $response = self::xml_query(self::check_data_url, $message_data, true);
- $spam_detected = (isset($response->text['spam-flag']) && $response->text['spam-flag'] == 'yes');
- if (!$return_full_data) return $spam_detected;
- return array(
- 'detected' => $spam_detected,
- 'request_id' => (isset($response->id))? $response->id : null,
- 'spam_links' => (isset($response->links))? $response->links : array()
- );
- }
Данный метод позволит нам отправлять данные на проверку с автоматической подстановкой IP-адреса пользователя. В зависимости от второго параметра, функция может возвращать либо просто true или false, либо массив с подробной информацией, содержащий список ссылок, заподозренных как спамерские, а также сгенерированный Яндексом id запроса. Он нам, кстати, далее пригодится.
Получение CAPTCHA
Яндекс предлагает нам воспользоваться его собственной «капчей» и надо сказать, что у этого решения есть очевидные плюсы — во-первых, снижается нагрузка на наш сервер, а во-вторых, забота о «взломоустойчивости» CAPTCHA ложится на плечи «Яндекса». Метод будет предельно простым:
- /* Получение CAPTCHA */
- public function get_captcha($id = null)
- {
- $response = self::xml_query(self::get_captcha_url, array('id' => $id));
- if (!$response || !isset($response->captcha)) return false;
- return array('captcha_id' => $response->captcha, 'captcha_url' => $response->url);
- }
Как видно из предпоследней строки, метод возвращает ID «капчи» и ссылку на само изображение.
Ссылка, как правило, имеет следующий вид:
u.captcha.yandex.net/image?key=ID_CAPTCHA
Лучше использовать оба выдаваемых параметра, чтобы защита не сломалась, если Яндекс что-нибудь изменит в формате ссылки.
Проверка CAPTCHA
Наконец, третий метод класса будет использоваться для проверки введённого пользователем значения CAPTCHA.
Чтобы им воспользоваться, нам надо будет передать ему id «капчи», выданный предыдущим методом, а также то, что ввёл пользователь. Не лишним будет также передать и id запроса, который мы получили, когда отправляли сообщение на проверку, однако это необязательно.
- /* Проверка CAPTCHA */
- public function check_captcha($captcha_id, $captcha_value, $id = null)
- {
- $parameters = array(
- 'captcha' => $captcha_id,
- 'value' => $captcha_value,
- 'id' => $id
- );
- $response = self::xml_query(self::check_captcha_url, $parameters);
- return isset($response->ok);
- }
Примеры использования
Для полноценной проверки системы «Чистого Веба» можно загрузить простой демонстрационный скрипт. Перед проверкой не забудьте получить свой ключ API «Чистого Веба» и указать его в скрипте!
Можно также скачать класс отдельно или посмотреть его полный код в браузере.
Проверка содержимого формы:
- // Вызываем класс и задаём свой ключ API
- require('YandexCW.class.php');
- YandexCW::$api_key = '12345';
- // Отправляем данные формы на проверку
- $post_data = array(
- 'email' => (isset($_POST['email']))? $_POST['email'] : null,
- 'name' => (isset($_POST['name']))? $_POST['name'] : null,
- 'login' => (isset($_POST['login']))? $_POST['login'] : null,
- 'realname' => (isset($_POST['realname']))? $_POST['realname'] : null,
- 'subject-plain' => (isset($_POST['subject']))? $_POST['subject'] : null,
- 'body-plain' => (isset($_POST['body']))? $_POST['body'] : null
- );
- $is_spam = YandexCW::is_spam($post_data, true);
- // Выводим итоги проверки
- var_dump($is_spam);
Особенности
Большинство параметров при вызове методов API являются необязательными.
Например, можно не использовать проверку на спам, а просто подключить себе CAPTCHA «Яндекса», аналогично тому, как подключают ReCAPTCHA.
Подробнее — на api.yandex.ru.
Автор: empr