Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Módulo Perl de interface para ambiente do bate-papo do Universo Online (webchat). Possibilita a interação completa com o sistema via API, isso é, você mesmo poderá escrever programas que façam automaticamente tudo o que um ser humano com um navegador pode fazer.
branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
UOL
.gitignore
README.pod
UOLbot.pm
simples.pl
uolker.ini
uolker.lst
uolker.pl

README.pod

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 'nome@uol.com.br' 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/

Something went wrong with that request. Please try again.