Devlooped.WhatsApp 1.0.0-rc.3

Prefix Reserved
This is a prerelease version of Devlooped.WhatsApp.
There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package Devlooped.WhatsApp --version 1.0.0-rc.3
                    
NuGet\Install-Package Devlooped.WhatsApp -Version 1.0.0-rc.3
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Devlooped.WhatsApp" Version="1.0.0-rc.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Devlooped.WhatsApp" Version="1.0.0-rc.3" />
                    
Directory.Packages.props
<PackageReference Include="Devlooped.WhatsApp" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Devlooped.WhatsApp --version 1.0.0-rc.3
                    
#r "nuget: Devlooped.WhatsApp, 1.0.0-rc.3"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#addin nuget:?package=Devlooped.WhatsApp&version=1.0.0-rc.3&prerelease
                    
Install Devlooped.WhatsApp as a Cake Addin
#tool nuget:?package=Devlooped.WhatsApp&version=1.0.0-rc.3&prerelease
                    
Install Devlooped.WhatsApp as a Cake Tool

Create agents for WhatsApp using Azure Functions.

Usage

var builder = FunctionsApplication.CreateBuilder(args);
builder.ConfigureFunctionsWebApplication();

builder.UseWhatsApp<MyWhatsAppHandler>();

builder.Build().Run();

Instead of providing an IWhatsAppHandler implementation, you can also register an inline handler using minimal API style:

builder.UseWhatsApp(message =>
{
    // MessageType: Content | Error | Interactive | Status
    Console.WriteLine($"Got message type {message.Type}"); 
    switch (message)
    {
        case ContentMessage content:
            // ContentType = Text | Contact | Document | Image | Audio | Video | Location | Unknown (raw JSON)
            Console.WriteLine($"Got content type {content.Content.Type}"); 
            break;
        case ErrorMessage error:
            Console.WriteLine($"Error: {error.Error.Message} ({error.Error.Code})");
            break;
        case InteractiveMessage interactive:
            Console.WriteLine($"Interactive: {interactive.Button.Title} ({interactive.Button.Id})");
            break;
        case StatusMessage status:
            Console.WriteLine($"Status: {status.Status}");
            break;
    }
    return Task.CompletedTask;
});

If the handler needs additional services, they can be provided directly as generic parameters of the UseWhatsApp method, such as:

builder.UseWhatsApp<IWhatsAppClient, ILogger<Program>>(async (client, logger, message) =>
{
    logger.LogInformation($"Got message type {message.Type}");
    // Reply to an incoming content message, for example.
    if (message is ContentMessage content)
        await client.ReplyAsync(message, $"☑️ Got your {content.Content.Type}");
}

You can also specify the parameter types in the delegate itself and avoid the generic parameters:

builder.UseWhatsApp(async (IWhatsAppClient client, ILogger<Program> logger, Message message) =>

The provided IWhatsAppClient provides a very thin abstraction allowing you to send arbitrary payloads to WhatsApp for Business:

public interface IWhatsAppClient
{
    /// Payloads from https://developers.facebook.com/docs/whatsapp/cloud-api/reference/messages
    Task SendAync(string from, object payload);
}

Extensions methods for this interface take care of simplifying usage for some common scenarios, such as reacting to a message and replying with plain text:

if (message is ContentMessage content)
{
    await client.ReactAsync(message, "🧠");
    // simulate some hard work at hand, like doing some LLM-stuff :)
    await Task.Delay(2000);
    var json = JsonSerializer.Serialize(content, options);
    await client.ReplyAsync(message, $"☑️ Got your {content.Content.Type}:\r\n{json}");
}

The above code would render as follows in WhatsApp:

alternate text is missing from this package README image

Configuration

You need to register an app in the Meta App Dashboard. The app must then be configured to use the WhatsApp Business API, and the webhook and verification token (an arbitrary value) must be set up in the app settings under WhatsApp. The webhook URL is /whatsapp under your Azure Functions app.

Make sure you subscribe the webhook to the messages field, with API version v22.0 or later.

Configuration on the Azure Functions side is done via the ASP.NET options pattern and the MetaOptions type. When you call UseWhatsApp, the options will be bound by default to the Meta section in the configuration. You can also configure it programmatically as follows:

builder.Services.Configure<MetaOptions>(options =>
{
    options.VerifyToken = "my-webhook-1234";
    options.Numbers["12345678"] = "asff=";
});

Via configuration:

{
  "Meta": {
    "VerifyToken": "my-webhook-1234",
    "Numbers": {
      "12345678": "asff="
    }
  }
}

The Numbers dictionary is a map of WhatsApp phone identifiers and the corresponding access token for it. To get a permanent access token for use, you'd need to create a system user with full control permissions to the WhatsApp Business API (app).

Scalability and Performance

In order to quickly and efficiently process incoming messages, the library uses Azure Storage Queues to queue incoming messages from WhatsApp, which provides a reliable and scalable way to handle incoming messages. It also uses Azure Table Storage to detect duplicate messages and avoid processing the same message multiple times.

If QueueServiceClient and TableServiceClient are registered in the DI container before invoking UseWhatsApp, the library will automatically use them. Otherwise, it will register both services using the AzureWebJobsStorage connection string, therefore sharing storage with the Azure Functions runtime.

License

We offer this project under a dual licensing model, tailored to the needs of commercial distributors and open-source projects.

For open-source projects and free software developers:

If you develop free software (FOSS) and want to leverage this project, the open-source version under AGPLv3 is ideal. If you use a FOSS license other than AGPLv3, Devlooped offers an exception, allowing usage without requiring the entire derivative work to fall under AGPLv3, under certain conditions.

See AGPLv3 and Universal FOSS Exception.

For OEMs, ISVs, VARs, and other commercial users:

If you use this project and distribute or host commercial software without sharing the code under AGPLv3, you must obtain a commercial license from Devlooped. Alternatively, you can sponsor on GitHub Sponsors at the AGPLv3 tier or above per developer, which grants you a commercial license for the duration of the sponsorship. You can sponsor through each individual developer's account or through your GitHub organization.

Sponsors

Clarius Org MFB Technologies, Inc. Torutek DRIVE.NET, Inc. Keith Pickford Thomas Bolon Kori Francis Toni Wenzel Uno Platform Dan Siegel Reuben Swartz Jacob Foshee alternate text is missing from this package README image Eric Johnson Ix Technologies B.V. David JENNI Jonathan Charley Wu Jakob Tikjøb Andersen Ken Bonny Simon Cropp agileworks-eu sorahex Zheyu Shen Vezel ChilliCream 4OTC Vincent Limo Jordan S. Jones domischell

Sponsor this project  

Learn more about GitHub Sponsors

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Devlooped.WhatsApp:

Package Downloads
dotnet-whatsapp

A WhatsApp simulator client that complements Devlooped.WhatsApp.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.0-rc.13 105 6/18/2025
1.0.0-rc.12 209 5/16/2025
1.0.0-rc.11 271 5/13/2025
1.0.0-rc.10 274 5/13/2025
1.0.0-rc.9 292 5/12/2025
1.0.0-rc.8 261 5/12/2025
1.0.0-rc.7 267 5/8/2025
1.0.0-rc.6 157 5/5/2025
1.0.0-rc.5 63 5/2/2025
1.0.0-rc.4 117 4/11/2025
1.0.0-rc.3 317 4/9/2025
1.0.0-rc.2 137 4/9/2025