0

In this documentation, it shows the QnA Maker service perform Rest calls and deserializing Json responses - Step 3 *How to link Luis with Qna

Specific section of the module string I think i am looking for:

/* START - QnA Maker Response Class */
public class Metadata
{
    public string name { get; set; }
    public string value { get; set; }
}

public class Answer
{
    public IList<string> questions { get; set; }
    public string answer { get; set; }
    public double score { get; set; }
    public int id { get; set; }
    public string source { get; set; }
    public IList<object> keywords { get; set; }
    public IList<Metadata> metadata { get; set; }
}

public class QnAAnswer
{
    public IList<Answer> answers { get; set; }
}
/* END - QnA Maker Response Class */

I'm not going to guess what part of that would have the answer, but QNA should simply reply to a question with a filename which then needs to be concatenated in place of @~\folder\folder\ filename.json so a proper stored Adaptive Card displays as the response.

I give more context than necessary because I'm sure there are others out there who would like a simple means of displaying a card when a question calls for one.

Feel free to edit this or rephrase with proper terminology.

Thanks

2 Answers2

1

If I got your question right you are looking for the answers you will get from the bot. If so the answers will be in the body of the HTTP response displayed like this

{
    "answers": [
        {
            "questions": [
                "What is the closing time?"
            ],
            "answer": "10.30 PM",
            "score": 100,
            "id": 1,
            "source": "Editorial",
            "metadata": [
                {
                    "name": "restaurant",
                    "value": "paradise"
                },
                {
                    "name": "location",
                    "value": "secunderabad"
                }
            ]
        }
    ]
}

so in theory it's going to be in Answer.answer

Edit:

You need to add this method first:

    public string GetAnswer(string query)
    {
        var client = new RestClient( qnaServiceHostName + "/qnamaker/knowledgebases/" + knowledgeBaseId + "/generateAnswer");
        var request = new RestRequest(Method.POST);
        request.AddHeader("authorization", "EndpointKey " + endpointKey);
        request.AddHeader("content-type", "application/json");
        request.AddParameter("application/json", "{\"question\": \"" + query + "\"}", ParameterType.RequestBody);
        IRestResponse response = client.Execute(request);

        // Deserialize the response JSON
        QnAAnswer answer = JsonConvert.DeserializeObject<QnAAnswer>(response.Content);

        // Return the answer if present
        if (answer.answers.Count > 0)
            return answer.answers[0].answer;
        else
            return "No good match found.";
    }
}

And then you can just call:

Console.WriteLine ("the answer to how is the weather today is : " + GetAswers ("how's the weather today") + "... end of answer");

and there you go.

Nader Zouaoui
  • 39
  • 3
  • 15
  • Yes that sounds right. Do you know how to place the Answer.answer into the middle of a string? Needed it to fill the place of "filename".json as a variable. Thanks – Douglas Moody Aug 28 '18 at 20:37
1

QNA should simply reply to a question with a filename which then needs to be concatenated in place of @~\folder\folder\ filename.json so a proper stored Adaptive Card displays as the response.

It seems that you’d like to dynamically render an Adaptive Card from a json file based on the result returned by QnA Maker service. To achieve the requirement, you can refer to the following sample code.

[LuisIntent("Help")]
public async Task HelpIntent(IDialogContext context, LuisResult result)
{
    var replymes = context.MakeMessage();

    var answer = GetAnswer(result.Query);

    var cardjson = await GetCardText($"{answer}");

    var results = AdaptiveCard.FromJson(cardjson);
    var card = results.Card;

    replymes.Attachments.Add(new Attachment()
    {
        Content = card,
        ContentType = AdaptiveCard.ContentType,
        Name = "Card"
    });

    await context.PostAsync(replymes);
    context.Wait(MessageReceived);
}

GetCardText method:

public async Task<string> GetCardText(string cardName)
{
    var path = System.Web.HttpContext.Current.Server.MapPath($"~/AdaptiveCards/{cardName}.json");

    if (!File.Exists(path))
        return string.Empty;

    using (var f = File.OpenText(path))
    {
        return await f.ReadToEndAsync();
    }
}

Test result:

enter image description here

Note:

1) In my above test, my QnA Maker service would return filename as answer directly, so I pass the returned answer as filename

2) I’m using AdaptiveCards -Version 1.0.3 in my bot application to build adaptive card object

Fei Han
  • 26,415
  • 1
  • 30
  • 41
  • Thanks @Fei-Han, actually ended up hosting the .json files externally and then calling them so the results would be file based rather than in the app. Example: https://i.imgur.com/NtDxXWs.png Had some help with this but you can see the host location is a variable of the response from QNA as well as what type Card and there are other variables in mind not displayed. – Douglas Moody Sep 11 '18 at 17:15