Search code examples
azurebotframeworkdirect-line-botframework

BotFramework conversation not found


I've been trying to test a function app sending an activity to a bot that has an existing conversation, but to simplify for this post, I'll speak in terms of sending it via postman. I've have been butting up against an issue wherein the conversationId is not being found, despite confirming it does exist beforehand and I'm not entirely sure what I've done wrong.

I log onto portal azure, and go to my bot to Test in Web Chat. I authenticate the bot, and the conversation starts.

Here, I've checked the conversationId is exactly what I expect to be by examining the conversation calls response in Chromes debug tools, in this case it is 1GJ0N9UYKGyELu3LqpDF6b-a

Here is the exact conversation response...

conversationId: "1GJ0N9UYKGyELu3LqpDF6b-a"
expires_in: 3600
referenceGrammarId: "fcab5fbf-67c7-bf55-934a-274e525c78a9"
streamUrl: "wss://webchat.botframework.com/v3/directline/conversations/1GJ0N9UYKGyELu3LqpDF6b-a/stream?watermark=-&t=ew0KICAi...."
token: "ew0KICA..."

So from here, in my mind I should be able to do the following in postman

POST https://webchat.botframework.com/v3/directline/conversations/1GJ0N9UYKGyELu3LqpDF6b-a/activities
Content-Type: application/json
Authorization: Bearer {My webchats channels secret code}
Body:
{
  "type": "message",
  "from": {
    "name": "foo"
  },
  "text": "bar"
}

I'd expect a 200OK and the message 'bar' to appear in my Test In Web Chat from 'foo', but it does not. Instead I get an error in postman stating:

{
    "error": {
        "code": "BadArgument",
        "message": "Conversation not found"
    }
}

How exactly can this be? If I've just created that conversation and can demonstrate that conversationId is in use, why is the post message saying it can't be found? Am I incorrectly using channels? Or doing something blindingly obvious here?


Solution

  • So to answer my own question, to make a long story short. It looks like the example activity supplied in the Microsoft documentation doesn't quite cut it. There is something else that is required, although I didn't have time to narrow it down.

    The solution I took, as I was running low on time was to write a method to save an activity to cosmosDb as part of the authentication flow. This way I have an ironclad activity that I know has worked in at least the invoke stages of the dialog, and I know a conversation reference is correct and present. From there I pulled the activity and changed 4 fields in it.

    activity.Type = "message",
    activity.From = new From { Id = "{BotId}", Name = "Gilbert Bottfried", Role = "bot },
    activity.Text = "{My message}",
    activity.Subject = "{my message subject}"
    

    From there, it was essentially a case of just creating a connector client and firing off this repurposed activity.

    AppCredentials.TrustServiceUrl(serviceUrl, DateTime.MaxValue);
    ConnectorClient client = new ConnectorClient(
        new Uri(serviceUrl),
        MicrosoftAppId,
        MicrosoftAppPassword);
    
    await client.Conversations.SendToConversationAsync(activity.Conversation.Id, activity);
    

    It seems that this was enough to get it working, and it makes for a nice referenceable conversation Id for future messages. Although I found other issues with working with WebChat, because I suspect it's not entirely stable sending messages to and throw via websockets. The testing experience was much more stable on msteams itself, it seemed to handle my barrage of test messages like a champ.

    This is essentially a bruteforce method, as I'm storing and sending a lot of unnecessary data, but it works. I may append this answer to trim down what I find to be necessary in the future, but that will require testing.