在瀑布对话框上接受附件并将其本地存储在bot Framework v4中

时间:2019-10-11 08:05:46

标签: c# botframework attachment chatbot sample

我试图添加一种从用户处获取输入附件的功能,基本上是试图将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函数,我是从上面链接的bot构建器示例中借用的。

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);
}

这是对话的笔录: Transcript bot framework

编辑: 我已经为此编辑了代码,它仍然不等我上传附件。只需完成此步骤即可。

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;
}

2 个答案:

答案 0 :(得分:1)

因此,我感谢了这篇文章:github.com/microsoft/botframework-sdk/issues/5312

我的代码现在看起来如何:

声明附件提示:

<figure>
  <div class="top-semi-circle"></div>
  <div class="bottom-semi-circle"></div>
</figure>

在瀑布中询问附件提示:

 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);
        //}

    }

希望你有个主意。 谢谢@Kyle和@Michael

答案 1 :(得分:0)

WaterfallStepContext继承自DialogContext,因此ITurnContext可以通过其Context属性进行访问。您发布的瀑布步骤代码在使用stepContext.Context.SendActivityAsyncstepContext.Context.Activity时已经执行了此操作。