> ## Documentation Index
> Fetch the complete documentation index at: https://docs.squarecloud.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Comment héberger des bots X (Twitter)

> Apprenez à créer et héberger un bot X (Twitter) sur Square Cloud. Tutoriel complet avec configuration, déploiement et exemples pratiques en Node.js et Python.

export const RecommendedPlan = ({lang, plan, tier, cpu, appType}) => {
  const url = `https://squarecloud.app/${lang}/pay?plan=${plan.toLowerCase()}&tier=${tier}`;
  if (lang == 'en') {
    return <Note>
        <b>Wondering how much RAM and CPU your plan needs to host {appType}?</b><br />
        Don't worry, we're here to help.
        Our <a href={url}>{plan}</a> plan offers <b>{tier}GB</b> of RAM and <b>{cpu}vCPU</b>, which should be sufficient for most {appType}. 
        However, if you are working on a larger project and seeking extra stability, we recommend considering our <b>Pro</b> plan. With additional resources, you can maintain stability even during demand spikes. 
        To purchase, simply click <a href="https://squarecloud.app/en/pay?plan=pro">here</a>.
      </Note>;
  } else {
    return <Note>
          <b>Está se perguntando quanta RAM e CPU seu plano precisa para hospedar {appType}?</b><br />
          Não se preocupe, estamos aqui para ajudar.
          Nosso plano <a href={url}>{plan}</a> oferece <b>{tier}GB</b> de RAM e <b>{cpu}vCPU</b>, o que deve ser suficiente para a maioria dos {appType}.
          No entanto, se você estiver trabalhando em um projeto maior e precisar de mais estabilidade, recomendamos considerar nosso plano <b>Pro</b>.
          Com recursos adicionais, você pode manter a estabilidade mesmo durante picos de demanda.
          Para comprar, basta clicar <a href={`https://squarecloud.app/${lang}/pay?plan=pro`}>aqui</a>.
        </Note>;
  }
};

export const appType_0 = "a X (Twitter) bot"

## Introduction

Pour développer et héberger {appType_0} sur Square Cloud, il est essentiel de suivre une séquence structurée de configurations et de prérequis. Ce guide technique couvrira l'ensemble du processus, de la configuration initiale au déploiement en production.

### Prérequis

* **Compte Square Cloud** : Inscrivez-vous via la [page d'inscription](https://squarecloud.app/fr/signup) en utilisant votre adresse e-mail.
* **Plan payant actif** : Garantit des ressources dédiées et des performances optimisées pour votre application. Consultez nos [plans disponibles](https://squarecloud.app/fr/pricing) et choisissez celui qui convient le mieux à vos besoins.

<RecommendedPlan appType="X (Twitter)" plan="Hobby" tier="2" cpu="2" lang="en" />

### Création du projet

Un compte X (Twitter) actif est requis pour l'authentification et le fonctionnement du bot. Si vous n'avez pas de compte, inscrivez-vous sur le [site officiel de X](https://x.com/).\
Un compte X Developer est également requis pour accéder aux API. Demandez l'accès via le [X Developer Portal](https://developer.x.com/en).

### Application du bot sur X

<Steps>
  <Step title="Accéder au Developer Portal">
    1. Rendez-vous sur le [X Developer Portal](https://developer.x.com/en/portal/dashboard).
    2. Connectez-vous avec votre compte X (Twitter).
    3. Si c'est votre première fois, complétez le processus de demande d'accès développeur.
  </Step>

  <Step title="Création du projet">
    1. Dans le tableau de bord, cliquez sur "Create Project".
    2. Choisissez un nom pour votre projet (par ex. "Square Cloud Bot").
    3. Sélectionnez le cas d'usage le plus approprié (par ex. "Making a bot").
    4. Fournissez une description détaillée de votre bot.
    5. Confirmez la création du projet.
  </Step>

  <Step title="Configuration de l'application">
    1. Au sein du projet créé, cliquez sur "Create App".
    2. Définissez un nom unique pour votre application.
    3. Confirmez la création de l'application.
    4. Notez l'**App ID** généré pour référence future.
  </Step>

  <Step title="Génération des clés d'API">
    1. Accédez à la section "Keys and tokens" de votre application.
    2. Dans la section "Consumer Keys", cliquez sur "Regenerate" pour générer :
       * **API Key** (Consumer Key)
       * **API Secret Key** (Consumer Secret)
    3. **Important** : Copiez et enregistrez ces clés immédiatement, car vous ne pourrez plus les consulter par la suite.
  </Step>

  <Step title="Configuration des permissions">
    1. Rendez-vous dans la section "App permissions".
    2. Cliquez sur "Edit" pour modifier les permissions.
    3. Sélectionnez "Read and write" pour permettre à votre bot de publier des tweets.
    4. Si nécessaire, sélectionnez "Read and write and Direct message" pour la fonctionnalité de DM.
    5. Enregistrez les modifications.
  </Step>

  <Step title="Génération des jetons d'accès">
    1. Retournez dans la section "Keys and tokens".
    2. Dans la section "Access Token and Secret", cliquez sur "Generate".
    3. Confirmez la génération des jetons.
    4. Copiez et enregistrez :
       * **Access Token**
       * **Access Token Secret**
    5. **Attention** : Ces jetons ne peuvent plus être consultés après avoir fermé la page.
  </Step>

  <Step title="Vérification des identifiants">
    1. Confirmez que vous disposez des 4 identifiants requis :
       * API Key (Consumer Key)
       * API Secret Key (Consumer Secret)
       * Access Token
       * Access Token Secret
    2. Conservez ces identifiants dans un endroit sécurisé
    3. **Important** : Ne partagez ni n'exposez jamais publiquement ces identifiants
  </Step>
</Steps>

## Développement du projet

1. **Vérification de Node.js** : Vérifiez que Node.js est installé sur votre système. Sinon, téléchargez-le depuis le [site officiel de Node.js](https://nodejs.org/).

2. **Initialisation du projet** : Créez un nouveau projet Node.js en exécutant :

```bash Terminal theme={null}
npm init -y
```

3. **Installation des dépendances** : Installez les bibliothèques requises pour le bot :

```bash Terminal theme={null}
npm install twitter-api-v2
```

4. **Configuration des variables d'environnement** : Créez un fichier `.env` pour stocker vos identifiants de manière sécurisée :

```env .env theme={null}
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
```

5. **Création du fichier principal** : Développez le fichier `index.js` avec la structure de base du bot :

```javascript index.js theme={null}
// 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();
```

## Déploiement

Après avoir préparé les fichiers de votre projet, vous pouvez maintenant les téléverser sur Square Cloud et héberger votre projet.
Pour ce faire, créez un fichier ZIP contenant tous les fichiers de votre projet.

<AccordionGroup>
  <Accordion title="Variables d'environnement" icon="key">
    <Note>**Sécurité** : N'incluez jamais vos identifiants d'API directement dans le code. Utilisez toujours des variables d'environnement sur Square Cloud.</Note>

    Sur Square Cloud, configurez les variables d'environnement suivantes via le panneau de contrôle :

    * `API_KEY` : Votre clé d'API X
    * `API_SECRET_KEY` : Votre clé secrète d'API X
    * `ACCESS_TOKEN` : Votre jeton d'accès
    * `ACCESS_TOKEN_SECRET` : Votre secret de jeton d'accès
  </Accordion>
</AccordionGroup>

### Via le tableau de bord

<Steps>
  <Step title="Accéder à la page d'upload">
    Accédez à la [page d'upload](https://squarecloud.app/fr/dashboard/new) et téléversez le fichier zip de votre projet.
  </Step>

  <Step title="Configurer votre environnement">
    Après avoir téléversé votre zip, vous devrez configurer le nom, le fichier principal ou l'environnement d'exécution ainsi que d'autres paramètres de votre projet.\
    Si vous téléversez un projet web, veillez à sélectionner « Publication Web » et à définir un sous-domaine pour votre projet.
  </Step>

  <Step title="Déployer votre projet">
    Enfin, cliquez sur le bouton « Deploy » pour héberger votre projet sur Square Cloud.\
    Une fois le déploiement effectué, vous pouvez suivre l'état et les logs de votre projet depuis le tableau de bord.

    <Frame>
      <img src="https://cdn.squarecloud.app/docs/articles/dashboard/uploading.gif" alt="Téléversement d'une application vers Square Cloud" style={{ borderRadius: "0.2rem" }} />
    </Frame>
  </Step>
</Steps>

### Via la CLI

Pour utiliser cette méthode, vous devez créer un fichier de configuration nommé `squarecloud.app` à la racine de votre projet. Ce fichier contiendra la configuration nécessaire à votre projet.

<Card title="En savoir plus : comment créer le fichier de configuration pour Square Cloud." icon="link" href="/fr/getting-started/config-file">
  Le fichier squarecloud.app est un fichier de configuration qui servira à configurer votre application ; il sera utilisé pour définir votre environnement.
</Card>

<Steps>
  <Step title="Installer la CLI">
    Tout d'abord, vous devez avoir la CLI installée dans votre environnement. Si ce n'est pas encore le cas, exécutez la commande suivante dans votre terminal :

    ```
    npm install -g @squarecloud/cli
    ```

    Si vous l'avez déjà, nous vous recommandons de la mettre à jour. Pour cela, exécutez la commande suivante dans votre terminal :

    <Tabs>
      <Tab title="Windows">
        ```bash theme={null}
        squarecloud update
        ```
      </Tab>

      <Tab title="Linux, macOS et WSL">
        ```bash theme={null}
        curl -fsSL https://cli.squarecloud.app/install | bash
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="S'authentifier">
    Maintenant, pour vous authentifier et utiliser les autres commandes de la CLI, vous trouverez votre clé d'autorisation [ici](https://squarecloud.app/fr/account/security) en cliquant sur « Request API Key ». Après avoir obtenu votre clé d'autorisation, exécutez la commande suivante :

    ```bash theme={null}
    squarecloud auth login
    ```
  </Step>

  <Step title="Téléverser votre projet">
    Enfin, pour déployer votre application sur Square Cloud à l'aide de la CLI, vous devez exécuter la commande suivante :

    ```bash theme={null}
    squarecloud upload 
    ```

    Ou si vous avez créé le zip manuellement, vous pouvez utiliser :

    ```bash theme={null}
    squarecloud upload --file <path/to/zip> 
    ```
  </Step>
</Steps>

## Ressources supplémentaires

Pour approfondir vos connaissances sur le développement de bots X avec twitter-api-v2, consultez la [documentation officielle de la bibliothèque twitter-api-v2](https://github.com/PLhery/node-twitter-api-v2). La documentation fournit des guides détaillés, des tutoriels avancés et des références complètes de l'API pour maximiser votre implémentation.

Consultez également :

* [Documentation officielle de l'API X](https://docs.x.com/overview)
* [Politiques d'utilisation de l'API X](https://developer.x.com/en/developer-terms/policy)
* [Guide des bonnes pratiques pour les bots](https://docs.x.com/x-api/getting-started/about-x-api)

### Surveillance de hashtags

```javascript theme={null}
// 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);
    }
  }
}
```

### Publications programmées

```javascript theme={null}
// 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);
```

### Limitation de débit

X (Twitter) applique des limites de débit strictes. Mettez en place des contrôles pour éviter de dépasser ces limites :

```javascript theme={null}
// 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();
  }
};
```

### Gestion des erreurs

```javascript theme={null}
// 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)));
    }
  }
}
```

## Contactez-nous

Si vous rencontrez toujours des **difficultés techniques**, notre **équipe de support spécialisée** est disponible pour vous aider. [**Contactez-nous**](https://squarecloud.app/fr/support) et nous serons ravis de vous aider à résoudre tout problème.
