Usa Telegram para enviar tus nuevas publicaciones

Como crear un bot de telegram para enviar mis nuevas publicaciones a un canal de telegram gratis Bot para enviar mis nuevas publicaciones a un canal de telegram gratis

En una publicación anterior, aprendimos a crear y alojar un bot de Telegram gratis y al finalizar prometí que le agregaríamos funcionalidades interesantes. Pues esta es una de ellas, la cual te permitirá informar de tus nuevas publicaciones (tanto de Blogger como WordPress) a tus suscriptores en tus canales de Telegram.

Requisitos

Configurar el worker

Vamos a hacer algunos cambios en las configuraciones en Cloudflare, ya que necesitamos preparar todo antes de implementar los cambios en el código.

Crear un espacio de nombres KV

Primero, en el menú izquierdo, ve a "Workers y Pages", selecciona "KV", haz clic en "Crear espacio de nombres", dale un nombre y guarda los cambios.

Workers y Pages KV

Crear variables de entorno

Ve al apartado Información general de Workers y Pages, da clic sobre tu worker y dirígete a la Configuración. Aquí selecciona la sección Variables y en "Variables de entorno", haz clic en "Editar variables":

Editar variables de entorno

En el campo "Nombre de variable" escribe CURRENT_FEED y en el campo "Valor" agrega la url de un feed de Blogger o WordPress, por ejemplo:

https://www.example.com/feeds/posts/default?alt=json&max-results=1
https://www.example.com/wp-json/wp/v2/posts?per_page=1

Guarda los cambios y en la misma sección desplázate hacia abajo hasta encontrar "Enlaces de espacios de nombres de KV". Agrega una nueva variable en donde el campo Nombre de variable debe ser KV_STORAGE_FEED y en el campo "Valor" selecciona el espacio de nombres que creaste anteriormente, por último guarda los cambios.

Configurar Triggers / Activadores

Tras finalizar la configuración de las variables, dirígete a la pestaña "Activadores", desplázate hacia abajo hasta encontrar "Activadores de Cron" y haz clic en "Agregar activador".

Configurar activador en cloudflare gratis

Solo debes especificar el intervalo de tiempo en el que quieres que se ejecute el activador, por ejemplo, si especificas 30 minutos el bot buscará si hay nuevas publicaciones cada 30 minutos.

Agregar el código

Si hiciste todo correctamente, felicidades, ya casi terminamos. Ahora solo vamos a editar el código precionando el botón "Edición rápida", recuerda que aquí ya tenemos un código que corresponde al tutorial anterior.

Nuevas variables

En la primera línea del código, haz un espacio y agrega las siguientes variables que harán referencia a las variables de entorno que configuramos anteriormente.

const FEED = CURRENT_FEED
const KV_NAMESPACE = KV_STORAGE_FEED

Función para obtener canales

El trabajo de esta función será de obtener y parsear el objeto, que almacena el ID de todos los canales en donde el bot se haya agregado como administrador. Es importante para más adelante:

// Obtiene los canales de KV
async function getChannels () {
  let channels = await KV_NAMESPACE.get('channels') || {}

  // Si channels no es un objeto, convertirlo
  if (typeof channels !== 'object') {
    channels = JSON.parse(channels)
  }

  return channels
}

Función para gestionar la lista de canales

Cuando el bot es agregado a un canal, esta función se encargará de incluir el ID junto con el nombre del canal a nuestro espacio de nombres. Si el bot es eliminado de un canal, ese ID también será borrada del registro.

// Maneja el estado de miembro
// https://core.telegram.org/bots/api#chatmember
async function manageMember (member) {
  const chatTitle = member.chat.title
  const chatId = member.chat.id
  const chatType = member.chat.type

  // bot status (administrator, kicked, left, member, restricted, creator)
  const status = member.new_chat_member.status

  // Si el tipo de chat no es "channel", no hacer nada
  if (chatType !== 'channel') {
    return
  }

  // Obtener los canales de KV o crear un objeto vacío
  const channels = await getChannels()

  // Si el bot es "administrator", agregar y almacenarlo en KV
  if (status === 'administrator') {
    channels[chatId] = chatTitle
    await KV_NAMESPACE.put('channels', JSON.stringify(channels))
  }

  // Si el estado es "left" o "kicked", eliminar el canal de KV
  if (status === 'left' || status === 'kicked') {
    delete channels[chatId]
    await KV_NAMESPACE.put('channels', JSON.stringify(channels))
  }
}

Actualizar la funcion onUpdate

En el tutorial anterior ya habíamos creado esta función, pero para esta característica será necesario modificarla. Busca la función onUpdate() y reemplázala con esta nueva versión:

async function onUpdate (update) {
  // Si la actualización contiene un mensaje, se llama a la función "onMessage".
  if ('message' in update) {
    await onMessage(update.message)
  }

  // Si es un estado de miembro, se llama a la función "manageMember".
  if ('my_chat_member' in update) {
    await manageMember(update.my_chat_member)
  }
}

Función para gestionar el feed

Esta función obtiene el feed, diferencia si es de Blogger o WordPress, obtiene la última publicación y la envia a tus canales. En el proceso, también se almacenará el ID de la última publicación en el espacio de nombres KV para futuras comparaciones.

// Manejar las actualizaciones de manera asíncrona
async function handleScheduled (event) {
  try {
    // Obtener el enlace de la entrada (Solo Blogger)
    function getLink (links) {
      for (const link of links) {
        if (link.rel === 'alternate') {
          return link.href
        }
      }
    }

    // Obtener el feed de Blogger o WordPress
    const feed = await fetch(FEED)
    const data = await feed.json()

    // Verificar si el feed es de Blogger
    const isBlogger = data.feed

    // Obtener la ultima entrada del feed
    const newEntry = isBlogger ? data.feed.entry[0] : data[0]

    // Obtener el ID de la entrada más reciente y del KV
    const newEntryId = isBlogger ? newEntry.id.$t : newEntry.id
    const getEntryId = await KV_NAMESPACE.get('currentEntryId')

    // Convertir la ID de la entrada en un número (Solo WordPress)
    const currentEntryId = isBlogger ? getEntryId : Number(getEntryId)

    // Si hay un nuevo ID de entrada, enviar a todos los canales
    if (!currentEntryId || newEntryId !== currentEntryId) {
      // Actualizar la ID de la entrada almacenado en KV
      await KV_NAMESPACE.put('currentEntryId', newEntryId)

      // Obtener el título y el enlace de la entrada
      const title = isBlogger ? newEntry.title.$t : newEntry.title.rendered
      const link = isBlogger ? getLink(newEntry.link) : newEntry.link

      // Establecer el texto del mensaje
      const messageText = `${title}\n${link}`

      const channels = await getChannels()

      // Enviar mensajes a todos los canales
      for (const channelId of Object.keys(channels)) {
        await sendPlainText(channelId, messageText)
      }
    }
  } catch (error) {
    console.error('Error al obtener o procesar el feed:', error)
  }
}

Ahora, solo nos falta llamar a la función handleScheduled en el evento scheduled, para ello, agrega el siguiente código debajo de la función anterior:

// Ejecuta en intervalos regulares para enviar actualizaciones
addEventListener('scheduled', event => {
  event.waitUntil(handleScheduled(event))
})

Pulsa el botón "Guardar e implementar" y ya hemos terminado. Ahora solo tienes que agregar tu bot como administrador a un canal de telegram para que este empiece a enviar tus actualizaciones.

Conclusión

Esta es una excelente, cómoda y gratuita forma de informar a tus suscriptores de tus nuevas publicaciones sin tener que llenarlos de correos electrónicos. Si quieres ver este código funcionando, puedes suscribirte a mi canal de Telegram y comprobar las actualizaciones.

Si tienes alguna duda o sugerencia, no dudes en dejarla en los comentarios, estaré encantado de ayudarte. No olvides compartir este aporte en tus redes sociales, siempre lo agradezco. Muchas gracias por pasar.