Code Monkey home page Code Monkey logo

uolbot's Introduction

NOME

UOLbot - interface Perl para bate-papo do UOL

PLATAFORMAS SUPORTADOS

Teoricamente, todos onde roda o perl. Oficialmente, foi testado em:

  • Linux (perl 5.6.1)

  • Windows (ActivePerl 5.6.1 Build 632)

RESUMO

#!/usr/bin/perl
use UOLbot;

my $bot = new UOLbot (Nick => 'uolbot');

$bot->login ('batepapo4.uol.com.br:3999');
$bot->send ("Hello World!");
$bot->logout;

exit;

DESCRIÇÃO

O UOLbot é um módulo Perl que implementa interface para webchat (batepapo) do UOL (http://www.uol.com.br/). Basicamente, a idéia é poder acessar as funções comunicativas do chat de fora do navegador. No caso, à partir de um programa escrito em Perl. Um detalhe em destaque: a intenção é implementar interface completa. Por exemplo, clientes tais como Jane, UOLME e Chat-Nóia 666 implementam só um pouco à mais do que parte interativa. "O grosso" do trabalho em tais clientes é feito pelas DLLs do Internet Explorer. Já o UOLbot é independente de Internet Explorer assim como é independente do Windows como todo.

Então, conforme o próprio nome diz, você pode escrever bots de propaganda (robôs de propaganda que andam de sala em sala enchendo o saco das pessoas) utilizando UOLbot. Você também pode fazer algo útil como o primeiro cliente de batepapo UOL que seja cross-platform. Fiz de tudo para tais tarefas sejam mais simplificadas possíveis, apenas repare no exemplo acima ;)

Bom, qualquer coisa, esse projeto está quase sempre em expansão. Comecei aplicando uma engenharia reversa para saber como o Microsoft Internet Explorer 6.0 interage com servidores do UOL (sim, a lógica de operação é do IE do começo ao fim), e atualmente tenho em mãos um módulo orientado à objetos (híbrido, para ser honesto) que faz virtualmente tudo o que você faria num webchat.

Obs: antes que me pergunte, "eu estou lendo em português aqui, então por que send e não enviar, ou logout ao invés de sair?" A razão é simples: o "resto" do perl está em inglês, certo? Por mim, fica estranho ler e entender o que faz algo como

next if $bot->enviar and not scalar $bot->usuarios;

INTRODUÇÃO

Agora, o princípio ativo. Antes de tudo, você deve criar uma instância do bot:

my $bot = new UOLbot (Nick => 'uolbot');

O parâmetro Nick especifica o nickname do bot. Você pode passar outros, que serão descritos posteriormente. Você também pode não passar nenhum, aí o seu bot será um discreto "unnamed". Você pode ter várias instâncias, só não sei qual o sentido disso. Vários robôs para várias salas em um só programa?

Pronto, você criou o seu bot... E agora? Ele deve entrar numa sala, né?

$bot->login ('batepapo4.uol.com.br:3999');

(ótima sala para propaganda, eheheh) Aí você passa a URL da sala. É o único parâmetro necessário. É claro que ter que saber essa URL é um pé no saco, você pode entrar na sala só sabendo o seu nome/número. Mas isso é para depois.

Opa, mas espere um pouco. Você já deve ter percebido aqueles códigos de verificação anti-spam, né (antes não existia isso não)... O que fazer agora? NADA. Lhes apresento orgulhosamente o UOL::OCR!!! É um sub-componente composto por filtros digitais de imagem e um programa de OCR (Optical Character Recognition), atualmente o jocr (http://jocr.sourceforge.net). Tal componente trata dos códigos de verificação para você, e aparentemente muito bem ;)

Bom, e estando na sala, o que fazer? Falar!

$bot->send ("Hello World!");

"Oi mundo" :P Sem comentários aqui.

Quando você "falou" tudo o que quis, tchau para todos!

$bot->logout;  

Isso é o básico. Se não entendeu, pare por aqui.

REQUISITOS

  • LWP - The World-Wide Web library for Perl (libwww-perl)

  • Image::Magick (opcional)

CONSTRUTOR

new ([ARGS])

Construtor para o bot. Retorna a referência para objeto UOL::bot. Argumentos ARGS devem ser passados em forma:

new (Chave1 => 'valor1',
     Chave2 => 2);

Note que alguns dos argumentos você poderá alterar posteriormente com métodos apropriados, e outros não. Argumentos válidos (todos opcionais):

UA

referência para objeto LWP::UserAgent externo (é criada instância interna por default)

Nick

o nickname (valor default é "unnamed")

Color

a cor do nickname (valor default é 0)

Obs: valores possíveis são:

0 - Preto
1 - Vermelho
2 - Verde
3 - Azul
4 - Laranja
5 - Cinza
6 - Roxo
Avatar

define "carinha" na frente do nick (número inteiro, para ser descoberto na tentativa e erro :(

Obs: a "carinha" só vai aparecer se você for autenticado com auth!

Obs2: pra tirar a "carinha" já definida, chame $bot->avatar (-1).

Fast

se setado em 1 faz UOLbot pular passos desnecessários de autenticação/login na sala. Pode fazer diferença em conexões lentas, porém pode gerar incompatibilidades, cuidado ao usar!

Tries

número de tentativas para processar/reentrar código de verificação. Tenha em mente que o OCR embutido pode errar para algum tipo de fonte/fundo/texto, porém quem sabe se na próxima ele acerta? Default é 3.

Auth_Magic

preconfigura o cookie mágico que UOL utiliza para saber se o usuário é registrado. Uma boa idéia é não tocar nisso, se quiser experimentar, primeiro dê um auth com login/senha válidos, depois dê um

print $bot->auth_magic, "\n";

depois copie o que for impresso e cole no

my $bot = new UOLbot (Auth_Magic => ...);
ImgCode_Handler

referência para a rotina que vai processar a imagem com código de verificação. A minha sugestão é que você não toque nisso. O default é tentar carregar um OCR aqui, se falhar, então a URL da imagem com código de verificação é impressa e você (usuário) tem que ler/digitar... Argh. De qualquer forma, a sintaxe é:

ImgCode_Handler => \&my_imgcode_handler
...
sub my_imgcode_handler {
   my ($req, $ua) = @_;
   # $req é istância HTTP::Request
   # $ua é instância LWP::UserAgent
   my $resp = $ua->request ($req);
   ...
   return $code;
}

No caso:

$req é instância HTTP::Request da imagem-código $ua é instância LWP::UserAgent atualmente usada pelo UOLbot $code é código de 4 caracteres [a-z0-9]

Listen_Handler

referência para a rotina que vai processar as informações recebidas da sala (indefinido por default). Por exemplo:

Listen_Handler => sub { print $_[0] }

imprime qualquer coisa recebida e

Listen_Handler => \&listen_handler
...
sub listen_handler {
   my $data = shift;
   ...
   return;
}

define a sub-rotina listen_handler como handler de 'escuta'. Nesse caso, variável $data recebe pacotes com código HTML recebidos.

Obs: lembre que nem sempre há uma mensagem em um pacote. O servidor (ou buffer do sistema operacional) pode juntar vários pacotes num só.

MÉTODOS

Os métodos do UOLbot são:

ua
nick
color
avatar
fast
tries
auth_magic
imgcode_handler
listen_handler

Métodos para ler/definir os parâmetros definidos pelo new.

Obs: Você pode ler os valores a qualquer momento, mas só poderá definir quando a instância não estiver logada com login!

list_subgrp (SUBGRP)

Enumera as salas de bate-papo de um sub-grupo SUBGRP. O tal sub-grupo é o documento onde nomes das salas, suas URLs e suas lotações são fornecidos. list_subgrp é simplesmente uma interface para esse documento. Parâmetro SUBGRP é uma string com URL de formato 'http://batepapo.uol.com.br/bp/excgi/salas_new.cgi?ID=idim_he.conf' ou então simplesmente 'idim_he.conf'. Os dois são equivalentes. Quando você usa list_subgrp antes de login, SUBGRP é salvo e utilizado como REF de login automaticamente. O método retorna um array de hashes se tiver sucesso e () se houver falha. O array retornado pode ser expandido com:

my @room = $bot->list_subgrp ('idim_he.conf');
foreach $room (@room) {
   print $room->{URL}, "\n",
         $room->{Title}, "\n",
         $room->{Load}, "\n\n";
}

onde URL é a URL da sala de bate-papo, Title é o título dela e Load é o número de pessoas na sala (0-40, -1 significa "sala lotada").

search (STRING)

Busca por usuário com STRING contido no nickname em todas as salas. Retorna () caso nenhum seja encontrado ou array semelhante ao do list_subgrp:

my @room = $bot->search ('uolbot');
foreach $room (@room) {
   print $room->{Nick}, "\n",
         $room->{URL}, "\n",
         $room->{Title}, "\n",
         $room->{Load}, "\n\n";
}

Onde Nick refere o nickname completo do usuário encontrado, URL é o endereço da sala onde o usuário atualmente se encontra, Title é o título da mesma (cortado, foi mal) e Load é quantidade de pessoas presentes na mesma sala.

brief (ROOM)

"Espia" na sala sem entrar nela. Retorna 0 se falha. Caso tiver sucesso,

  1. guarda a lista com nomes de usuários para depois ser vista com users

  2. passa o fragmento da conversa para rotina definida em Listen_Handler

  3. retorna 1

auth ([USER, PASS])

Autentica usuário registrado. Permite entrar nas salas com mais de 30 pessoas e usar "carinha" na frente do nick. USER é o nome de usuário em forma '[email protected]' e PASS é a senha. Agora, o mais velho hack de sistema de chat... Omita USER e PASS e terás todos os privilégios de um usuário registrado sem ser um ;)

Retorna 0 se houver falha (username/senha inválidos) e 1 se tiver sucesso.

Obs: você deve autenticar antes de efetuar login!

Obs2: auth utiliza conexão encriptada via SSL automaticamente quando o módulo Crypt::SSLeay é encontrado no sistema. Sem esse módulo, a conexão efetuada é insegura e a senha pode ser vista por pessoas mal-intencionadas! Duvido muito, mas o que custa fazer direito?!

login (ROOM [, REF])

Efetua login na sala ROOM de bate-papo. Chama internamente imgcode_handler. Parâmetro ROOM consiste de uma string de formato "http://batepapo4.uol.com.br:3999/". Se você for preguiçoso como eu, pode usar "batepapo4.uol.com.br:3999" apenas. Parâmetro REF, opcional, é o Referer, o documento que continha o link para ROOM. Se você omitir o REF, valor 'http://batepapo.uol.com.br/bp/excgi/salas_new.shl' será usado automaticamente. Se você estiver usado list_subgrp ou search antes de login, a URL de sub-grupo listado será usada como REF. Leia mais sobre list_subgrp/search.

Retorna 0 se houver falha e 1 se tiver sucesso. A "falha" mais provável é que a sala esteja cheia. Utilize o login_error para obter mais detalhes sobre a falha ocorrida.

is_logged

Retorna não-0 se o bot estiver atualmente numa sala de bate-papo e 0 caso contrário.

Detalhes Técnicos: Para ser exato, retorna o número de tentativas de efetuar a verificação.

encode

Retorna a parte "encriptada" da URL da última imagem processada contendo código de verificação.

decode

Retorna o código lido.

is_auth

Retorna 1 se o bot estiver autenticado como usuário registrado do UOL.

login_error

Retorna o código do erro durante login:

0     - sucesso
1     - nickname já foi utilizado
2     - sala está cheia
3     - código de verificação incorreto
undef - erro desconhecido (ver valor de $!)
users

Retorna array de nicknames de usuários atualmente presentes na sala de bate-papo. Os dados são atualizados toda vez que você efetua login, send ou brief. Desculpe, não fui eu quem inventou isso... Retorna no mínimo o próprio nickname (a sala não está vazia se você está lá ;) ou () no caso de falha. Detalhe: se você usou brief, a sala pode estar vazia portando () não significa erro.

send ([MSG] [, ATTR])

Envia mensagem MSG para sala de bate-papo. Possui 4 sintaxes:

  1. $bot->send ('mensagem 1');

    a mais simples, envia string 'mensagem 1'

  2. $bot->send ('mensagem 2', To => 'TODOS', Action => 15);

    envia string 'mensagem 2' com atributos To e Action explicados abaixo

  3. $bot->send (Msg => 'mensagem 3', To => 'TODOS', Action => 15);

    o mesmo de cima para 'mensagem 3'

  4. $bot->send ();

    sintaxe mais obscura, não envia nada, apenas atualiza a lista que pode ser obtida com método users. De novo, não fui eu quem inventou!

Agora, sobre atributos ATTR. São todos opcionais (forma Chave => 'Valor'), aqui está a lista com uma breve explicação:

Msg

a mensagem em si, string (só pode ser usado com sintaxe 3, ignorado na sintaxe 2!)

Action

ação, valor inteiro. Ações possíveis:

0  - fala para (default)
1  - pergunta para
2  - responde para
3  - concorda com
4  - discorda de
5  - desculpa-se com
6  - surpreende-se com
7  - murmura para
8  - sorri para
9  - suspira por
10 - flerta com
11 - entusiasma-se com
12 - ri de
13 - dá um fora em
14 - briga com
15 - grita com
16 - xinga

18 - IGNORAR mensagens de
19 - só receber mensagens de
20 - não IGNORAR mais
To

o nickname do receptor da ação Action, string. Valor default é 'TODOS'.

Obs1: não necessariamente é alguém que esteja na sala. Isto é, você pode fazer:

$bot->send ('bots do UOL, uní-vos!', To => 'bots renegados');

desde que não seja uma mensagem reservada (Reserved => 1)!

Obs2: independentemente do valor do To, todos os usuários da sala irão ler a mensagem. Para mensagens privadas, use Reserved.

Reserved

pode ser 1 ou 0. Quando 1, a mensagem é enviada reservadamente para nickname To. Valor default é 0.

Sound

som a ser enviado, inteiro. Sons possíveis:

0  - nenhum (default)
14 - Ahn???
15 - Bang!
16 - Banjo
17 - Dinossauro
18 - Fiu-fiu
19 - Ocupado
20 - Oinc
21 - Pigarro
22 - Smack!
23 - Susto
24 - Telefone
25 - Tôlôca
26 - Tosse
07 - Como é?
08 - Não entendi
Icon

ícone a ser enviado, inteiro. Ícones possíveis:

0  - nenhum (default)
38 - Assustado
27 - Bocejo
23 - Careta
30 - Dentuço
18 - Desejo
31 - Eca !
32 - Gargalhada
33 - Indeciso
34 - Louco
28 - Na praia
35 - Ohhh !
20 - OK!
36 - Piscada
37 - Raiva
19 - Smack!
21 - Sorriso
26 - Zangado

Retorna 0 se houver falha e 1 se tiver sucesso.

Obs: aparentemente o servidor não aceita mensagens > 200 bytes.

scroll (TIMEOUT)

Obs: Provavelmente a parte mais chatinha... Mas indispensável se você quer comunicação bidirecional, isto é, o seu bot envia E recebe dados.

O scroll visa limpar buffers de entrada e enviar dados para sub-rotina definida em Listen_Handler (leia mais sobre argumentos de new). Se o listen_handler for omitido então os buffers serão limpos e a rotina retornará sucesso (1). Só retorna 0 se houver quebra inesperada de conexão.

O parâmetro TIMEOUT é o tempo que o scroll deva esperar até retornar caso o buffer esteja vazio, em segundos. Resumindo, scroll() ou scroll(0) retorna imediatamente (timeout 0). scroll(10) aguarda 10 segundos pelo dado. scroll(-1) pausa o programa até que um dado apareça no buffer.

O scroll é chamado automaticamente pelos métodos login, logout e send, portando, não há como o seu Listen_Handler perder algum dado. Porém, se você quiser mais controle, rode um scroll com timeout razoável sempre que estiver esperando alguma resposta do servidor.

Obs: Alguém aí pensou fork? Acredite em mim, não vale a pena! Eu comecei a desenvolver bot bifurcado, com um child para entrada (rodando só while ($bot->scroll(-1)) { ... }) e outro para saída (rodando $bot->send(...)). A sincronização dos dois virou um inferno e o ActivePerl, meu plataforma principal, não era muito amigo do fork. Se você pensar um pouco, verá que o problema em questão é totalmente linear, nunca duas ações são feitas em paralelo. Agora, se você estiver usando plataforma UNIX e não quiser se preocupar onde pôr o scroll, coloque antes do login:

$SIG{ALRM} = sub { $bot->scroll; alarm 1 };
alarm 1;

Se você está vendo essa técnica pela 1-a vez, conforme-se com o que já tem.

logout

Efetua logout da sala de bate-papo. Retorna 0 se houver falha e 1 se tiver sucesso.

BUGS

Testei rigorosamente esse módulo, afinal por que a idéia é que um bot rode 24 horas por dia 7 dias por semana sem manutenção.

Porém sempre há coisas que não planejamos afinal, tais como:

  • organização estranha de módulos/métodos

    É resultado dificilmente evitável do progresso do UOLbot. Começa-se de um jeito, aí muda-se de idéia e termina de um jeito totalmente diferente. Com certeza você deve estar se perguntando algo do tipo: "mas para quê dar um nick à instância que vai apenas checkar a sala?" ou então: "não seria mais fácil encapsular o endereço da sala em HTTP::Request por exemplo, afinal vira e mexe aparece URL de um jeito ou de outro!". A pergunta é: a funcionalidade é prejudicada? Caso contrário, para que perder tempo arrumando coisa insignificante, afinal, não é um código para massas ;)

  • incompatibilidade com Win32

    Calma, calma, você pode executar o UOLbot num plataforma Win32. O grande inconveniente é eu não ter o port do jocr necessário e biblioteca Image::Magick para testar funções OCR... Aliás, vi que as vezes há falhas muito estranhas no LWP. Uma hora tá tudo OK, outra hora não funciona. Eu fiz testes com ActivePerl 5.6.1 Build 632, utilizando Windows 98, Windows 98 SE e Windows XP Professional. O primeiro e o terceiro não apresentaram falhas, o segundo apresentou raramente. Mas na minha opinião pessoal, eu não confiaria em nada feito pela Micro$oft. Não confiaria nem nos softwares livres rodando em cima de produtos da Micro$oft. Portando, aqui vai uma dica que vai te livrar de muitos problemas: use Linux.

  • tolerância à falhas humanas

    O mínimo esperado do usuário é que passe parâmetros corretos; não passe string onde um número é esperado e nem passe expressão regular onde era para pôr referência ao código...

    Ainda assim, fiz o necessário para proteger o usuário contra dar um logout antes que seja feito um login, portanto não se desanime.

  • utilizar um proxy HTTP

    Grande maioria dos proxies públicos (os normalmente utilizados para anonimizar acessos) não deixa conectar nas portas não-HTTP. Nenhuma das salas de bate-papo reside na porta HTTP (80). E então?

Outra coisa... Olha a data desse arquivo. Nessa data UOLbot estava funcionando, pode ter certeza. Se não está agora, é porque pessoal do UOL alterou o sistema de webchat. Sinto muitíssimo... O que você tem a fazer é ou procurar versão mais atual de UOLbot ou adaptar o código desse aqui. Não deve ser difícil, fiz código o mais claro e limpo que pude, até comentei tudo (ôôô)!

O mesmo se aplica a qualquer valor ou tabela citados aqui. O UOL muda constantemente o seu sistema de webchat, fazer o quê...

REFERÊNCIAS

  • LWP - Library for WWW access in Perl

Vários exemplos distribuídos junto com o módulo:

simples.pl

a aplicação mais simples; listar um sub-grupo, entrar na sala #15, repetir mensagem 5 vezes, sair.

crawler.pl

bot de propaganda; entra em todas as salas nos sub-grupos especificados e deixa uma mensagem.

list.pl

busca em sub-grupos especificados e retorna lista de URLs de salas de bate-papo e seus respectivos títulos.

VERSÃO

2.02

HISTÓRICO

  • 1.0 (25/Jan/2002) - primeira versão funcional.

  • 1.1 (09/Fev/2002) - utilizado o Carp::croak para erros de usuário e adicionado o método brief. Correções menores na documentação.

  • 1.2 (03/Mar/2002) - adicionados métodos auth e avatar (para tirar proveito de ser usuário registrado do UOL ;).

  • 1.2a (04/Mar/2002) - atualizações na documentação.

  • 1.3 (27/Mar/2002) - reestruturado o processo de login devido às alterações feitas nos servidores do UOL. Agora você deve dar um join na sala escolhida, obter o código de verificação e completar operação com login. Maldição!

  • 1.4 (22/Jul/2002) - Código levemente reestruturado para compatibilidade com módulo OCR (para reconhecimento do código de verificação) que estou fazendo. Algumas correções menores também.

  • 2.0 (04/Ago/2002) - Código fortemente reestruturado. Muitas mudanças. Módulo UOL::OCR incluído.

  • 2.01 (06/Dez/2002) - Correção menor devido à atualização de protocolo nos servidores do UOL.

  • 2.02 (25/Mai/2003) - Arrumado o repentinamente surgido problema com "trailers" de linha. Agora está 100% IE :).

COPYRIGHT

Copyright (C) por Stanislaw Y. Pusep, Janeiro de 2002
  1. A utilização desse módulo, assim como distribuição do módulo e/ou suas versões (alterações feitas no módulo por terceiros) somente deve ser feita com autorização explicita proveniente do autor.

  2. Aqueles que tem cópia autorizada do módulo tem o direito de gerar versões (alterar o módulo conforme for conveniente a eles). (*)

  3. Qualquer programa feito com utilização desse módulo pode ser usado para quaisquer fins (inclusive lucrativos). (*)

(*)

Desde que não haja infração do item 1.

AUTOR

Nome: Stanislaw Y. Pusep

E-Mail: stanis AT linuxmail DOT org

Homepage: http://sysdlabs.hypermart.net/

POD ERRORS

Hey! The above document had some coding errors, which are explained below:

Around line 39:

Non-ASCII character seen before =encoding in 'DESCRIÇÃO'. Assuming UTF-8

uolbot's People

Contributors

creaktive avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.