Inicio Foro Noticias Retos Articulos Grupos iHackerss Mapa Creditos Youtube
foros de discusión

Welcome Guest ( Log In | Register )

 
Reply to this topicStart new topic
> Twitter Bot Example (source code), Java
marioly
post Sep 27 2008, 02:11 AM
Post #1


Regia
Group Icon


Group: Root Admin
Posts: 2,380
Joined: 14-April 06
From: Mty, Nuevo Leon
Member No.: 38



Primero decir que, pareciera que en muchos de mis topics me decanto por la opción de no explicar demasiado las cosas y por solo dar las instrucciones de una forma general, pero esto sucede por que estoy convencida de que la mejor forma de aprender a programar es: viendo los códigos (y escribiendo, claro esta), allí están las respuestas y después de un tiempo de leer te vas dando cuenta realmente el por que se hicieron las cosas de tal modo, es lo positivo y lindo del software libre, allí esta el medio para aprender.


Empezando

Twitter es un servicio de microblogging muy popular en estos tiempos, el cual cuenta con una API para facilitar el desarrollo de aplicaciones de terceros. Nuestro ejemplo de robot (para hacerlo mas divertido), tratara de leer el RSS del foro y por cada nueva entrada actualizar una cuenta en twitter (partiendo de la idea de que ya se cuenta con una, ej: http://www.twitter.com/hackerss )

Primero necesitamos una clase para facilitarnos las peticiones por HTTP, usaremos esta:


CODE
/**
* Hackerss Examples
*
* @ Author Marioly Garza (marioly@gmail.com)
* @ Copyright (C) 2008 hackerss.com
*
*
**/

package com.hss;

import java.io.*;
import java.net.*;
import java.util.ArrayList;


public class WebRequest {
    protected URL url = null;
    protected URLConnection conn = null;
    protected DataOutputStream out = null;
    protected BufferedReader in = null;
    protected ArrayList<RequestProperty> props = new ArrayList<RequestProperty>();
    protected String postdata = null;
    
    
    WebRequest(String target)
    {
        try {
            url = new URL(target);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
    }
    
    public void connect()
    {
        try {
            conn = url.openConnection();
            conn.setDoInput(true);
            conn.setDoOutput(true);
            
            if( props.size() > 0 )
                for(RequestProperty rp : props)
                {
                    conn.setRequestProperty(rp.getName(), rp.getValue());
                }
            
            out = new DataOutputStream (conn.getOutputStream ());
            if( this.postdata != null)
                out.writeBytes(this.postdata);
            
            out.flush();
            out.close();
            
            in = new BufferedReader (new InputStreamReader(conn.getInputStream ()));
        } catch (IOException e) {
            e.printStackTrace();
        }    
    }
    
    public void setPostData(String postdata)
    {
        addRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        this.postdata = postdata;
    }
    
    public void addRequestProperty(String name, String value)
    {
        props.add(new RequestProperty(name, value));
    }
    
    public String getResponse() throws IOException
    {
        String line;
        String response = "";
        while( (line = in.readLine()) != null ) {
            response += line + "\n";
        }
        in.close ();
        
        return response;
    }
    
    class RequestProperty
    {
        protected String name;
        protected String value;
        
        RequestProperty(String name, String value)
        {
            this.name = name;
            this.value = value;
        }
        
        public String getName()
        {
            return this.name;
        }
        
        public String getValue()
        {
            return this.value;
        }
    }
}



Que a pesar que es algo vieja, es funcional. Esta clase permite agregar propiedades a la consulta y enviar por metodo POST. Lo cual es importante ya que la opción que usaremos del API de twitter requiere este método (sobre la clase, no hay mucho que explicar, usa "URLConnection" y dos streams)

Ahora, necesitaremos una clase para leer el RSS del foro, específicamente esta fuente:
http://foros.hackerss.com/index.php?act=rssout&id=2

Para nuestro ejemplo usaremos esto:

CODE
/**
* Hackerss Examples
*
* @ Author Marioly Garza (marioly@gmail.com)
* @ Copyright (C) 2008 hackerss.com
*
*
**/

package com.hss;

import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.*;

public class HssRss {
    
    public ArrayList<HssEntry> getEntries()
    {
        ArrayList<HssEntry> entries = new ArrayList<HssEntry>();

        try {
            WebRequest req = new WebRequest("http://foros.hackerss.com/index.php?act=rssout&id=2");
            req.connect();
            String xml = req.getResponse();
            
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder;
            
            builder = factory.newDocumentBuilder();        
            Document doc =  builder.parse(new InputSource(new StringReader(xml)));
            
            doc.getDocumentElement().normalize();
                
            NodeList statuses = (NodeList) doc.getElementsByTagName("item");
            
            for(int i = 0; i < statuses.getLength(); i++)
            {
                Node sNode = statuses.item(i);
                Element el = (Element)sNode;
                
                String title = el.getElementsByTagName("title").item(0).getTextContent();
                String link = el.getElementsByTagName("link").item(0).getTextContent();
                String starter = el.getElementsByTagName("starter").item(0).getTextContent();
                String poster = el.getElementsByTagName("starter").item(0).getTextContent();
                String pubDate = el.getElementsByTagName("pubDate").item(0).getTextContent();

                entries.add(new HssEntry(title, link, starter, poster, pubDate));
            }            
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return entries;
    }
}



Tengo que decir que no es en si una clase para leer RSS (coge los nodes de una forma rara tongue.gif ), pero funciona y es corta, lo que es perfecto para el ejemplo
Entonces, esta clase al ser usada lee el xml de la dirección de hackerss, lo evalua y con "getEntries" nos devuelve un ArrayList con las entradas recientes.
Ahora que se tienen las entradas, se requeriría por supuesto algo que las envíe a twitter:

CODE
/**
* Hackerss Examples
*
* @ Author Marioly Garza (marioly@gmail.com)
* @ Copyright (C) 2008 hackerss.com
*
*
**/

package com.hss;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;

import sun.misc.BASE64Encoder;

public class TwitterUpdater extends Thread {
    static public String user = "mi_user";
    static public String pass = "mi_pass";
    static public ArrayList<String> msgs = new ArrayList<String>();
    public String status;
    
    TwitterUpdater(String status)
    {
        this.status = status;
    }
    
    public void run() {
        try {
        
            WebRequest req = new WebRequest("http://www.twitter.com/statuses/update.xml");
            req.addRequestProperty("Authorization", "Basic " + new BASE64Encoder().encode((TwitterUpdater.user + ":" + TwitterUpdater.pass).getBytes()));
            req.setPostData("status=" + URLEncoder.encode(this.status, "UTF-8"));

            req.connect();
            
            //String resp = req.getResponse();    
            if( msgs.contains(new String(status)) )    {
                return;
            }
            else {
                msgs.add(status);
            }

            System.out.println("Enviado: " + status);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}



Esta es una clase que extiende a Thread (asi que corre como un hilo), y cada que se ejecuta envía a twitter una actualización. Aquí hay algunas cosas interesantes; Twitter para la mayoria de sus servicios requiere una autentificación del tipo: HTTP Basic Authentication , asi que debemos agregar un parámetro especial:
Authentication: Basic user:pass

Hecho esto, podemos utilizar sus opciones, en este caso requerimos enviar la actualización por POST, para eso usamos: "setPostData('status=' + nstatus)" siendo nstatus el nuevo mensajes pasado por urlencode, y al terminar imprimiría un mensaje de éxito.
En este ejemplo va guardando los mensajes en un ArrayList para revisar que no hayan sido enviado antes, claro esto no es lo mas optimo.., lo escribí por rapidez.


Ahora ya tenemos como leer el feed de hackerss y como enviarlo, pero necesitamos la clase que las conjunte y las utilice smile.gif , la cual es la siguiente:

CODE
/**
* Hackerss Examples
*
* @ Author Marioly Garza (marioly@gmail.com)
* @ Copyright (C) 2008 hackerss.com
*
*
**/

package com.hss;

import java.util.ArrayList;
import java.util.TimerTask;

public class TwitterBot extends TimerTask {

    @Override
    public void run() {
        HssRss rss = new HssRss();
        ArrayList<HssEntry> entries = rss.getEntries();
        
        for(HssEntry e : entries) {
            TwitterUpdater twit = new TwitterUpdater(e.toString());
            twit.start();
        }
    }

}




Esta clase consume el rss de hackerss, toma las entradas y por cada una trata de actualizar nuestro twitter. En este caso extiende a TimerTask para poder ser establecida como una tarea.

Solo falta el metodo que lo inicie todo:

CODE
/**
* Hackerss Examples
*
* @ Author Marioly Garza (marioly@gmail.com)
* @ Copyright (C) 2008 hackerss.com
*
*
**/

package com.hss;

import java.util.Timer;

public class Main {
    
    static public void main(String[] args)
    {
        Timer timer = new Timer();
        TwitterBot twit = new TwitterBot();
        timer.schedule(twit, 1000, 600000);
    }
}



La clase Main inicia la aplicación, establece la instancia de "TwitterBot" para que corra primero en 1 segundo y después cada 10 minutos, y asi logramos que se este actualizando nuestro twtitter constantemente smile.gif

Yo hice mi prueba actualizando la cuenta:

http://www.twitter.com/hackerss



Claro esta vez solo lo he corrido por poco tiempo tongue.gif


Y ya esta, con estas cuatro clases logramos tener un bot que actualize nuestro twitter desde un RSS .

A pesar de que no se explique a fondo como están escritas, como dije antes, las respuestas están alli, como leer un xml, como enviar peticiones HTTP, como usar el API de twitter..

Espero sea útil, gracias =)


--------------------
Go to the top of the page
 
+Quote Post
marioly
post Sep 30 2008, 03:22 AM
Post #2


Regia
Group Icon


Group: Root Admin
Posts: 2,380
Joined: 14-April 06
From: Mty, Nuevo Leon
Member No.: 38



gracias publico! . A la otra pondre fotos con mujeres en poca ropa en el post o algo.., ya la programacion en si ya simplemente no atrae u.u


--------------------
Go to the top of the page
 
+Quote Post
Bucio
post Sep 30 2008, 03:32 AM
Post #3


Descaradamente Guapo =Þ
Group Icon


Group: Colaborador
Posts: 4,518
Joined: 26-April 06
From: Chiapas México.
Member No.: 382



jojojo genial D: lic ¡¡ eje


--------------------
Go to the top of the page
 
+Quote Post
Mao
post Sep 30 2008, 06:23 AM
Post #4


no soy juaker :P
Group Icon


Group: Root Admin
Posts: 3,053
Joined: 29-March 06
From: Bucaramanga, Colombia.
Member No.: 24



QUOTE(marioly @ Sep 30 2008, 04:22 AM) [snapback]64379[/snapback]
gracias publico! . A la otra pondre fotos con mujeres en poca ropa en el post o algo.., ya la programacion en si ya simplemente no atrae u.u

los que programanen java ni se aparecen por aca..XD
php tiene mas gente lambiscona..XD

de todas formas gracias marioly por estos codigos que siempre nos ayudan en algo, en este caso conocer un poco la api de twiter...

/delete


--------------------
Go to the top of the page
 
+Quote Post
Ironic
post Sep 30 2008, 07:58 AM
Post #5


Hackerss Member
******


Group: Hackerss Member
Posts: 1,592
Joined: 7-July 07
From: Buenos Aires, Argentina
Member No.: 2,688



Jaja marioly!

yo te banco a muerte, no se porque pero recien ahora veo el post tongue.gif
prefiero usar los status update de facebook tongue.gif


--------------------
Mi blog: http://www.ironicnet.com
Mi fotolog: http://www.fotolog.com/ironicnet_com

Cualquier cosa: ironic@ironicnet.com
Msn: ironic@ironicnet.com

Registrate en Bux.to y sumate unos dolares mensuales!
No te hace millonario, pero ayuda...

Go to the top of the page
 
+Quote Post
Blako
post Oct 2 2008, 01:44 PM
Post #6


Forista
****


Group: Hackerss Member
Posts: 240
Joined: 22-February 07
From: Somewhere
Member No.: 1,873



Eres Genial Mariolyy!!

Cuantos chikos estaran enamorados de Marioly, y ni la conocen fisikamente!!

+1!!!


--------------------
<<<<Disappear - Be Free>>>>
Go to the top of the page
 
+Quote Post
nekro
post Oct 4 2008, 02:38 PM
Post #7


animich's baby
****


Group: Hackerss Member
Posts: 948
Joined: 18-March 06
From: /
Member No.: 2



entonces por tu culpa!!! me anda followeando el nullcoll ese u.u


--------------------
Contacto, dudas, sugerencias, quejas, etc a:
me@nekrox.com - msn@nekrox.com - http://nekrox.org

BLOG
Go to the top of the page
 
+Quote Post
Bucio
post Oct 4 2008, 03:13 PM
Post #8


Descaradamente Guapo =Þ
Group Icon


Group: Colaborador
Posts: 4,518
Joined: 26-April 06
From: Chiapas México.
Member No.: 382



QUOTE(Blako @ Oct 2 2008, 02:44 PM) [snapback]64633[/snapback]
Eres Genial Mariolyy!!

Cuantos chikos estaran enamorados de Marioly, y ni la conocen fisikamente!!

+1!!!



Creoq ue solo io :$


--------------------
Go to the top of the page
 
+Quote Post
NullCool
post Oct 4 2008, 07:33 PM
Post #9


Fuck u!
******


Group: Hackerss Member
Posts: 1,655
Joined: 10-May 06
From: Mex DF
Member No.: 575



QUOTE(nekro @ Oct 4 2008, 03:38 PM) [snapback]64909[/snapback]
entonces por tu culpa!!! me anda followeando el nullcoll ese u.u

maldito destructor de autoestima sad.gif


--------------------
Mail me!!!
Partituras y MIDIS
Visita mi Blog
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic

 

RSS Lo-Fi Version Time is now: 2nd September 2010 - 10:42 PM