Todo lo que hay que tener en cuenta antes de programar una función para compartir un enlace

El otro día me puse a rehacer el código de LinksDV.com, quiero renovarlo, simplificarlo y dejarlo bien simple y fácil de usar.

Así que me puse a programar desde cero una funcionalidad muy básica: compartir un enlace. Tal vez para la mayoría esto pueda resultar trivial pero ahora les voy a explicar TODO lo que hay que hacer para sencillamente compartir un enlace, no, no son pocas cosas.

Pero quería contarlo para que vieran todo el proceso mental que requiere un desarrollador y que nunca es el caso de "apreta dos botones y sale", no, el software es complejo y siempre falla.

Un enlace

Un enlace, una URL, es tan sólo eso, si lo queremos compartir lo escribimos o lo copiamos y pegamos y "listo".

Pero un enlace es mucho más que eso hoy en día porque, primero que nada ¿Existe? Si, parece una pregunta estúpida pero antes de terminar en un error 404 de un servidor diciéndonos que eso que pedíamos no existía deberíamos chequearlo.

Entonces no era tan fácil, claro que no, mi primer método es consultar los headers, no traerme todo el contenido sino sólo los primeros encabezados HTTP que conformarían la conexión.

¿Qué espero encontrar?

HTTP/1.1 200 OK 
HTTP/1.1 302 Found

Cualquier otra cosa es que esta conversación entre servidores falló así que lo primero es preguntar si este enlace existe y que lo que está detrás sea algo útil. Eso me lo contesta el servidor, en PHP se hace con un simple get_headers($url); y listo.

Pero además tengo algo en LinksDV ¿Y si ya lo publicó alguien? Pues bien, tengo que verificar contra la base de datos que ningún otro usuario haya compartido ese mismo enlace anteriormente, así que ya tenemos un primer query a la base de datos que agrega unos milisegundos a la respuesta al usuario. Tengan en cuenta que del otro lado siempre hay un impaciente :D

A veces algún usuario abusa de repetición, demasiadas urls desde la misma fuente, eso atenta contra la variedad y sólo es "aceptable" si hablamos de, por ejemplo, Youtube o sitios de noticias. Así que hago un conteo (consulta a la DB) y verifico que en la última semana no tenga demasiados envíos tal o cual dominio.

Pero no todos los enlaces nacieron iguales, muchas veces recibo spam y tengo que "limitarlo", para ello contrasto con una lista de enlaces previamente bloqueados, así que ya tenemos una segunda consulta a la base de datos ¿Este enlace no lo bloqueé? okey, que pase.

El contenido

Ahora que tengo el enlace y validé que es real, que existe, que no es repetido, que no es abuso ni spam ¿Qué hago? Pues bien, vamos a recolectar todo lo que se pueda sacar de allí ¿Por qué? Porque la gente es MUY VAGA a la hora de llenar campos tan simples como Título, Descripción y Tags, de alguna forma tengo que facilitarlo. (en la versión vieja de LinksDV esto ni existe, es nuevo)

Es decir, ahora me tengo que enterar qué hay del otro lado y eso implica muchas "preguntas" al servidor, ya me tengo que traer lo que allí esté pero ahora es donde empiezan los "problemas".

¿Es HTML? ¿pusieron un enlace directo a un JPG o un PNG o un PDF? ¿Es un servicio conocido y hasta podría incrustar un player de video? ¡Cuántas preguntas!

Desde ya que muchas de estas se pueden resolver desde la misma url, si termina en ".pdf" se podría resolver más fácil pero no alcanza.

Una cosa que suelo hacer es tomar ese contenido (si ya pasó algunos filtros) y analizarlo. En PHP se puede hacer con file_get_contents o, si esto falla, ir al clásico y conocido CURL que sirve para todo.

Tengan en cuenta que no siempre funciona ¿Por qué? Porque hay muchos servicios de proxy que filtran spiders que no se identifican correctamente. Para hacerse pasar por un usuario real (no lo somos, pero casi) hay que indicarle un "contexto" y eso se hace con un user-agent decente como:

"User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36".

Funciona la mayoría de las veces pero si no funcionó por uno ni por el otro, mala suerte, no podremos saber nada más de ese enlace.

Cuando tenemos suerte (más bien lo usual en mis pruebas, el 99% de las veces) podemos hacer algo MUY copado que es usar un DOMDocument.

Casi todos los lenguajes modernos tienen librerías para procesar HTML o XML de forma cómoda y conveniente, en PHP uso :

$doc = new DOMDocument(); // para crear un documento

$doc->loadHTML(mb_convert_encoding($contentpage, 'HTML-ENTITIES', 'UTF-8'); // para cargarle contenido

Lo bueno es que nos permite recorrer el HTML y encontrar entidades reconocibles.

De dónde sacar los datos

Recorriendo el HTML podemos buscar el título y descripción del HTML de la página o, algo MUY útil, buscar los "Open Graph" https://ogp.me/.

Debe ser una de las pocas cosas útiles que promovió en su momento Facebook pero las páginas que incluyen los tags "og" en su encabezado te facilitan datos excelentes como: tipo de contenido, título, descripción, url a una imagen, el tamaño de dicha imagen (ideal para el thumbnail de un link) y así.

Es lo primero que tomo pero NO SIEMPRE existen. Si la página es vieja es posible que tengamos que ir al título-descripción básico que traía el HTML viejo.

Así que lo primero que hago es buscar los OG, luego los "default" y si nada de eso sirve, mala suerte, irá el formulario vacío y deberá llenar todo el usuario. Más no me queda (si se les ocurre algo me avisan Guiño )

Ahora bien, queda la foto. Si está en los tags Open Graph es genial porque tenemos una url perfecta de forma directa, el sitio ya nos está diciendo "usá esta foto". Cuando compartimos un enlace en Facebook lo primero que busca son estos datos y así arma tu posteo, por eso algunos se ven bien y otros no. Aquí estamos haciendo el mismo trabajo que haría Facebook!

Si no encuentro una imagen ¿cuál utilizo? Bueno, se me ocurrió una solución hace un tiempo que es falible pero en la mayoría de los casos funciona: recorrer de nuevo el HTML.

Si lo parseamos buscando los tags < img > podemos encontrar un src (source) y, si el contenido de adentro es un JPG, posiblemente sea la imagen que estábamos buscando. ¿Por qué dejo afuera GIF y PNG? Porque en los sitios se usan mucho para los componentes de diseño de la página (por las transparencias) así que lo más probable es que el primer JPG que encuentres esté en el contenido de la nota (con más probable no hablamos de seguro, claro).

Conclusión

Ahora tengo todo, los datos escenciales, validé la url, su contenido, lo analicé, peraré todo para que el usuario pueda postearlo y todavía ni siquiera lo sumé a la base de datos.

Como verán hay que pensar en TODO esto antes de tan sólo compartir un enlace, hay que tener en cuenta todos los errores posibles de entrada de datos, el usuario puede fallar, el sitio puede estar caído, la página pudo haber sido actualizada por última vez en 2004, y así, todas las variables posibles.

No importa mucho el lenguaje o framework que uses: si no tenés claro todo el proceso vas a incorporar errores tontos y fallos al comienzo. Por eso a veces se tarda tanto en empezar. Muchas de estas validaciones no salen a la luz en el diseño porque muchos creen que el mundo es perfecto y donde no existen cosas fallidas. Error.

Lo más común es que tengas que atajar excepciones, cosas incompletas, malas prácticas de otro dev (el que hizo el link a compartir) y de alguna forma tengas que evitar la frustración de tu usuario para que no mande tu linksharing a la mierda (como sucede habitualmente).

Y todo esto hay que hacerlo rápido! Si encima lo hacen desde un teléfono estás más jugado, por eso en esta nueva versión traté de tomar toda la metadata posible para "escribirle" el título y descripción y no tenga que trabajar tanto. Sí, son vagos, pero también es muy frustrante cuando la plataforma no reconoce lo que le estas enviando. Uno, como desarrollador, tiene que ubicarse más del lado del usuario aunque éste sea odioso y un desagradecido de mierda :D

Otros posts que podrían llegar a gustarte...

Comentarios

  • Alejandro    

    Ademas de los codigos 200 y 302 podrias verificar si te devuelve un 301 o 302, el enlace puede que siga existiendo pero se movio a una nueva url.

    Saludos

    • Responder
    • Citar
    • Comentado:
  • Ale Sarco    

    Podrías usar la Google Image API (o algo similar) para tratar de detectar la mejor imágen. Eso te agregaría unos ms., pero lo podrías hacer asincrónicamente mientras hacés otra cosa.

    • Responder
    • Citar
    • Comentado:
    • y quién paga por el uso de la API? señor, somos pobres acá! :D

      • Responder
      • Citar
      • Comentado:
  • Chino    

    Si no encontras titulos o descripcion, siempre como ultimo recurso podes buscar palabras claves en los ids o names del DOM y si ahi ya no encontras nada, fue jaja que se maneje

    • Responder
    • Citar
    • Comentado:
    • Si te linkean un doc o una foto es más o menos imposible, es el único caso que encontré donde no encontrás nada útil así que sólo en esos casos que se ponga a escribir y no sea vago :P

      • Responder
      • Citar
      • Comentado:
  • Rotietip    

    Lo de comprobar un enlace también depende del servidor, la mayoría de las veces funciona pero hay sitios que siempre devuelven OK u otra mierda inconsistente (como Youtube o Instagram).
    Fabio Baccaglioni dijo:

    Más no me queda (si se les ocurre algo me avisan)

    Otra forma seria comprobar si el sitio tiene RSS e intentar sacar los datos desde ahí (aunque no siempre funciona ya que los RSS suelen tener los últimos 5 o 10 artículos publicados) y no estoy seguro de si Wordpress cuenta con una API para eso.
    Fabio Baccaglioni dijo:
    es el único caso que encontré donde no encontrás nada útil

    Siempre podes usar librerías especializadas que parseen esos archivos para intentar obtener algo de ahí, luego le sacas el mimetype y lo metes en un switch.

    • Responder
    • Citar
    • Comentado:
    • Si pero pensá que tiene que ser algo rápido, si tenés que parsear demasiado ya el costo por el link es demasiado, ahí ya no conviene tanto. El RSS no sirve para eso, lamentablemente, y no todo usa Wordpress, de hecho, esos son los sitios con menos problemas para obtener data, el problema mayor se da con sitios viejos

      • Responder
      • Citar
      • Comentado:
  • Ya que te pusiste a programar algo, sería algo bueno para el SEO de este blog eliminar los enlaces de las páginas que ya no existen y que están en tu menú de "Sitios".

    Saludos!

    • Responder
    • Citar
    • Comentado:
    • si, y no sólo esos, tengo que limpiar muchos posteos viejos pero... son 18 años de posteos! Mucho laburo, posta

      • Responder
      • Citar
      • Comentado:

Deje su comentario:

Tranquilo, su email nunca será revelado.
La gente de bien tiene URL, no se olvide del http/https
Para evitar bots, si se tardó mucho en leer la nota seguramente no sirva y tenga que intentar dos veces

Negrita Cursiva Imagen Enlace


comentarios ofensivos o que no hagan al enriquecimiento del post serán borrados/editados por el administrador