Invia messaggi WhatsApp da Google Sheets usando C NET

18 dicembre 2024

In questo tutorial imparerai come inviare messaggi a numeri di telefono memorizzati in un file CSV di Google Sheets usando C# e Wassenger API. Scaricheremo il file CSV da Google Sheets, leggeremo i numeri di telefono e invieremo i messaggi tramite il tuo numero WhatsApp

Come automatizzare WhatsApp con l'AI

Prerequisiti

  • Conoscenze di base di C# (.NET): Familiarità con la programmazione in C# e la gestione di API HTTP.
  • .NET installato: Assicurati che lo SDK .NET sia installato sul tuo computer. Puoi scaricarlo dal sito .NET di Microsoft.
  • Pacchetti NuGet: Installa le seguenti librerie:
    • CsvHelper: per il parsing dei file CSV scaricati da Google Sheets.
    • RestSharp: per le richieste HTTP all'API di Wassenger.
  • Token API di Wassenger: Puoi ottenere il tuo token API da Wassenger registrandoti, creando uno workspace e generando una chiave API.
  • URL di download CSV di Google Sheets: Pubblica il tuo Google Sheets come file CSV e copia l'URL di download. Questo richiede di abilitare “Pubblica sul web” in Google Sheets e copiare il link.

Installa i pacchetti richiesti

Per prima cosa, crea una nuova directory per il tuo progetto e spostati in essa nel terminale. Poi esegui i seguenti comandi per installare le librerie necessarie:

Installa i pacchetti richiesti

  1. Crea una nuova directory per il tuo progetto:
mkdir WhatsAppMessaging cd WhatsAppMessaging
  1. Inizializza un nuovo progetto .NET:
dotnet new console
  1. Installa i pacchetti NuGet necessari:
  • CsvHelper per leggere i file CSV:
dotnet add package CsvHelper
  • RestSharp per gestire le richieste HTTP:
dotnet add package RestSharp

Prepara il file CSV di Google Sheets

Crea un nuovo documento Google Sheets e compilalo con due colonne:

  • Prima colonna: numero di telefono in formato E.164 con il prefisso internazionale.
  • Seconda colonna: testo del messaggio da inviare al numero di destinazione.

Il documento Google Sheets dovrebbe avere almeno due colonne e apparire così:

Il documento Sheets equivalente esportato come CSV dovrebbe apparire così:

(+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! 🤗");

Ottieni l'URL di download del tuo documento Google Sheets

  1. Clicca su "File" nell'angolo in alto a sinistra.
  2. Vai su "Condividi" > "Pubblica sul web".
  3. Nella scheda "Link", seleziona "Valori separati da virgola (.csv)" dal menu a tendina.
  4. Seleziona la pagina del foglio desiderata con i dati rilevanti: di default la prima.
  5. Clicca su "Pubblica" e copia l'URL.

Inviare messaggi di testo

Crea un nuovo file chiamato sendMessages.cs nella directory del tuo progetto e aggiungi il seguente codice:

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; }
}

}

Esegui e prova il codice nel cloud senza installare alcun software sul tuo computer. Crea un account gratuito su Replit e inizia in pochi minuti

Inviare messaggi multimediali

In questo esempio, creeremo un programma diverso sendMedia.cs per inviare più messaggi multimediali (immagini) a diversi numeri di telefono caricati da un documento Google Sheets.

Per inviare un messaggio multimediale, il modo più semplice è fornire un URL di download del file. Se il tuo file non è già caricato da qualche parte, puoi caricarlo su Google Drive e rendere il file pubblicamente disponibile per essere scaricato dall'API e inviato successivamente.

Esempio di URL di download da un file pubblico su Google Drive:

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

Importante: l'URL di download fornito deve restituire il contenuto binario del file, altrimenti fallirà.

Crea un nuovo file chiamato sendMedia.cs nella directory del tuo progetto e aggiungi il seguente codice:

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; }
}

}

Esegui e prova il codice nel cloud senza installare alcun software sul tuo computer. Crea un account gratuito su Replit e inizia in pochi minuti

Sostituire l'URL di Google Sheets per esportare come CSV

Nei file sendMessages.cs e sendMedia.cs, assicurati di aver sostituito l'URL CSV di Google Sheets e il token API reale di Wassenger:

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

Vedi le indicazioni sopra per ottenere l'URL di download di Google Sheets da inserire qui.

Sostituire il token API

Nel file send_messages.php, assicurati di aver definito il token API del tuo account Wassenger:

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

Opzionalmente, se hai più numeri WhatsApp collegati al tuo account Wassenger, puoi specificare quale numero WhatsApp vuoi usare per la consegna dei messaggi specificando l'ID univoco del dispositivo Wassenger (valore esadecimale di 24 caratteri) nella seguente riga:

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

Esegui il programma

Prima di eseguire il programma, se prevedi di inviare centinaia di messaggi uno dopo l'altro, consigliamo di definire una velocità di consegna dei messaggi inferiore, non più di 2–3 messaggi al minuto, per prevenire problemi di ban dovuti alle politiche anti-spam di WhatsApp. Scopri di più sulle best practice e come ridurre il rischio qui.

Esegui il programma nel cloud

Puoi eseguire il programma nel cloud gratuitamente su Replit.com senza installare alcun software sul tuo computer.

Semplicemente crea un nuovo progetto e copia & incolla il codice fornito, poi clicca su “Run” per inviare i messaggi. È così semplice 😀

Esegui il programma sul tuo computer

Apri un terminale nella directory del tuo progetto ed esegui il seguente comando per eseguire lo script sendMessages.cs o sendMedia.cs:

dotnet run --project sendMessages.csproj

Allo stesso modo, puoi eseguire lo script sendMedia.cs per inviare messaggi multimediali:

dotnet run --project sendMedia.csproj

Se tutto è configurato correttamente, dovresti vedere un output che indica che i messaggi sono stati creati con successo:

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

Nota: i messaggi verranno aggiunti alla coda di consegna del tuo numero e consegnati in modo asincrono in background nel tempo, in base al limite di velocità di consegna dei messaggi al minuto del tuo numero o alla velocità di consegna configurata manualmente nelle impostazioni del tuo numero.

I messaggi potrebbero impiegare diversi minuti o ore, a seconda di quanti ne hai creati, per essere effettivamente recapitati ai numeri di telefono target tramite WhatsApp. Puoi monitorare l'avanzamento della consegna dei messaggi nel pannello web o automaticamente usando gli eventi webhook.

FAQ

Come posso ottenere l'URL di download CSV di Google Sheets da utilizzare con il programma C#.NET?

I passaggi dettagliati per pubblicare un documento Google Sheets come CSV sono trattati sopra, inclusa la procedura per condividere il file pubblicamente:

  1. Apri il tuo documento Google Sheets.
  2. Vai su File > Condividi > Pubblica sul web.
  3. Nella scheda "Link", seleziona Valori separati da virgola (.csv) come formato.
  4. Copia il link generato e incollalo nella variabile GoogleSheetsCsvUrl nel tuo script C#.NET.

Quali prerequisiti sono necessari per inviare messaggi WhatsApp da Google Sheets usando C#.NET?

Per eseguire il programma C#.NET, ti serve:

  • SDK .NET installato: Installa l'ultimo SDK .NET dal sito .NET di Microsoft.

  • Pacchetti NuGet richiesti:

  • CsvHelper: per il parsing dei file CSV.

  • RestSharp: per gestire le richieste HTTP all'API di Wassenger.

  • Token API di Wassenger: ottieni il token API dalla dashboard di Wassenger.

  • URL CSV di Google Sheets: pubblica il tuo Google Sheets come file CSV e copia l'URL di download.

Esegui i seguenti comandi nel terminale per installare le dipendenze:

dotnet add package CsvHelper
dotnet add package RestSharp

Come posso assicurarmi che i messaggi vengano consegnati senza attivare le politiche anti-spam di WhatsApp?

Le best practice per evitare problemi di anti-spam includono:

  • Limitare la velocità di invio dei messaggi: riduci l'invio a 2–3 messaggi al minuto introducendo una pausa tra le richieste:
await Task.Delay(30000); // Adds a 30-second delay
  • Personalizzare i messaggi: usa leggere variazioni nei messaggi per evitare di essere rilevati come spam.
  • Seguire le linee guida di WhatsApp: evita di inviare messaggi non richiesti o contenuti ripetuti in modo eccessivo.
  • Monitorare le risposte dell'API: verifica errori o messaggi di rate-limiting nelle risposte dell'API di Wassenger per adeguare il tuo programma.

Per una guida più dettagliata, consulta la documentazione di Wassenger sulle best practice e le politiche anti-spam.

Ready to transform your WhatsApp communication?

Start automating your customer interactions today with Wassenger

Get Started Free