WhatsAppCloud.Net
1.0.2
dotnet add package WhatsAppCloud.Net --version 1.0.2
NuGet\Install-Package WhatsAppCloud.Net -Version 1.0.2
<PackageReference Include="WhatsAppCloud.Net" Version="1.0.2" />
<PackageVersion Include="WhatsAppCloud.Net" Version="1.0.2" />
<PackageReference Include="WhatsAppCloud.Net" />
paket add WhatsAppCloud.Net --version 1.0.2
#r "nuget: WhatsAppCloud.Net, 1.0.2"
#:package WhatsAppCloud.Net@1.0.2
#addin nuget:?package=WhatsAppCloud.Net&version=1.0.2
#tool nuget:?package=WhatsAppCloud.Net&version=1.0.2
WhatsAppCloud.Net
The missing .NET SDK for Meta's WhatsApp Business Cloud API — more complete than Meta's own Node.js SDK: every message type, read receipts, replies, webhook security, and typed parsing.
Send text, template, image, video, audio, document, sticker, location,
contacts, and interactive buttons/lists. Verify webhooks, parse inbound
messages. No dependencies beyond System.Text.Json. Targets netstandard2.0
and net8.0.
Install
dotnet add package WhatsAppCloud.Net
(package publishing coming with v1.0.0 — for now reference the project)
Quick start
using WhatsAppCloud;
var client = new WhatsAppClient(new WhatsAppClientOptions
{
PhoneNumberId = "<phone-number-id>", // from the Meta developer console
AccessToken = "<access-token>" // system user token
});
// Free-form text (needs an open 24h customer service window)
await client.SendTextAsync("201012345678", "Hello from .NET!");
// Approved template with {{1}}, {{2}} parameters
await client.SendTemplateAsync("201012345678", "order_update", "en_US",
new[] { "Eslam", "12345" });
// Image by URL
await client.SendImageAsync("201012345678",
"https://example.com/order.jpg", caption: "Your order shipped!");
// Video, audio, document, sticker
await client.SendVideoAsync("201012345678", "https://example.com/demo.mp4");
await client.SendDocumentAsync("201012345678", "https://example.com/invoice.pdf", filename: "invoice.pdf");
// Location & contacts
await client.SendLocationAsync("201012345678", 30.0444, 31.2357, "Cairo", "Egypt");
await client.SendContactsAsync("201012345678", new[]
{
new WhatsAppContact { FormattedName = "Ahmed Hassan", FirstName = "Ahmed",
Phones = new List<ContactPhone> { new ContactPhone { Phone = "+201012345678" } } }
});
// Interactive reply buttons (up to 3)
await client.SendButtonsAsync("201012345678", "Confirm your order?",
new[]
{
new ReplyButton { Id = "confirm", Title = "Confirm" },
new ReplyButton { Id = "cancel", Title = "Cancel" }
});
// Interactive list
await client.SendListAsync("201012345678", "Pick a drink", "Open menu",
new[]
{
new ListSection
{
Title = "Drinks",
Rows = new List<ListRow>
{
new ListRow { Id = "tea", Title = "Tea" },
new ListRow { Id = "coffee", Title = "Coffee", Description = "Freshly brewed" }
}
}
});
// Reply to a specific message (works on every send method)
await client.SendTextAsync("201012345678", "Got it!", replyToMessageId: "wamid.xyz");
// Blue ticks — call when your webhook receives a message
await client.MarkAsReadAsync("wamid.xyz");
Bring your own HttpClient (e.g. from IHttpClientFactory):
var client = new WhatsAppClient(options, httpClient);
Webhooks
Verification handshake (the GET Meta sends when you save the webhook URL):
using WhatsAppCloud.Webhooks;
var challenge = WebhookSecurity.VerifyChallenge(
mode, verifyToken, challengeParam, expectedVerifyToken);
if (challenge != null) return Results.Text(challenge); // 200 with the challenge
Validate inbound POSTs — never skip this on a public URL:
var signature = Request.Headers["X-Hub-Signature-256"];
var body = await new StreamReader(Request.Body).ReadToEndAsync();
if (!WebhookSecurity.IsValidSignature(appSecret, body, signature))
return Results.Unauthorized();
var payload = WebhookParser.Parse(body);
foreach (var msg in WebhookParser.GetMessages(payload))
Console.WriteLine($"{msg.From}: {msg.Text}");
foreach (var status in WebhookParser.GetStatuses(payload))
Console.WriteLine($"{status.MessageId}: {status.Status}");
API notes
- Default Graph API version is
v26.0; override withWhatsAppClientOptions.ApiVersion. - API errors throw
WhatsAppApiExceptionwith Meta'scodeandtype. SendMessageResult.MessageIdis thewamid.…you can correlate with webhook statuses.
Why not just use the REST API directly?
You can — this SDK just removes the boilerplate: correct payload shapes, template components, auth headers, error mapping, webhook signature validation (constant-time), and payload parsing. PRs welcome.
License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- System.Text.Json (>= 8.0.5)
-
net8.0
- System.Text.Json (>= 8.0.5)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
NuGet polish release: branded package icon, embedded README, and full repository metadata.