Microsoft Bot Framework是否免费?求免费渠道替代及自建Web API教程
Hey there, let's break down your questions one by one based on what I know about Bot Framework and alternatives post-2018:
Unfortunately, no. After March 2018, Microsoft eliminated the permanent free Bot Channel Registration option. The only free tier available is the Azure Bot Service's free plan, which caps you at 10,000 messages per month—once you exceed that, you'll move to the pay-as-you-go model ($0.50 per 1,000 messages). There's no official way to get unlimited free message capacity through Azure's managed channel registration anymore.
Absolutely, here are some solid options that let you run bots with no message limits (since you host them yourself):
- Rasa: An open-source NLP and bot framework that's completely free. You can deploy it on your existing IIS server (or any other server) and build custom conversational flows. It supports custom web APIs and can be paired with your own chat UI for embedding in websites.
- Botpress: Another open-source bot platform with built-in chat UI tools. It's self-hosted, so you control the infrastructure and have no message caps. It has out-of-the-box support for embedding chat widgets into external sites.
- Custom Bot Framework deployment (no Azure Channel Registration): Wait, you already have your Bot Framework bot deployed on IIS! You don't actually need Azure's Channel Registration if you build your own communication channel. More on this in the next section.
Yes, this is actually the perfect solution for your scenario since you already have the bot on IIS. Here's how to pull it off:
Step 1: Expose a custom Web API endpoint for your bot
Your Bot Framework bot is already a web app—you just need to add a custom controller to handle direct Get/Post requests (bypassing the Bot Framework Channel Service). For an ASP.NET Core bot, here's a simplified example:
[ApiController] [Route("api/chat")] public class CustomChatController : ControllerBase { private readonly IBot _bot; private readonly BotFrameworkAdapter _adapter; // Use a simple in-memory store to track bot replies (replace with a database for production) private readonly Dictionary<string, string> _conversationReplies = new(); public CustomChatController(IBot bot, BotFrameworkAdapter adapter) { _bot = bot; _adapter = adapter; } [HttpPost] public async Task<IActionResult> PostUserMessage([FromBody] UserChatInput input) { // Create a temporary conversation reference for the custom channel var convRef = new ConversationReference { User = new ChannelAccount { Id = input.UserId ?? "anonymous-user" }, Bot = new ChannelAccount { Id = "my-custom-bot" }, Conversation = new ConversationAccount { Id = input.ConvId ?? Guid.NewGuid().ToString() }, ChannelId = "custom-web-channel", ServiceUrl = $"{Request.Scheme}://{Request.Host}" }; // Track the bot's reply by intercepting the send activity _adapter.OnTurnError = async (turnContext, exception) => { await turnContext.SendActivityAsync($"Oops, something went wrong: {exception.Message}"); }; // Process the user's message through the bot await _adapter.ProcessActivityAsync(convRef, input.Message, async (turnContext) => { // Capture the bot's reply and store it temporarily turnContext.OnSendActivities(async (ctx, activities, next) => { var result = await next(); if (activities.Any(a => a.Type == ActivityTypes.Message)) { _conversationReplies[convRef.Conversation.Id] = activities.First(a => a.Type == ActivityTypes.Message).Text; } return result; }); await _bot.OnTurnAsync(turnContext); }, CancellationToken.None); // Return the bot's reply to the frontend if (_conversationReplies.TryGetValue(convRef.Conversation.Id, out var reply)) { _conversationReplies.Remove(convRef.Conversation.Id); // Clean up return Ok(new { Reply = reply }); } return Ok(new { Reply = "Sorry, I didn't catch that." }); } } // Simple model for user input public class UserChatInput { public string Message { get; set; } public string UserId { get; set; } public string ConvId { get; set; } }
Step 2: Build a frontend chat UI
Create a simple chat widget using HTML/CSS/JS that sends requests to your new API endpoint. Here's a basic example:
<div id="custom-chat-widget"> <div id="chat-messages"></div> <div id="chat-input-area"> <input type="text" id="user-message-input" placeholder="Type your message..."> <button onclick="sendMessage()">Send</button> </div> </div> <script> // Generate a unique conversation ID for the user const convId = `conv-${Date.now()}`; async function sendMessage() { const inputElement = document.getElementById('user-message-input'); const message = inputElement.value.trim(); if (!message) return; // Add user message to the UI addMessageToUI('user', message); inputElement.value = ''; // Call your custom API try { const response = await fetch('https://your-iis-server-url/api/chat', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ Message: message, ConvId: convId }) }); const data = await response.json(); // Add bot reply to the UI addMessageToUI('bot', data.Reply); } catch (err) { addMessageToUI('bot', "Sorry, I couldn't connect right now."); console.error('API error:', err); } } function addMessageToUI(sender, text) { const messagesContainer = document.getElementById('chat-messages'); const messageDiv = document.createElement('div'); messageDiv.className = sender === 'user' ? 'user-message' : 'bot-message'; messageDiv.textContent = text; messagesContainer.appendChild(messageDiv); // Scroll to the bottom of the chat messagesContainer.scrollTop = messagesContainer.scrollHeight; } </script> <style> #custom-chat-widget { width: 320px; border: 1px solid #e0e0e0; border-radius: 8px; font-family: Arial, sans-serif; overflow: hidden; } #chat-messages { height: 280px; padding: 10px; overflow-y: auto; background-color: #f9f9f9; } .user-message, .bot-message { margin: 8px 0; padding: 8px 12px; border-radius: 16px; max-width: 70%; } .user-message { background-color: #0078d4; color: white; margin-left: auto; } .bot-message { background-color: #e0e0e0; color: #333; margin-right: auto; } #chat-input-area { display: flex; padding: 10px; border-top: 1px solid #e0e0e0; } #user-message-input { flex: 1; padding: 8px; border: 1px solid #e0e0e0; border-radius: 20px; margin-right: 8px; } #chat-input-area button { padding: 8px 16px; border: none; border-radius: 20px; background-color: #0078d4; color: white; cursor: pointer; } </style>
Step 3: Embed the widget in other sites
You have two easy options for embedding:
- Iframe: Host the chat widget HTML as a standalone page on your IIS server, then other sites can embed it with:
<iframe src="https://your-iis-server-url/chat-widget.html" width="320" height="350" frameborder="0"></iframe> - JS snippet: Package the chat widget's CSS and JS into external files, then provide a snippet for other sites to include (e.g., a script that loads the widget and injects it into their page).
Tutorial guidance (no external links)
For deeper dives:
- For the Bot Framework custom endpoint: Refer to the official Bot Framework docs on "custom channels" and "adapters"—you'll learn how to extend the adapter to handle non-standard incoming requests.
- For frontend embedding: Look into vanilla JS widget development best practices, like encapsulating styles to avoid conflicts with the host site's CSS, and handling cross-origin requests if your bot is on a different domain than the embedding site (enable CORS in your IIS server settings).
内容的提问来源于stack exchange,提问作者user8321763

