用于.NET的Bot Framework SDK v4
此存储库包含Microsoft Bot Framework SDK的.NET版本的代码。Bot Framework SDK v4使开发人员能够使用.NET建模对话并构建复杂的bot应用程序。
这个回购是Microsoft Bot框架的一部分- 一个用于构建企业级会话AI体验的综合框架。
科 描述 建立状态 覆盖状态 功能测试状态
主 4.5。*预览构建 建立状态 覆盖状态 建立状态
4.4 4.4。*预览构建 建立状态 覆盖状态 建立状态
4.3 4.3。*预览构建 建立状态 覆盖状态 建立状态
4.2 4.2。*预览构建 建立状态 覆盖状态
4.1 4.1。*补丁构建 建立状态 覆盖状态
4 4.0。*补丁构建 建立状态 N / A
执照 小胶质
// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Threading; using System.Threading.Tasks; using Microsoft.Bot.Connector.Authentication; using Microsoft.Bot.Schema; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; namespace Microsoft.Bot.Builder.Tests { [TestClass] public class ActivityHandlerTests { [TestMethod] public async Task TestMessageActivity() { // Arrange var activity = MessageFactory.Text("hello"); var turnContext = new TurnContext(new NotImplementedAdapter(), activity); // Act var bot = new TestActivityHandler(); await ((IBot)bot).OnTurnAsync(turnContext); // Assert Assert.AreEqual(1, bot.Record.Count); Assert.AreEqual(bot.Record[0], "OnMessageActivityAsync"); } [TestMethod] public async Task TestMemberAdded1() { // Arrange var activity = new Activity { Type = ActivityTypes.ConversationUpdate, MembersAdded = new List<ChannelAccount> { new ChannelAccount { Id = "b" }, }, Recipient = new ChannelAccount { Id = "b" }, }; var turnContext = new TurnContext(new NotImplementedAdapter(), activity); // Act var bot = new TestActivityHandler(); await ((IBot)bot).OnTurnAsync(turnContext); // Assert Assert.AreEqual(1, bot.Record.Count); Assert.AreEqual(bot.Record[0], "OnConversationUpdateActivityAsync"); } [TestMethod] public async Task TestMemberAdded2() { // Arrange var activity = new Activity { Type = ActivityTypes.ConversationUpdate, MembersAdded = new List<ChannelAccount> { new ChannelAccount { Id = "a" }, new ChannelAccount { Id = "b" }, }, Recipient = new ChannelAccount { Id = "b" }, }; var turnContext = new TurnContext(new NotImplementedAdapter(), activity); // Act var bot = new TestActivityHandler(); await ((IBot)bot).OnTurnAsync(turnContext); // Assert Assert.AreEqual(2, bot.Record.Count); Assert.AreEqual(bot.Record[0], "OnConversationUpdateActivityAsync"); Assert.AreEqual(bot.Record[1], "OnMembersAddedAsync"); } [TestMethod] public async Task TestMemberAdded3() { // Arrange var activity = new Activity { Type = ActivityTypes.ConversationUpdate, MembersAdded = new List<ChannelAccount> { new ChannelAccount { Id = "a" }, new ChannelAccount { Id = "b" }, new ChannelAccount { Id = "c" }, }, Recipient = new ChannelAccount { Id = "b" }, }; var turnContext = new TurnContext(new NotImplementedAdapter(), activity); // Act var bot = new TestActivityHandler(); await ((IBot)bot).OnTurnAsync(turnContext); // Assert Assert.AreEqual(2, bot.Record.Count); Assert.AreEqual(bot.Record[0], "OnConversationUpdateActivityAsync"); Assert.AreEqual(bot.Record[1], "OnMembersAddedAsync"); } [TestMethod] public async Task TestMemberRemoved1() { // Arrange var activity = new Activity { Type = ActivityTypes.ConversationUpdate, MembersAdded = new List<ChannelAccount> { new ChannelAccount { Id = "c" }, }, Recipient = new ChannelAccount { Id = "c" }, }; var turnContext = new TurnContext(new NotImplementedAdapter(), activity); // Act var bot = new TestActivityHandler(); await ((IBot)bot).OnTurnAsync(turnContext); // Assert Assert.AreEqual(1, bot.Record.Count); Assert.AreEqual(bot.Record[0], "OnConversationUpdateActivityAsync"); } [TestMethod] public async Task TestMemberRemoved2() { // Arrange var activity = new Activity { Type = ActivityTypes.ConversationUpdate, MembersAdded = new List<ChannelAccount> { new ChannelAccount { Id = "a" }, new ChannelAccount { Id = "c" }, }, Recipient = new ChannelAccount { Id = "c" }, }; var turnContext = new TurnContext(new NotImplementedAdapter(), activity); // Act var bot = new TestActivityHandler(); await ((IBot)bot).OnTurnAsync(turnContext); // Assert Assert.AreEqual(2, bot.Record.Count); Assert.AreEqual(bot.Record[0], "OnConversationUpdateActivityAsync"); Assert.AreEqual(bot.Record[1], "OnMembersAddedAsync"); } [TestMethod] public async Task TestMemberRemoved3() { // Arrange var activity = new Activity { Type = ActivityTypes.ConversationUpdate, MembersAdded = new List<ChannelAccount> { new ChannelAccount { Id = "a" }, new ChannelAccount { Id = "b" }, new ChannelAccount { Id = "c" }, }, Recipient = new ChannelAccount { Id = "c" }, }; var turnContext = new TurnContext(new NotImplementedAdapter(), activity); // Act var bot = new TestActivityHandler(); await ((IBot)bot).OnTurnAsync(turnContext); // Assert Assert.AreEqual(2, bot.Record.Count); Assert.AreEqual(bot.Record[0], "OnConversationUpdateActivityAsync"); Assert.AreEqual(bot.Record[1], "OnMembersAddedAsync"); } [TestMethod] public async Task TestMemberAddedJustTheBot() { // Arrange var activity = new Activity { Type = ActivityTypes.ConversationUpdate, MembersAdded = new List<ChannelAccount> { new ChannelAccount { Id = "b" }, }, Recipient = new ChannelAccount { Id = "b" }, }; var turnContext = new TurnContext(new NotImplementedAdapter(), activity); // Act var bot = new TestActivityHandler(); await ((IBot)bot).OnTurnAsync(turnContext); // Assert Assert.AreEqual(1, bot.Record.Count); Assert.AreEqual(bot.Record[0], "OnConversationUpdateActivityAsync"); } [TestMethod] public async Task TestMemberRemovedJustTheBot() { // Arrange var activity = new Activity { Type = ActivityTypes.ConversationUpdate, MembersAdded = new List<ChannelAccount> { new ChannelAccount { Id = "c" }, }, Recipient = new ChannelAccount { Id = "c" }, }; var turnContext = new TurnContext(new NotImplementedAdapter(), activity); // Act var bot = new TestActivityHandler(); await ((IBot)bot).OnTurnAsync(turnContext); // Assert Assert.AreEqual(1, bot.Record.Count); Assert.AreEqual(bot.Record[0], "OnConversationUpdateActivityAsync"); } [TestMethod] public async Task TestTokenResponseEventAsync() { // Arrange var activity = new Activity { Type = ActivityTypes.Event, Name = "tokens/response", }; var turnContext = new TurnContext(new NotImplementedAdapter(), activity); // Act var bot = new TestActivityHandler(); await ((IBot)bot).OnTurnAsync(turnContext); // Assert Assert.AreEqual(2, bot.Record.Count); Assert.AreEqual(bot.Record[0], "OnEventActivityAsync"); Assert.AreEqual(bot.Record[1], "OnTokenResponseEventAsync"); } [TestMethod] public async Task TestEventAsync() { // Arrange var activity = new Activity { Type = ActivityTypes.Event, Name = "some.random.event", }; var turnContext = new TurnContext(new NotImplementedAdapter(), activity); // Act var bot = new TestActivityHandler(); await ((IBot)bot).OnTurnAsync(turnContext); // Assert Assert.AreEqual(2, bot.Record.Count); Assert.AreEqual(bot.Record[0], "OnEventActivityAsync"); Assert.AreEqual(bot.Record[1], "OnEventAsync"); } [TestMethod] public async Task TestEventNullNameAsync() { // Arrange var activity = new Activity { Type = ActivityTypes.Event, }; var turnContext = new TurnContext(new NotImplementedAdapter(), activity); // Act var bot = new TestActivityHandler(); await ((IBot)bot).OnTurnAsync(turnContext); // Assert Assert.AreEqual(2, bot.Record.Count); Assert.AreEqual(bot.Record[0], "OnEventActivityAsync"); Assert.AreEqual(bot.Record[1], "OnEventAsync"); } [TestMethod] public async Task TestUnrecognizedActivityType() { // Arrange var activity = new Activity { Type = "shall.not.pass", }; var turnContext = new TurnContext(new NotImplementedAdapter(), activity); // Act var bot = new TestActivityHandler(); await ((IBot)bot).OnTurnAsync(turnContext); // Assert Assert.AreEqual(1, bot.Record.Count); Assert.AreEqual(bot.Record[0], "OnUnrecognizedActivityTypeAsync"); } [TestMethod] public async Task TestDelegatingTurnContext() { // Arrange var turnContextMock = new Mock<ITurnContext>(); turnContextMock.Setup(tc => tc.Activity).Returns(new Activity { Type = ActivityTypes.Message }); turnContextMock.Setup(tc => tc.Adapter).Returns(new BotFrameworkAdapter(new SimpleCredentialProvider())); turnContextMock.Setup(tc => tc.TurnState).Returns(new TurnContextStateCollection()); turnContextMock.Setup(tc => tc.Responded).Returns(false); turnContextMock.Setup(tc => tc.OnDeleteActivity(It.IsAny<DeleteActivityHandler>())); turnContextMock.Setup(tc => tc.OnSendActivities(It.IsAny<SendActivitiesHandler>())); turnContextMock.Setup(tc => tc.OnUpdateActivity(It.IsAny<UpdateActivityHandler>())); turnContextMock.Setup(tc => tc.SendActivityAsync(It.IsAny<IActivity>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(new ResourceResponse())); turnContextMock.Setup(tc => tc.SendActivitiesAsync(It.IsAny<IActivity[]>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(new[] { new ResourceResponse() })); turnContextMock.Setup(tc => tc.DeleteActivityAsync(It.IsAny<ConversationReference>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(new ResourceResponse())); turnContextMock.Setup(tc => tc.UpdateActivityAsync(It.IsAny<IActivity>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult(new ResourceResponse())); // Act var bot = new TestDelegatingTurnContextActivityHandler(); await bot.OnTurnAsync(turnContextMock.Object); // Assert turnContextMock.VerifyGet(tc => tc.Activity, Times.AtLeastOnce); turnContextMock.VerifyGet(tc => tc.Adapter, Times.Once); turnContextMock.VerifyGet(tc => tc.TurnState, Times.Once); turnContextMock.VerifyGet(tc => tc.Responded, Times.Once); turnContextMock.Verify(tc => tc.OnDeleteActivity(It.IsAny<DeleteActivityHandler>()), Times.Once); turnContextMock.Verify(tc => tc.OnSendActivities(It.IsAny<SendActivitiesHandler>()), Times.Once); turnContextMock.Verify(tc => tc.OnUpdateActivity(It.IsAny<UpdateActivityHandler>()), Times.Once); turnContextMock.Verify(tc => tc.SendActivityAsync(It.IsAny<IActivity>(), It.IsAny<CancellationToken>()), Times.Once); turnContextMock.Verify(tc => tc.SendActivitiesAsync(It.IsAny<IActivity[]>(), It.IsAny<CancellationToken>()), Times.Once); turnContextMock.Verify(tc => tc.DeleteActivityAsync(It.IsAny<ConversationReference>(), It.IsAny<CancellationToken>()), Times.Once); turnContextMock.Verify(tc => tc.UpdateActivityAsync(It.IsAny<IActivity>(), It.IsAny<CancellationToken>()), Times.Once); } private class NotImplementedAdapter : BotAdapter { public override Task DeleteActivityAsync(ITurnContext turnContext, ConversationReference reference, CancellationToken cancellationToken) { throw new NotImplementedException(); } public override Task<ResourceResponse[]> SendActivitiesAsync(ITurnContext turnContext, Activity[] activities, CancellationToken cancellationToken) { throw new NotImplementedException(); } public override Task<ResourceResponse> UpdateActivityAsync(ITurnContext turnContext, Activity activity, CancellationToken cancellationToken) { throw new NotImplementedException(); } } private class TestInvokeAdapter : NotImplementedAdapter { public IActivity Activity { get; private set; } public override Task<ResourceResponse[]> SendActivitiesAsync(ITurnContext turnContext, Activity[] activities, CancellationToken cancellationToken) { Activity = activities.FirstOrDefault(activity => activity.Type == ActivityTypesEx.InvokeResponse); return Task.FromResult(new ResourceResponse[0]); } } private class TestActivityHandler : ActivityHandler { public List<string> Record { get; } = new List<string>(); protected override Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken) { Record.Add(MethodBase.GetCurrentMethod().Name); return base.OnMessageActivityAsync(turnContext, cancellationToken); } protected override Task OnConversationUpdateActivityAsync(ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken) { Record.Add(MethodBase.GetCurrentMethod().Name); return base.OnConversationUpdateActivityAsync(turnContext, cancellationToken); } protected override Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken) { Record.Add(MethodBase.GetCurrentMethod().Name); return base.OnMembersAddedAsync(membersAdded, turnContext, cancellationToken); } protected override Task OnMembersRemovedAsync(IList<ChannelAccount> membersRemoved, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken) { Record.Add(MethodBase.GetCurrentMethod().Name); return base.OnMembersRemovedAsync(membersRemoved, turnContext, cancellationToken); } protected override Task OnEventActivityAsync(ITurnContext<IEventActivity> turnContext, CancellationToken cancellationToken) { Record.Add(MethodBase.GetCurrentMethod().Name); return base.OnEventActivityAsync(turnContext, cancellationToken); } protected override Task OnTokenResponseEventAsync(ITurnContext<IEventActivity> turnContext, CancellationToken cancellationToken) { Record.Add(MethodBase.GetCurrentMethod().Name); return base.OnTokenResponseEventAsync(turnContext, cancellationToken); } protected override Task OnEventAsync(ITurnContext<IEventActivity> turnContext, CancellationToken cancellationToken) { Record.Add(MethodBase.GetCurrentMethod().Name); return base.OnEventAsync(turnContext, cancellationToken); } protected override Task OnUnrecognizedActivityTypeAsync(ITurnContext turnContext, CancellationToken cancellationToken) { Record.Add(MethodBase.GetCurrentMethod().Name); return base.OnUnrecognizedActivityTypeAsync(turnContext, cancellationToken); } } private class TestDelegatingTurnContextActivityHandler : ActivityHandler { protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken) { // touch every var activity = turnContext.Activity; var adapter = turnContext.Adapter; var turnState = turnContext.TurnState; var responsed = turnContext.Responded; turnContext.OnDeleteActivity((t, a, n) => Task.CompletedTask); turnContext.OnSendActivities((t, a, n) => Task.FromResult(new ResourceResponse[] { new ResourceResponse() })); turnContext.OnUpdateActivity((t, a, n) => Task.FromResult(new ResourceResponse())); await turnContext.DeleteActivityAsync(activity.GetConversationReference()); await turnContext.SendActivityAsync(new Activity()); await turnContext.SendActivitiesAsync(new IActivity[] { new Activity() }); await turnContext.UpdateActivityAsync(new Activity()); } } } }
StackExchange
除了.NET SDK之外,Bot Builder还支持在其他流行的编程语言中创建机器人,如JavaScript,Python(预览版)和Java(预览版)。
要开始,请参阅v4 SDK 的Azure Bot服务文档。
该机器人Framework示例包括一套丰富的样本库的。
包
名称 发布包 每日建设
Microsoft.Bot.Builder BotBuilder徽章 BotBuilder徽章
Microsoft.Bot.Builder.AI.LUIS BotBuilder徽章 BotBuilder徽章
Microsoft.Bot.Builder.AI.QnA BotBuilder徽章 BotBuilder徽章
Microsoft.Bot.Builder.Azure BotBuilder徽章 BotBuilder徽章
Microsoft.Bot.Builder.Dialogs BotBuilder徽章 BotBuilder徽章
Microsoft.Bot.Builder.TemplateManager BotBuilder徽章 BotBuilder徽章
Microsoft.Bot.Builder.Integration.ApplicationInsights.Core BotBuilder徽章 BotBuilder徽章
Microsoft.Bot.Builder.Integration.ApplicationInsights.WebApi BotBuilder徽章 BotBuilder徽章
Microsoft.Bot.Configuration BotBuilder徽章 BotBuilder徽章
Microsoft.Bot.Connector BotBuilder徽章 BotBuilder徽章
Microsoft.Bot.Schema BotBuilder徽章 BotBuilder徽章
要使用发布到MyGet的每日构建,请按照此处的说明进行操作。
特约
该项目欢迎提供意见和建议。大多数贡献要求您同意授权许可协议(CLA),声明您有权并且实际上授予我们使用您的贡献的权利。有关详细信息,请访问https://cla.microsoft.com。当您提交拉取请求时,CLA-bot将自动确定您是否需要提供CLA并适当地装饰PR(例如,标签,评论)。只需按照机器人提供的说明操作即可。您只需要使用我们的CLA在所有回购中执行此操作一次。该项目采用了Microsoft开源行为准则。有关更多信息,请参阅行为准则常见问题解答或联系opencode@microsoft.com 有任何其他问题或意见。
报告安全问题
安全问题和错误,应秘密报告,通过电子邮件,微软安全响应中心(MSRC)在secure@microsoft.com。您应该会在24小时内收到回复。如果由于某种原因您没有,请通过电子邮件跟进,以确保我们收到您的原始邮件。可以在Security TechCenter中找到更多信息,包括MSRC PGP密钥。
版权所有(c)Microsoft Corporation。版权所有。