在BotFramework上发布从bot到用户的消息

Art*_*tem 12 .net c# azure-webjobs botframework

我有一个基于BotFramework 3.5的机器人,并作为WebApp托管在Azure上.我没有遇到机器人需要响应用户输入的情况的实施问题.但是,有必要教他按一些时间表开始对话.为了达到目标,我创建了一个WebJob,它基本上是一个简单的控制台应用程序.以下是用于启动从bot到用户的消息的代码:

            var botAccount = new ChannelAccount(id: from);
            var userAccount = new ChannelAccount(id: to);
            var conversation = new ConversationAccount(false, conversationId);

            var connector = new ConnectorClient(serviceUrl);

            IMessageActivity message = Activity.CreateMessageActivity();
            message.From = botAccount;
            message.Recipient = userAccount;
            message.Conversation = conversation;
            message.Text = text;
            message.Locale = locale;
            await connector.Conversations.SendToConversationAsync((Activity)message);
Run Code Online (Sandbox Code Playgroud)

from, to, serviceUrl, conversationId - 取自之前的对话,所以我希望它们有效.但是SendToConversationAsync 抛出异常:

System.UnauthorizedAccessException: Authorization for Microsoft App ID 3a26a4d4-f75a-4feb-b3e0-37a7fa24e5fc failed with status code Unauthorized and reason phrase 'Unauthorized' ---> System.Net.Http.HttpRequestException: Response status code does not indicate success: 401 (Unauthorized)
Run Code Online (Sandbox Code Playgroud)

app.config文件包含与原始bot API相同的值,包括AppId和AppSecret.我在同一主题上看到了一些问题,但没有找到答案.

我错过了什么吗?它是从控制台应用程序代表bot发送消息的有效方法吗?

Bru*_*hen 20

根据您的描述,我按照本教程开始使用Connector,并按照本教程进行发送和接收活动.

基于您的代码,我创造了我的控制台应用程序,我可以重现同样的问题,然后我发现了一个混帐问题有关类似的问题.经过一些试验,我可以按照预期在我身边工作,你可以参考它:

MicrosoftAppCredentials.TrustServiceUrl("{ServiceUrl}", DateTime.Now.AddDays(7));
var account=new MicrosoftAppCredentials("MicrosoftAppIdKey", "MicrosoftAppPasswordKey");
var connector = new ConnectorClient(new Uri("{ServiceUrl}"),account);
Run Code Online (Sandbox Code Playgroud)

要么

实现DelegatingHandler

public class MyDelegatingHandler : DelegatingHandler
{
    private string _token;
    public MyDelegatingHandler(string token)
    {
        _token = token;
    }

    protected override Task<HttpResponseMessage> SendAsync(
    HttpRequestMessage request, CancellationToken cancellationToken)
    {
        request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _token);
        return base.SendAsync(request, cancellationToken);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您需要构建ConnectorClient如下:

var account=new MicrosoftAppCredentials("{MicrosoftAppIdKey}", "{MicrosoftAppPasswordKey}");
var jwtToken=await account.GetTokenAsync();
var connector = new ConnectorClient(new Uri("{serviceUrl}"),handlers:new MyDelegatingHandler(jwtToken));
Run Code Online (Sandbox Code Playgroud)

这是我的控制台应用程序代码片段,您可以参考它:

try
{
    var userAccount = new ChannelAccount() { Id = "default-user", Name = "user" };
    var botAccount = new ChannelAccount() { Id = "934493jn5f6f348f", Name = "console-Bot" };
    string url = "{serviceUrl}";

    MicrosoftAppCredentials.TrustServiceUrl(url, DateTime.Now.AddDays(7));
    var account = new MicrosoftAppCredentials("{MicrosoftAppIdKey}", "{MicrosoftAppPasswordKey}");
    var connector = new ConnectorClient(new Uri(url), account);

    IMessageActivity message = Activity.CreateMessageActivity();
    message.From = botAccount;
    message.Recipient = userAccount;
    message.Conversation = new ConversationAccount() { Id = "{conversationId}" };
    message.Text = "Message sent from console application!!!";
    message.Locale = "en-us";
    var response = await connector.Conversations.SendToConversationAsync((Activity)message);
    Console.WriteLine($"response:{response.Id}");
}
catch (Exception e)
{
    Console.WriteLine($"exception:{e.Message}\r\n{e.StackTrace}");
}
Run Code Online (Sandbox Code Playgroud)

结果

在此输入图像描述

  • 不能过分夸大这一点! (3认同)