Уже достаточно долгое время Яндекс предоставляет бесплатный сервис обнаружения спама в сообщениях под названием «Яндекс.Чистый Веб», однако до сих пор он остаётся малопопулярным.
В этом посте я продемонстрирую основные методы работы с API «Яндекс.Чистый Веб» на примере простого PHP-класса.
Итак, сервис поддерживает четыре метода — обнаружение спама, получение CAPTCHA, проверка введённой CAPTCHA и обжалование решения детектора спама. Мы рассмотрим работу с первыми тремя методами.
Для удобства оформим всё это в виде простого статического класса.
Приступим к реализации методов класса. API «Чистого Веба» принимает GET и POST запросы в зависимости от необходимого метода, и отдаёт результат в формате XML. Поэтому сперва мы напишем в нашем классе несложный приватный метод для отправки запросов и чтения ответов. Будем использовать SimpleXML для чтения ответов, а вот CURL применять не станем — благо, стандартная функция file_get_contents позволяет совершать и GET- и POST-запросы с помощью контекстов.
Этот метод существенно упростит нам работу с API — он автоматически подставляет ключ, формирует контекст для file_get_contents, если нам понадобится сделать POST-запрос, а также возвращает ответ уже в виде объекта SimpleXML. Думаю, код не нуждается в более подробном комментировании. Так что перейдём непосредственно к методам для работы с API.
В первую очередь реализуем метод для отправки содержимого сообщения Яндексу и последующей проверки его на спам. Однако перед тем, как просто привести код, следует кое-что уточнить. Согласно описанию метода check-spam, он может принимать следующие параметры, касающиеся содержимого сообщения:
Набор отправляемых на проверку данных может быть произвольным, за исключением того, что из семейства параметров body и subject может быть указан лишь один тип — или plain, или html, или bbcode. Обязательных параметров также нет. Поэтому передавать все эти данные нашему методу мы будем не идущими последовательно параметрами, а одним массивом с произвольным набором данных.
Данный метод позволит нам отправлять данные на проверку с автоматической подстановкой IP-адреса пользователя. В зависимости от второго параметра, функция может возвращать либо просто true или false, либо массив с подробной информацией, содержащий список ссылок, заподозренных как спамерские, а также сгенерированный Яндексом id запроса. Он нам, кстати, далее пригодится.
Яндекс предлагает нам воспользоваться его собственной «капчей» и надо сказать, что у этого решения есть очевидные плюсы — во-первых, снижается нагрузка на наш сервер, а во-вторых, забота о «взломоустойчивости» CAPTCHA ложится на плечи «Яндекса». Метод будет предельно простым:
Как видно из предпоследней строки, метод возвращает ID «капчи» и ссылку на само изображение.
Ссылка, как правило, имеет следующий вид:
u.captcha.yandex.net/image?key=CAPTCHA ID
Лучше использовать оба выдаваемых параметра, чтобы защита не сломалась, если Яндекс что-нибудь изменит в формате ссылки.
Наконец, третий метод класса будет использоваться для проверки введённого пользователем значения CAPTCHA.
Чтобы им воспользоваться, нам надо будет передать ему id «капчи», выданный предыдущим методом, а также то, что ввёл пользователь. Не лишним будет также передать и id запроса, который мы получили, когда отправляли сообщение на проверку, однако это необязательно.
Для полноценной проверки системы «Чистого Веба» можно загрузить простой демонстрационный скрипт. Перед проверкой не забудьте получить свой ключ API «Чистого Веба» и указать его в скрипте!
Можно также скачать класс отдельно или посмотреть его полный код в браузере.
Проверка содержимого формы:
Большинство параметров при вызове методов API являются необязательными.
Например, можно не использовать проверку на спам, а просто подключить себе CAPTCHA «Яндекса», аналогично тому, как подключают ReCAPTCHA.
Подробнее — на api.yandex.ru.
В этом посте я продемонстрирую основные методы работы с 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=CAPTCHA ID
Лучше использовать оба выдаваемых параметра, чтобы защита не сломалась, если Яндекс что-нибудь изменит в формате ссылки.
Проверка 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';
// Отправляем данные формы на проверку
$allowed_keys = array('email', 'name', 'login', 'realname', 'subject-plain', 'body-plain');
$post_data = array_intersect_key($_POST, array_fill_keys($allowed_keys, null));
$is_spam = YandexCW::is_spam($post_data, true);
// Выводим итоги проверки
var_dump($is_spam);
Особенности
Большинство параметров при вызове методов API являются необязательными.
Например, можно не использовать проверку на спам, а просто подключить себе CAPTCHA «Яндекса», аналогично тому, как подключают ReCAPTCHA.
Подробнее — на api.yandex.ru.