Пишем groups-manager для vk.com. Часть 1



Введение.

У многих, наверное, есть группы или сообщества на сайте vk.com. Многое, для удобного администрирования предусмотрели разработчики: и статистика в удобном виде, и возраст аудитории, и забанить нерадивого юзера можно. Но вот что нельзя - так это просмотреть тех, кто нарушил правила (Первое правило Бойцовского клуба: не упоминать о Бойцовском клубе.) сообщества и вышел. Ведь их нужно забанить! Зачем? Объясню на примере. У нас есть небольшая группа, народ постоянно как вступает, так и выходит. В группе я оказываю некоторую бесплатную помощь людям, и вступая в сообщество, они подписываются под правилом - остаться в нём. Конечно же есть те, кто воспользовавшись помощью - вышел. Лично мне их категорически нужно забанить. Зачем? Народ постоянно прибывает, и те, кто когда-то вышел, могут зайти снова, воспользоваться и выйти. А нам оно надо? Конечно нет.

В статистике указано, сколько человек покинули сообщество, но не указано - кто. Когда в сообществе 100 человек - реально отследить вышедших и злостно покарать баном. Когда 200 - сложновато. А когда 1000 - почти невозможно. Покопавшись в подобном софте (который умеет с группами работать), ничего путнего я не нашёл. А если я не нашёл то, что мне требовалось - я это напишу :).

Определяемся с целью.

Показать, как разработать приложение, способное отслеживать, кто вышел и пришёл в группу, уведомлять об этом и банить автоматом тех, вышел. То есть сделаем то, о чём не позаботились разработчики vk, а что порой так нужно. Смысл в том, что я лишь покажу основной код, а все плюшки (вроде упоминалку из трее, время упоминания и файл настроек) - крутите вы сами. Ну или, если кому-то понадобится, выложу уже готовую, получившуюся у меня.

На чём пишем: Делфи.

К делу.

Алгоритм работы программы в 2-х пунктах:

1) При первой авторизации и указании группы, спарсить список всех пользователей и сохранить их в заданную дирректорию.

2) Далее, посапывая в трее, через указанный интервал просыпаться и сканировать пользователей. Сверять их с первоначальным листом. Изменения есть? Уведомлять! Кто-то ушёл? Банить! Кто-то пришёл? Ура. Все действия писать в журнал (если последний нужен пользователю). Ну и заменить исходный список на спарсенный заново, если есть изменения.

Вот и вся логика. Поехали.

Вы любите дизайн?

А я на него срал!

Стране нужны паровозы! Нам нужен металл!

Это говорит о том, что с формой я определюсь в последний момент. Пока пишем движок. Перейдём в код, там зададим небольшую процедурку:

function tuc: TStringList;
var
reg: TregExpr; //В uses - RegExpr. Переменная типа регулярных выражений (TregExpr).
mas_all: array [1..1000] of string; //Стринговый массив
i: integer;
s: string;
data, list_new: TStringlist; //Стринг-листы (говори массивы)
begin
{Всеобщая инициализация}
reg:= TregExpr.Create;
list_new:= TStringlist.Create;
data:= TStringlist.Create;
{Шлём запрос с функцией groups.getMembers}
data.Text:= http.Get('https://api.vk.com/method/groups.getMembers?group_id=ID_группы&sort=id_asc&offset=0&count=1000&v=5.5');
//Сортировка
    reg.InputString:= data.Text;  //Данные, где регулярить :)
    reg.Expression:= '[\d](.*?),'; // Регулярка
    if reg.Exec(data.Text) then
    repeat
      n:= n+1;
      mas_all[n]:= reg.Match[0]; //В массив кладём первое (оно и так одно) совпадение.
    until (not reg.ExecNext);
{удаляем запятые}
    for i := 1 to n do begin
      if pos(',', mas_all[i]) <> 0 then delete (mas_all[i], pos(',', mas_all[i]), 1);
    end;
{убираем 1-ую строку (в ней число, но оно обозначает не id пользователя, а количество участников)}
    for I := 1 to n do
      begin
        if i = n then break;
        mas_all[i]:= mas_all[i+1];
      end;
{записываем всё в StringList и присваиваем результат}
    for i := 1 to n-1 do
       list_new.Add(mas_all[i]);
    Result:= list_new;
end;


Начну с запроса. API-функция groups.getMembers возвращает список всех участников сообщества. Её параметры:

group_id - идентификатор сообщества
sort - сортировка пользователей (id_asc, id_desc, time_asc, time_desc. )
offset - смещение (укажете 100 - будет выводить, начиная с 100-ого пользователя)
count - количество (max - 100. затем ставим смещение на 1001 и выводим ещё 1000. И т.д.)

Запрос вернёт нам такой вид:

response: {
count: 279017,users: [4525, 4568, 4615, 4617, 4731, 4751, 4812, 4923, 5047, 5131]
}


Как понятно - надо парсить. Процесс парсинга и сортировки - закомментировал как мог.

Именно эта функция - основной костяк программы. Она будет получать самые свежие списки пользователей (а верней их (пользователей) ID).

Теперь сохраняем файл - я пока сделал отдельную кнопку, куда, на событие onclick разместил такой код:

var
  filee: TextFile;
  list: TStringlist;
  i: integer;
  path,s: string;
begin
list:= TstringList.Create;
if not form2.sd1.Execute then exit else path:= sd1.FileName;
AssignFile(filee, path);
Rewrite(filee);
list:= tuc; //Получаем в стринглист LIST данные, которые вернёт нам наша прекрасная функция, что выше.
 
for i := 1 to list.Count-1 do
  begin
    s:= list.Strings[i]; 
    writeln (filee, s);   //Записываем в файл  
  end;
CloseFile(filee);
end;


П.с: Переменную, в которой лежит путь, рекомендую сделать публичной. Т.к. загружать файл для сравнения нам ещё предстоит.

Всё, в файл запилили. Что дальше?
Дальше на 3-ю кнопку забиндим самое святое, что будет в программе - отлов вышедших и зашедших:

var
list_old, list_new: TStringlist;
  i: Integer;
  j,n,k,index: Integer;
  news,old: array[1..1000] of string;
  st: integer;
begin
list_old:= TStringList.Create;
list_new:= TStringlist.Create;
list_new:= tuc; //Получаем список юзеров группы
n:=0; k:=0; index:=0;
list_old.LoadFromFile(path); // Вот поэтому я и говорил - "Сохрани в публичную переменную ключ, мать твою!"
if list_old.Count = list_new.Count then ShowMessage('Изменений нет') else // Если выгруженный лист = только что полученному, то изменений нет
 
if list_old.Count < list_new.Count then //Если полученный>старого, то есть пополнение!
  begin
    MessageBox(handle, Pchar('Есть пополнение!'), Pchar('Ура!!'), mb_ok);
    for i := 0 to list_new.Count-1 do
    begin
      if Pos (list_new.Strings[i], list_old.Text) = 0 then
        begin
          k:= k+1;
          news[k]:= list_new.Strings[i]; //Запись всех тех, кто пришёл.
        end;
    end;
  end else
 
if list_old.Count > list_new.Count then //если же наоборот, то кто-то вышел.
  begin
    MessageBox(handle, Pchar('Есть вышедшие пользователи'), Pchar('Убить и изнасиловать!!'), mb_ok);
    for i := 0 to list_old.Count-1 do
    begin
      if Pos (list_old.Strings[i], list_new.Text) = 0 then
         begin
          k:= k+1;
          old[k]:= list_old.Strings[i]; //Запись в массив old всех тех, кто посмел выйти.
          data.Text:= http.Get('https://api.vk.com/method/groups.banUser?group_id=ID_группы&user_id=old[k]&reason=0&comment=totoje!&v=5.7&token=ТОКЕН'); //Забанили засранца
        end;
    end;
 
  end;
end;


В FormN.Create у меня прописана инициализация и создание idhttp:

http:= TidHTTP.Create(nil);
http.HandleRedirects:= true;
http.IOHandler:= form2.IdSSLIOHandlerSocketOpenSSL1;


Собственно всё - это и есть основной код, движок, программки. Я, для своей, планирую допилить удобную оповещалку, файл настроек и конечно же оптимизировать код (синзронизировать всё между собой). Как закончу - выложу, может кому пригодится.

Спасибо за внимание.
Теги:
вышел, нужно, пишем, забанить, когда, Зачем, последний, сообщества, постоянно, человек, группы, нужен, Когда, пришёл, нашёл, Конечно, сообщество, указано, пользователей, список
Добавлено: 24 Февраля 2015 21:13:57 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...