Я пытаюсь реализовать пользовательский соединитель для моего бота Microsoft внутри webapi, чтобы его можно было вызывать из разных приложений через Rest API (например, из rasberripy). Цель состоит в том, чтобы внедрить пользовательский соединитель в WebAPIиспользуя прямой API, чтобы другое приложение могло просто использовать вызовы rest для связи с этим API, который, в свою очередь, будет общаться с моим ботом с помощью API dirtectline.Я протестировал следующий код от micrososft , который работает внутри консольного приложения.Я переместил тот же код в WebAPI, здесь тот же код ведет себя по-разному.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Threading.Tasks;
using Microsoft.Bot.Connector.DirectLine;
using Newtonsoft.Json;
using System.Configuration;
namespace BotConnector.Web.Controllers
{
public class BotController : Controller
{
private static string directLineSecret = ConfigurationManager.AppSettings["DirectLineSecret"];
private static string botId = ConfigurationManager.AppSettings["BotId"];
private static string fromUser = "APISampleClientUser";
// GET: Bot
public ActionResult Index()
{
return View();
}
public string Connect()
{
var conversation=StartBotConversation();
return conversation.ConversationId;
}
public string ReadBotMessages(string conversationId,string message)
{
//DirectLineClient client = (Session["client"] == null) ? new DirectLineClient(directLineSecret) : Session["client"] as DirectLineClient;
//Session["client"] = client;
DirectLineClient client = new DirectLineClient(directLineSecret);
var activity = new Activity
{
From = new ChannelAccount(fromUser),
Text = message,
Type = ActivityTypes.Message
};
client.Conversations.PostActivityAsync(conversationId, activity);
var response = ReadBotMessagesAsync(client, conversationId);
//var heroCard = JsonConvert.DeserializeObject<HeroCard>(response[0].Content.ToString());
return response.Result;
}
private static Conversation StartBotConversation()
{
//var session = System.Web.HttpContext.Current.Session["client"];
//DirectLineClient client = (session == null) ? new DirectLineClient(directLineSecret) : session as DirectLineClient;
//System.Web.HttpContext.Current.Session["client"] = client;
var client = new DirectLineClient(directLineSecret);
var conversation = client.Conversations.StartConversationAsync().Result;
//new System.Threading.Thread(async () => await ReadBotMessagesAsync(client, conversation.ConversationId)).Start();
return conversation;
}
private static async Task<string> ReadBotMessagesAsync(DirectLineClient client, string conversationId)
{
string watermark = null;
var attachments = new List<Attachment>();
string message = string.Empty;
while (true)
{
var activitySet = client.Conversations.GetActivities(conversationId, watermark);
watermark = activitySet?.Watermark;
var activities = from x in activitySet.Activities
where x.From.Id == botId
select x;
foreach (Activity activity in activities)
{
message = activity.Text;
if (activity.Attachments != null)
{
foreach (Attachment attachment in activity.Attachments)
{
if (attachment.ContentType== "application/vnd.microsoft.card.hero")
{
var heroCard = JsonConvert.DeserializeObject<HeroCard>(attachment.Content.ToString());
message = heroCard.Text;
//attachments.Add(attachment);
}
}
}
}
//if (attachments.Count > 0) break;
if (!string.IsNullOrEmpty(message)) break;
//await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);
}
return message;
}
}
}
Сначала я позвоню Bot / Connect, чтобы сгенерировать Идентификатор разговора, а позже я 'Позвоню Bot / ReadBotMessages с идентификатором и пользовательским вопросом.
Проблема, с которой я сталкиваюсь, заключается в коде
var activitySet = client.Conversations.GetActivities(conversationId, watermark);
, возвращающем несколько действий каждый раз при получении удара, а также ответы на предыдущие вопросы (), но я должен получить одно действие, связанное с текущим ответом. Та же логика прекрасно работает в консольном приложении от github , который возвращает только одно единственное текущее действие.Кто-нибудь может предложить обходной путь, или я делаю что-нибудь еще?