0
votes

I've got a Bot Framework V3 bot code base that is working in a half dozen or so different customer Teams tenants, and on our internal Teams tenant without issues.

In one particular customer tenant, attempts to create a proactive message to a Teams Channel are failing with a ConversationNotFound 404 error, when I call ConnectorClient.Conversations.CreateConversationAsync().

My code to create the conversation and post an activity in the channel looks like this:

    var teamsChannelId = "19:deadbeef1234@thread.skype"; // insert the real channel ID obtained from lookups against Graph API...
    var botCredentials = new MicrosoftAppCredentials(/* Bot ID & password */);

    MicrosoftAppCredentials.TrustServiceUrl("https://smba.trafficmanager.net/amer/", DateTime.MaxValue);
    using (var connectorClient = new ConnectorClient(new Uri("https://smba.trafficmanager.net/amer/"), botCredentials)) {
        var botId = new ChannelAccount("28:" + botCredentials.MicrosoftAppId);
        var msg = Activity.CreateMessageActivity();
        msg.From = botId;
        var card = MakeCard(); // builds an AdaptiveCard...
        msg.Attachments.Add(new Attachment(AdaptiveCard.ContentType, content: card));

        var parameters = new ConversationParameters() {
            Bot = botId,
            ChannelData = new TeamsChannelData() {
                Channel = new ChannelInfo(teamsChannelId)
            },
            Activity = (Activity)msg
        };
        // This throws an Microsoft.Bot.Connector.ErrorResponseException with the code "ConversationNotFound"
        ConversationResourceResponse convoResponse = await connectorClient .Conversations.CreateConversationAsync(parameters);
    }

As I mentioned initially, this code may not be perfect, but it is working on a number of different Teams and Azure environments, but failing in this particular environment. The HTTP response from Bot Framework looks like this:

"Response": {
"StatusCode": 404,
"ReasonPhrase": "Not Found",
"Content": "{\"error\":{\"code\":\"ConversationNotFound\",\"message\":\"Conversation not found.\"}}",
"Headers": {
  "Date": [
    "Wed, 04 Sep 2019 14:43:24 GMT"
  ],
  "Server": [
    "Microsoft-HTTPAPI/2.0"
  ],
  "Content-Length": [
    "77"
  ],
  "Content-Type": [
    "application/json; charset=utf-8"
  ]
}

Stack Trace:

Microsoft.Bot.Connector.ErrorResponseException: Operation returned an invalid status code 'NotFound'
   at Microsoft.Bot.Connector.Conversations.<CreateConversationWithHttpMessagesAsync>d__6.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Bot.Connector.ConversationsExtensions.<CreateConversationAsync>d__3.MoveNext()
  • The bot is able to handle incoming 1-1 chat conversations without issue over webchat, directline and the Teams connectors, so I don't think there are any issues with the bot credentials, or the bot registration configuration.
  • The bot has been added as an app for Microsoft Teams, uploaded to the tenant, and added to the appropriate Team.
  • I've explored the possibility that the region of the Bot Framework registration in Azure might be causing an issue, but I've reproduced the client's configuration on our end, and can't reproduce the problem.

Any suggestions would be very welcome.

1
Please do not hard code serviceURL value. When a user sends a message to your bot, the incoming request contains an Activity object with a serviceUrl property that specifies the endpoint to which your bot should send its response. Please use service URL for specific tenant and try again.Trinetra-MSFT
I don't have an incoming response that would work - this is a proactive message, that is being sent over a different channel than any incoming requests from users. Is there a list documented anywhere of what the available service URLs are and what they should correspond to? It's frustrating as all hell trying to do anything moderately outside the happy path with Bot Framework, as so little is documented and so much is obfuscated.EricRRichards
Were you able to get this working with my answer? If so, please "accept" and upvote it so others can quickly find the answer and I can clear this from my support tracker. If not, let me know how else I can help!mdrichardson

1 Answers

1
votes

I have a feeling your parameters is missing the Tenant. This may explain why it fails on some tenants and not others. Try something like this:

var parameters = new ConversationParameters
{
    Members = new[] { new ChannelAccount(userId) },
    ChannelData = new TeamsChannelData
    {
        Tenant = new TenantInfo(activity.Conversation.TenantId),
    },
};

@Trinetra-MSFT is also correct. You should not hard-code the service URL; some of your users may be outside /amer.

Although possible to some extent, "Proactive Messaging" shouldn't be thought of as "messaging users who have not spoken with the bot", so much as "messaging a user about something not related to a previous conversation". Generally speaking, proactive messaging needs to be done by saving a conversation reference from a user that the bot has had a past conversation with. This is how the Bot Framework, specifically, defines Proactive Messaging.

For Teams, per Proactive Messaging for Bots:

Bots can create new conversations with an individual Microsoft Teams user as long as your bot has user information obtained through previous addition in a personal, groupChat or team scope. This information enables your bot to proactively notify them. For instance, if your bot was added to a team, it could query the team roster and send users individual messages in personal chats, or a user could @mention another user to trigger the bot to send that user a direct message.

See this SO answer for additional help. Note: it's written for a V4 bot, so you may need to make some adjustments.

Let me know if you run into issues and I will adjust my answer accordingly.