We are using the botframework to power a chatbot experience in Microsoft Teams. Many of our use cases involve proactively messaging users, we have followed the documentation closely by storing/retrieving conversation references and trusting the serviceUrl from the retrieved reference, allowing us to successfully send proactive messages.
We have noticed that whenever we restart the bot, we get the following error when attempting to send a proactive message: Authorization has been denied for this request.
We first encountered this error message after the bot had not been interacted with for at least a day which was resolved by altering the following statement with an increased expiration time on the serviceUrl
:
MicrosoftAppCredentials.trustServiceUrl(conversationReference.serviceUrl, new Date(8640000000000000));
However, we now get this message every time the bot server is restarted, which happens often due to our CI/CD pipelines.
We can resolve this issue quite quickly by manually messaging the bot beforehand, which will then work, however this is quite cumbersome as we can have many deployments per day.
To Manually Resolve
Envrionment: Node.js Docker container deployed to AWS
Managed to figure this out by using the botframework-connector to create the conversation and send the proactive message.
Assuming you have stored and retrieved a conversationReference
, start by connecting to the bot
const msAppCredentials = new MicrosoftAppCredentials(MS_APP_ID, MS_APP_PASSWORD);
const client = new ConnectorClient(MSAppCredentials, { baseUri: conversationReference.serviceUrl });
Once connected, you can build up the conversation parameters and create the conversation:
const parameters = {
bot: { id: MS_APP_ID, name: conversationReference.bot.name },
members: [{ id: conversationReference.user.id, name: conversationReference.user.name }],
activity: MessageFactory.text("oi oi oi"),
tenantId: conversationReference.conversation.tenantId,
isGroup: false,
channelData: { ...conversationReference.conversation.channelData }
}
const resource = await client.conversations.createConversation(parameters);
Finally, send the message to the conversation
await client.conversations.sendToConversation(resource.id, parameters.activity);