Joseph Blair
Joseph Blair

Reputation: 1455

Authorization denied for bot when attempting to create conversation via API

I'm trying to develop a bot to be used exclusively for proactive messaging (since unfortunately, it appears Connectors do not support direct messaging). I stood up a web service, and was able to receive the payload from Teams when I sent a message to the bot.

I'm now trying to send a proactive message from the bot back to my user, as described here. Per the instructions, I am POSTing the following payload to <serviceUrl>/v3/conversations. (Values in brackets are interpolated from the payload I received from Teams)

{
    "bot": {
        "id": <recipient.id>,
        "name": <recipient.name>
    },
    "isGroup": false,
    "members": [
        {
            "id": <from.id>,
            "name": <from.name>
        }
    ],
    "tenantId": <channelData.tenant.id>,
    "topicName": "News Alert"
}

I also included a Bearer token that I got by calling https://login.microsoftonline.com/<channelData.tenant.id>/oauth2/v2.0/token. Yet, whenever I try to create the conversation, it fails with an error that "Authorization has been denied for this request." As far as I can tell, the token should be valid, so I'm not sure what else could be going on here. I saw something about trusting the service URL, but I'm not sure how I would do that since I'm not using the Bot SDK. Perhaps I'm going about this wrong and should be trying to create an Activity rather than a Conversation?

Upvotes: 0

Views: 705

Answers (2)

Joseph Blair
Joseph Blair

Reputation: 1455

I think I've figured out the problem. I sent my token request to https://login.microsoftonline.com/<channelData.tenant.id>/oauth2/v2.0/token, which was successful and gave me a token back. However, the instructions outlined here say not to use <channelData.tenant.id>, but instead just the hardcoded string botframework.com. After requesting the token that way, my requests appear to be working.

Upvotes: 1

Hilton Giesenow
Hilton Giesenow

Reputation: 10844

There are basically two steps in sending pro-active messages. The first step is just a once-off - it's getting the unique ID of the conversation between the bot and the user. It's the paragraph you're linking to in your original question, and it's the payload sample you're showing. Once you've got that conversation id, you'd then proceed to sending messages at any time in the future (that's this paragraph).

However, in Teams, the first part is handled differently. Rather than calling the bot framework conversation endpoint (recall that bot framework is used for other things aside from Teams bots), you wait for the user to install the app, which includes your bot. When this is done, your bot will receive a conversationUpdate event. When this fires, you'll be sent a payload which includes the conversationId of the newly-created conversation. This replaces the call you're currently making.

You need to save the conversationId, and the serviceUrl (which will be similar too 'https://smba.trafficmanager.net/apis', but unique for Teams, and will be the 'base' of the URL you'll call later).

Importantly, it is possible to "pre-install" an app for a user, using the Graph API. See Install app for user.

That should help with what you're missing. However, as an 'fyi', you can use libraries for this instead of making the call directly yourself. In dotnet, for instance, you can reference Microsoft.Bot.Connector.ConnectorClient (in Microsoft.Bot.Connector), which has a Conversations.SendToConversationAsync(..) method.

Upvotes: 2

Related Questions