> ## Knowledge Base Index
> Fetch the complete knowledge base index at: https://help.squarecloud.app/sitemap.xml
> Use this file to discover available pages before exploring further.
> Pure-Markdown content can be obtained by appending a '.md' suffix to the content URLs listed in the sitemap (without the trailing slash).

# Cómo crear un bot de música (Lavalink)

# Cómo alojar un bot de música con Lavalink en Square Cloud

Si has intentado crear o alojar un bot de música para Discord recientemente, sabes que procesar audio directamente en la misma aplicación del bot puede consumir mucha CPU y generar tirones en la reproducción. La solución profesional para esto es **Lavalink**, un servidor de audio independiente (standalone) basado en Java, optimizado específicamente para Discord.

En este tutorial, aprenderás el paso a paso para alojar tanto el servidor Lavalink como tu bot de música en **Square Cloud**, garantizando estabilidad y audio de alta calidad 24/7.

---

## 🛠️ Arquitectura de la solución

Para que el sistema funcione, dividiremos el proyecto en dos aplicaciones independientes dentro de Square Cloud:

1. **El servidor Lavalink:** Responsable de conectarse a YouTube/Spotify/SoundCloud, descargar el audio, decodificarlo y transmitirlo.
2. **El bot de Discord:** Responsable de recibir los comandos de los usuarios (`!play`, `!skip`) y gestionar la cola, enviando las instrucciones de reproducción a Lavalink.

---

## Paso 1: Configurando y alojando Lavalink

Lavalink necesita un archivo de configuración llamado `application.yml` y el archivo ejecutable `.jar`.

### 1. Estructura de archivos de Lavalink
Crea una carpeta en tu computadora llamada `lavalink-server` con los siguientes archivos:

* `lavalink.jar` (Descarga la versión más reciente del repositorio oficial de Lavalink en GitHub)
* `application.yml`

### 2. Configurando el `application.yml`
Este es el archivo que define el puerto y la contraseña que usará tu bot para conectarse. Usa la configuración base a continuación:

```yaml
server:
  port: 80
  address: 0.0.0.0
lavalink:
  server:
    password: "SUA_SENHA_SUPER_SEGURA"
    sources:
      youtube: true
      bandcamp: true
      soundcloud: true
      twitch: true
      vimeo: true
      mixer: false
      http: true
      local: false
    filters:
      volume: true
      equalizer: true
    bufferDurationMs: 400
    youtubePlaylistLoadLimit: 6 # Límite de páginas de lista de reproducción
    playerUpdateInterval: 5
    youtubeSearchEnabled: true
    soundcloudSearchEnabled: true
    gc-warnings: true
```

> ⚠️ **Nota sobre la memoria:** Lavalink se ejecuta sobre la JVM (Java Virtual Machine), que suele ser exigente. Recomendamos asignar un mínimo de **512MB** de RAM para evitar bloqueos al cargar canciones pesadas.

### 3. Envío a Square Cloud
1. Comprime los archivos (`lavalink.jar` y `application.yml`) en un archivo **.zip**.
2. Ve al Dashboard de Square Cloud, haz clic en **Nueva aplicación**, adjunta el zip, selecciona el archivo jar como el principal y marca la opción de publicar en la web.
3. Una vez enviado, ve a la pestaña **Configuraciones** de tu Lavalink en Square Cloud y copia, en la pestaña de **Network**, el **Dominio Público** (ej: `tu-lavalink.squareweb.app`).

---

## Paso 2: Configurando el bot de música

Ahora que el servidor de audio está en línea, puedes elegir el lenguaje de programación de tu preferencia para construir el bot. A continuación se muestran los ejemplos en **Python** y **Node.js**.

### Opción A: Implementación en Python (usando `wavelink`)

Para proyectos en Python, la biblioteca `wavelink` es la integración más robusta y moderna con Lavalink.

#### 1. Archivos necesarios:
* `main.py`
* `requirements.txt`

#### 2. Dependencias (`requirements.txt`):
```text
discord.py
wavelink
```

#### 3. Código del Bot (`main.py`):
```python
import discord
from discord.ext import commands
import wavelink

class MusicBot(commands.Bot):
    def __init__(self):
        intents = discord.Intents.default()
        intents.message_content = True
        super().__init__(command_prefix="!", intents=intents)

    async def setup_hook(self):
        # Configura el nodo de Lavalink apuntando a Square Cloud
        node = wavelink.Node(
            uri="[https://tu-lavalink.squareweb.app:443](https://tu-lavalink.squareweb.app:443)", # Dominio generado con el puerto 443 (SSL)
            password="SUA_SENHA_SUPER_SEGURA"
        )
        await wavelink.Pool.connect(nodes=[node], client=self)

bot = MusicBot()

@bot.event
async def on_ready():
    print(f"Bot conectado como {bot.user}")

@bot.event
async def on_wavelink_node_ready(payload: wavelink.NodeReadyEventPayload):
    print(f"El nodo Lavalink \"{payload.node.identifier}\" está conectado y listo!")

@bot.command()
async def play(ctx: commands.Context, *, search: str):
    if not ctx.author.voice:
        return await ctx.send("¡Necesitas estar en un canal de voz!")

    # Se conecta al canal de voz si no está conectado
    if not ctx.voice_client:
        vc: wavelink.Player = await ctx.author.voice.channel.connect(cls=wavelink.Player)
    else:
        vc: wavelink.Player = ctx.voice_client

    # Busca la canción
    tracks = await wavelink.Tracks.search(search)
    if not tracks:
        return await ctx.send("No se encontró ninguna canción.")

    track = tracks[0]
    await vc.play(track)
    await ctx.send(f"Reproduciendo ahora: **{track.title}**")

bot.run("SEU_DISCORD_BOT_TOKEN")
```

---

### Opción B: Implementación en Node.js (usando `erela.js`)

Si prefieres JavaScript/TypeScript, puedes usar la estructura a continuación.

#### 1. Archivos necesarios:
* `index.js`
* `package.json`

#### 2. Dependencias (`package.json`):
```json
{
  "dependencies": {
    "discord.js": "^14.x",
    "erela.js": "^2.x"
  }
}
```

#### 3. Código del Bot (`index.js`):
```javascript
const { Client, GatewayIntentBits } = require("discord.js");
const { Manager } = require("erela.js");

const client = new Client({
    intents: [
        GatewayIntentBits.Guilds,
        GatewayIntentBits.GuildMessages,
        GatewayIntentBits.MessageContent,
        GatewayIntentBits.GuildVoiceStates
    ]
});

client.manager = new Manager({
    nodes: [
        {
            host: "tu-lavalink.squareweb.app", // Dominio proporcionado por Square Cloud
            port: 443, // Puerto estándar seguro para HTTPS/WSS
            password: "SUA_SENHA_SUPER_SEGURA",
            secure: true // Fuerza el uso de SSL/TLS de Square Cloud
        }
    ],
    send(id, payload) {
        const guild = client.guilds.cache.get(id);
        if (guild) guild.shard.send(payload);
    }
});

client.on("raw", (d) => client.manager.updateVoiceState(d));

client.once("ready", () => {
    console.log(`Bot conectado como ${client.user.tag}`);
    client.manager.init(client.user.id);
});

client.manager.on("nodeConnect", node => console.log(`Nodo Lavalink "${node.options.identifier}" conectado.`));
client.manager.on("nodeError", (node, error) => console.log(`Error en el nodo: ${error.message}`));

client.login("SEU_DISCORD_BOT_TOKEN");
```

---

## Paso 3: Poniéndolo todo junto

1. En el dashboard de Square Cloud, inicia tu **Lavalink Server** y asegúrate de que muestre el estado `Online`.
2. Elige una de las opciones anteriores (Python o Node.js), coloca todos los archivos de la carpeta del bot elegido dentro de un archivo **.zip**.
3. Envía el zip del bot a Square Cloud a través del botón **Nueva aplicación**.
4. Inicia el bot y abre la terminal de logs. Si la conexión es exitosa, verás el mensaje confirmando que el Nodo Lavalink está listo.

---

## 💡 Consejos de optimización y solución de problemas

* **Error de conexión (WebSocket Error / Connection Refused):** Square Cloud gestiona los domínios web bajo conexiones seguras con sus propios certificados SSL. Por lo tanto, al configurar tu bot (ya sea en Python o Node.js), usa obligatoriamente el puerto público `443` e habilita el parámetro `secure / https / wss`, en lugar de intentar acceder directamente al puerto interno `80`.
* **Cortes y latencia en el audio:** El procesamiento de audio depende mucho de la CPU disponible. Monitorea los recursos de Lavalink en el Dashboard. Si notas picos recurrentes del 100% de uso de CPU al decodificar streams, considera aumentar los recursos asignados al servidor Lavalink y al bot para garantizar más núcleos de procesamiento.
* **Estabilidad del bot:** Los bots de música tienden a acumular objetos de colas muy extensas en la memoria RAM. Monitorea frecuentemente el consumo del bot para mitigar las fugas de memoria (*Memory Leaks*) utilizando limpiezas periódicas de colas inactivas.

---

## ⚠️ El gran desafío: Restricciones de IP de YouTube (Sign-in Required)

Si configuras todo correctamente y, al intentar reproducir una canción, el bot simplemente se salta la pista o muestra un error como `403 Forbidden` o `Sign-in required`, acabas de tropezar con la protección de YouTube.

YouTube bloquea agresivamente las solicitudes provenientes de **IPs de datacenters** (como los servidores de Square Cloud, AWS, Google Cloud, etc.) para evitar abusos y el web scraping de audio. Como miles de bots comparten los mismos rangos de IP de grandes servidores, estas IPs entran rápidamente en la "lista negra" de la plataforma.

### ¿Cómo solucionar este problema?

Para que tu Lavalink en Square Cloud funcione con enlaces de YouTube de forma estable, tienes tres caminos principales:

1. **Utilizar el plugin Youtube-Source con Cookies:** Las versiones más recientes de las fuentes de Lavalink te permiten exportar un archivo de cookies de una cuenta secundaria de YouTube (usando extensiones de navegador como *Get cookies.txt LOCALLY*) y configurarlo en el servidor. Esto simula a un usuario real autenticado.
2. **Cambiar a fuentes alternativas:** Configurar el bot para utilizar de forma nativa **SoundCloud**, **Bandcamp** o **Twitch** como motores de búsqueda predeterminados en el `application.yml` evade por completo el bloqueo de YouTube. 
3. **Integración con Spotify:** Para **Spotify**, recuerda que los plugins solo convierten los metadatos de la canción (nombre y artista) para buscarla en una plataforma de audio; por lo tanto, el audio final aún necesitará provenir de una fuente que no esté bloqueada (como SoundCloud).

## Compatibilidad de versiones (Lavalink v3 vs v4) y conexión

Usa siempre una **versión de Lavalink compatible con el client (wrapper)** de tu bot: **Lavalink v4 está basado en REST y no se comunica con un client v3**, lo que tumba el WebSocket. Resumen de red en Square Cloud: el **servidor Lavalink abre en el puerto 80** y el **client conecta en el puerto 443 con `secure: true`**. Si aparece `WebSocket closed abnormally (1006)`, mira [Lavalink closed abnormally (1006): cómo resolver](https://help.squarecloud.app/es/article/lavalink-closed-abnormally-1006-como-resolver-jxl2ie/).