在瀑布对话框中接受附件并将它们本地存储在 bot 框架 v4 中

Accepting attachments on a waterfall dialog and storing them locally in bot framework v4

我试图添加一个功能来从用户那里获取输入附件,基本上是试图合并来自 bot 框架的 handling-attachments bot 示例和我的自定义瀑布对话框。

但是如何在瀑布对话框中访问 iturncontext 函数? .下面是我的代码的解释。

我的瀑布步之一:

private async Task<DialogTurnResult> DescStepAsync2(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{


    stepContext.Values["Title"] = (string)stepContext.Result;
    await stepContext.Context.SendActivityAsync(MessageFactory.Text("upload a image"), cancellationToken);

    var activity = stepContext.Context.Activity;
    if (activity.Attachments != null && activity.Attachments.Any())
    {

        Activity reply = (Activity)HandleIncomingAttachment(stepContext.Context.Activity);
        return await stepContext.PromptAsync(nameof(TextPrompt), new PromptOptions { Prompt = reply }, cancellationToken);
    }
    else
    {
        var reply = MessageFactory.Text("else image condition thrown");
        //  reply.Attachments.Add(Cards.GetHeroCard().ToAttachment());
        return await stepContext.PromptAsync(nameof(TextPrompt), new PromptOptions { Prompt = reply }, cancellationToken);
    }
}

这是我从上面链接的机器人生成器示例中借用的 HandleIncomingAttachment 函数。

private static IMessageActivity HandleIncomingAttachment(IMessageActivity activity)
{
    string replyText = string.Empty;
    foreach (var file in activity.Attachments)
    {
        // Determine where the file is hosted.
        var remoteFileUrl = file.ContentUrl;

        // Save the attachment to the system temp directory.
        var localFileName = Path.Combine(Path.GetTempPath(), file.Name);

        // Download the actual attachment
        using (var webClient = new WebClient())
        {
            webClient.DownloadFile(remoteFileUrl, localFileName);
        }

        replyText += $"Attachment \"{file.Name}\"" +
                     $" has been received and saved to \"{localFileName}\"\r\n";
    }

    return MessageFactory.Text(replyText);
}

以下是对话记录:

编辑: 我已经为此编辑了我的代码,它仍然不等我上传附件。只是完成了这一步。

private async Task<DialogTurnResult> DescStepAsync2(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
    stepContext.Values["Desc"] = (string)stepContext.Result;
    var reply = (Activity)ProcessInput(stepContext.Context);
    return await stepContext.PromptAsync(nameof(AttachmentPrompt), new PromptOptions { Prompt = reply }, cancellationToken);
}

处理输入函数:

private static IMessageActivity ProcessInput(ITurnContext turnContext)
{
    var activity = turnContext.Activity;
    IMessageActivity reply = null;

    if (activity.Attachments != null && activity.Attachments.Any())
    {
        // We know the user is sending an attachment as there is at least one item .
        // in the Attachments list.
        reply = HandleIncomingAttachment(activity);
    }
    else
    {
        reply = MessageFactory.Text("No attachement detected ");
        // Send at attachment to the user.              
    }
    return reply;
}

一个WaterfallStepContext inherits from DialogContext and therefore the ITurnContext can be accessed through its Context属性。您发布的瀑布步骤代码在使用 stepContext.Context.SendActivityAsyncstepContext.Context.Activity.

时已经执行此操作

所以我想通了,多亏了这个post:github。com/microsoft/botframework-sdk/issues/5312

我的代码现在的样子:

声明附件提示:

 public class CancelDialog : ComponentDialog
{

    private static string attachmentPromptId = $"{nameof(CancelDialog)}_attachmentPrompt";
    public CancelDialog()
        : base(nameof(CancelDialog))
    {

        // This array defines how the Waterfall will execute.
        var waterfallSteps = new WaterfallStep[]
        {
            TitleStepAsync,
            DescStepAsync,
          //  AskForAttachmentStepAsync,
            UploadAttachmentAsync,
            UploadCodeAsync,
            SummaryStepAsync,

        };

        // Add named dialogs to the DialogSet. These names are saved in the dialog state.
        AddDialog(new WaterfallDialog(nameof(WaterfallDialog), waterfallSteps));
        AddDialog(new TextPrompt(nameof(TextPrompt)));
        AddDialog(new NumberPrompt<int>(nameof(NumberPrompt<int>), AgePromptValidatorAsync));
        AddDialog(new ChoicePrompt(nameof(ChoicePrompt)));
        AddDialog(new ConfirmPrompt(nameof(ConfirmPrompt)));
        AddDialog(new AttachmentPrompt(attachmentPromptId));

在瀑布中请求附件提示:

private async Task<DialogTurnResult> UploadAttachmentAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
    {

        stepContext.Values["desc"] = (string)stepContext.Result;
     //   if ((bool)stepContext.Result)
        {
            return await stepContext.PromptAsync(
        attachmentPromptId,
        new PromptOptions
        {
            Prompt = MessageFactory.Text($"Can you upload a file?"),
        });
        }
        //else
        //{
        //    return await stepContext.NextAsync(-1, cancellationToken);
        //}

    }

正在处理文件并存储它:

private async Task<DialogTurnResult> UploadCodeAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
    {
        List<Attachment> attachments = (List<Attachment>)stepContext.Result;
        string replyText = string.Empty;
        foreach (var file in attachments)
        {
            // Determine where the file is hosted.
            var remoteFileUrl = file.ContentUrl;

            // Save the attachment to the system temp directory.
            var localFileName = Path.Combine(Path.GetTempPath(), file.Name);

            // Download the actual attachment
            using (var webClient = new WebClient())
            {
                webClient.DownloadFile(remoteFileUrl, localFileName);
            }

            replyText += $"Attachment \"{file.Name}\"" +
                         $" has been received and saved to \"{localFileName}\"\r\n";
        }}

希望你有一个想法。 谢谢@Kyle 和@Michael