Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can we test bot in own client without azure or bot emulator?

I'm new to this. I have checked the already asked questions and i could not find the answer for my scenario.

Query: Im trying to create a bot locally, in which i succeeded with the help of docs. I can test that in bot emulator. Now, i want to create my own client in wpf , all the samples i found online having directline secret from azure. But, the emulator working without internet,so i thought ,they must be doing this without secret.

since i'm wpf application developer, i could not understand the emulator source code or make it run-able.

Can any one tell me or point out where i can check how to run bot client locally without azure direcltline secret?

Bot

[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)
        {
        }

    }
}

Client:

 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));
        }
    }
}

Please let me know, if im doing anything wrong.

Thank in Advance

like image 723
WPFUser Avatar asked Sep 14 '25 17:09

WPFUser


1 Answers

Take a look at the excellent Offline DirectLine node package from my colleague Ryan Volum. Don't let the fact that it's Node based deter you just because you're writing a .NET based bot. All it does is stand up a local web server that emulates the DirectLine API and tunnels the requests through to your bot.

It's super simple to use, just follow the usage directions on the package page.

like image 115
Drew Marsh Avatar answered Sep 16 '25 07:09

Drew Marsh