在 BotFramework 上启动从机器人到用户的消息
Initiate a message from bot to user on BotFramework
我有一个基于 BotFramework 3.5 构建并作为 WebApp 托管在 Azure 上的机器人。在实现机器人需要响应用户输入的场景时,我没有遇到任何问题。然而,有必要教他按某个时间表开始对话。
为了达到目标,我创建了一个 WebJob,它基本上是一个简单的控制台应用程序。这是用于启动从机器人到用户的消息的代码:
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
- 取自之前的对话,所以我希望它们是有效的。但是在 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)
app.config 文件包含与原始 bot API 相同的值,包括 AppId 和 AppSecret。我看到了关于同一主题的几个问题,但没有找到答案。
我错过了什么吗?从控制台应用程序代表机器人发送消息是一种有效的方法吗?
尝试像这样创建一个新对话:
var conversationId = await connector.Conversations.CreateDirectConversationAsync(botAccount, userAccount);
根据您的描述,我按照此 tutorial for getting started with the Connector and followed this tutorial 进行发送和接收活动。
根据你的代码,我创建了我的控制台应用程序,我可以重现同样的问题,然后我发现了一个关于类似问题的 git issue。经过一些尝试,我这边可以正常使用了,你可以参考一下:
MicrosoftAppCredentials.TrustServiceUrl("{ServiceUrl}", DateTime.Now.AddDays(7));
var account=new MicrosoftAppCredentials("MicrosoftAppIdKey", "MicrosoftAppPasswordKey");
var connector = new ConnectorClient(new Uri("{ServiceUrl}"),account);
或
实现您的 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);
}
}
然后,您需要按如下方式构建 ConnectorClient
:
var account=new MicrosoftAppCredentials("{MicrosoftAppIdKey}", "{MicrosoftAppPasswordKey}");
var jwtToken=await account.GetTokenAsync();
var connector = new ConnectorClient(new Uri("{serviceUrl}"),handlers:new MyDelegatingHandler(jwtToken));
这是我的控制台应用程序代码片段,您可以参考它:
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}");
}
结果
我有一个基于 BotFramework 3.5 构建并作为 WebApp 托管在 Azure 上的机器人。在实现机器人需要响应用户输入的场景时,我没有遇到任何问题。然而,有必要教他按某个时间表开始对话。 为了达到目标,我创建了一个 WebJob,它基本上是一个简单的控制台应用程序。这是用于启动从机器人到用户的消息的代码:
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
- 取自之前的对话,所以我希望它们是有效的。但是在 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)
app.config 文件包含与原始 bot API 相同的值,包括 AppId 和 AppSecret。我看到了关于同一主题的几个问题,但没有找到答案。
我错过了什么吗?从控制台应用程序代表机器人发送消息是一种有效的方法吗?
尝试像这样创建一个新对话:
var conversationId = await connector.Conversations.CreateDirectConversationAsync(botAccount, userAccount);
根据您的描述,我按照此 tutorial for getting started with the Connector and followed this tutorial 进行发送和接收活动。
根据你的代码,我创建了我的控制台应用程序,我可以重现同样的问题,然后我发现了一个关于类似问题的 git issue。经过一些尝试,我这边可以正常使用了,你可以参考一下:
MicrosoftAppCredentials.TrustServiceUrl("{ServiceUrl}", DateTime.Now.AddDays(7));
var account=new MicrosoftAppCredentials("MicrosoftAppIdKey", "MicrosoftAppPasswordKey");
var connector = new ConnectorClient(new Uri("{ServiceUrl}"),account);
或
实现您的 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);
}
}
然后,您需要按如下方式构建 ConnectorClient
:
var account=new MicrosoftAppCredentials("{MicrosoftAppIdKey}", "{MicrosoftAppPasswordKey}");
var jwtToken=await account.GetTokenAsync();
var connector = new ConnectorClient(new Uri("{serviceUrl}"),handlers:new MyDelegatingHandler(jwtToken));
这是我的控制台应用程序代码片段,您可以参考它:
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}");
}
结果