首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >实现自定义连接器的机器人框架( "client.Conversations.GetActivities(conversationId,水印)“返回多个活动

实现自定义连接器的机器人框架( "client.Conversations.GetActivities(conversationId,水印)“返回多个活动
EN

Stack Overflow用户
提问于 2018-06-05 23:12:54
回答 1查看 639关注 0票数 3

我正在尝试为我的微软机器人在webapi中实现自定义连接器,以便可以通过Rest API从不同的应用程序调用它(对于exmp: from rasberripy).The意图是在WebAPI中使用directline API实现自定义连接器,以便其他应用程序可以使用rest调用来与此API对话,这反过来将使用dirtectline API与我的机器人对话。我测试了下面的code from micrososft,它在一个控制台应用程序中工作。我已经将相同的代码移到了WebAPI,在这里相同的代码表现不同。

代码语言:javascript
复制
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来生成问题,随后我将使用Id和conversationId - later调用Bot/ReadBotMessages。

我面临的问题是代码

var activitySet = client.Conversations.GetActivities(conversationId, watermark);在每次命中时都会返回多个活动,还会返回之前问题的响应(

),但我应该得到与当前响应相关的单个活动,相同的逻辑在github的控制台应用程序中工作得很好,它只返回一个当前活动。有没有人能给我一个变通的建议,或者我在做什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-06 03:52:56

为了只获取最新的活动,您需要确保将当前水印存储在连接器中的某个位置。

调用以下方法:

代码语言:javascript
复制
Client.Conversations.PostActivityAsync(conversationId, activity);

将返回一个格式如下的字符串:

代码语言:javascript
复制
"IRBO9ZhxkwID1QnNbAoOHX|0000008"

代码语言:javascript
复制
"{ConversationId|Watermark}"

您需要将此调用的水印部分保存在连接器中的某个位置,因为稍后在连接器的消息接收调用中使用它将只允许您获得对消息的即时响应:

代码语言:javascript
复制
    private static async Task<string> ReadBotMessagesAsync(DirectLineClient client, string conversationId)
    {
        string watermark = null; //this should be the current watermark

基本上,会话的端点获取调用:

代码语言:javascript
复制
/v3/directline/conversations/{conversationID}/activities?watermark={watermark}

返回bot存储的会话,从"watermark“开始,如果设置为null,则返回bot内存中可用会话的一部分,从bot与bot进行reconnecting之前发送的最后一条消息开始(这就是您看到的内容)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50703476

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档