24 February 2011

Автоматическая фильтрация комментариев в Livejournal при помощи XML-RPC

PHP
В этой статье я расскажу о том, как при помощи XML-RPC получать информацию о комментариях к своим постам в ЖЖ, и даже немножечко их удалять.

Изначально скрипт писался в связи с ситуацией в ЖЖ Навального, где неизвестный бот тысячами постит одно и то же сообщение, мешая развитию дискуссии в комментариях. Я не вполне разделяю его точку зрения (и уж точно не отношусь к его фанатам), но мне дорога свобода слова в интернете, так что я потратил некоторое время на изучение возможностей по обработке комментариев скриптом.

Каждая запись в Livejournal имеет уникальный id (jitemid), не повторяющийся в пределах одного журнала. Это обычный автоинкрементный идентификатор, но в URL записи он не фигурирует непосредственно. Вместо него используется ditemid, вычисляемый по следующей формуле:

ditemid = 256*jitemid + anum

Здесь anum — случайное число от 0 до 255, заданное единожды при создании поста и хранящееся вместе с информацией о нем.

Та же методика применяется и к комментариям, за исключением того, что anum у них не свой, а берется из поста. Соответствующие параметры комментариев назваются jtalkid и dtalkid.

Протокол XML-RPC, применительно к ЖЖ, описан здесь. Используя метод getevents, мы можем получить все записи в журнале (я забираю последние n записей, для этого надо указать параметры selecttype=lastn и howmany=n). Информация о записях, полученных таким способом, содержит itemid(=jitemid) и anum — как раз то, что мы и хотели получить. Также передается reply_count — число комментариев к записи. Кстати, указывая явно userjournal, можно получить доступные вам записи из любого журнала (включая подзамочные, если вы включены в список друзей).

Переходим непосредственно к комментариям. Тут нас подстерегает облом. Судя по описанию протокола, никаких методов для работы с комментариями нет.

К счастью, чтение исходников позволяет нам найти нужные методы в коде обработчика протокола (use the force, read the source!). Оказывается, там вообще много интересного:

my %HANDLERS = (
login => \&login,
getfriendgroups => \&getfriendgroups,
getfriends => \&getfriends,
friendof => \&friendof,
checkfriends => \&checkfriends,
getdaycounts => \&getdaycounts,
postevent => \&postevent,
editevent => \&editevent,
syncitems => \&syncitems,
getevents => \&getevents,
editfriends => \&editfriends,
editfriendgroups => \&editfriendgroups,
consolecommand => \&consolecommand,
getchallenge => \&getchallenge,
sessiongenerate => \&sessiongenerate,
sessionexpire => \&sessionexpire,
getusertags => \&getusertags,
getfriendspage => \&getfriendspage,
getinbox => \&getinbox,
sendmessage => \&sendmessage,
setmessageread => \&setmessageread,
addcomment => \&addcomment,
checksession => \&checksession,
getrecentcomments => \&getrecentcomments,
getcomments => \&getcomments,
delcomments => \&delcomments,
screencomments => \&screencomments,
unscreencomments => \&unscreencomments,
freezecomments => \&unfreezecomments,
editcomment => \&editcomment,
);

Для наших целей пригодятся getcomments и delcomments.

Чтобы получить комментарии к посту при помощи getcomments, передаем ему следующее: ditemid (идентификатор нашего поста), journal (журнал, в котором размещен этот пост, например, navalny), page (номер страницы комментариев). Если мы не хотим разворачивать треды, указываем expand_strategy=mobile_thread. Как и в случае getevents, мы можем получить любые комментарии, доступные нам. В ответ нам придет массив комментариев первого уровня. Если на комментарий есть ответы, они прикрепляются к нему в виде массива.

Далее нам остается только пройтись по всем страницам комментариев, а на страницах — по всем доступным комментариям, и проверить их. Я использовал просто стоп-слово, но проверить можно все, что угодно, вплоть до даты регистрации автора (понадобится отдельный запрос по каждому). Выбранные dtalkid передаем методу delcomments (дополнительный параметр recursive позволяет удалять весь тред целиком). Вуаля! У нас чистенький журнал!

Исходники скрипта на PHP можно посмотреть на GitHub.

Я благодарен авторам этого и этого за ценную информацию.
Tags:livejournalxml-rpcphpфильтрация спама
Hubs: PHP
+55
2.4k 48
Comments 22
Popular right now
Middle PHP developer (удалённо)
from 120,000 ₽BoxberryRemote job
Веб-разработчик php (1с-Битрикс)
from 35,000 to 50,000 ₽Пластилин-АртКурскRemote job
PHP-разработчик
from 40,000 to 60,000 ₽Dota2.ruRemote job
PHP-разработчик
from 120,000 ₽iCharRemote job
PHP разработчик
to 110,000 ₽Sportmaster LabМоскваRemote job