c# - 我们可以在没有 azure 或机器人模拟器的情况下在自己的客户端中测试机器人吗?

标签 c# azure botframework offline direct-line-botframework

我对此很陌生。我已经检查了已经提出的问题,但找不到适合我的场景的答案。

查询: 我尝试在本地创建一个机器人,在文档的帮助下我成功了。我可以在机器人模拟器中测试它。现在,我想在 wpf 中创建自己的客户端,我在网上找到的所有示例都具有来自 azure 的直接 secret 。但是,模拟器在没有互联网的情况下工作,所以我想,他们一定是在 secret 地这样做。

由于我是 wpf 应用程序开发人员,因此我无法理解模拟器源代码或使其可运行。

任何人都可以告诉我或指出我可以在哪里检查如何在没有 azure 直接 secret 的情况下在本地运行机器人客户端吗?

机器人

[BotAuthentication]
public class MessagesController : ApiController
{
    /// <summary>
    /// POST: api/Messages
    /// Receive a message from a user and reply to it
    /// </summary>
    public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
    {
        if (activity.Type == ActivityTypes.Message)
        {
            await Conversation.SendAsync(activity, () => new DirectLineBotDialog());
        }
        else
        {
            await HandleSystemMessage(activity);
        }

        var response = Request.CreateResponse(HttpStatusCode.OK);
        return response;
    }

    private async Task HandleSystemMessage(Activity message)
    {
        if (message.Type == ActivityTypes.DeleteUserData)
        {
            // Implement user deletion here
            // If we handle user deletion, return a real message
        }
        else if (message.Type == ActivityTypes.ConversationUpdate)
        {
            // Handle conversation state changes, like members being added and removed
            // Use Activity.MembersAdded and Activity.MembersRemoved and Activity.Action for info
            // Not available in all channels

            if (message.MembersAdded.Any(o => o.Id == message.Recipient.Id))
            {
                ConnectorClient client = new ConnectorClient(new Uri(message.ServiceUrl));

                var reply = message.CreateReply();

                reply.Text = "Welcome to the Bot to showcase the DirectLine API. Send 'Show me a hero card' or 'Send me a BotFramework image' to see how the DirectLine client supports custom channel data. Any other message will be echoed.";

                await client.Conversations.ReplyToActivityAsync(reply);
            }
        }
        else if (message.Type == ActivityTypes.ContactRelationUpdate)
        {
            // Handle add/remove from contact lists
            // Activity.From + Activity.Action represent what happened
        }
        else if (message.Type == ActivityTypes.Typing)
        {
            // Handle knowing tha the user is typing
        }
        else if (message.Type == ActivityTypes.Ping)
        {
        }

    }
}

客户:

 class Program
{
    private static string directLineSecret = ConfigurationManager.AppSettings["DirectLineSecret"];
    private static string botId = ConfigurationManager.AppSettings["BotId"];
    private static string fromUser = "DirectLineSampleClientUser";

    static void Main(string[] args)
    {
        StartBotConversation().Wait();
    }


    private static async Task StartBotConversation()
    {
        DirectLineClient client = new DirectLineClient(directLineSecret);
        var conversation = await client.Conversations.StartConversationAsync();

        new System.Threading.Thread(async () => await ReadBotMessagesAsync(client, conversation.ConversationId)).Start();

        Console.Write("Command> ");

        while (true)
        {
            string input = Console.ReadLine().Trim();

            if (input.ToLower() == "exit")
            {
                break;
            }
            else
            {
                if (input.Length > 0)
                {
                    Activity userMessage = new Activity
                    {
                        From = new ChannelAccount(fromUser),
                        Text = input,
                        Type = ActivityTypes.Message
                    };

                    await client.Conversations.PostActivityAsync(conversation.ConversationId, userMessage);
                }
            }
        }
    }

    private static async Task ReadBotMessagesAsync(DirectLineClient client, string conversationId)
    {
        string watermark = null;

        while (true)
        {
            var activitySet = await client.Conversations.GetActivitiesAsync(conversationId, watermark);
            watermark = activitySet?.Watermark;

            var activities = from x in activitySet.Activities
                             where x.From.Id == botId
                             select x;

            foreach (Activity activity in activities)
            {
                Console.WriteLine(activity.Text);

                if (activity.Attachments != null)
                {
                    foreach (Attachment attachment in activity.Attachments)
                    {
                        switch (attachment.ContentType)
                        {
                            case "application/vnd.microsoft.card.hero":
                                RenderHeroCard(attachment);
                                break;

                            case "image/png":
                                Console.WriteLine($"Opening the requested image '{attachment.ContentUrl}'");

                                Process.Start(attachment.ContentUrl);
                                break;
                        }
                    }
                }

                Console.Write("Command> ");
            }

            await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);
        }
    }

    private static void RenderHeroCard(Attachment attachment)
    {
        const int Width = 70;
        Func<string, string> contentLine = (content) => string.Format($"{{0, -{Width}}}", string.Format("{0," + ((Width + content.Length) / 2).ToString() + "}", content));

        var heroCard = JsonConvert.DeserializeObject<HeroCard>(attachment.Content.ToString());

        if (heroCard != null)
        {
            Console.WriteLine("/{0}", new string('*', Width + 1));
            Console.WriteLine("*{0}*", contentLine(heroCard.Title));
            Console.WriteLine("*{0}*", new string(' ', Width));
            Console.WriteLine("*{0}*", contentLine(heroCard.Text));
            Console.WriteLine("{0}/", new string('*', Width + 1));
        }
    }
}

如果我做错了什么,请告诉我。

提前致谢

最佳答案

看看the excellent Offline DirectLine node package来 self 的同事 Ryan Volum。不要因为它是基于 Node 的事实而阻止您仅仅因为您正在编写基于 .NET 的机器人。它所做的只是建立一个本地 Web 服务器来模拟 DirectLine API 并将请求通过隧道传送到您的机器人。

使用 super 简单,关注the usage directions on the package page即可.

关于c# - 我们可以在没有 azure 或机器人模拟器的情况下在自己的客户端中测试机器人吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54141479/

相关文章:

c# - ASP.NET 用户控件客户端名称在重命名后不会重置

c# - 如何从asp.net core中的cshtml View 获取编译后的C#代码?

azure - 使用 Azure 数据工厂 v2 中启用的 Polybase 将空十进制值传输到 Azure 数据仓库时出错

sql-server - Golang 连接到 SQL Server 错误 - "TLS Handshake failed: Cannot read handshake packet: EOF"

Botframework - C# - 自适应卡片 - 提交操作 - 异常

node.js - 如何在微软bot框架中以表格格式显示数据

c# - 找不到 ASP.NET 5.0 中的 HttpClient?

c# - 如何在多行字符串中找到分布在多行的句子

c# - 使用 API 删除和重新创建数据库时,Azure Cosmos DB 上的存储设置不断从“无限制”更改为“固定”

botframework - 如何仅使用图像的 base64 编码字符串在 Microsoft bot 框架中显示图像?