DevJojo.WAdapter
1.0.0
dotnet add package DevJojo.WAdapter --version 1.0.0
NuGet\Install-Package DevJojo.WAdapter -Version 1.0.0
<PackageReference Include="DevJojo.WAdapter" Version="1.0.0" />
<PackageVersion Include="DevJojo.WAdapter" Version="1.0.0" />
<PackageReference Include="DevJojo.WAdapter" />
paket add DevJojo.WAdapter --version 1.0.0
#r "nuget: DevJojo.WAdapter, 1.0.0"
#:package DevJojo.WAdapter@1.0.0
#addin nuget:?package=DevJojo.WAdapter&version=1.0.0
#tool nuget:?package=DevJojo.WAdapter&version=1.0.0
DevJojo.WAdapter
A WhatsApp adapter for Microsoft Bot Framework, enabling seamless integration of WhatsApp messaging with Bot Framework applications.
Overview
DevJojo.WAdapter bridges WhatsApp Business API with Microsoft Bot Framework, allowing you to build sophisticated chatbots that can communicate through WhatsApp using familiar Bot Framework patterns and dialogs.
Features
- 🤖 Bot Framework Integration: Full compatibility with Microsoft Bot Framework
- 📱 WhatsApp Native: Support for all WhatsApp message types and features
- 💬 Rich Conversations: Interactive buttons, lists, and quick replies
- 🔄 Activity Translation: Seamless conversion between Bot Framework activities and WhatsApp messages
- 🎯 Dialog Support: Full support for Bot Framework dialogs and conversation flow
- 📊 Channel Data: Access to WhatsApp-specific features through channel data
- 🔐 Secure: Built-in webhook validation and security
Installation
Install the package via NuGet Package Manager:
dotnet add package DevJojo.WAdapter
Or via Package Manager Console:
Install-Package DevJojo.WAdapter
Quick Start
Basic Setup
using DevJojo.WAdapter;
using Microsoft.Bot.Builder;
using Microsoft.Extensions.DependencyInjection;
public void ConfigureServices(IServiceCollection services)
{
// Add Bot Framework services
services.AddBotFramework();
// Add WhatsApp adapter
services.AddWhatsAppAdapter(configuration);
// Add your bot
services.AddTransient<IBot, YourBot>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// Configure WhatsApp webhook endpoint
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapPost("/api/whatsapp", async (HttpContext context) =>
{
var adapter = context.RequestServices.GetService<WhatsAppAdapter>();
var bot = context.RequestServices.GetService<IBot>();
await adapter.ProcessAsync(context.Request, context.Response, bot);
});
});
}
Simple Echo Bot
using Microsoft.Bot.Builder;
using Microsoft.Bot.Schema;
public class EchoBot : ActivityHandler
{
protected override async Task OnMessageActivityAsync(
ITurnContext<IMessageActivity> turnContext,
CancellationToken cancellationToken)
{
var replyText = $"Echo: {turnContext.Activity.Text}";
await turnContext.SendActivityAsync(
MessageFactory.Text(replyText),
cancellationToken);
}
}
WhatsApp-Specific Features
using Wadapter.src.Converter;
using static Wadapter.src.WhatsappAdapter;
public class WhatsAppBot : ActivityHandler
{
protected override async Task OnMessageActivityAsync(
ITurnContext<IMessageActivity> turnContext,
CancellationToken cancellationToken)
{
// Send WhatsApp quick reply
var quickReplyActivity = MessageFactory.Text(string.Empty);
quickReplyActivity.ChannelData = new QuickReplyChannelData
{
Type = WhatsappMessageTypes.QUICK_REPLY,
Body = "Choose an option:",
Buttons = new[]
{
new() { Id = "option1", Title = "Option 1" },
new() { Id = "option2", Title = "Option 2" }
}
};
await turnContext.SendActivityAsync(quickReplyActivity, cancellationToken);
}
}
Configuration
App Settings
{
"WhatsApp": {
"ApiBaseUrl": "https://graph.facebook.com/v17.0",
"PhoneNumberId": "your-phone-number-id",
"AccessToken": "your-access-token",
"WebhookVerifyToken": "your-webhook-verify-token"
},
"MicrosoftAppId": "",
"MicrosoftAppPassword": ""
}
Startup Configuration
using Wadapter.Extensions;
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// Configure WhatsApp adapter
services.AddWhatsAppServices(Configuration);
// Add Bot Framework
services.AddBotFramework()
.AddWhatsAppAdapter();
// Register your bot
services.AddTransient<IBot, MyBot>();
}
}
WhatsApp Message Types
Interactive Lists
var listActivity = MessageFactory.Text(string.Empty);
listActivity.ChannelData = new ListChannelData
{
Type = WhatsappMessageTypes.LIST,
Heading = "Choose a service:",
ButtonText = "Services",
Menus = new[]
{
new() { Id = "service1", Title = "Service 1", Description = "Description 1" },
new() { Id = "service2", Title = "Service 2", Description = "Description 2" }
}
};
await turnContext.SendActivityAsync(listActivity, cancellationToken);
Quick Replies
var quickReplyActivity = MessageFactory.Text(string.Empty);
quickReplyActivity.ChannelData = new QuickReplyChannelData
{
Type = WhatsappMessageTypes.QUICK_REPLY,
Body = "Select your preference:",
Buttons = new[]
{
new() { Id = "yes", Title = "Yes" },
new() { Id = "no", Title = "No" }
}
};
await turnContext.SendActivityAsync(quickReplyActivity, cancellationToken);
Media Messages
// Send image
var imageActivity = MessageFactory.Attachment(new Attachment
{
ContentType = "image/jpeg",
ContentUrl = "https://example.com/image.jpg",
Name = "image.jpg"
});
await turnContext.SendActivityAsync(imageActivity, cancellationToken);
// Send document
var documentActivity = MessageFactory.Attachment(new Attachment
{
ContentType = "application/pdf",
ContentUrl = "https://example.com/document.pdf",
Name = "document.pdf"
});
await turnContext.SendActivityAsync(documentActivity, cancellationToken);
Dialog Integration
Waterfall Dialog Example
using Microsoft.Bot.Builder.Dialogs;
public class GreetingDialog : ComponentDialog
{
public GreetingDialog() : base(nameof(GreetingDialog))
{
var waterfallSteps = new WaterfallStep[]
{
NameStepAsync,
ConfirmStepAsync,
FinalStepAsync
};
AddDialog(new WaterfallDialog(nameof(WaterfallDialog), waterfallSteps));
AddDialog(new TextPrompt(nameof(TextPrompt)));
AddDialog(new ConfirmPrompt(nameof(ConfirmPrompt)));
InitialDialogId = nameof(WaterfallDialog);
}
private async Task<DialogTurnResult> NameStepAsync(
WaterfallStepContext stepContext,
CancellationToken cancellationToken)
{
return await stepContext.PromptAsync(
nameof(TextPrompt),
new PromptOptions { Prompt = MessageFactory.Text("What's your name?") },
cancellationToken);
}
private async Task<DialogTurnResult> ConfirmStepAsync(
WaterfallStepContext stepContext,
CancellationToken cancellationToken)
{
stepContext.Values["name"] = (string)stepContext.Result;
return await stepContext.PromptAsync(
nameof(ConfirmPrompt),
new PromptOptions
{
Prompt = MessageFactory.Text($"Hello {stepContext.Values["name"]}, is this correct?")
},
cancellationToken);
}
private async Task<DialogTurnResult> FinalStepAsync(
WaterfallStepContext stepContext,
CancellationToken cancellationToken)
{
if ((bool)stepContext.Result)
{
await stepContext.Context.SendActivityAsync(
MessageFactory.Text($"Great! Nice to meet you, {stepContext.Values["name"]}!"),
cancellationToken);
}
return await stepContext.EndDialogAsync(null, cancellationToken);
}
}
Webhook Handling
The adapter automatically handles WhatsApp webhooks and converts them to Bot Framework activities:
// Webhook endpoint
[HttpPost("api/whatsapp")]
public async Task PostAsync([FromServices] WhatsAppAdapter adapter, [FromServices] IBot bot)
{
await adapter.ProcessAsync(Request, Response, bot);
}
// Webhook verification
[HttpGet("api/whatsapp")]
public async Task GetAsync([FromServices] WhatsAppAdapter adapter)
{
await adapter.ProcessAsync(Request, Response, null);
}
Channel Data Types
The adapter provides several channel data types for WhatsApp-specific features:
QuickReplyChannelData- Quick reply buttonsListChannelData- Interactive listsMediaChannelData- Media messages with metadataLocationChannelData- Location sharingContactChannelData- Contact sharing
Error Handling
public class ErrorHandlerBot : IBot
{
public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken)
{
try
{
// Bot logic here
}
catch (WhatsAppApiException ex)
{
await turnContext.SendActivityAsync(
MessageFactory.Text("Sorry, there was an issue with WhatsApp. Please try again."),
cancellationToken);
}
}
}
Advanced Features
Custom Middleware
public class WhatsAppMiddleware : IMiddleware
{
public async Task OnTurnAsync(
ITurnContext turnContext,
NextDelegate next,
CancellationToken cancellationToken)
{
// Pre-processing
if (turnContext.Activity.ChannelId == "whatsapp")
{
// WhatsApp-specific processing
}
await next(cancellationToken);
// Post-processing
}
}
State Management
services.AddSingleton<IStorage, MemoryStorage>();
services.AddSingleton<UserState>();
services.AddSingleton<ConversationState>();
Requirements
- .NET 8.0 or later
- Microsoft Bot Framework 4.23.0 or later
- WhatsApp Business API account
- DevJojo.WApi package
Dependencies
DevJojo.WApi(1.0.0) - Core WhatsApp API functionalityMicrosoft.Bot.Builder.Integration.AspNet.Core(4.23.0) - Bot Framework integration
Supported Activities
The adapter supports the following Bot Framework activity types:
- Message Activities: Text, media, and interactive messages
- Event Activities: Member added/removed events
- Typing Activities: Converted to WhatsApp read receipts
- End of Conversation: Conversation termination
Best Practices
- Use Channel Data: Leverage WhatsApp-specific features through channel data
- Handle Errors Gracefully: Implement proper error handling for network issues
- Optimize Media: Compress images and videos for better performance
- User Experience: Design conversations that work well in WhatsApp's interface
- Rate Limiting: Respect WhatsApp's rate limits and implement backoff strategies
Examples
Check out the examples in the repository:
- Echo Bot
- Menu-driven Bot
- Media Handling Bot
- Dialog Flow Bot
Contributing
We welcome contributions! Please feel free to submit issues, feature requests, or pull requests.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
For support and questions:
- Create an issue on GitHub
- Check the Bot Framework documentation
- Review the WhatsApp Business API documentation
Changelog
v1.0.0
- Initial release
- Bot Framework 4.23.0 compatibility
- WhatsApp message type support
- Interactive message support
- Dialog integration
- Webhook handling
DevJojo.WAdapter - Bringing the power of Microsoft Bot Framework to WhatsApp.
| Product | Versions 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. |
-
net8.0
- DevJojo.WApi (>= 1.0.0)
- Microsoft.Bot.Builder.Integration.AspNet.Core (>= 4.23.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 379 | 9/17/2025 |