0

My bot keeps failing on the following line of code with the error in Skype, WebChat, and FB chat. I've tried entering the MS App ID and password via the app settings and the web.config. This works fine in the emulator without any errors. When I ran remote debugging I found that this fails on Webchat, Skype, and FB messenger at this line of code:

await connector.Conversations.ReplyToActivityAsync(reply1);

My bot is integrated with SmartThings so the smart accessories are turning on and off as expected but the response back that should be returned in the chat seems to be failing. I've tried creating a new bot service app but it fails as well.

Update including all code:

using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
using Microsoft.Bot.Connector;
using System.Net.Http.Headers;
using System.Threading;
using Microsoft.IdentityModel.Protocols;
using System.Configuration;

namespace FirstBotApp
{
[BotAuthentication]

public class Switches
{
    public string name { get; set; }
    public string value { get; set; }

}



public class MessagesController : ApiController
{

    static HttpClient client = new HttpClient();
    static HttpResponseMessage responsemain = null;
    static int j = 0;

    static void ShowSwitches(Switches[] switches)
    {

        for (int i = switches.Length - 1; i >= 0; i--)
        {
            Console.WriteLine($"Name: {switches[i].name}\tPrice: {switches[i].value}\t");
        }
        return;
    }

    static async Task<Switches[]> GetSwitchesAsync(string path)
    {
        Switches[] switches = null;
        responsemain = await client.GetAsync(path);
        //Console.WriteLine(client.GetAsync(path));
        //Console.WriteLine(response);
        if (responsemain.IsSuccessStatusCode)
        {
            //Console.WriteLine($"Successful response: {response.StatusCode}");
            var response1 = await client.GetStringAsync("");
            Console.WriteLine($"{response1}");

            switches = await responsemain.Content.ReadAsAsync<Switches[]>();

            //JObject j = JObject.Parse(response1);
        }
        else Console.WriteLine($"Error in response: {responsemain.StatusCode}");

        return switches;
    }

    static async Task<Switches> UpdateSwitchesAsync(Switches switches)
    {
        Console.WriteLine("Turning off the light");
        HttpResponseMessage response = await client.PutAsJsonAsync($"switches/off?room=LivingRoom", switches);
        response.EnsureSuccessStatusCode();
        Console.WriteLine($"The response from the server was: {response.StatusCode}");

        // Deserialize the updated switches from the response body.
        switches = await response.Content.ReadAsAsync<Switches>();
        Thread.Sleep(10000);
        Console.WriteLine($"Turning on the light");

        response = await client.PutAsJsonAsync($"switches/on?room=LivingRoom", switches);
        Console.WriteLine($"The response from the server was: {response.StatusCode}");
        Thread.Sleep(10000);
        return switches;
    }

    static async Task<HttpStatusCode> DeleteSwitchesAsync(string id)
    {
        HttpResponseMessage response = await client.DeleteAsync($"api/switchess/{id}");
        return response.StatusCode;
    }


    /// <summary>
    /// POST: api/Messages
    /// Receive a message from a user and reply to it
    /// </summary>
    public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
    {

        Switches[] switches = null;
        ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));
        //string appdId = AppSettings.Settings["MicrosoftAppId"];
        //string appPassword = ConfigurationManager.AppSettings["MicrosoftAppPassword"];
        if (j == 0)
        {
            //client.Timeout = TimeSpan.FromSeconds(4);

            //Declaration of client and Switches variable

            string accessToken = "xxxxx";
            client.BaseAddress = new Uri("xxxxx");
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
            j++;
            //client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue ("Authorization", "Bearer " + accessToken);
        }

        if (activity.Type == ActivityTypes.Message)
        {
            //, appdId, appPassword);
            //Switches switches = new Switches;
            Activity reply1;// = activity.CreateReply($"breakpoint1");
                            //await connector.Conversations.ReplyToActivityAsync(reply1);


            switch (activity.Text.ToLower())
            {
                case"turn on livingroom":
                    try
                    {
                        Console.WriteLine("Turning on the light");
                        responsemain = await client.PutAsJsonAsync($"switches/on?room=LivingRoom", switches);
                        responsemain.EnsureSuccessStatusCode();
                        //Console.WriteLine($"The response from the server was: {responsemain.StatusCode}");

                        // Deserialize the updated product from the response body.
                        switches = await responsemain.Content.ReadAsAsync<Switches[]>();
                        reply1 = activity.CreateReply($"Successfully turned on LivingRoom Light");
                        await connector.Conversations.ReplyToActivityAsync(reply1);
                    }
                    catch
                    {
                        reply1 = activity.CreateReply($"Error");
                        await connector.Conversations.ReplyToActivityAsync(reply1);
                    }
                    break;


                case "turn off livingroom":
                    try
                    {
                        Console.WriteLine("Turning off the light");
                        responsemain = await client.PutAsJsonAsync($"switches/off?room=LivingRoom", switches);
                        responsemain.EnsureSuccessStatusCode();
                        Console.WriteLine($"The response from the server was: {responsemain.StatusCode}");

                        // Deserialize the updated product from the response body.
                        switches = await responsemain.Content.ReadAsAsync<Switches[]>();
                        reply1 = activity.CreateReply($"Successfully turned off LivingRoom Light");
                        await connector.Conversations.ReplyToActivityAsync(reply1);
                    }

                    catch
                    {
                        reply1 = activity.CreateReply($"Error");
                        await connector.Conversations.ReplyToActivityAsync(reply1);
                    }
                    break;


                default: //"What lights are on?":
                    try
                    {
                        switches = await GetSwitchesAsync("");
                        //Console.WriteLine($"About to show the product");
                        ShowSwitches(switches);
                        //await connector.Conversations.ReplyToActivityAsync(switches[].ToString);

                        for (int i = switches.Length - 1; i >= 0; i--)
                        {
                            reply1 = activity.CreateReply($"Room: ");//{switches[i].name}\tStatus: {switches[i].value}\t");
                            responsemain.EnsureSuccessStatusCode();

                            await connector.Conversations.ReplyToActivityAsync(reply1);
                        }



                        break;
                    }
                    catch
                    {

                    }
                    break;




            }

            // calculate something for us to return
            //int length = (activity.Text ?? string.Empty).Length;

            // return our reply to the user
            //Activity reply = activity.CreateReply($"You sent {activity.Text} which was {length} characters");
            //await connector.Conversations.ReplyToActivityAsync(reply);
        }
        else
        {
            HandleSystemMessage(activity);
        }
        // var response = Request.CreateResponse(HttpStatusCode.OK);

        return responsemain;
    }

    static Activity 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
        }
        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)
        {
        }

        return null;
    }``
    //client.dispose();

}
}
MrBrooks
  • 186
  • 6
  • I'm voting to close this question as off-topic because it's must include the details to reproduce. Check if something from http://stackoverflow.com/questions/42611413/bot-framework-emulator-not-working/42729525#42729525 helps you. – Ezequiel Jadib Mar 24 '17 at 09:55
  • @MrBrooks could you please add more code, especially where the "reply1" comes from or how you generate it? – Just Shadow Mar 25 '17 at 11:15
  • @JustShadow updated the post with my full code – MrBrooks Mar 25 '17 at 16:20
  • The emulator works a little different for authentication; if you don't have your id & password set for example, it ignores authentication. There is an alternate definition of the ConnectorClient constructor that lets you specify the credentials when you call it, but if your web.config is set properly it shouldn't need it. – Jim Lewallen Mar 26 '17 at 16:52

1 Answers1

2

I found the error after some additional troubleshooting with remote debugging. Based on @JimLewallen's response I looked closer at the "Credentials" portion of the connector object. The OAuthScope for version 3.0 of the Botframework (connector-> Credentials->OAuthScope in the locals of the remote debugger) was pointing to api.botframework.com/.default when it should have been pointing at "graph.microsoft.com/.default". When I created a new bot service application in Visual Studios using the bot template the OAuthScope showed the correct endpoint.

Incorrect Value: OAuthScope "api.botframework.com/.default"

Correct Value: Image from the Remote Debugger showing the correct OAuthScope

MrBrooks
  • 186
  • 6