Home
%3CLINGO-SUB%20id%3D%22lingo-sub-400530%22%20slang%3D%22en-US%22%3EAdd%20chat%20bot%20feature%20to%20your%20desktop%20app%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-400530%22%20slang%3D%22en-US%22%3E%3CDIV%3E%3CFONT%20style%3D%22background-color%3A%20%23ffffff%3B%22%3E%3CFONT%20style%3D%22background-color%3A%20%23ffffff%3B%22%3ERecently%2C%20we%20have%20seen%20a%20lot%20of%20chatbots.%20For%20example%20FAQ%20bots%20and%20navigation%20bots%20and%20more.%3CBR%20%2F%3E%26nbsp%3B%3CBR%20%2F%3EIf%20the%20app%20users%20are%20looking%20for%20how%20to%20use%20the%20app%2C%20then%20chatbot%20UI%20is%20a%20good%20way%20for%20asking%20about%20apps.%3CBR%20%2F%3EYou%20can%20create%20a%20FAQ%20bot%20using%20Azure%20Bot%20Service%20and%20QnA%20Maker.%20It%20is%20straightforward.%3CBR%20%2F%3EThe%20following%20document%20explains%20how%20to%20create%20QA%20bots.%3CBR%20%2F%3E%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fbot-service%2Fbot-builder-howto-qna%3Fview%3Dazure-bot-service-4.0%26amp%3Btabs%3Dcs%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3EUse%20QnA%20Maker%20to%20answer%20questions%3C%2FA%3E%3CBR%20%2F%3E%26nbsp%3B%3CBR%20%2F%3EIf%20you%20want%20to%20integrate%20a%20bot%20feature%20in%20your%20app%2C%20then%20you%20can%20use%20DirectLine%20APIs.%3CBR%20%2F%3EYou%20can%20use%20it%20add%20Microsoft.Bot.Connector.DirectLine%20package%20using%20NuGet.%3CBR%20%2F%3E%26nbsp%3B%3CBR%20%2F%3E%3CFONT%20size%3D%225%22%3E%3CSTRONG%3EHow%20to%20use%20DirectLine%3F%3C%2FSTRONG%3E%3C%2FFONT%3E%3CBR%20%2F%3EAt%20first%2C%20you%20create%20a%20DirectLineClient%20instance.%3CBR%20%2F%3E%3C%2FFONT%3E%3C%2FFONT%3E%3CPRE%3Evar%20directLineClient%20%3D%20new%20DirectLineClient(%22here%20is%20key%20that%20is%20got%20from%20Bot%20Channels%20Registration%22)%3B%3C%2FPRE%3E%0A%3CFONT%20style%3D%22background-color%3A%20%23ffffff%3B%22%3E%3CFONT%20style%3D%22background-color%3A%20%23ffffff%3B%22%3E%3CBR%20%2F%3ENext%2C%20start%20a%20conversation.%3CBR%20%2F%3E%3C%2FFONT%3E%3C%2FFONT%3E%0A%3CPRE%3Evar%20conversation%20%3D%20await%20directLineClient.Conversations.StartConversationAsync()%3B%3C%2FPRE%3E%0A%3CFONT%20style%3D%22background-color%3A%20%23ffffff%3B%22%3EYou%20can%20send%20a%20message%20to%20bot%20using%20the%20conversation%20id.%3CBR%20%2F%3E%3C%2FFONT%3E%3C%2FDIV%3E%0A%3CDIV%3E%0A%3CPRE%3Eawait%20directLineClient.Conversations.PostActivityAsync(conversation.ConversationId%2C%20new%20Activity%0A%7B%0A%20%20%20%20From%20%3D%20new%20ChannelAccount(%22User%20id%22)%2C%0A%20%20%20%20Text%20%3D%20%22a%20message%20send%20to%20bot%22%2C%0A%20%20%20%20Type%20%3D%20ActivityTypes.Message%2C%0A%7D)%3B%3C%2FPRE%3E%0A%3CFONT%20style%3D%22background-color%3A%20%23ffffff%3B%22%3EAnd%20you%20can%20also%20get%20messages%20from%20the%20bot.%3CBR%20%2F%3E%3C%2FFONT%3E%3C%2FDIV%3E%0A%3CDIV%3E%0A%3CPRE%3Estring%20watermark%20%3D%20null%3B%0Awhile(true)%0A%7B%0A%20%20%20%20var%20activitySet%20%3D%20await%20directLineClient.Conversations.GetActivitiesAsync(conversation.ConversationId%2C%20watermark)%3B%0A%20%20%20%20watermark%20%3D%20activitySet.Watermark%3B%0A%20%20%20%20var%20botMessages%20%3D%20activitySet.Activities.Where(x%20%3D%26gt%3B%20x.From.Id%20%3D%3D%20%22bot%20id%22)%3B%0A%20%20%20%20foreach%20(var%20message%20in%20botMessages)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%2F%2F%20process%20a%20message%20that%20is%20from%20the%20bot%0A%20%20%20%20%7D%0A%20%20%20%20await%20Task.Delay(2000)%3B%0A%7D%3C%2FPRE%3E%0A%3CFONT%20style%3D%22background-color%3A%20%23ffffff%3B%22%3EIt's%20very%20simple%20and%20easy.%3C%2FFONT%3E%3C%2FDIV%3E%0A%3CDIV%3E%3CFONT%20style%3D%22background-color%3A%20%23ffffff%3B%22%3E%3CBR%20%2F%3E%3CFONT%20size%3D%225%22%3E%3CSTRONG%3EHow%20to%20display%20rich%20contents%3F%3C%2FSTRONG%3E%3C%2FFONT%3E%3CBR%20%2F%3EThe%20bots%20that%20are%20created%20by%20Azure%20Bot%20Service%20send%20some%20rich%20contents%20like%20image%20contents%20%2Cand%20cards%20contents(hero%20cards%2C%20adaptive%20cards)%20%2Cand%20more.%3CBR%20%2F%3EIf%20you%20want%20to%20support%20those%20contents%2C%20then%20you%20can%20use%20AdaptiveCards%20Renderer.%3C%2FFONT%3E%3C%2FDIV%3E%0A%3CUL%3E%0A%3CLI%3E%3CA%20href%3D%22https%3A%2F%2Fwww.nuget.org%2Fpackages%2FAdaptiveCards.Rendering.Wpf%2F%22%20target%3D%22_self%22%20rel%3D%22nofollow%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3E%3CFONT%20style%3D%22background-color%3A%20%23ffffff%3B%22%3EFor%20WPF%20package%3C%2FFONT%3E%3C%2FA%3E%3C%2FLI%3E%0A%3CLI%3E%3CA%20href%3D%22https%3A%2F%2Fwww.nuget.org%2Fpackages%2FAdaptiveCards.Rendering.Uwp%2F%22%20target%3D%22_self%22%20rel%3D%22nofollow%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3E%3CFONT%20style%3D%22background-color%3A%20%23ffffff%3B%22%3EFor%20UWP%20package%3C%2FFONT%3E%3C%2FA%3E%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CDIV%3E%3CFONT%20style%3D%22background-color%3A%20%23ffffff%3B%22%3EIf%20you%20detect%20rich%20contents%20in%20attachments%20of%20the%20message%2C%20then%20convert%20it%20to%20an%20AdaptiveCard%20instance%2C%20and%20then%20you%20can%20render%20it%20using%20AdaptiveCards%20Renderer.%3C%2FFONT%3E%3C%2FDIV%3E%0A%3CDIV%3E%3CFONT%20style%3D%22background-color%3A%20%23ffffff%3B%22%3E%3CFONT%20style%3D%22background-color%3A%20%23ffffff%3B%22%3EThe%20convert%20logic%20is%20like%20below%3A%3CBR%20%2F%3E%3C%2FFONT%3E%3C%2FFONT%3E%0A%3CPRE%3Eprivate%20IEnumerable%26lt%3BAdaptiveCard%26gt%3B%20ConvertAttachmentsToAdaptiveCard(IEnumerable%26lt%3BAttachment%26gt%3B%20attachments)%0A%7B%0A%20%20%20%20AdaptiveCard%20parseHeroCard(string%20json)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20var%20heroCard%20%3D%20JsonConvert.DeserializeObject%26lt%3BHeroCard%26gt%3B(json)%3B%0A%20%20%20%20%20%20%20%20return%20new%20AdaptiveCard(%221.0%22)%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20Body%20%3D%20new%20List%26lt%3BAdaptiveElement%26gt%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20new%20AdaptiveTextBlock(heroCard.Title)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Size%20%3D%20AdaptiveTextSize.Medium%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Weight%20%3D%20AdaptiveTextWeight.Bolder%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20new%20AdaptiveTextBlock(heroCard.Text)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%7D%3B%0A%20%20%20%20%7D%0A%20%20%20%20return%20attachments%3F.Select(x%20%3D%26gt%3B%20x.ContentType%20switch%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%22application%2Fvnd.microsoft.card.hero%22%20%3D%26gt%3B%20parseHeroCard(x.Content.ToString())%2C%0A%20%20%20%20%20%20%20%20%22image%2Fpng%22%20%3D%26gt%3B%20new%20AdaptiveCard(%221.0%22)%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20Body%20%3D%20new%20List%26lt%3BAdaptiveElement%26gt%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20new%20AdaptiveImage(x.ContentUrl)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20_%20%3D%26gt%3B%20null%2C%0A%20%20%20%20%20%20%20%20%7D)%0A%20%20%20%20%20%20%20%20%3F.Where(x%20%3D%26gt%3B%20x%20!%3D%20null)%3B%0A%7D%3C%2FPRE%3E%0A%3CFONT%20style%3D%22background-color%3A%20%23ffffff%3B%22%3EThe%20rendering%20logic%20is%20like%20following%20code%3A%3CBR%20%2F%3E%3C%2FFONT%3E%0A%3CPRE%3E%2F%2F%20The%20code%20for%20UWP%0Avar%20renderer%20%3D%20new%20AdaptiveCardRenderer()%3B%0Avar%20adaptiveCard%20%3D%20...%20%2F%2F%20Get%20an%20AdaptiveCards.AdaptiveCard%20instance%0Avar%20renderedCard%20%3D%20renderer.RenderAdaptiveCard(AdaptiveCard.FromJsonString(adaptiveCard.ToJson()))%3B%0ArenderedCard.FrameworkElement%3B%20%2F%2F%20get%20result%3C%2FPRE%3E%0A%3CFONT%20style%3D%22background-color%3A%20%23ffffff%3B%22%3E%3CFONT%20size%3D%225%22%3E%3CSTRONG%3EThe%20sample%20program%3C%2FSTRONG%3E%3C%2FFONT%3E%3CBR%20%2F%3EThe%20following%20repository%20is%20a%20sample%20app%20to%20render%20simple%20text%20messages%2C%20Hero%20cards%20and%20images.%3CBR%20%2F%3E%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2Frunceel%2FDirectLineClient%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3Ehttps%3A%2F%2Fgithub.com%2Frunceel%2FDirectLineClient%3C%2FA%3E%3CBR%20%2F%3E%3C%2FFONT%3E%3C%2FDIV%3E%0A%3CDIV%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-left%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F105846iBBECB497C64BEA61%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20alt%3D%22screenshot.jpg%22%20title%3D%22screenshot.jpg%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FDIV%3E%0A%3CDIV%3E%26nbsp%3B%3C%2FDIV%3E%3C%2FLINGO-BODY%3E%3CLINGO-LABS%20id%3D%22lingo-labs-400530%22%20slang%3D%22en-US%22%3E%3CLINGO-LABEL%3Ekaota%40microsoft.com%3C%2FLINGO-LABEL%3E%3C%2FLINGO-LABS%3E%3CLINGO-SUB%20id%3D%22lingo-sub-451482%22%20slang%3D%22en-US%22%3ERe%3A%20Add%20chat%20bot%20feature%20to%20your%20desktop%20app%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-451482%22%20slang%3D%22en-US%22%3E%3CP%3E%3CSPAN%3EHas%20anyone%20been%20able%20to%20find%20a%20way%20to%20remove%20the%20quick%20links%20to%20user%20profile%20folders%20programmatically%3F%26nbsp%3B%20It%20seems%20like%20there%20should%20be%20a%20registry%20key%20or%20some%20other%20value%20that%20can%20be%20changed%20via%20Group%20Policy%20or%20otherwise%20to%20change%20the%20appearance%20%3CA%20target%3D%22_blank%22%20rel%3D%22noopener%22%3Ehttps%3A%2F%2Fwww.nrmovers.ae%3C%2FA%3E%3C%2FSPAN%3E%3C%2FP%3E%3C%2FLINGO-BODY%3E
Microsoft
Recently, we have seen a lot of chatbots. For example FAQ bots and navigation bots and more.
 
If the app users are looking for how to use the app, then chatbot UI is a good way for asking about apps.
You can create a FAQ bot using Azure Bot Service and QnA Maker. It is straightforward.
The following document explains how to create QA bots.
Use QnA Maker to answer questions
 
If you want to integrate a bot feature in your app, then you can use DirectLine APIs.
You can use it add Microsoft.Bot.Connector.DirectLine package using NuGet.
 
How to use DirectLine?
At first, you create a DirectLineClient instance.
var directLineClient = new DirectLineClient("here is key that is got from Bot Channels Registration");

Next, start a conversation.
var conversation = await directLineClient.Conversations.StartConversationAsync();
You can send a message to bot using the conversation id.
await directLineClient.Conversations.PostActivityAsync(conversation.ConversationId, new Activity
{
    From = new ChannelAccount("User id"),
    Text = "a message send to bot",
    Type = ActivityTypes.Message,
});
And you can also get messages from the bot.
string watermark = null;
while(true)
{
    var activitySet = await directLineClient.Conversations.GetActivitiesAsync(conversation.ConversationId, watermark);
    watermark = activitySet.Watermark;
    var botMessages = activitySet.Activities.Where(x => x.From.Id == "bot id");
    foreach (var message in botMessages)
    {
        // process a message that is from the bot
    }
    await Task.Delay(2000);
}
It's very simple and easy.

How to display rich contents?
The bots that are created by Azure Bot Service send some rich contents like image contents ,and cards contents(hero cards, adaptive cards) ,and more.
If you want to support those contents, then you can use AdaptiveCards Renderer.
If you detect rich contents in attachments of the message, then convert it to an AdaptiveCard instance, and then you can render it using AdaptiveCards Renderer.
The convert logic is like below:
private IEnumerable<AdaptiveCard> ConvertAttachmentsToAdaptiveCard(IEnumerable<Attachment> attachments)
{
    AdaptiveCard parseHeroCard(string json)
    {
        var heroCard = JsonConvert.DeserializeObject<HeroCard>(json);
        return new AdaptiveCard("1.0")
        {
            Body = new List<AdaptiveElement>
            {
                new AdaptiveTextBlock(heroCard.Title)
                {
                    Size = AdaptiveTextSize.Medium,
                    Weight = AdaptiveTextWeight.Bolder,
                },
                new AdaptiveTextBlock(heroCard.Text),
            },
        };
    }
    return attachments?.Select(x => x.ContentType switch
        {
        "application/vnd.microsoft.card.hero" => parseHeroCard(x.Content.ToString()),
        "image/png" => new AdaptiveCard("1.0")
        {
            Body = new List<AdaptiveElement>
            {
                new AdaptiveImage(x.ContentUrl),
            }
        },
        _ => null,
        })
        ?.Where(x => x != null);
}
The rendering logic is like following code:
// The code for UWP
var renderer = new AdaptiveCardRenderer();
var adaptiveCard = ... // Get an AdaptiveCards.AdaptiveCard instance
var renderedCard = renderer.RenderAdaptiveCard(AdaptiveCard.FromJsonString(adaptiveCard.ToJson()));
renderedCard.FrameworkElement; // get result
The sample program
The following repository is a sample app to render simple text messages, Hero cards and images.
https://github.com/runceel/DirectLineClient

screenshot.jpg

 
1 Comment
Occasional Visitor

Has anyone been able to find a way to remove the quick links to user profile folders programmatically?  It seems like there should be a registry key or some other value that can be changed via Group Policy or otherwise to change the appearance https://www.nrmovers.ae