0

I am writing a chat bot that can ask a user for name and a requirement to search job with.

Name and Requirement will be stored in UserData and PrivateConversationData.

I am trying to send the requirement as an index, 1-5, to a method dialog and to specify a requirement like salary amount and then call an appropriate api. But the bot keep giving an error when passing the parameter. How can I fix the error? Is it the way my method receives it or I use the wrong way to call it?

I'm trying to combine the requirement and job stuff into one single to prevent [Community Edit: To prevent what?]

private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
{

        if (string.IsNullOrEmpty(name))//ask for the name
        {
           //code for get name
        }
        else
        {
            context.PrivateConversationData.TryGetValue<int>("Index", out int index);

            if (!Enumerable.Range(1, 5).Contains(index))
            {
                var getRequirement =
                    FormDialog.FromForm(Requirement.BuildForm,
                        FormOptions.PromptInStart);

                context.Call(getRequirement, AfterGetRequirementAsync);//able to get requirement index as int 1~5. next going to ask what specific value
            }
            else
            {

                await context.PostAsync($"{name}:{index}: {activity.Text}");//testing: it is able to print the name and the index user choose
                context.Wait(MessageReceivedAsync);
            }
}

I am using context.Call(getRequirement, AfterGetRequirementAsync) to try to get both requirement and then ask for the specific value in AfterGetRequirementAsync.

private async Task AfterGetRequirementAsync(IDialogContext context, IAwaitable<Requirement> result)
    {
        //Requirement requirementindex = null;

        var requirementindex = await result;
        context.PrivateConversationData.SetValue<int>("Index", requirementindex.Index);


        await context.PostAsync($"Result:{JsonConvert.SerializeObject(requirementindex)}");//for testing index after user's input about index

        var jobs = await GetJobDialog.LoadJob(requirementindex.Index);//Im trying to pass the .Index
        //await context.PostAsync($"Job Search Result : {Environment.NewLine}{JsonConvert.SerializeObject(jobs)}");//trying to print the list of result to user

        context.Wait(MessageReceivedAsync);
    }

In AfterGetRequirementAsync, it is able to get the requirementindex and I can store it in PrivateConversationData in MessageReceivedAsync as Index. But when I try to pass the requirementindex.Index to GetJobDialog.JobModel.LoadJob it give me error of [Community Edit: What's the error?]

public class GetJobDialog
{
    public Task StartAsync(IDialogContext context)
    {
        context.Wait(LoadJob(context.UserData));

        return Task.CompletedTask;
    }
    public static async Task<List<JobModel>>  LoadJob(IDialog context, IAwaitable<JobResultModel> result, int index)//depends on the job searching index, using different method to search.
        {//it should return list of jobs to user.
            string url = "";

            if (index == 1)//posting type
            { //code like index == 4 }
            else if (index == 2)//level
            { //code like index == 4 }
            else if (index == 3)//full time or part time
            { //code like index == 4 }
            else if (index == 4)//salary from
            {   //ask for internal or external and change the end= to match value
                url = $"https://data.cityofnewyork.us/resource/kpav-sd4t.json?salary_range_from=40000";
            }//the only thing different is after .json? the index = specific value
            else if (index == 5)//salary to
            { //code like index == 4 }
            else//if not getting any valid option, throw error message and ask for index again
            {

            }

            using (HttpResponseMessage response = await ApiHelper.ApiHelper.ApiClient.GetAsync(url))
            {
                if (response.IsSuccessStatusCode)
                {
                    JobResultModel job = await response.Content.ReadAsAsync<JobResultModel>();

                    return job.Results;
                }
                else
                {
                    throw new Exception(response.ReasonPhrase);
                }
            }
    }
}

I am also trying to get the user to input the specific amount in the GetJobDialog. That way, the user doesn't have to enter anything to trigger the chat bot again.

I'm just posting the API caller incase I have some mistake because I learn all these by myself and do not have a clear understanding of how C# and api work.

public static class ApiHelper
{
    public static HttpClient ApiClient { get; set; }

    public static void InitializeClient()
    {
        ApiClient = new HttpClient();
        ApiClient.DefaultRequestHeaders.Accept.Clear();
        ApiClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    }
}

I expect the chat bot be able to pass the index to LoadJob and ask for specific value before or after the call of LoadJob. Then response a list of job with different field to the user.

mdrichardson
  • 7,141
  • 1
  • 7
  • 21

1 Answers1

1

I see a few issues with your code that might be causing this. If you can link me to all of your code, I might be able to help debug. In the meantime, here's some things might be causing the problem:

  1. You're using BotBuilder V3 Code. If you're writing a new bot, you should really be using Botframework V4. Here's a State Management Sample Bot that can help you get started. You really should switch to V4, especially if this is a newer bot. If you run into issues in the future, you'll receive better support.

  2. It looks like you're saving Index to PrivateConversationData, but when you pass it LoadJob(), you're using UserData instead.

  3. I'm not sure that you can pass information when using context.Wait(). None of the V3 Samples do that. I don't use V3 much, so I can't tell for sure. What you should instead do, is use something like context.PrivateConversationData.TryGetValue<int>("Index", out int index); to load the index instead of passing it.

It also looks like you didn't post the error message. If you can post that and all of your code, I can help debug further (if the above doesn't work).

mdrichardson
  • 7,141
  • 1
  • 7
  • 21
  • Thank you so much for helping me with the code, I have updated something for my code. Im able to do with the index and next step is to call api to request data from a database but that has a problem of the data it response back is jsonArray but I only find tutorial to handles json object. Im trying to print the result to user. here is the link of the chatbot in github [link](https://github.com/teddyw1024/CISC4900) – teddyw1024 May 16 '19 at 22:26
  • Im also having some error with that chatbot too. I copied the message [link](https://justpaste.it/edit/28500070/ad38fb4e74968d57) – teddyw1024 May 16 '19 at 22:29
  • [This link should help](https://stackoverflow.com/questions/18490599/parsing-json-rest-api-response-in-c-sharp). The error is because the response you get from the HttpRequest doesn't match your `JobResultModel` (at least on the one that I tested). This sort of thing deserves its own Stack Overflow question and isn't really bot-related – mdrichardson May 16 '19 at 23:44