我正在为IIS托管并在Azure中注册为BOT通道注册BOT的BOT主动消息。
我遇到错误了,
消息:操作返回了无效的状态码“未经授权”
StackTrace:位于 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务 任务) System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务) Microsoft.Bot.Connector.ConversationsExtensions.d__17.MoveNext()
代码如下,
-Notify.cs
public class Notify
{
private readonly IBotFrameworkHttpAdapter _adapter;
private readonly string _appId;
private readonly ConcurrentDictionary<string, ConversationReference> _conversationReferences;
public Notify(IBotFrameworkHttpAdapter adapter, string appId, ConcurrentDictionary<string, ConversationReference> conversationReferences)
{
_adapter = adapter;
_appId = appId;
_conversationReferences = conversationReferences;
}
public async Task<IActionResult> Get()
{
try
{
foreach (var conversationReference in _conversationReferences.Values)
{
await ((BotAdapter)_adapter).ContinueConversationAsync(_appId, conversationReference, BotCallback, default(CancellationToken));
}
// Let the caller know proactive messages have been sent
return new ContentResult()
{
Content = "<html><body><h1>Proactive messages have been sent.</h1></body></html>",
ContentType = "text/html",
StatusCode = (int)HttpStatusCode.OK,
};
}
catch (Exception ex)
{
throw ex;
}
}
private async Task BotCallback(ITurnContext turnContext, CancellationToken cancellationToken)
{
await turnContext.SendActivityAsync("proactive hello");
}
}
编辑1:
我正在尝试将主动消息发送到显示在 系统托盘图标。我们创建了一个Windows应用程序,通过该应用程序 正在向用户发送Windows通知。当用户点击 通知它将打开系统托盘图标中存在的机器人,并且它应该 在BOT中显示与主动消息相同的消息通知消息。
我们正在使用直接API来创建会话参考。我们 通过相同的对话参考并使用 BotApadater的ContinueConversationAsync填充相同的消息 从打开的机器人。 form.cs和Notify.cs的完整代码将在Windows应用程序中返回,并且该漫游器托管在IIS上并在Azure中注册为 BOT通道注册BOT。
当前,我们未收到未授权错误,并且代码为 执行成功,但没有收到任何主动消息 从机器人。 为了打开机器人,我们在Windows应用程序中使用iframe URL。
请帮助我在这里做错的事情或提出其他建议。
窗口系统托盘应用程序Form.cs方法
using (HttpClient httpClient = new HttpClient())
{
httpClient.BaseAddress = new Uri("https://directline.botframework.com/api/tokens");
httpClient.DefaultRequestHeaders.Accept.Clear();
//httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("BotConnector", "Directline secret");
HttpResponseMessage response = httpClient.GetAsync(httpClient.BaseAddress).Result;
if (response.IsSuccessStatusCode)
{
var jsonString = response.Content.ReadAsStringAsync();
var token = jsonString.Result;
var finaltoken = token.Replace(@"\", string.Empty);
finaltoken = finaltoken.Replace('"', ' ').Trim();
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("https://directline.botframework.com/v3/directline/conversations");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(finaltoken);
var httptokenResponse = httpClient.PostAsync("/api/conversations/", new StringContent(string.Empty, System.Text.Encoding.UTF8, "application/json"));
var tokenResponse = httptokenResponse.Result;
string convId = string.Empty;
string activityId = string.Empty;
HttpClient finalclient = new HttpClient();
Microsoft.Bot.Schema.Activity act = new Microsoft.Bot.Schema.Activity();
ConversationReference convRef = new ConversationReference();
if (tokenResponse.IsSuccessStatusCode)
{
var tokenjsonString = tokenResponse.Content.ReadAsStringAsync().Result;
var conversationToken = Newtonsoft.Json.JsonConvert.DeserializeObject<Conversation>(tokenjsonString.ToString());
HttpClient lastclient = new HttpClient();
lastclient.BaseAddress = new Uri("https://directline.botframework.com/v3/directline/conversations/" + conversationToken.conversationId + "/activities");
lastclient.DefaultRequestHeaders.Accept.Clear();
lastclient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
lastclient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "Directline secret");
string conversationUrl = conversationToken.conversationId + "/activities/";
string msg2 = "User Message";
Rootobject rootobject = new Rootobject();
rootobject.type = "message";
rootobject.text = msg2;
From from = new From();
from.id = "User ID";
from.user = "User Name";
rootobject.from = from;
string json = "";
json = Newtonsoft.Json.JsonConvert.SerializeObject(rootobject);
var httpconvResponse = lastclient.PostAsync(lastclient.BaseAddress, new StringContent(json, System.Text.Encoding.UTF8, "application/json"));
var tokenconvResponse = httpconvResponse.Result;
if (tokenconvResponse.IsSuccessStatusCode)
{
var tokenconvjsonString = tokenconvResponse.Content.ReadAsStringAsync().Result;
var conversationconvToken = Newtonsoft.Json.JsonConvert.DeserializeObject<ConversationActivityInfo>(tokenconvjsonString.ToString());
convId = conversationToken.conversationId;
activityId = conversationconvToken.id.Split('|')[1];
finalclient.BaseAddress = new Uri("https://directline.botframework.com/v3/directline/conversations/" + conversationToken.conversationId + "/activities");
finalclient.DefaultRequestHeaders.Accept.Clear();
finalclient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
finalclient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "Directline Secret");
var httpconvfinalResponse = finalclient.GetAsync(finalclient.BaseAddress).Result;
var jsonResponseString = httpconvfinalResponse.Content.ReadAsStringAsync();
var finalresponse = jsonResponseString.Result;
var activitiesObject = Newtonsoft.Json.JsonConvert.DeserializeObject<ActivitiesRO>(finalresponse);
act = activitiesObject.activities[1];
convRef = act.GetConversationReference();
}
}
string MicroSoftAppId = "YOUR Microsoft APP ID";
string MicroSoftAppPassword = "YOUR Microsoft APP PASSWORD";
ICredentialProvider credentialProvider = new SimpleCredentialProvider(MicroSoftAppId, MicroSoftAppPassword);
MicrosoftAppCredentials.TrustServiceUrl(convRef.ServiceUrl);
IBotFrameworkHttpAdapter adapter = new BotFrameworkHttpAdapter(credentialProvider);
ConcurrentDictionary<string, ConversationReference> conversationReferences = new ConcurrentDictionary<string, ConversationReference>();
convRef.Bot = new ChannelAccount("Bot ID", "Bot Name");
conversationReferences.GetOrAdd("test", convRef);
Notify notify = new Notify(adapter, MicroSoftAppId, conversationReferences);
Task<IActionResult> obj = notify.Get();
}
}
**编辑2:** 请参考下面的屏幕截图,将请求发送到以下网址后,我们将获得三个活动ID, https://directline.botframework.com/v3/directline/conversations/” + sessionToken.conversationId +“ /活动”
我们正在其中使用Index 1活动,因为它包含服务URL和主动消息需要发送给的用户详细信息,并且没有BOT详细信息(Bot属性),因此我们手动进行分配。
答案 0 :(得分:0)
我相信您的问题可能是您试图为不存在的对话创建ConversationReference
(尽管我不知道convoId
的来源)。
如果这是一个全新的对话,而用户尚未与漫游器进行交互,则可以使用CreateConversationAsync。您可以在测试here中看到我们的操作方式:
var activity = new Activity()
{
Type = ActivityTypes.Message,
Recipient = User,
From = Bot,
Text = "TEST Create Conversation",
};
var param = new ConversationParameters()
{
Members = new ChannelAccount[] { User },
Bot = Bot,
Activity = activity,
};
var convoId = await client.Conversations.CreateConversationAsync(param);
注意:当用户从未与漫游器通话时(主要是与电子邮件/ SMS相关的渠道),某些客户端不允许主动发送消息
如果用户已经与漫游器进行了交互,则可以使用Proactive Sample作为参考。特别是here:
var conversationReference = activity.GetConversationReference();
或者,它可能是TrustServiceUrl Issue。
您可以通过将频道的ServiceUrl添加到受信任的URL列表中来对其进行修复:
var serviceUrl = <GetThisFrom Activity.ServiceUrl>;
MicrosoftAppCredentials.TrustServiceUrl(serviceUrl);
这里是the method definition。注意:您也可以为此添加到期时间。否则,browsing these issues应该有所帮助。
您的机器人也有可能在睡觉。您可以转到Azure Portal > Your App Service > Configuration > General Settings > Always On <enable>
此“信任服务URL问题”很常见。尝试使用主动消息传递时,许多其他URL也会发生这种情况。只需将serviceUrl
替换为适合您的用例的内容即可。是的,如果您使用多个渠道,则可以在使用MicrosoftAppCredentials.TrustServiceUrl()
时通过多次调用来添加多个URL。