从 Angular 调用我的 .NET Core Teams 机器人

Calling my .NET Core Teams Bot from Angular

我按照此处找到的示例在 .NET Core 中创建了一个 Teams 机器人:https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/57.teams-conversation-bot

这正在工作并且 运行 在本地使用 ngrok。我有一个路由为 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);
    }
}

我现在想从我的 Angular 客户端调用 POST 到 api/messages,使用 TypeScript 向特定 Teams 用户发送主动消息。

我确实弄清楚了如何通过执行以下操作将 TeamsConversationBot.cs 中的 ConversationParameters 设置为特定的 Teams 用户:

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,
};

但我正在努力解决的是如何构建一个 JSON 请求,该请求将 Teams 用户 guid(可能还有一些其他详细信息)发送到我从 TypeScript 的 api/messages 路由。

我该怎么做?我需要发送什么parameters/body?我无法在网上找到展示如何执行此操作的示例。


更新下方以进一步说明

我正在使用 Angular 为我们的客户构建一个网络聊天应用程序。我想做的是,当客户通过聊天应用程序执行某些操作(发起对话、发送消息等)时,向我们使用 Microsoft Teams 的内部员工发送主动消息。

我使用 .NET Core 使用此示例构建了一个 Teams 机器人:https://kutt.it/ZCftjJ。修改该示例,我可以对我的 Teams 用户 ID 进行硬编码,主动消息在 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);

我遇到的问题是:

  1. 如何配置我的 Angular 应用程序以通知我的机器人我要发送一条新的主动消息。
  2. 如何配置机器人以接受一些自定义参数(Teams 用户 ID、消息)。

听起来您在主动消息传递方面已经取得了一些进展。是否 100% 有效?如果没有,我已经在堆栈溢出上多次讨论了这个主题——这里有一个可能有帮助的例子:

但是,关于 - 触发 - 主动消息,事实是你可以从 anywhere/in 以任何方式做到这一点。例如,我有 Azure Functions 运行 在他们自己的时间表上,并且主动发送消息 就好像它们来自 bot,即使代码不是运行完全在机器人内部。您还没有完全描述 Angular 应用程序在图片中的位置(比如谁在用它做什么),但作为您场景中的示例,您可以在机器人控制器内创建另一个端点,并在其中完成工作直接在那里(例如添加如下内容:)

[HttpPost]
    public async Task ProActiveMessage([FromQuery]string conversationId)
    {
        //retrieve conversation details by id from storage (e.g. database)
        //send pro-active message
        //respond with something back to the Angular client
    }

希望对您有所帮助,

Hilton 的回答仍然不错,但是关于在没有事先交互的情况下主动向他们发送消息的部分需要太长的响应。因此,回复您的最新评论:

是的,无论用户所在的任何团队,您都需要为您想要主动发送消息的团队安装机器人。否则它将无权这样做。


您不需要覆盖 OnMembersAddedAsync;只需查询花名册(见下文)。


您不需要对话 ID 即可执行此操作。相反,我会让你的 API 接受他们的 Teams ID。您可以通过 获得此信息,您需要提前将其存储在散列 table 或其他内容中……如果您的团队规模足够大,则可能是数据库。

就所需信息而言,您需要足够的 build the ConversationParameters:

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

...然后用于 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);

是的,您可以修改该样本。它 returns 是一个错误的请求,因为 /api/messages 上只允许特定的模式。您需要添加自己的端点。这是 NotifyController, which one of our other samples uses. You can see that it accepts GET requests 的示例。您只需要修改我们构建您自己的接受 POST 请求的内容。


综上所述,所有这一切似乎是一项比您准备好要完成的更大的任务。没有错;这就是我们学习的方式。我不会直接跳到这个,而是开始:

  1. Proactive Sample 工作并深入研究代码,直到您 真正 理解 API 部分的工作原理。

  2. Teams Sample 正常工作,然后尝试让它向个人用户发送消息。

  3. 然后 构建您的机器人,无需事先交互即可向用户发送消息。

如果您 运行 遇到麻烦,请随时浏览 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(样本 50-60)展示如何做几乎所有事情。