Cómo traer tu historial de Medium en 17ms usando Cloudflare Workers

Obteniendo más que solo los últimos 10 artículos en formato JSON

TLDR: Demo en vivo. Repositorio.

¿Por qué necesitaría traer mi historial de Medium?

Por otro lado, como quiero mantenerme dentro de todo actualizado con lo que está pasando en la Web y en las tendencias de la industria del software, suelo ir a Meetups, workshops y otros eventos.

Y pasa que el mejor contenido que obtengo de éstos lugares muchas veces son fotos, entrevistas, enlaces a videos o a charlas, no necesariamente en el formato texto que utilizo en Medium.

Incluso si es material escrito, como un repositorio, encuentro a Github mucho más indicado para compartir contenido técnico porque puedo usar su propio versionado de código mientras lo hago y porque la industria está familiarizada en leer código dentro de repositorios.

Últimamente estuve pensando en explorar nuevos formatos de contenido, como videos o streams, teniendo en cuenta que contar una idea en diferentes formas ayuda a la persona del otro lado a poder comprenderla con mayor facilidad.

No hay manera de observar el asombroso flujo de trabajo de un streamer de Twitch como Noopkat sólamente leyendo documentación curada sobre las tecnologías que utiliza.

A veces encuentro que la esencia de lo informal y espontáneo se pierde en los artículos escritos.

Ahora, ¿Qué carajo tiene que ver todo esto con este post?

Bancame que ahí vamos.

typeof content !== ‘string’

Por eso, en un futuro pienso rehacer mi sitio web para que sea mi plataforma personal y tener a Medium como un ingreso de datos y no al revés.

Dan tiene un buen punto en su artículo, Why My New Blog Isn’t on Medium, cuando expresa que con tu sitio personal podés hacer lo que quieras.

En mi caso, me gustaría ofrecer la posibilidad de cambiar entre contenido en inglés o español, un simple filtro que en esta plataforma no poseo.

No solo por una mejor experiencia de usuario a nivel lenguajes, pero también; ¿Qué pasa si quiero compartir fotos de un evento de tecnología?

Podría simplemente subir un enlace a una galeria de Lightroom y nos re vimos. Imaginate subir un artículo a Medium con sólo fotos.

Sería raro.

Que no se mal interprete, amo Medium. Por otro lado, prefiero hacer publicaciones donde resulten más relevantes.

Podría narrar una historia debajo de cada foto para adaptarlo más al “formato Medium”, sin embargo; algunas historias están mejor contadas por escrito, otras tienen a una foto como su mejor narradora.

Trayendo el historial de Medium

  1. Usar el historial RSS de https://medium.com/feed/@yourUser
  2. Usar el historial JSON de https://medium.com/@alekrumkamp/latest?format=json
  3. Obtenerlo desde la API oficial de Medium

Como veremos a continuación, cualquiera de estas alternativas puede probar de ser inadecuada, dependiendo del escenario.

1. Usando el historial RSS

Dejando la nostalgia de lado, no sé vos, pero como alguien que codea principalmente en Javascript, siempre prefiero tener datos en JSON a tenerlos en XML, siendo la razón de que es mucho más transparente hacer JSON.parse()/JSON.stringify() y listo! Sin dependencias ni parsers personalizados.

Si ya estás familiarizade con XML y preferís este formato, puede resultar una solución aceptable para obtener tu historial de Medium.

Sin embargo, hay algunas cosas a tener en cuenta:

  • No más de 10 entradas son obtenidas utilizando este método, por lo que si querés traer a todos, podés ir descartando esta opción.
  • Problemas de CORS van a surgir si tratás de hacer un fetch desde el navegador, ya que la ruta no provee un encabezado Access-Control-Allow-Origin.

2. Obtener el historial en JSON

Si, no. Pará.

Si vas directo a la ruta vas a encontrar que en realidad, no hay un JSON válido

Hay uno, pero sólo después de la cadena de texto ‘’. Ésto lo hacen para prevenir JSON Hijacking.

Por esta razón, se necesita algo en el medio de las consultas entre Medium y otro sitio web para removerlo, si es que queremos poder consumir ese recurso.

Usando este método nos encontramos con los mismos dos problemas que tenemos usando el historial RSS:

  • No más de 10 entradas son traidas, asi que si se quiere traer toodo, de nuevo, no sirve.
  • Problemas de CORS van a surgir si tratás de hacer un fetch desde el navegador, ya que la ruta no provee un encabezado Access-Control-Allow-Origin.
  • Es necesario extraer esa cadena de texto inicial para remover la protección contra JSON Hijacking.
  • La ruta está situada detrás del IUAM de Cloudflare. I’m Under Attack Mode, o bien, “Modo Me Están Atacando”.

Para hacer énfasis en por qué este último punto es un tema importante; hace dos días estaba listo para publicar este artículo con su repositorio.

De repente, todas las peticiones usando este método empezaron a fallar.

Me empecé a preguntar qué podría haber pasado, teniendo en cuenta que ni siquiera había tocado el código cuando dejó de funcionar.

Después de algunos momentos de confusión y depuración, llegué a la conclusión de que la ruta ya no traía información útil, sino que recibía un documento HTML, provisto por Cloudflare, informando que en unos segundo más estaría siendo redireccionado al contenido.

Para hacerla corta; si Medium está bajo un ataque de DDoS, por más que no tengas nada que ver, este método va a dejar de funcionar inmediatamente.

3. Utilizando la API oficial de Medium

Si, cuentan con una API.

Sin embargo, el hecho de que tengo que mandar un mail para pedir una API key, para consumir un recurso público, mi historial de Medium, es suficiente para que no lo considere como alternativa. Especialmente cuando hay otras opciones.

Edición: tres días luego de pedir la API Key, Medium me la facilitó via email.

Encontrando una cuarta solución

Todo empezó examinando la pestaña de red en mi navegador de mi perfil, cuando descubrí que Medium utiliza una API de Graphql.

Como sólo me interesaba traer información pública, mis artículos, decidí seguir adelante y tratar de replicar la petición de Graphql que trae la información desde Postman.

¡Y funciono!

Con la salvedad de que cada petición requiere un userId y un to que representa la próxima página de artículos a ser traídos desde la API.

Si pudiera lograr traer estos datos restantes, debería poder traer todo mi historial como lo necesitaba.

¿Te acordás de la alternativa número 1, el historial en RSS? Lo usé para traer el userId.

Con respecto al campo to, resulta que cada respuesta de la API de Graphql retorna un objeto con una clave de objeto to que puede ser utilizada para traer los próximos 10 artículos de une usuarie.

Bingo.

Finalmente, como esta API no provee una manera fiable de obtener urls de imágenes, títulos y descripciones de cada entrada, tuve que iterar por cada uno y traer su contenido HTML, hacer una subselección del documento y buscar sus etiquetas de Open Graph, utilizando la url del artículo provista por la API de Graphql.

Che Ale, todo bien, pero interpretar un cacho de HTML de cada artículo una manera re cabeza de obtener esos atributos.

Y si, estoy de acuerdo, pero probó de ser la manera más fidedigna de obtener los datos sin utilizar un token de la API oficial.

Además, como estoy utilizando Cloudflare Workers, solamente la primera petición es lenta, todos los pedidos subsecuentes caen bajo la caché de Cloudflare.

Una vez que tenía todas las llamadas a las APIs que necesitaba, era cuestión de tiempo, refactors y depuración para crear un repositorio que provee una interfaz limpia que trae todos tus posts, utilizando Cloudflare Workers a una velocidad increíblemente rápida.

Espero que te pueda ahorrar un tiempo si te llegás a encontrar con la necesidad de obtener tu historial de Medium (:

Si querés mantenerte al día con el nuevo contenido que se viene, me podés encontrar en Twitter como @alekrumkamp.

¡Gracias por la lectura!

Written by

Ranging from APIs to sales funnels, I love building stuff. Full Stack Dev, Project Leader.@javascript_101 @workshopsjs Co-organizer. InfoSys Engineering Student

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store