Envoyer des messages WhatsApp depuis Google Sheets avec C NET

18 décembre 2024

Dans ce tutoriel, vous apprendrez à envoyer des messages vers des numéros de téléphone stockés dans un fichier CSV exporté depuis Google Sheets en utilisant C# et l’API Wassenger. Nous téléchargerons le fichier CSV depuis Google Sheets, lirons les numéros de téléphone et enverrons des messages via votre numéro WhatsApp

Comment automatiser WhatsApp avec l’IA

Prérequis

  • Connaissances de base en C# (.NET) : Familiarité avec la programmation en C# et la manipulation d’API HTTP.
  • .NET installé : Assurez-vous que le .NET SDK est installé sur votre machine. Vous pouvez le télécharger depuis le site .NET de Microsoft.
  • Packages NuGet : Installez les bibliothèques suivantes : - CsvHelper : Pour analyser les fichiers CSV téléchargés depuis Google Sheets. - RestSharp : Pour effectuer des requêtes HTTP vers l’API Wassenger.
  • Token API Wassenger : Vous pouvez obtenir votre token API depuis Wassenger en vous inscrivant, en créant un espace de travail et en générant une clé API.
  • URL de téléchargement CSV de Google Sheets : Publiez votre Google Sheets en tant que fichier CSV et copiez l’URL de téléchargement. Cela nécessite d’activer « Publier sur le web » dans Google Sheets et de copier le lien.

Installer les packages requis

Premièrement, créez un nouveau répertoire pour votre projet et placez-vous dedans dans le terminal. Ensuite, exécutez les commandes suivantes pour installer les bibliothèques nécessaires :

Installer les packages requis

  1. Créez un nouveau répertoire pour votre projet :
mkdir WhatsAppMessaging cd WhatsAppMessaging

2. Initialisez un nouveau projet .NET :

dotnet new console

3. Installez les packages NuGet nécessaires :

  • CsvHelper pour lire les fichiers CSV :
dotnet add package CsvHelper
  • RestSharp pour gérer les requêtes HTTP :
dotnet add package RestSharp

Préparer le fichier CSV de Google Sheets

Créez un nouveau document Google Sheets et remplissez-le avec deux colonnes :

  • Première colonne : numéro de téléphone au format E.164 avec l’indicatif du pays.
  • Deuxième colonne : message texte à envoyer au numéro cible.

Le document Google Sheets doit contenir au minimum deux colonnes et ressembler à :

Le document Sheets équivalent exporté en CSV devrait ressembler à ceci :

(+1234567890,
  '👋 Welcome to {{your-business-name}}! Thanks for signing up.We are just a message away!' +
    1234567890,
  "💐 Your order has been shipped.Tracking number is {{tracking-number}}.Don't hesitate to reach out to if you need help! 🤗");

Obtenir l’URL de téléchargement de votre document Google Sheets

  1. Cliquez sur « Fichier » en haut à gauche.
  2. Allez dans « Partager » > « Publier sur le web ».
  3. Dans l’onglet « Lien », sélectionnez « Valeurs séparées par des virgules (.csv) » dans le menu déroulant.
  4. Sélectionnez la feuille souhaitée contenant les données : par défaut la première.
  5. Cliquez sur « Publier » et copiez l’URL.

Envoyer des messages texte

Créez un nouveau fichier nommé sendMessages.cs dans le répertoire de votre projet et ajoutez le code suivant :

using CsvHelper; using RestSharp; using System.Globalization; using System.IO; using System.Linq; using System.Text.Json; using System.Text.Json.Serialization; using System.Threading.Tasks;

public class SendMessages { private static readonly string GoogleSheetsCsvUrl = "ENTER_GOOGLE_SHEETS_CSV_URL_HERE"; // Replace with the Google Sheets CSV URL private static readonly string Token = "API_KEY_GOES_HERE"; // Replace with your Wassenger API Token private static readonly string DeviceId = "DEVICE_ID"; // Replace with your Device ID private static readonly string MessagesUrl = "https://api.wassenger.com/v1/messages";

public static async Task RunAsync()
{
    var records = await DownloadAndParseCsvAsync(GoogleSheetsCsvUrl);
    if (records == null)
    {
        Console.WriteLine("Failed to process the CSV file.");
        return;
    }

    foreach (var record in records)
    {
        string phone = record.Phone;
        string message = record.Message;

        if (string.IsNullOrWhiteSpace(phone) || string.IsNullOrWhiteSpace(message))
        {
            continue;
        }

        string normalizedPhone = NormalizePhone(phone);
        if (!string.IsNullOrEmpty(normalizedPhone))
        {
            await SendMessageAsync(normalizedPhone, message);
        }
    }
}

private static async Task<IEnumerable<Record>> DownloadAndParseCsvAsync(string url)
{
    using var httpClient = new HttpClient();
    try
    {
        string csvContent = await httpClient.GetStringAsync(url);
        using var reader = new StringReader(csvContent);
        using var csv = new CsvReader(reader, CultureInfo.InvariantCulture);
        return csv.GetRecords<Record>().ToList();
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Error downloading or parsing CSV: {ex.Message}");
        return null;
    }
}

private static async Task SendMessageAsync(string phone, string message)
{
    var client = new RestClient(MessagesUrl);
    var request = new RestRequest(Method.POST)
        .AddHeader("Authorization", $"Bearer {Token}")
        .AddHeader("Content-Type", "application/json")
        .AddJsonBody(new
        {
            phone = phone,
            body = message,
            device = DeviceId
        });

    var response = await client.ExecuteAsync(request);
    if (response.IsSuccessful)
    {
        Console.WriteLine($"Message sent to {phone}");
    }
    else
    {
        Console.WriteLine($"Failed to send message to {phone}: {response.Content}");
    }
}

private static string NormalizePhone(string phone)
{
    return "+" + new string(phone.Where(char.IsDigit).ToArray());
}

public class Record
{
    \[JsonPropertyName("phone")\]
    public string Phone { get; set; }

    \[JsonPropertyName("message")\]
    public string Message { get; set; }
}

}

Jouer et exécuter du code dans le cloud sans installer de logiciel sur votre ordinateur. Créez un compte gratuit sur Replit et commencez en quelques minutes

Envoyer des messages média

Dans cet exemple, nous allons créer un programme différent sendMedia.cs pour envoyer plusieurs messages média (images) à différents numéros chargés depuis un document Google Sheets.

Pour envoyer un message média, la façon la plus simple est de fournir une URL de téléchargement du fichier. Si votre fichier n’est pas déjà hébergé, vous pouvez le téléverser sur Google Drive et rendre le fichier publiquement téléchargeable par l’API pour l’envoyer ensuite.

Exemple d’URL de téléchargement depuis un fichier public sur Google Drive :

https://drive.google.com/uc?id=1RG3CAPiwiFlFATUlIIwhk0RrbEU4PgVP&export=download

Important : l’URL de téléchargement fournie doit renvoyer le contenu binaire du fichier, sinon l’envoi échouera.*

Créez un nouveau fichier nommé sendMedia.cs dans le répertoire de votre projet et ajoutez le code suivant :

using CsvHelper; using RestSharp; using System.Globalization; using System.IO; using System.Linq; using System.Text.Json; using System.Text.Json.Serialization; using System.Threading.Tasks;

public class SendMedia { private static readonly string GoogleSheetsCsvUrl = "ENTER_GOOGLE_SHEETS_CSV_URL_HERE"; // Replace with the Google Sheets CSV URL private static readonly string FileUrl = "https://picsum.photos/seed/picsum/600/500"; // Replace with your media file URL private static readonly string Token = "API_KEY_GOES_HERE"; // Replace with your Wassenger API Token private static readonly string DeviceId = "DEVICE_ID"; // Replace with your Device ID private static readonly string BaseUrl = "https://api.wassenger.com/v1"; private static readonly string MessagesUrl = $"{BaseUrl}/messages"; private static readonly string FilesUrl = $"{BaseUrl}/files";

public static async Task RunAsync()
{
    // Download and parse Google Sheets CSV
    var records = await DownloadAndParseCsvAsync(GoogleSheetsCsvUrl);
    if (records == null)
    {
        Console.WriteLine("Failed to process the CSV file.");
        return;
    }

    // Upload file to Wassenger
    string fileId = await UploadFileAsync(FileUrl);
    if (fileId == null)
    {
        Console.WriteLine("Failed to upload the file.");
        return;
    }

    // Process and send messages
    foreach (var record in records)
    {
        string phone = record.Phone;
        string message = record.Message;

        if (string.IsNullOrWhiteSpace(phone) || string.IsNullOrWhiteSpace(message))
        {
            continue;
        }

        string normalizedPhone = NormalizePhone(phone);
        if (!string.IsNullOrEmpty(normalizedPhone) && normalizedPhone.Length >= 8)
        {
            await SendMessageAsync(normalizedPhone, message, fileId);
        }
    }
}

private static async Task<IEnumerable<Record>> DownloadAndParseCsvAsync(string url)
{
    using var httpClient = new HttpClient();
    try
    {
        string csvContent = await httpClient.GetStringAsync(url);
        using var reader = new StringReader(csvContent);
        using var csv = new CsvReader(reader, CultureInfo.InvariantCulture);
        return csv.GetRecords<Record>().ToList();
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Error downloading or parsing CSV: {ex.Message}");
        return null;
    }
}

private static async Task<string\> UploadFileAsync(string fileUrl)
{
    var client = new RestClient(FilesUrl);
    var request = new RestRequest(Method.POST)
        .AddHeader("Authorization", $"Bearer {Token}")
        .AddHeader("Content-Type", "application/json")
        .AddJsonBody(new { url = fileUrl });

    var response = await client.ExecuteAsync(request);
    if (response.IsSuccessful)
    {
        var responseBody = JsonSerializer.Deserialize<UploadFileResponse>(response.Content);
        return responseBody?.Id;
    }
    else
    {
        Console.WriteLine($"Failed to upload file: {response.Content}");
        return null;
    }
}

private static async Task SendMessageAsync(string phone, string message, string fileId)
{
    var client = new RestClient(MessagesUrl);
    var request = new RestRequest(Method.POST)
        .AddHeader("Authorization", $"Bearer {Token}")
        .AddHeader("Content-Type", "application/json")
        .AddJsonBody(new
        {
            phone = phone,
            message = message.Trim(),
            device = DeviceId,
            media = new { file = fileId }
        });

    var response = await client.ExecuteAsync(request);
    if (response.IsSuccessful)
    {
        Console.WriteLine($"Message sent to {phone}");
    }
    else
    {
        Console.WriteLine($"Failed to send message to {phone}: {response.Content}");
    }
}

private static string NormalizePhone(string phone)
{
    return "+" + new string(phone.Where(char.IsDigit).ToArray());
}

public class Record
{
    \[JsonPropertyName("phone")\]
    public string Phone { get; set; }

    \[JsonPropertyName("message")\]
    public string Message { get; set; }
}

public class UploadFileResponse
{
    \[JsonPropertyName("id")\]
    public string Id { get; set; }
}

}

Jouer et exécuter du code dans le cloud sans installer de logiciel sur votre ordinateur. Créez un compte gratuit sur Replit et commencez en quelques minutes

Remplacez l’URL Google Sheets pour l’exporter en CSV

Dans les fichiers sendMessages.cs et sendMedia.cs, assurez-vous d’avoir remplacé l’URL CSV de Google Sheets et votre vrai token API Wassenger :

// Replace this with the URL of your published Google Sheets CSV file
private static readonly string GoogleSheetsCsvUrl = "ENTER_GOOGLE_SHEETS_CSV_URL_HERE";

Voir les indications ci‑dessus pour obtenir l’URL de téléchargement Google Sheets à entrer ici.

Remplacez le token API

Dans le fichier send_messages.php, assurez-vous d’avoir défini le token API de votre compte Wassenger réel :

// Replace this with your Wassenger API token
private static readonly string Token = "ENTER API KEY HERE";

Optionnellement, si vous avez plusieurs numéros WhatsApp connectés à votre compte Wassenger, vous pouvez préciser quel numéro WhatsApp vous souhaitez utiliser pour la livraison des messages en spécifiant l’ID de périphérique unique Wassenger (valeur hexadécimale de 24 caractères) dans la ligne suivante :

// Optionally specify the target WhatsApp device ID connected to Wassenger private static readonly string DeviceId = "DEVICE ID GOES HERE";

Exécuter le programme

Avant d’exécuter le programme, si vous prévoyez d’envoyer des centaines de messages à la suite, nous recommandons de définir une vitesse d’envoi inférieure, pas plus de 2–3 messages par minute, afin de prévenir les problèmes de blocage dus aux politiques anti‑spam de WhatsApp. En savoir plus sur les bonnes pratiques et comment réduire les risques ici.

Exécuter le programme dans le cloud

Vous pouvez exécuter le programme gratuitement dans le cloud sur Replit.com sans installer de logiciel sur votre ordinateur.

Créez simplement un nouveau projet et copiez-collez le code fourni, puis cliquez sur « Run » pour envoyer les messages. C’est aussi simple que ça 😀

Exécuter le programme sur votre ordinateur

Ouvrez un terminal dans le répertoire de votre projet et exécutez la commande suivante pour lancer le script sendMessages.cs ou sendMedia.cs :

dotnet run --project sendMessages.csproj

De la même façon, vous pouvez exécuter le script sendMedia.cs pour envoyer des messages média :

dotnet run --project sendMedia.csproj

Si tout est correctement configuré, vous devriez voir un retour indiquant que les messages ont été créés avec succès :

Message sent to +1234567890
Message sent to +1234567890
Message sent to +1234567890

Notez que les messages seront ajoutés à la file de livraison de votre numéro et seront délivrés de manière asynchrone en arrière‑plan au fil du temps, en fonction de la vitesse de livraison par minute liée à l’abonnement de votre numéro ou de la vitesse de livraison configurée manuellement dans les paramètres de votre numéro.

Les messages peuvent mettre plusieurs minutes voire plusieurs heures, selon le volume créé, pour être effectivement délivrés aux numéros cibles via WhatsApp. Vous pouvez suivre la progression de la livraison des messages dans le panneau web ou automatiquement en utilisant les événements webhook.

FAQ

Comment puis‑je obtenir l’URL de téléchargement CSV de Google Sheets pour l’utiliser avec le programme C#.NET ?

Les étapes détaillées pour publier un document Google Sheets en CSV sont couvertes ci‑dessous, y compris comment rendre le fichier public :

  1. Ouvrez votre document Google Sheets.
  2. Allez dans Fichier > Partager > Publier sur le web.
  3. Sous l’onglet « Lien », sélectionnez Valeurs séparées par des virgules (.csv) comme format.
  4. Copiez le lien généré et collez‑le dans la variable GoogleSheetsCsvUrl de votre script C#.NET.

Quels prérequis sont nécessaires pour envoyer des messages WhatsApp depuis Google Sheets en C#.NET ?

Pour exécuter le programme C#.NET, vous avez besoin de :

  • .NET SDK installé : Installez le dernier .NET SDK depuis le site .NET de Microsoft.
  • Packages NuGet requis :

- CsvHelper : Pour analyser les fichiers CSV.

- RestSharp : Pour gérer les requêtes HTTP vers l’API Wassenger.

  • Token API Wassenger : Obtenez votre token API depuis le tableau de bord Wassenger.
  • URL CSV Google Sheets : Publiez votre Google Sheets en tant que fichier CSV et copiez l’URL de téléchargement.

Exécutez les commandes suivantes dans le terminal pour installer les dépendances :

dotnet add package CsvHelper
dotnet add package RestSharp

Comment puis‑je m’assurer que les messages sont délivrés sans déclencher les politiques anti‑spam de WhatsApp ?

Les bonnes pratiques pour éviter les problèmes anti‑spam incluent :

  • Ralentir la livraison des messages : Limitez l’envoi à 2–3 messages par minute en introduisant un délai entre les requêtes :
await Task.Delay(30000); // Adds a 30-second delay
  • Personnaliser les messages : Utilisez de légères variations dans les messages pour éviter d’être détecté comme spam.
  • Respecter les directives de WhatsApp : Évitez d’envoyer des messages non sollicités ou du contenu excessivement répétitif.
  • Surveiller les réponses de l’API : Vérifiez les erreurs ou les messages de limitation de taux dans les réponses de l’API Wassenger pour ajuster votre programme en conséquence.

Pour des conseils plus détaillés, consultez la documentation de Wassenger sur les bonnes pratiques et les politiques anti‑spam.

Ready to transform your WhatsApp communication?

Start automating your customer interactions today with Wassenger

Get Started Free