在BotFramework上从机器人向用户发起消息 [英] Initiate a message from bot to user on BotFramework

查看:101
本文介绍了在BotFramework上从机器人向用户发起消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个基于BotFramework 3.5构建的机器人,该机器人作为WebApp托管在Azure上。在机器人需要响应用户输入的场景的实现中,我没有遇到任何问题。但是,有必要教他按一定的时间表开始对话。
为了达到这个目标,我创建了一个WebJob,它基本上是一个简单的控制台应用程序。这是用于启动从机器人到用户的消息的代码:

  var botAccount = new ChannelAccount(id:from); 
var userAccount = new ChannelAccount(id:to);
var对话=新的ConversationAccount(false,对话ID);

var connector = new ConnectorClient(serviceUrl);

IMessageActivity消息= Activity.CreateMessageActivity();
消息。来自= botAccount;
message.Recipient = userAccount;
消息。对话=对话;
message.Text =文本;
message.Locale =语言环境;
等待连接器。Conversations.SendToConversationAsync((Activity)message);

从,到,serviceUrl,对话ID -取自上一次对话,所以我希望它们是有效的。但是在 SendToConversationAsync 上会引发异常:

  System.UnauthorizedAccessException:对Microsoft App ID 3a26a4d4-f75a-4feb-b3e0-37a7fa24e5fc失败,状态码为Unauthorized,原因短语为 Unauthorized ---> System.Net.Http.HttpRequestException:响应状态代码未指示成功:401(未经授权)

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



我错过了什么吗?

解决方案

根据您的描述,我遵循此方法吗?


I have a bot built on BotFramework 3.5 and hosted on Azure as a WebApp. I didn't face any problems with implementation of scenarios where the bot needs to respond to user's input. However there is a need to teach him to start conversations by some schedule. To reach the goal I created a WebJob which is a simple console app basically. Here is a code used to initiate a message from bot to user:

            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);

from, to, serviceUrl, conversationId - are taken from the previous conversation, so I'd expect they are valid. However on SendToConversationAsync exception is thrown:

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)

The app.config file contains the same values as the original bot API, including AppId and AppSecret. I saw a few questions raised on the same topic, but didn't manage to find an answer.

Am I missing something? Is it a valid approach to send messages on behalf of bot from the console app?

解决方案

According to your description, I followed this tutorial for getting started with the Connector and followed this tutorial for sending and Receiving Activities.

Based on your code, I created my console application and I could reproduce the same issue, then I found a git issue about the similar issue. After some trials, I could make it work as expected on my side, you could refer to it:

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

OR

Implement your 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);
    }
}

Then, you need to build your ConnectorClient as follows:

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

Here is my console application code snippet, you could refer to it:

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}");
}

Result

这篇关于在BotFramework上从机器人向用户发起消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆