Warm tip: This article is reproduced from stackoverflow.com, please click
botframework microsoft-teams

Calling my .NET Core Teams Bot from Angular

发布于 2020-04-07 10:17:41

I have created a Teams bot in .NET Core from following the sample found here: https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/57.teams-conversation-bot

This is working and is running locally with ngrok. I have a controller with a route of api/messages:

[Route("api/messages")]
[ApiController]
public class BotController : ControllerBase
{
    private readonly IBotFrameworkHttpAdapter Adapter;
    private readonly IBot Bot;

    public BotController(IBotFrameworkHttpAdapter adapter, IBot bot)
    {
        Adapter = adapter;
        Bot = bot;
    }

    [HttpPost]
    public async Task PostAsync()
    {
        // Delegate the processing of the HTTP POST to the adapter.
        // The adapter will invoke the bot.
        await Adapter.ProcessAsync(Request, Response, Bot);
    }
}

I now want to call a POST to api/messages from my Angular client using TypeScript to send a proactive message to a specific Teams user.

I did figure out how to set the ConversationParameters in TeamsConversationBot.cs to a specific Teams user by doing the following:

var conversationParameters = new ConversationParameters
{
    IsGroup = false,
    Bot = turnContext.Activity.Recipient,
    Members = new[] { new ChannelAccount("[insert unique Teams user guid here]") },
    TenantId = turnContext.Activity.Conversation.TenantId,
};

but what I'm struggling with is how to build a JSON request that sends the Teams user guid (and maybe a couple other details) to my api/messages route from TypeScript.

How do I go about doing this? What parameters/body do I need to send? I haven't been able to find samples online that show how to do this.


Update below for added clarification

I am building a web chat app using Angular for our customers. What I'm trying to do is send a proactive message to our internal employees, who are using Microsoft Teams, when a customer performs some action via the chat app (initiates a conversation, sends a message, etc.).

I've built a Teams bot using .NET Core using this sample: https://kutt.it/ZCftjJ. Modifiying that sample, I can hardcode my Teams user ID and the proactive message is showing up successfully in Teams:

var proactiveMessage = MessageFactory.Text($"This is a proactive message.");
var conversationParameters = new ConversationParameters
{
    IsGroup = false,
    Bot = turnContext.Activity.Recipient,
    Members = new[] { new ChannelAccount("insert Teams ID here") },
    TenantId = turnContext.Activity.Conversation.TenantId,
};

await ((BotFrameworkAdapter)turnContext.Adapter).CreateConversationAsync(teamsChannelId, serviceUrl, credentials, conversationParameters,
    async (t1, c1) =>
    {
        conversationReference = t1.Activity.GetConversationReference();
        await ((BotFrameworkAdapter)turnContext.Adapter).ContinueConversationAsync(_appId, conversationReference,
            async (t2, c2) =>
            {
                await t2.SendActivityAsync(proactiveMessage, c2);
            },
            cancellationToken);
    },
cancellationToken);

What I'm struggling with is:

  1. How to configure my Angular app to notify my bot of a new proactive message I want to send.
  2. How to configure the bot to accept some custom parameters (Teams user ID, message).
Questioner
Ryan Buening
Viewed
76
mdrichardson - MSFT 2020-02-05 03:49

Hilton's answer is still good, but the part about proactively messaging them without prior interaction requires too long of a response. So, responding to your latest comments:

Yes, the bot needs to be installed for whatever team the user resides in that you want to proactively message. It won't have permissions to do so, otherwise.


You don't need to override OnMembersAddedAsync; just query the roster (see below).


You don't need a conversation ID to do this. I'd make your API, instead, accept their Teams ID. You can get this by querying the Teams Roster, which you'll need to do in advance and store in a hash table or something...maybe a database if your team size is sufficiently large.

As far as required information, you need enough to build the ConversationParameters:

var conversationParameters = new ConversationParameters
{
    IsGroup = false,
    Bot = turnContext.Activity.Recipient,
    Members = new ChannelAccount[] { teamMember },
    TenantId = turnContext.Activity.Conversation.TenantId,
};

...which you then use to CreateConversationAsync:

await ((BotFrameworkAdapter)turnContext.Adapter).CreateConversationAsync(
    teamsChannelId,
    serviceUrl,
    credentials,
    conversationParameters,
    async (t1, c1) =>
    {
        conversationReference = t1.Activity.GetConversationReference();
        await ((BotFrameworkAdapter)turnContext.Adapter).ContinueConversationAsync(
            _appId,
            conversationReference,
            async (t2, c2) =>
            {
                await t2.SendActivityAsync(proactiveMessage, c2);
            },
            cancellationToken);
    },
    cancellationToken);

Yes, you can modify that sample. It returns a Bad Request because only a particular schema is allowed on /api/messages. You'll need to add your own endpoint. Here's an example of NotifyController, which one of our other samples uses. You can see that it accepts GET requests. You'd just need to modify that our build your own that accepts POST requests.


All of this being said, all of this seems like it may be a bigger task than you're ready for. Nothing wrong with that; that's how we learn. Instead of jumping straight into this, I'd start with:

  1. Get the Proactive Sample working and dig through the code until you really understand how the API part works.

  2. Get the Teams Sample working, then try to make it message individual users.

  3. Then build your bot that messages users without prior interaction.

If you run into trouble feel free to browse my answers. I've answered similar questions to this, a lot. Be aware, however, that we've switched from the Teams Middleware that I mention in some of my answers to something more integrated into the SDK. Our Teams Samples (samples 50-60) show how to do just about everything.