Marcos Ramírez BETA
Notas y un icono de vídeo de YouTube convergiendo por flechas hacia una tarjeta de GitHub Issue con etiqueta draft

Automatizo la captura de ideas del blog en GitHub Issues

· ⏱ 12+ min lectura

Tenía un problema tonto y muy real: las ideas para el blog se me escapaban.

Una se me ocurría en el coche y la apuntaba en el móvil. Otra venía de un vídeo que guardaba en YouTube “para verlo luego”. Otra la tecleaba en una nota que no volvía a abrir jamás. ¿El resultado? La mitad de las ideas buenas se perdían por el camino, y cuando me sentaba a escribir, me quedaba mirando la pantalla en blanco como si nunca hubiera tenido una idea en mi vida.

Así que dejé de pelearme con mi memoria y monté un sistema. Uno que recoge las ideas solo, las junte todas en el mismo sitio y no dependa de que yo me acuerde de nada.

La idea: una sola bandeja de entrada para todo

El principio es simple. Yo no quiero cambiar cómo apunto las cosas. Quiero seguir tirando ideas donde ya las tiro: una tarea rápida cuando se me ocurre algo, un vídeo guardado cuando veo algo que me inspira. Lo que quiero es que todo eso acabe en el mismo cajón, sin que yo mueva un dedo.

Ese cajón es GitHub Issues. Cada idea se convierte en una issue con la etiqueta draft, y ya está. Cuando me siento a escribir, abro el repo, miro las issues con esa etiqueta y elijo. Ahí está todo. Sin notas perdidas, sin pestañas abiertas desde hace tres semanas.

¿Por qué GitHub Issues y no Notion, o Trello, o una nota gigante? Por una razón muy egoísta: el blog ya vive en GitHub. Los posts son archivos en el repo. Si las ideas viven al lado del contenido, todo está en el mismo flujo. Una idea es una issue, escribir el post la cierra. Cero herramientas nuevas que mantener, cero suscripciones, cero sincronizaciones raras entre apps que un día deciden dejar de hablarse.

Las dos fuentes: cómo apunto ideas de verdad

El sistema lee de dos sitios, que son los dos sitios donde realmente apunto cosas.

Fuente 1: una lista de Google Tasks llamada “Posts”. Cuando se me ocurre algo, lo dicto o lo escribo ahí en dos segundos. “Negocio de barrio, pagar en efectivo”. “Importancia de establecer procedimientos”. Frases sueltas, semillas. No me paro a desarrollarlas: las suelto y sigo con mi vida.

Fuente 2: una lista de reproducción de YouTube llamada “Posts”. Cuando veo un vídeo que me da una idea para un post, le doy a guardar en esa lista. Una herramienta que descubro, una noticia, un tutorial que quiero comentar. El vídeo se queda ahí esperando.

Lo bonito es que ninguna de las dos cosas me saca de lo que estoy haciendo. Apuntar una tarea es instantáneo. Guardar un vídeo es un clic. El esfuerzo de capturar la idea es casi cero, que es exactamente como tiene que ser, porque si capturar cuesta, no capturas.

El script que lo pega todo: sync_ideas.py

Aquí entra el pegamento. Un script en Python que se llama sync_ideas.py y hace tres cosas en orden:

  1. Lee la lista “Posts” de Google Tasks y la lista “Posts” de YouTube.
  2. Por cada idea que encuentra, crea una issue en GitHub con la etiqueta draft.
  3. Limpia el origen para no reprocesar: marca la tarea como completada y borra el vídeo de la lista.

Tienes los cuatro archivos completos (el script, el generador de token, las dependencias y el workflow) en este gist, listos para copiar. Más abajo te dejo el paso a paso para montarlo tú.

Para hablar con GitHub uso PyGithub, que envuelve la API en algo cómodo de usar. Para Google, las librerías oficiales de cliente. Crear una issue acaba siendo una línea tan tonta como esta:

repo.create_issue(title=title, body=url, labels=["draft"])

En el caso de los vídeos, el título de la issue lleva un prefijo [YT] para que de un vistazo sepa de dónde viene la idea, y en el cuerpo meto el enlace al vídeo. Así, cuando abra la issue para escribir el post, tengo el vídeo a un clic en lugar de acordarme vagamente de “uno que vi sobre no sé qué”.

Marcar como hecho, cada fuente a su manera

El detalle importante, el que hace que el sistema no se vuelva loco, es cómo le digo a cada fuente que una idea ya está procesada.

En Google Tasks es fácil: marco la tarea como completada. Desaparece de la lista de pendientes y no la vuelvo a ver. En la siguiente pasada, el script ya ni la considera.

En YouTube no existe ese concepto de “completar”. Así que hago lo equivalente: borro el vídeo de la lista de reproducción. Para eso el script necesita permiso de escritura sobre tu cuenta de YouTube (el scope de lectura no basta), pero el resultado es el mismo que con las tareas: una vez convertido en issue, el vídeo sale de la lista y no se reprocesa. Las dos fuentes funcionan igual de cara a mí, aunque por dentro la mecánica sea distinta.

La red de seguridad: deduplicación

Aun marcando las fuentes, montar un cinturón además de los tirantes era lo prudente. Porque las automatizaciones fallan a mitad de camino, los procesos se cortan, y no quiero acabar con la misma idea convertida en issue cinco veces.

La solución es deduplicar por título. Antes de crear nada, el script se trae todas las issues que ya existen con la etiqueta draft, abiertas y cerradas, y se guarda sus títulos. Si una idea coincide con una issue que ya existe, la salta. Que cuente también las cerradas es clave: significa que aunque yo ya haya escrito el post (y cerrado la issue), esa idea no volverá a aparecer como nueva. Una idea procesada lo está para siempre.

Este tipo de pegamento entre APIs, que parece simple pero tiene su miga en los detalles de idempotencia y permisos, es justo lo que monto para empresas que tienen datos repartidos en cinco herramientas que no se hablan entre ellas.

El reloj: GitHub Actions cada hora

¿Quién ejecuta el script? Un workflow de GitHub Actions programado para correr cada hora. Instala las dependencias, lee los secrets y lanza sync_ideas.py. Nada más.

Y aquí viene algo que igual te chirría si me lees de antes: hace poco escribí un post entero sobre por qué el cron de GitHub Actions no es de fiar y cómo me llevé el reloj a Cloudflare. ¿No me estoy contradiciendo usando ese mismo cron aquí?

No. Y la diferencia es el motivo por el que conviene pensar antes de copiar soluciones de un sitio a otro.

Allí, la hora importaba al minuto: un post tenía que salir a las 8:30 en punto, y un cron que se retrasa una hora arruinaba la publicación. Aquí no. Esto es una bandeja de entrada de ideas. Me da exactamente igual que una idea tarde una hora o tres en convertirse en issue, porque no la voy a mirar hasta dentro de varios días. El cron “best effort” de GitHub, que para publicar era un desastre, para esto sobra de largo. La fiabilidad que necesitas depende de para qué lo necesitas.

Los secrets, fuera del código

Para que el script hable con Google y con GitHub hacen falta credenciales, y esas credenciales no se escriben en ningún archivo del repositorio. Van como secrets del repo, cifradas, y el workflow las inyecta como variables de entorno en tiempo de ejecución.

Son tres para Google: el CLIENT_ID, el CLIENT_SECRET y un REFRESH_TOKEN de OAuth que generé una sola vez en local con un script aparte. Ese refresh token es lo que permite al workflow autenticarse como yo sin que yo esté delante. El token de GitHub no hace falta ni crearlo: Actions provee uno automáticamente en cada ejecución, con permiso para crear issues en su propio repo.

La regla aquí es la de siempre: una credencial en un archivo del repo es una credencial regalada. Si el repo es público, hay bots rastreando secrets a todas horas. Cifradas y fuera del código, punto.

Cómo montarlo tú paso a paso

Si quieres replicarlo en tu blog (o para cualquier otra cosa que se te ocurra capturar), aquí va el camino completo. El código está en el gist: cuatro archivos que copias tal cual.

  1. Crea las dos listas “Posts”. Una lista en Google Tasks llamada exactamente “Posts” y una lista de reproducción en YouTube con el mismo nombre. El script las busca por ese nombre, así que respétalo (o cámbialo en el código si prefieres otro).

  2. Activa las APIs en Google Cloud. En un proyecto de Google Cloud, habilita la Google Tasks API y la YouTube Data API v3. Para este volumen son gratuitas.

  3. Crea credenciales OAuth de tipo “App de escritorio”. En la sección de credenciales del proyecto, genera un ID de cliente OAuth de tipo escritorio: te da un client ID y un client secret. En la pantalla de consentimiento, añádete como usuario de prueba, que si no el acceso te saldrá bloqueado cuando vayas a autorizar.

  4. Genera el refresh token una vez, en local. Con get_token.py, exporta el client ID y el secret como variables de entorno y ejecútalo. Se abre el navegador, das tu consentimiento (acceso a Tasks y a YouTube con escritura, que es lo que permite borrar vídeos de la lista) y el script te imprime un refresh token. Ese token es lo que deja al workflow autenticarse como tú sin estar tú delante.

pip install -r requirements.txt
GOOGLE_CLIENT_ID=tu_id GOOGLE_CLIENT_SECRET=tu_secret python get_token.py
  1. Mete tres secrets en tu repo de GitHub. En Settings → Secrets and variables → Actions, añade GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET y GOOGLE_REFRESH_TOKEN. El token de GitHub no lo añades: Actions ya provee uno con permiso para crear issues en su propio repo.

  2. Copia los archivos y deja que el cron trabaje. Pon sync_ideas.py, requirements.txt y el workflow en su sitio. A partir de ahí, GitHub Actions ejecuta el script cada hora. La primera pasada te vaciará de golpe todo lo que lleves acumulado.

Y ya está. Desde ese momento, lo único que tienes que hacer es apuntar una tarea o guardar un vídeo. El resto va solo.

El resultado: una bandeja que se llena sola

Lo monté, le di al botón, y la primera ejecución me creó de golpe más de cuarenta issues con todas las ideas que llevaba meses acumulando entre tareas y vídeos guardados. Cuarenta semillas de post que estaban ahí, dispersas, a punto de perderse.

Ahora el ciclo es invisible. Se me ocurre algo, lo apunto en Tasks. Veo un vídeo que me inspira, lo guardo en la lista. Y sin que yo haga nada más, en la siguiente hora eso aparece en mi repo, etiquetado y listo para cuando tenga ganas de escribir. La fuente se limpia sola, los duplicados no entran, y yo no toco nada.

La mejor automatización es la que no notas. Esta cumple: he dejado de pensar en “no se me puede olvidar apuntar esto” porque el sistema se acuerda por mí.

Preguntas frecuentes

¿Por qué usar GitHub Issues como bandeja de ideas y no una app de notas?

Porque el blog ya vive en GitHub: los posts son archivos del repositorio. Tener las ideas al lado del contenido las mantiene en el mismo flujo de trabajo, sin herramientas extra que mantener ni sincronizaciones entre apps. Una idea es una issue, y escribir el post la cierra.

¿Cómo se evita que la misma idea genere issues duplicadas?

Con deduplicación por título. Antes de crear nada, el script lee todas las issues con la etiqueta draft, abiertas y cerradas, y salta cualquier idea cuyo título ya exista. Que cuente también las cerradas evita que una idea ya escrita reaparezca como nueva.

¿Hace falta permiso de escritura en YouTube para esto?

Sí, si quieres que el vídeo se borre de la lista tras procesarlo. El scope de solo lectura permite leer la lista, pero para eliminar elementos necesitas el scope de escritura de la cuenta de YouTube. Es lo que da paridad con las tareas de Google, que sí se pueden marcar como completadas.

¿No es poco fiable el cron de GitHub Actions para esto?

Para publicar a una hora exacta, sí, es un problema. Para una bandeja de ideas, no: da igual que una idea tarde una hora o tres en convertirse en issue, porque no la vas a mirar hasta días después. La fiabilidad que necesitas depende del uso.

Fuentes


Compártelo si te ha resultado útil.

Si en tu empresa tenéis ideas, tickets o datos repartidos en herramientas que no se hablan, eso se conecta: cuéntame cómo trabajáis.

¿Dónde apuntas tú las ideas que no quieres perder, y cuántas se te escapan igualmente? Cuéntame.

Y… ahora a vaciar la bandeja, que cuarenta ideas no se escriben solas.

Artículos relacionados

Una tarjeta de GitHub Issue con etiqueta draft transformándose por una flecha en un documento de borrador con imagen de cabecera

La Inteligencia Artificial escribe los borradores del blog

Hace nada monté un sistema que recogía solo las ideas del blog y las dejaba como issues en GitHub. Funcionaba, pero el problema se había movido de sitio: ahora tenía cuarenta ideas mirándome y ninguna escrita. Así que cerré el círculo. Ahora un GitHub Action coge una idea-issue cada día, investiga, escribe el borrador entero en mi voz, le genera la imagen de cabecera y lo deja commiteado en el repo, listo para que yo lo revise. Lo mueve Claude Code corriendo dentro de Actions, autenticado con mi suscripción, sin pagar API. Te enseño cómo está montado y cómo replicarlo, con el código en un gist.

Pantalla de televisor apagada en una sala oscura con un aviso de error

🛑 Apago el log de Trakt: adiós a su acceso gratuito y a mi bot

Tenía montada una automatización que cada semana publicaba en el blog todo lo que había visto según Trakt. Ya no. Trakt ha cambiado su política, ha borrado las apps API gratuitas y ahora crear una nueva exige pagar el VIP. Sin avisar por email, sin nada: me enteré cuando el proceso empezó a fallar solo. Te cuento qué hacía ese invento, qué ha pasado exactamente y por qué, de momento, no me da la gana pagar dos euros para resucitarlo.

08:30 6 min Marcos Ramírez Lucía
Diagrama de flujo de un procedimiento dibujado en una pizarra, con pasos conectados por flechas, junto a una persona pensando

La importancia de los procedimientos, en la empresa y en casa

Por defecto, a un desconocido no le abro la puerta sin más ni le doy datos por teléfono porque me los pida. Primero verifico, y según lo que descubra, actúo. Suena exagerado, pero detrás hay algo simple y potente: un procedimiento, una forma fija de comprobar antes de reaccionar, que no cambia según el día ni según lo nervioso que esté. Y aquí viene lo interesante: todo lo que tiene un procedimiento claro, detallado y siempre igual se puede automatizar. Las recetas de cocina son procedimientos. Las empresas que funcionan van sobre procedimientos. Y tu vida personal mejora una barbaridad cuando dejas de improvisar las decisiones importantes y las conviertes en reglas. Te cuento por qué los procedimientos son una de las herramientas más infravaloradas que existen.