Saltar al contenido principal

Introducción

Para desarrollar y alojar en Square Cloud, es esencial seguir una secuencia estructurada de configuraciones y requisitos previos. Esta guía técnica cubrirá todo el proceso, desde la configuración inicial hasta el despliegue en producción.

Requisitos previos

  • Cuenta de Square Cloud: Regístrate a través de la página de registro usando tu correo electrónico.
  • Plan de pago activo: Garantiza recursos dedicados y un rendimiento optimizado para tu aplicación. Consulta nuestros planes disponibles y elige el más adecuado para tus necesidades.

Creando el proyecto

Se requiere una cuenta activa de X (Twitter) para la autenticación y el funcionamiento del bot. Si no tienes una cuenta, regístrate en el sitio web oficial de X.
También se requiere una cuenta de X Developer para acceder a las APIs. Solicita acceso a través del Portal de Desarrolladores de X.

Aplicación del bot en X

1

Accediendo al Portal de Desarrolladores

  1. Ve al Portal de Desarrolladores de X.
  2. Inicia sesión con tu cuenta de X (Twitter).
  3. Si es tu primera vez, completa el proceso de solicitud de acceso de desarrollador.
2

Creación del proyecto

  1. En el panel, haz clic en “Create Project”.
  2. Elige un nombre para tu proyecto (por ejemplo, “Square Cloud Bot”).
  3. Selecciona el caso de uso más apropiado (por ejemplo, “Making a bot”).
  4. Proporciona una descripción detallada de tu bot.
  5. Confirma la creación del proyecto.
3

Configuración de la aplicación

  1. Dentro del proyecto creado, haz clic en “Create App”.
  2. Define un nombre único para tu aplicación.
  3. Confirma la creación de la aplicación.
  4. Anota el App ID generado para futuras referencias.
4

Generación de las claves de API

  1. Navega a la sección “Keys and tokens” de tu aplicación.
  2. En la sección “Consumer Keys”, haz clic en “Regenerate” para generar:
    • API Key (Consumer Key)
    • API Secret Key (Consumer Secret)
  3. Importante: Copia y guarda estas claves de inmediato, ya que no podrás volver a verlas.
5

Configuración de permisos

  1. Ve a la sección “App permissions”.
  2. Haz clic en “Edit” para modificar los permisos.
  3. Selecciona “Read and write” para permitir que tu bot publique tweets.
  4. Si es necesario, selecciona “Read and write and Direct message” para la funcionalidad de DM.
  5. Guarda los cambios.
6

Generación de los tokens de acceso

  1. Regresa a la sección “Keys and tokens”.
  2. En la sección “Access Token and Secret”, haz clic en “Generate”.
  3. Confirma la generación del token.
  4. Copia y guarda:
    • Access Token
    • Access Token Secret
  5. Advertencia: Estos tokens no podrán volver a verse después de cerrar la página.
7

Verificación de credenciales

  1. Confirma que tienes las 4 credenciales requeridas:
    • API Key (Consumer Key)
    • API Secret Key (Consumer Secret)
    • Access Token
    • Access Token Secret
  2. Almacena estas credenciales en un lugar seguro
  3. Importante: Nunca compartas ni expongas estas credenciales públicamente

Desarrollando el proyecto

  1. Verificación de Node.js: Verifica que Node.js esté instalado en tu sistema. Si no, descárgalo desde el sitio web oficial de Node.js.
  2. Inicialización del proyecto: Crea un nuevo proyecto de Node.js ejecutando:
Terminal
npm init -y
  1. Instalar dependencias: Instala las bibliotecas necesarias para el bot:
Terminal
npm install twitter-api-v2
  1. Configuración de variables de entorno: Crea un archivo .env para almacenar tus credenciales de forma segura:
.env
API_KEY=your_api_key_here
API_SECRET_KEY=your_api_secret_key_here
ACCESS_TOKEN=your_access_token_here
ACCESS_TOKEN_SECRET=your_access_token_secret_here
  1. Crear el archivo principal: Desarrolla el archivo index.js con la estructura base del bot:
index.js
// Import necessary modules
const { TwitterApi } = require('twitter-api-v2');

// Configure Twitter client with authentication
const client = new TwitterApi({
  appKey: process.env.API_KEY,
  appSecret: process.env.API_SECRET_KEY,
  accessToken: process.env.ACCESS_TOKEN,
  accessSecret: process.env.ACCESS_TOKEN_SECRET,
});

// Client with read and write permissions
const rwClient = client.readWrite;

// Stores the authenticated bot user id (set in verifyBot)
let botUserId = null;

// Function to check if the bot is working
async function verifyBot() {
  try {
    // Get authenticated user information (X API v2)
    const me = await rwClient.v2.me();
    botUserId = me.data.id;
    console.log(`Bot successfully initialized! User: @${me.data.username}`);
    return true;
  } catch (error) {
    console.error('Error verifying bot:', error);
    return false;
  }
}

// Function to post a tweet
async function postTweet(text) {
  try {
    const tweet = await rwClient.v2.tweet(text);
    console.log(`Tweet posted successfully! ID: ${tweet.data.id}`);
    return tweet;
  } catch (error) {
    console.error('Error posting tweet:', error);
    throw error;
  }
}

// Function to respond to mentions
async function respondToMentions() {
  if (!botUserId) return;
  try {
    // Fetch recent mentions (X API v2)
    const mentions = await rwClient.v2.userMentionTimeline(botUserId, {
      max_results: 10,
    });

    for (const tweet of mentions.data?.data ?? []) {
      // Check if it's a new mention (implement control logic)
      if (tweet.text.includes('!ping')) {
        // Reply to the mention
        await rwClient.v2.reply(
          'Pong! 🤖 X Bot working correctly!',
          tweet.id
        );
        console.log(`Replied to mention (tweet ID: ${tweet.id})`);
      }
    }
  } catch (error) {
    console.error('Error processing mentions:', error);
  }
}

// Function to search and interact with specific tweets
async function searchAndInteract(query) {
  if (!botUserId) return;
  try {
    // Search recent tweets (X API v2)
    const tweets = await rwClient.v2.search(query, {
      max_results: 10,
    });

    for (const tweet of tweets.data?.data ?? []) {
      // Like the tweet
      await rwClient.v2.like(botUserId, tweet.id);
      console.log(`Liked tweet ID: ${tweet.id}`);

      // Wait a bit between actions to avoid rate limiting
      await new Promise(resolve => setTimeout(resolve, 2000));
    }
  } catch (error) {
    console.error('Error searching and interacting:', error);
  }
}

// Main bot function
async function runBot() {
  console.log('Starting X bot...');
  
  // Check if the bot is configured correctly
  const botOk = await verifyBot();
  if (!botOk) {
    console.error('Bot initialization failed');
    return;
  }
  
  // Example: Post an initialization tweet
  try {
    await postTweet('🤖 X Bot initialized and running on Square Cloud!');
  } catch (error) {
    console.log('Initialization tweet failed, but bot continues running');
  }
  
  // Main bot loop
  setInterval(async () => {
    try {
      // Check and respond to mentions every 5 minutes
      await respondToMentions();
      
      // Example: Search and interact with tweets about a specific topic
      // await searchAndInteract('#SquareCloud');
      
    } catch (error) {
      console.error('Error in main loop:', error);
    }
  }, 5 * 60 * 1000); // 5 minutes
  
  console.log('Bot running. Press Ctrl+C to stop.');
}

// Signal handling for graceful shutdown
process.on('SIGINT', () => {
  console.log('\nShutting down X bot...');
  process.exit(0);
});

process.on('SIGTERM', () => {
  console.log('\nShutting down X bot...');
  process.exit(0);
});

// Initialize the bot
runBot();

Desplegando

Tras preparar los archivos de tu proyecto, ya puedes subirlos a Square Cloud y alojar tu proyecto. Para ello, crea un archivo ZIP que contenga todos los archivos de tu proyecto.
Seguridad: Nunca incluyas tus credenciales de la API directamente en el código. Usa siempre variables de entorno en Square Cloud.
En Square Cloud, configura las siguientes variables de entorno a través del panel de control:
  • API_KEY: Tu clave de API de X
  • API_SECRET_KEY: Tu clave secreta de API de X
  • ACCESS_TOKEN: Tu token de acceso
  • ACCESS_TOKEN_SECRET: Tu secreto del token de acceso

A través del panel

1

Accede a la página de subida

Accede a la página de subida y sube el archivo zip de tu proyecto.
2

Configura tu entorno

Después de subir tu zip, deberás configurar el nombre, el archivo principal o el entorno de ejecución y otros ajustes de tu proyecto.
Si estás subiendo un proyecto web, asegúrate de seleccionar “Publicación Web” y de definir un subdominio para tu proyecto.
3

Despliega tu proyecto

Por último, haz clic en el botón “Deploy” para alojar tu proyecto en Square Cloud.
Tras el despliegue, puedes monitorear el estado y los logs de tu proyecto desde el panel.
Subiendo aplicación a Square Cloud

A través de la CLI

Para usar este método, necesitas crear un archivo de configuración llamado squarecloud.app en el directorio raíz de tu proyecto. Este archivo contendrá la configuración necesaria para tu proyecto.

Aprende más sobre: cómo crear el archivo de configuración para Square Cloud.

El archivo squarecloud.app es un archivo de configuración que se usará para configurar tu aplicación; se utilizará para definir tu entorno.
1

Instala la CLI

Primero, necesitas tener la CLI instalada en tu entorno. Si aún no la tienes, ejecuta el siguiente comando en tu terminal:
npm install -g @squarecloud/cli
Si ya la tienes, te recomendamos actualizarla. Para ello, ejecuta el siguiente comando en tu terminal:
squarecloud update
2

Autentícate

Ahora, para autenticarte y usar otros comandos de la CLI, encontrarás tu clave de autorización aquí haciendo clic en “Request API Key”. Después de obtener tu clave de autorización, ejecuta el siguiente comando:
squarecloud auth login
3

Sube tu proyecto

Por último, para desplegar tu aplicación en Square Cloud usando la CLI, necesitas ejecutar el siguiente comando:
squarecloud upload 
O si creaste el zip manualmente, puedes usar:
squarecloud upload --file <path/to/zip> 

Recursos adicionales

Para profundizar tus conocimientos sobre el desarrollo de bots de X usando twitter-api-v2, consulta la documentación oficial de la biblioteca twitter-api-v2. La documentación proporciona guías detalladas, tutoriales avanzados y referencias completas de la API para maximizar tu implementación. Consulta también:

Monitoreo de hashtags

// Function to monitor specific hashtags
async function monitorHashtags(hashtags) {
  for (const hashtag of hashtags) {
    try {
      const tweets = await rwClient.v2.search(`#${hashtag}`, {
        max_results: 10,
      });

      // Process found tweets
      for (const tweet of tweets.data?.data ?? []) {
        console.log(`Tweet found with #${hashtag}: ${tweet.text}`);
        // Implement interaction logic
      }
    } catch (error) {
      console.error(`Error monitoring #${hashtag}:`, error);
    }
  }
}

Publicaciones programadas

// Function to schedule posts
function schedulePost(text, delay) {
  setTimeout(async () => {
    try {
      await postTweet(text);
      console.log('Scheduled post published successfully!');
    } catch (error) {
      console.error('Error publishing scheduled post:', error);
    }
  }, delay);
}

// Example: Schedule a post for 1 hour
schedulePost('🤖 Scheduled post by the bot!', 60 * 60 * 1000);

Rate Limiting

X (Twitter) tiene límites de tasa estrictos. Implementa controles para evitar exceder estos límites:
// Rate limiting control
const rateLimiter = {
  lastRequest: 0,
  minInterval: 1000, // 1 second between requests
  
  async wait() {
    const now = Date.now();
    const timeSinceLastRequest = now - this.lastRequest;
    
    if (timeSinceLastRequest < this.minInterval) {
      const waitTime = this.minInterval - timeSinceLastRequest;
      await new Promise(resolve => setTimeout(resolve, waitTime));
    }
    
    this.lastRequest = Date.now();
  }
};

Manejo de errores

// Helper function to retry an operation on failure
async function retryOperation(operation, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await operation();
    } catch (error) {
      console.error(`Attempt ${i + 1} failed:`, error.message);
      
      if (i === maxRetries - 1) {
        throw error;
      }
      
      // Wait before retrying
      await new Promise(resolve => setTimeout(resolve, 2000 * (i + 1)));
    }
  }
}

Contáctanos

Si continúas enfrentando dificultades técnicas, nuestro equipo de soporte especializado está disponible para ayudarte. Contáctanos y estaremos encantados de ayudarte a resolver cualquier problema.