I have an Azure Bot installed in my organization through Teams. Interactions with the bot are properly functioning.
We have a scenario where we need to send notifications to our users from an external process (C# app running in Azure).
I attempted to use the Bot Framework REST API to create a conversation with a user in order to then message them with the notification as outlined here
This scenario does not work as I cannot get an access token for a bot that is not using the global Bot Framework Tenant. Our Bot is installed on our Azure tenant as a SingleTenant BotType so I get the following error:
Application with identifier 'BOT-APP-ID' was not found in the directory 'Bot Framework'
I've poured over various options including DirectLine channels, BotConnector SDK and Power Automate - but nothing seems to fit with my needs.
Is there a way to use a Rest API against the Bot we have installed to create conversations and send messages? This would be ideal as then I can initiate these notifications directly from the events that triggered them.
UPDATE
Hilton's answer below brought some much needed clarity to the situation. Ultimately I had to deploy a new Bot set to use the Multitenant BotType.
This configured an AppRegistration tied to the Bot set to use MultiTenant as well.
Additionally in the WebApp where you have your api/messages endpoint hosted you have to include a property called MicrosoftAppType and set that to MultiTenant as well. Here is the full configuration required for the WebApp:
MicrosoftAppId: [The AppId of the AppRegistration]
MicrosoftAppPassword: [The Secret of the AppRegistration]
MicrosoftAppTenantId: [Your Tenant Id]
MicrosoftAppType: MultiTenant
To capture the ConversationId, ServiceUrl and UserId I added the following to the OnMembersAddedAsync
foreach (var member in membersAdded)
{
if (!string.IsNullOrEmpty(member.AadObjectId))
{
//This is a user in our AAD. Store the conversation id reference:
var userId = member.AadObjectId;
var serviceUrl = turnContext.Activity.ServiceUrl;
var conversationId = turnContext.Activity.Conversation.Id;
//Save variables to your state store here...
}
else
{
// This is likely a test outside of Teams
//var userId = member.Id; //<-- Not used in my scenario
}
}
Then in my external app (A Console in this example) I can use those variables (along with the AppRegistration credentials) to create a Bot ConnectorClient and update the conversation:
using Microsoft.Bot.Connector;
using Microsoft.Bot.Connector.Authentication;
using Microsoft.Bot.Schema;
var botAppId = "[BOT_ID/APP_REG_ID]";
var botAppKey = "[APP_REG_SECRET]";
var conversationId = "[CONVERSATION_ID]";
var serviceUrl = "[SERVICE_URL]";
MicrosoftAppCredentials.TrustServiceUrl(serviceUrl);
var connector = new Microsoft.Bot.Connector.ConnectorClient(new Uri(serviceUrl), botAppId, botAppKey);
var activity = new Activity()
{
Text = "Proactively saying **Hello**",
Type = ActivityTypes.Message,
Conversation = new ConversationAccount(false, "personal", conversationId)
};
try
{
var result = await connector.Conversations.SendToConversationAsync(conversationId, activity);
Console.WriteLine("Notification sent!");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}