【问题标题】:Bot framework : Detect when the user uploaded a fileBot 框架:检测用户何时上传文件
【发布时间】:2018-06-06 00:52:42
【问题描述】:

我正在尝试在我的机器人中创建一个表单,用户必须在其中上传一个文件以及其他文本输入。为此,我制作了一个 ReceiveAttachmentDialog,它会在其中验证用户是否上传了文件,问题是我不知道如何检测用户何时上传文件,从而午餐 ReceiveAttachmentDialo。

forDialog 是这样的:

[Serializable]
    public class FraisDialog : IDialog<object>
    {

        public async Task StartAsync(IDialogContext context)
        {
            // Root dialog initiates and waits for the next message from the user. 
            // When a message arrives, call MessageReceivedAsync.

            var replyMessage = context.MakeMessage();


            replyMessage.Attachments = new List<Connector.Attachment> { CreateAdaptiveCardwithEntry() };
            await context.PostAsync("Veuillez compléter le formulaire ci-dessous");
            await context.PostAsync(replyMessage, CancellationToken.None);
            context.Wait(this.MessageReceivedAsync);
        }


        public virtual async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
        {

            context.Wait(MessageReceivedAsync);
            var message = await result;

            if (message.Value != null)
            {
                // Got an Action Submit
                dynamic value = message.Value;
                string submitType = value.Type.ToString();
                switch (submitType)
                {
                    case "SaveFunction":
                        if (value.titre == "")
                        {
                            await context.PostAsync("Veuillez compléter tous les paramètres du formulaire \n");
                        }
                        else
                        {
                            await context.PostAsync($"Vous avez saisie les paramètres suivants : \n titre :  {value.titre} \n date : {value.date} \n montant :  {value.montant}");

                           context.Done<string>(null);
                       }
                       return;
                }
            }
       }

        public Connector.Attachment CreateAdaptiveCardwithEntry()
        {
            var submitActionData = JObject.Parse("{ \"Type\": \"SaveFunction\" }");
            var card = new AdaptiveCard()
            {

                Body = new List<CardElement>()
                {  
                    // Hotels Search form  

                    new TextBlock() { Text = "Titre de la note des frais" },
                    new TextInput()
                    {
                        Id = "titre",
                        Speak = "<s>Veuillez saisir le titre</s>",
                        Placeholder = "Veuillez saisir le titre",
                        Style = TextInputStyle.Text
                    },
                    new TextBlock() { Text = "Date de la note des frais" },
                    new DateInput()
                    {
                        Id = "date",
                        Placeholder ="Veuillez saisir la Date de la note des frais"
                    },

                    new TextBlock() { Text = "Montant en euros de la note de frais" },
                    new NumberInput()
                    {
                        Id = "montant",
                        Speak = "<s>Veuillez saisir le Montant en euros de la note de frais</s>",
                        Placeholder = "Veuillez saisir le Montant de la note de frais",

                    },

                },

                Actions = new List<ActionBase>()
                {
                    new SubmitAction()
                    {
                       Title = "Envoyer",
                       Speak = "<s>Envoyer</s>",
                       DataJson = submitActionData.ToString()

                    }
                }
            };

            Connector.Attachment attachment = new Connector.Attachment()
            {
                ContentType = AdaptiveCard.ContentType,
                Content = card
            };
            return attachment;
        }
    }

我的问题是我如何检测用户何时上传了文件?我应该把await context.Forward(new ReceiveAttachmentDialog(), this.ResumeAfterRecieveDialog, context.Activity, CancellationToken.None);放在哪里

【问题讨论】:

    标签: c# .net file-upload botframework


    【解决方案1】:

    正如@Ali Heikal 所说,formflow 对您来说是一个完全有效的选择。另一个不使用 formflow 的选项是检查机器人从用户那里收到的 Activity 是否有任何AttachmentsActivity.Attachments 是一个 IList&lt;Attachment&gt;,它将包含用户上传到机器人的任何文件。所以只需检查Activity.Attachments.Any() 就会给你一个布尔值,它会告诉你用户是否上传了文件。

    这是RootDialog.cs 中的一个简单示例:

    using Microsoft.Bot.Builder.Dialogs;
    using Microsoft.Bot.Connector;
    using System;
    using System.Linq;
    using System.Net;
    using System.Threading.Tasks;
    
    namespace Bot_Application1.Dialogs
    {
        [Serializable]
        public class RootDialog : IDialog<object>
        {
            public Task StartAsync(IDialogContext context)
            {
                context.Wait(MessageReceivedAsync);
    
                return Task.CompletedTask;
            }
    
            private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
            {
                var activity = await result as Activity;
    
                if (activity.Attachments.Any())
                {
                    //do something with the file
                    //it looks like this is where you would put your 
                    //context.Forward() 
                    await context.Forward(new ReceiveAttachmentDialog(), this.ResumeAfterRecieveDialog, context.Activity, CancellationToken.None);
    
                    await context.PostAsync($"you sent a file");
                }
                else
                {
                    await context.PostAsync($"No File received");
                }
                context.Wait(MessageReceivedAsync);
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      如果您还没有使用 FormFlow,我建议您使用 FormFlow,并检查位于 hereImagesForm.cs 的示例以了解表单本身。

      using System;
      using System.Collections.Generic;
      using System.IO;
      using System.Runtime.Serialization;
      using System.Threading.Tasks;
      
      using Microsoft.Bot.Builder.Dialogs;
      using Microsoft.Bot.Builder.FormFlow;
      using Microsoft.Bot.Builder.FormFlow.Advanced;
      using Microsoft.Bot.Connector;
      
      namespace Microsoft.Bot.Sample.FormFlowAttachmentsBot
      {
          [Serializable]
          public class MyAwaitableImage : AwaitableAttachment
          {
              // Mandatory: you should have this ctor as it is used by the recognizer
              public MyAwaitableImage(Attachment source) : base(source) { }
      
              // Mandatory: you should have this serialization ctor as well & call base
              protected MyAwaitableImage(SerializationInfo info, StreamingContext context) : base(info, context) { }
      
              // Optional: here you can check for content-type for ex 'image/png' or other..
              public override async Task<ValidateResult> ValidateAsync<T>(IField<T> field, T state)
              {
                  var result = await base.ValidateAsync(field, state);
      
                  if (result.IsValid)
                  {
                      var isValidForMe = this.Attachment.ContentType.ToLowerInvariant().Contains("image/png");
      
                      if (!isValidForMe)
                      {
                          result.IsValid = false;
                          result.Feedback = $"Hey, dude! Provide a proper 'image/png' attachment, not any file on your computer like '{this.Attachment.Name}'!";
                      }
                  }
      
                  return result;
              }
      
              // Optional: here you can provide additional or override custom help text completely..
              public override string ProvideHelp<T>(IField<T> field)
              {
                  var help = base.ProvideHelp(field);
      
                  help += $"{Environment.NewLine}- Only 'image/png' can be attached to this field.";
      
                  return help;
              }
      
              // Optional: here you can define your custom logic to get the attachment data or add custom logic to check it, etc..
              protected override async Task<Stream> ResolveFromSourceAsync(Attachment source)
              {
                  var result = await base.ResolveFromSourceAsync(source);
      
                  // You can apply custom logic to result or avoid calling base and resolve it yourself
                  // For ex. if you plan to use your instance several times you can return a MemoryStream instead
      
                  return result;
              }
          }
      
          [Serializable]
          public class ImagesForm
          {
              // Attachment field has no validation - any attachment would work
              public AwaitableAttachment BestImage;
      
              // Attachment field is optional - validation is done through AttachmentContentTypeValidator usage
              [Optional]
              [AttachmentContentTypeValidator(ContentType = "png")]
              public AwaitableAttachment SecondaryImage;
      
              // You can use an AwaitableAttachment descendant in order to have your own custom logic
              public IEnumerable<MyAwaitableImage> CustomImages;
      
              public static IForm<ImagesForm> BuildForm()
              {
                  OnCompletionAsyncDelegate<ImagesForm> onFormCompleted = async (context, state) =>
                  {
                      await context.PostAsync("Here is a summary of the data you submitted:");
      
                      var bestImageSize = await RetrieveAttachmentSizeAsync(state.BestImage);
                      await context.PostAsync($"Your best image is '{state.BestImage.Attachment.Name}' - Type: {state.BestImage.Attachment.ContentType} - Size: {bestImageSize} bytes");
      
                      if (state.SecondaryImage != null)
                      {
                          var secondaryImageSize = await RetrieveAttachmentSizeAsync(state.SecondaryImage);
                          await context.PostAsync($"Your secondary image is '{state.SecondaryImage.Attachment.Name}' - Type: {state.SecondaryImage.Attachment.ContentType} - Size: {secondaryImageSize} bytes");
                      }
                      else
                      {
                          await context.PostAsync($"You didn't submit a secondary image");
                      }
      
                      var customImagesTextInfo = string.Empty;
                      foreach (var image in state.CustomImages)
                      {
                          var imgSize = await RetrieveAttachmentSizeAsync(image);
                          customImagesTextInfo += $"{Environment.NewLine}- Name: '{image.Attachment.Name}' - Type: {image.Attachment.ContentType} - Size: {imgSize} bytes";
                      }
      
                      await context.PostAsync($"Here is the info of custom images you submitted: {customImagesTextInfo}");
                  };
      
                  // Form localization is done by setting the thread culture
                  System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-us");
      
                  return new FormBuilder<ImagesForm>()
                      .Message("Welcome, please submit all required images")
                      .OnCompletion(onFormCompleted)
                      .Build();
              }
      
              private static async Task<long> RetrieveAttachmentSizeAsync(AwaitableAttachment attachment)
              {
                  var stream = await attachment;
                  return stream.Length;
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-22
        • 1970-01-01
        • 1970-01-01
        • 2021-09-12
        • 1970-01-01
        • 2013-07-20
        相关资源
        最近更新 更多