Si hay algo interesante en utilizar google docs(para mi gusto) es el detalle de tener tus documentos disponibles a cualquier hora y donde sea, no importando si tienes laptop o una memoria usb para andar cargando tus chivas. Pero, ¿Qué tal si trabajamos un poco desde afuera utilizando su API?.

En ésta, como en muchas otras ocasiones, utilizaré Ruby, es práctico, sencillo y muy expresivo. Veamos como obtener la lista de los documentos que tenemos en google docs.

Para comenzar indaguemos un poco acerca del API, lo primero que tenemos que hacer es autenticarnos con google, para ello debemos conectarnos al servidor de google y pedir una autenticación a ClientLogin con SSL y unos datos que pasaremos por POST.

En Ruby necesitamos añadir net/http y net/https para las conexiones, además de rexml/document para parsear lo que escupe el servidor. Podríamos hacer todo a mano, con sockets y todo el rollo, pero en ésta ocasión nos centraremos en el uso del API de google docs y no en las conexiones de red en si. Según la documentación, necesitamos mandar por POST a http://www.google.com/accounts/ClientLogin los siguientes datos:

  • accountType: Es el tipo de cuenta, es decir, si la cuenta es de google o es una cuenta de un dominio específico hospedado en google. Los posibles valores son: GOOGLE, para una cuenta tipo deathwarr17@google.com. HOSTED, para una cuenta como deathwarrior@deathwarrior.net que hospedo en google gracias a google domains. O el último valor puede ser HOSTED_OR_GOOGLE cubriendo ambas posibilidades intentando la autenticación en ese orden.
  • Email: Es eso mismo, el correo electrónico completo, como deathwarrior@deathwarrior.net o deathwarr17@gmail.com.
  • Passwd: No necesita explicarse.
  • service: El servicio de google donde queremos autenticarnos, para nuestros fines google docs, aunque en realidad debemos pasar “writely”.
  • source: El cual es una cadena en el que indicamos a google quien es el intermediario entre Juan Pérez y el servidor de google, o sea, nuestro programa. Según la documentación, debe de seguir el siguiente formato: Compañía-Programa-Version. Yo lo he bautizado así: LIDSOL-RubyGoogleDocs-0.1b. Mucha imaginación, ¿apoco no?.

Bien, ahora veamos como queda en Ruby nuestra conexión con google:


require 'net/http'

require 'net/https'

require 'rexml/document'

URLAUTH = 'https://www.google.com/accounts/ClientLogin'

SERVICE = 'writely'

ATYPE = 'GOOGLE'

SOURCE = 'LIDSOL-RubyGoogleDocs-0.1b'

email = 'deathwarr17@gmail.com'

passwd = 'mypass'

postdata = "accountType=#{ATYPE}&Email=#{email}&Passwd=#{passwd}&"

postdata += "service=#{SERVICE}&source=#{SOURCE}"

headers = {'Content-Type' => 'application/x-www-form-urlencoded'}

parsed = URI.parse(URL)

conn = NET::HTTP.new(parsed.host, parsed.port)

conn.use_ssl = true

resp, data = conn.post(parsed.path, postdata, headers)

Ahora bien, la conexión y la petición fueron hechas. Tenemos que checar si el servidor nos autenticó(código 200) o si falló(otró código que no me acuerdo). Lo anterior con un simple if:


if resp.code.to_i == 200

    puts "Autenticado"

else

    puts "Autenticación fallida, revise sus datos"

    Kernel::exit(-1)

end

Se supone que si nuestros datos eran correctos, en la respuesta del servidor viene una cadena de autenticación que usaremos cada que hagamos una petición a google. Nos regresa 3 valores separados por un salto de linea y el que necesitamos viene al último. Los otros dos -dice google- no se usan. Entonces, para obtener la cadena haremos lo siguiente:


auth = data.split[2].split('=')[1]

Esa cadena de autenticación debemos pasarla en los headers de ahora en adelante del siguiente modo:


headers = { 'Content-Type' => 'application/x-www-form-urlencoded',
  'Authorization' => "GoogleLogin auth=#{auth}",
  'GData-Version' => GDV

}

Y GDV siempre debe ser 2 según el API, por lo que lo agregamos en nuestras constantes del principio. Recuerden, debe ser un 2 “letra” no un 2 “número” o Ruby chillará por ahí.

Ahora bien, una vez autorizados, podemos obtener la lista de documentos guardados en google docs. Para ello necesitamos pedirla a docs.google.com/feed/documents/private/full. Lo haremos del siguiente modo:


URLDOCS = 'https://docs.google.com/feed/documents/private/full'

parsed = URI.parse(URLDOCS)

conn = NET::HTTP.new(parsed.host, parsed.port)

conn.use_ssl = true

resp, data = conn.get(parsed.path, headers)

Y lo que nos regresará el servidor será un documento XML que debemos analizar para obtener los títulos de los documentos. Si vemos en modo plano lo que nos regresa, vemos que los documentos están dentro de los tags feed/entry/title. Por lo que usaremos rexml/document para analizarlo.

doc = REXML::Document.new(data)

titles = []

doc.elements.each(‘feed/entry/title’) do |title|

    titles << title.text     puts title.text end [/sourcecode] Y con eso imprimimos la lista de los documentos. Por ahora ha sido una práctica muy sencilla. En artículos posteriores analizaremos opciones más avanzadas para trabajar con los documentos. El código completo lo dejo a continuación: [sourcecode language='ruby'] require 'net/http' require 'net/https' require 'rexml/document' URLAUTH = 'https://www.google.com/accounts/ClientLogin' URLDOCS = 'https://docs.google.com/feed/documents/private/full' SERVICE = 'writely' ATYPE = 'GOOGLE' SOURCE = 'LIDSOL-RubyGoogleDocs-0.1b' email = 'deathwarr17@gmail.com' passwd = 'mypass' postdata = "accountType=#{ATYPE}&Email=#{email}&Passwd=#{passwd}&" postdata += "service=#{SERVICE}&source=#{SOURCE}" headers = {'Content-Type' => 'application/x-www-form-urlencoded'} parsed = URI.parse(URL) conn = NET::HTTP.new(parsed.host, parsed.port) conn.use_ssl = true resp, data = conn.post(parsed.path, postdata, headers) if resp.code.to_i == 200     puts "Autenticado" else     puts "Autenticación fallida, revise sus datos"     Kernel::exit(-1) end auth = data.split[2].split('=')[1] headers = { 'Content-Type' => ‘application/x-www-form-urlencoded’,
  ‘Authorization’ => “GoogleLogin auth=#{auth}”,
  ‘GData-Version’ => GDV

}

parsed = URI.parse(URLDOCS)

conn = NET::HTTP.new(parsed.host, parsed.port)

conn.use_ssl = true

resp, data = conn.get(parsed.path, headers)

doc = REXML::Document.new(data)

titles = []

doc.elements.each(‘feed/entry/title’) do |title|

    titles << title.text     puts title.text end [/sourcecode] Comentarios, sugerencias y demás, no duden en escribir. Un saludo y un genial inicio de año.

4 responses »

  1. David Valdez says:

    Si, ahora que veo tu código me doy cuenta que google tiene para todas sus apis una forma similar de uso.

    Hace unos meses tuve que hacer unas cosas con la api de youtube y mas o menos es el mismo procedimiento.

    Que bonitas apis de google la verdad🙂

  2. sonny_taz says:

    Ñoñis,

    Feliz día!! No se me ocurrió otro lugar para hacerlo más que aquí😉

    Pásatela súper!!

    Abrazos y abrazos… jajajajaj😛

  3. Alex says:

    Una consulta no tengo conocimientos de Ruby, lo que necesito en google docs es una hoja de calculo donde pueda ingresar mis gatos y sacar reportes de gastos semanales, mensuales, etc, se puede hacer con Ruby, me podrias decir como please?

  4. Ivan says:

    Google docs funciona de manera muy similar a excel y libreoffice, en realidad la ventaja de gdocs es que tienes todo online y no necesitas cargar con nada.

    Para lo que tú requieres puedes buscar un tutorial de libreoffice calc o de excel y sin problemas puedes hacer que cada celda calcule algún valor basado en las demás.

    Suerte y gracias.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s