Acortador de enlaces fácil en JavaScript, Cloudflare Workers y Telegram Bot

¿Qué sucede si necesita crear rápidamente un enlace corto? Por supuesto, use un acortador de enlaces. ¿Qué pasa si también hace que este enlace sea legible? ¿Sigues usando tu propio dominio? Y sería mejor hacerlo sin servidores adicionales. Parece que hay una respuesta.






Fondo

Se me ocurrió la idea de un "acortador de enlaces fácil" cuando buscaba una opción de redireccionamiento utilizando un dominio para una de las salas de la nueva red social Clubhouse . La esencia de la idea del desvío de llamadas de sala era reiniciar una sala con el mismo nombre, pero siempre en línea . Era necesario resolver el problema de cambiar constantemente la dirección de la habitación estacionando un enlace de este tipo al subdominio.





La decisión surgió por sí sola, ya que el sitio se instaló previamente en Cloudflare. Inicialmente, utilicé la función “Reglas de página”, que te permite establecer, entre otras cosas, reglas de redireccionamiento, pero pronto surgió la idea de hacer que este redireccionamiento sea más flexible y modificable sin necesidad de entrar en la configuración del servicio. Por supuesto, Telegram Bot se convirtió en una de esas soluciones.





Formulación del problema

Para lograr nuestro plan, es necesario resolver varios problemas:





  • ¿Cómo redireccionar desde un subdominio específico?





  • ¿Dónde guardar los enlaces por clave (abreviatura) - valor (dirección de reenvío)?





  • ¿Cómo crear tales abreviaturas?





Como habrás adivinado, las respuestas a estas preguntas se encuentran en el mismo título del artículo. Por tanto, propongo pasar a la parte práctica.





Condiciones previas

Para una descripción más detallada, señalaré las condiciones básicas necesarias para la implementación de nuestro proyecto:





  • Dominio conectado a Cloudflare;





  • Conocimientos generales de JavaScript;





  • Se creó el bot de Telegram;





  • Documentación para Cloudflare Workers y Telegram Bot API .





En este artículo no se explica cómo cumplir las condiciones previas necesarias. La solución a estos problemas queda en manos del lector.





Capacitación

, , — « ?». :





1. – Cloudflare KV.





Cloudflare KV — Worker' « - ». , Cloudflare.





: Workers KV, , .





Página KV de Cloudflare
Cloudflare KV

. , . , , .





Dentro de nuestra bóveda

2. Worker .





«Create worker», Worker («Save and Deploy») .





Así es como se ve la página del nuevo trabajador
Worker'

«Settings» Telegram , .





Configuración del trabajador
Worker'

3. -





, url.mydomain.com



, «-» -.





Página de trabajadores para nuestro dominio
Workers

, «Workers» «Route» -.





Agregar una nueva redirección

, , (path - ) .



.





, DNS DNS .





Nuevo registro DNS que contendrá el acortador de enlaces
DNS

! .





. , Cloudlfare. Worker. «Quick edit» .





Editor de código

:













(URL path) . 404.





addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})

/**
 * Respond to the request
 * @param {Request} request
 */
async function handleRequest(request) {
  const requestUrl = new URL(request.url);
  const path = requestUrl.pathname.substring(1); //   "/"
  return await redirect(path)
}

/**
 * Make redirect
 * @param {string} shortName
 */
async function redirect(shortName) {
  //        
  const url = await db.get(shortName);
  if (url) {
    //   
    return Response.redirect(url)
  }
  //    
  return new Response(null, {status: 404})
}

      
      



, , :





¡Hay un contacto!
!

. . Telegram URL. , Telegram User ID . . webhook'.





addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})

const ADMIN = 11111111; //   Telegram User ID

/**
 * Respond to the request
 * @param {Request} request
 */
async function handleRequest(request) {
  const requestUrl = new URL(request.url);
  const path = requestUrl.pathname.substring(1);
  //        
  if (path == BOT_TOKEN) {
    return await bot(await request.json())
  }

  return await redirect(path)
}

/**
 * Make redirect
 * @param {string} shortName
 */
async function redirect(shortName) {
  const url = await db.get(shortName);
  if (url) {
    return Response.redirect(url)
  }
  return new Response(null, {status: 404})
}

/**
 * Create new shorten URL
 * @param {Object} update
 */
async function bot(update) {
  //     
  if (update.message.from.id != ADMIN) {
    return new Response("OK", {status: 200})
  }
  //    "shortname url"
  const [shortName, url] = update.message.text.split(" ");
  //    
  await db.put(shortName, url);
  const response = {
    //         
    "method": "sendMessage",
    //        -  
    "text": ` ${url}     url.mydomain.com/${shortName}`,
    //   ,     ADMIN (  ), 
    //  update.message.chat.id      
    //     
    "chat_id": update.message.from.id
  }

  return new Response(
    JSON.stringify(response), 
    {
      status: 200,
      headers: new Headers({"Content-Type": "application/json"})
    }
  )
}

      
      



, , :





Parece viable

( ):





Trabajando

– Telegram Bot Webhook. , :





https://api.telegram.org/bot[BOT_TOKEN]/setWebhook?url=url.domain.com/[BOT_TOKEN]







Telegram API :





{"ok":true,"result":true,"description":"Webhook was set"}
      
      



. , , .



« !»





« » .





, Cloudflare Worker'. , :





  • 1000 ( );





  • leer de la base de datos hasta 100.000 veces al día (número máximo de visitas);





  • el script en sí se puede ejecutar hasta 100.000 veces al día (la cantidad de mensajes al bot y visitas a enlaces abreviados);





  • la secuencia de comandos no debe ejecutarse más de 1000 veces por minuto.





Estas restricciones deberían ser suficientes para uso personal, comparta su opinión sobre esto en los comentarios.








All Articles