Saltar al contenido
Development

Rastrear publicaciones programadas de Medium sin una extensión de navegador

Por Victor Da Luz
railsrubymediumdev-logblog-manager

He estado construyendo blog-manager para manejar la sindicación entre Medium y LinkedIn. La integración con Medium empezó simple: las publicaciones son not_imported, draft, o published. Eso cubría todo lo que necesitaba hasta que empecé a programar publicaciones en Medium, configurándolas para publicarse en una fecha futura. Medium no expone eso a través de su API, así que mi app no tenía forma de saber que una publicación estaba en estado programado.

La solución es la Fase 1 de un enfoque de dos fases: modelar el estado en la app, permitir configurarlo manualmente, y mostrarlo en la interfaz. La Fase 2 automatizaría la detección. Pero antes de construir ninguna automatización, quería saber: ¿la versión manual realmente genera suficiente fricción como para justificar la complejidad? Así que primero construí solo el modelo de datos y la interfaz.

Lo que agregué

El cambio central es un nuevo valor de enum. Rails hace esto sencillo, pero hay una regla que vale la pena señalar: los valores enteros de un enum deben ser estables. Si alguna vez se cambia el entero detrás de una clave existente, por ejemplo por insertar un valor en el medio, cada fila de la base de datos cambia de significado en silencio. Por eso siempre agrego al final:

enum :medium_status, { not_imported: 0, draft: 1, published: 2, scheduled: 3 }, prefix: :medium

Escribí una prueba que verifica el hash exacto, no solo que el nuevo valor funcione:

test "medium_status integer mappings are stable" do
  assert_equal({ "not_imported" => 0, "draft" => 1, "published" => 2, "scheduled" => 3 },
               Post.medium_statuses)
end

Esa prueba detectaría de inmediato cualquier reordenamiento futuro.

La migración solo agrega una columna datetime medium_scheduled_at que admite nulos. Sin default, sin constraint. La fecha es opcional porque a veces programo algo en Medium sin anotar la hora exacta.

Para la interfaz, tres cosas necesitaban actualizarse:

El partial de la insignia de estado ya tenía un mapa preestablecido indexado por el valor string del enum. Agregar "scheduled" al mapa fue una sola línea. Toma la clase status-soon (amarillo), igual que draft, lo cual se siente correcto; ambos son estados de “todavía no publicado”.

El dropdown de filtro del índice de publicaciones se autocompleta desde Post.medium_statuses.each_key, así que scheduled apareció ahí gratis en cuanto se actualizó el enum. Cero cambios explícitos necesarios en el filtro.

El dashboard obtuvo un nuevo widget “Próximas en Medium”. Consulta Post.kept.where(medium_status: :scheduled).includes(:blog).order(medium_scheduled_at: :asc) y se renderiza solo cuando hay resultados. Las publicaciones sin fecha programada muestran un guion.

Lo que decidí no construir

El issue originalmente incluía un formulario de edición para poder llenar medium_scheduled_at manualmente. Lo eliminé. Todo el punto de esta fase es preparar el modelo de datos para que la automatización de la Fase 2 pueda escribir en él. Si necesito probar algo manualmente, un one-liner de rails runner alcanza. Un formulario de edición es alcance real, y prefiero validar que el estado se muestre correctamente antes de construir la interfaz de edición.

Lo que me sorprendió

El filtro simplemente funcionó. Asumí que necesitaría agregar scheduled explícitamente a las opciones del dropdown, pero como la vista itera Post.medium_statuses.each_key, agregar el valor del enum fue todo lo que hizo falta. Los enums de Rails son sorprendentemente buenos en esto.

Qué sigue

La Fase 2 se trata de automatizar la detección, ya sea consultando el feed RSS de Medium o analizando correos. Eso terminó convirtiéndose en la extensión de navegador en su lugar. Por ahora, al menos puedo marcar publicaciones como programadas manualmente y aparecerán en el dashboard.

Lecturas relacionadas