2

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.

EricRRichards
  • 474
  • 7
  • 20
  • 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 Sep 05 '19 at 12:22
  • 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 Sep 05 '19 at 13:32
  • 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 Sep 11 '19 at 15:26

1 Answers1

1

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.

mdrichardson
  • 7,141
  • 1
  • 7
  • 21
  • I got around the problem by making the service URL configurable. It still requires some trial and error to find what the appropriate values are - I don't think the possible values are published anywhere, but if you log events and have a Teams user initiate a chat at the bot, you can find out what is needed. I guess one could use Graph API for messaging scenarios, if those APIs are out of Beta, but it's weird to need a mix of Bot Framework for incoming chat sessions and another API for outgoing chats. Still kind of clunky to support scenarios that were simple with Lync/S4B. – EricRRichards Sep 12 '19 at 16:07
  • 1
    Glad you got it working! Note that S4B is being deprecated soon. – mdrichardson Sep 13 '19 at 16:31
  • As far as I'm aware, on-premise Skype for Business is still going to be around for a while, is that no longer the case? – EricRRichards Sep 16 '19 at 13:37
  • 1
    @EricRRichards Until [July 31, 2021](https://learn.microsoft.com/en-us/microsoftteams/faq-journey#how-does-the-skype-for-business-online-retirement-announcement-affect-organizations-with-hybrid-configurations-skype-for-business-online-and-skype-for-business-server) – mdrichardson Sep 16 '19 at 14:29