【问题标题】:How to deal with Context.Done(R value)如何处理 Context.Done(R 值)
【发布时间】:2017-07-19 06:02:57
【问题描述】:

我有一个 msbot 聊天对话框,我希望它具有以下行为:

user -> get me some info about GARY
bot -> which gary, (prompt: choice options)
user -> gary peskett
bot -> sure, (hero card with gary's contact details)

我有这个代码

public class CustomerRepository
{
    private IList<Customer> _customerList = new List<Customer>
    {
        new Customer
        {
            Name = "Gary Peskett"
        },
        new Customer
        {
            Name = "Gary Richards"
        },
        new Customer
        {
            Name = "Barry White"
        }
    };

    public async Task<IEnumerable<Customer>> GetAll()
    {
        // usually calls a database (which is why async is on this method)
        return _customerList;
    }
}

public class XDialog : IDialog
{
    private readonly IIntent _intent;
    private readonly CustomerRepository _customerRepository;

    public XDialog(IIntent intent, CustomerRepository customerRepository)
    {
        // An intent is decided before this point
        _intent = intent;
        _customerRepository = customerRepository;
    }

    public async Task StartAsync(IDialogContext context)
    {
        // // An intent can provide parameters
        string name = _intent.Parameters["Name"] as string;
        IEnumerable<Customer> customers = await _customerRepository.GetAll();
        IList<Customer> limitedList = customers.Where(x => x.Name.Contains(name)).ToList();

        if (limitedList.Any())
        {
            if (limitedList.Count > 1)
            {
                PromptDialog.Choice(context, LimitListAgain, limitedList,
                    "Can you specify which customer you wanted?");
            }
            else
            {
                Customer customer = limitedList.FirstOrDefault();
                Finish(context, customer);
            }
        }
        else
        {
            context.Done("No customers have been found");
        }
    }

    private static async Task LimitListAgain(IDialogContext context, IAwaitable<Customer> result)
    {
        Customer customer = await result;
        Finish(context, customer);
    }

    private static void Finish(IDialogContext context, Customer customer)
    {
        HeroCard heroCard = new HeroCard
        {
            Title = customer?.Name
        };

        context.Done(heroCard);
    }
}

我发现通常当我执行 context.Done(STRING) 时,它会输出给用户,这对于结束对话非常有用。由于我想以英雄卡结束,它输出类型名

Microsoft.Bot.Connector.HeroCard

谁能帮忙解释一下使用 context.Done(R value) 的更好方法,或者帮我返回一张英雄卡以结束对话?

对话框正在被调用

Chain.PostToChain()
    .Select(msg => Task.Run(() => _intentionService.Get(msg.ChannelId, msg.From.Id, msg.Text)).Result)
    .Select(intent => _actionDialogFactory.Create(intent)) // returns IDialog based on intent
    .Unwrap()
    .PostToUser();

【问题讨论】:

  • 这篇帖子github.com/Microsoft/BotBuilder-Samples/blob/master/CSharp/… 表明他们返回了 context.Done(null);我想知道这是否是最好的选择:s
  • 谁在调用 XDialog?
  • 它是从 Chain.PostToChain() 调用的。我已经用我使用的代码更新了问题
  • 对.. 我明白了。我会发布答案

标签: bots botframework chatbot


【解决方案1】:

我认为问题是使用Chain 的副作用。

您可能知道,context.Done 不会向用户返回任何内容,它只是使用提供的值结束当前对话框。

发给用户的帖子实际上发生在Chain 末尾的.PostToUser() 中。现在,通过查看PostToUser's code,我意识到在游戏结束时,它正在执行item.ToString() 中的context.PostAsync,在这种情况下是context.Done 中提供的有效载荷。见this

一个选项(我还没有测试过),可以使用.Do 而不是.PostToUser() 并手动执行PostToUserDialog 所做的事情,最后通过创建一个新的IMessageActivity 来执行 context.PostAsync()并将HeroCard 添加为附件。

【讨论】:

猜你喜欢
  • 2018-10-23
  • 2020-09-25
  • 2014-04-27
  • 2021-12-23
  • 1970-01-01
  • 1970-01-01
  • 2020-07-12
  • 1970-01-01
  • 2015-04-13
相关资源
最近更新 更多