Search code examples
c#.netbotframeworkchatbot

trying to accept photo as Microsoft chat bot attachment and send it as an email attachment C#


i am trying to accept a photo as an attachment in Microsoft chat-bot waterFall Dialog...then sending it as an attachment or (even in the body) of an email functionality (which i created).. the email functionality seems to be working....however i am unable to pass the photo attachment in the email

it is like:

cannot convert from microsoft bot schema attachment to string

this is my code : the first method is to ask user to upload photo

  private static async Task<DialogTurnResult> UploadAttachmentAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
    {
        stepContext.Values["desc"] = (string)stepContext.Result;
        if (lang == "en")
        {
            lang = "en";
            return await stepContext.PromptAsync(

                attachmentPromptId,
                new PromptOptions
                {
                    Prompt = MessageFactory.Text($"Can you upload a ScreenShot of the Error?"),
                });
        }
        else if (lang == "ar")
        {
            lang = "ar";
            return await stepContext.PromptAsync(

               attachmentPromptId,
               new PromptOptions
               {
                   Prompt = MessageFactory.Text($"هل يمكنك تحميل لقطة شاشة للخطأ؟"),
               });
        }
        else return await stepContext.NextAsync(); 


    }

the second method is the upload code itself:

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

         return await stepContext.NextAsync();                          
    }

and the third is to store the photo as activity result to pass it later

  private static async Task<DialogTurnResult> ProcessImageStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
    {
        stepContext.Values["picture"] = ((IList<Attachment>)stepContext.Result)?.FirstOrDefault();
        await stepContext.PromptAsync(nameof(TextPrompt), new PromptOptions { Prompt = MessageFactory.Text("Attachment Recieved...Thank you!!") }, cancellationToken);
        return await stepContext.EndDialogAsync();
    }

and finally the step where i am storing the values i got from each stepcontext and should be passed in an email body: (the attachment is supposed to be stoted in ticketProfile.screenShot)

 private static async Task<DialogTurnResult> SummaryStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
    {
        var ticketProfile = await _ticketDialogAccessor.GetAsync(stepContext.Context, () => new Ticket(), cancellationToken);

        ticketProfile.userType = (string)stepContext.Values["userType"];
        ticketProfile.staffType = (string)stepContext.Values["staffType"];
        ticketProfile.empIdInfo = (string)stepContext.Values["shareId"];
        ticketProfile.emailInfo = (string)stepContext.Values["shareEmail"];
        ticketProfile.helpType = (string)stepContext.Values["helpType"];
        ticketProfile.describeHelp = (string)stepContext.Values["desc"];
        ticketProfile.screenShot = (Attachment)stepContext.Values["picture"];

        string[] paths = { ".", "adaptiveCard.json" };
        var cardJsonObject = JObject.Parse(File.ReadAllText(Path.Combine(paths)));

        var userEmailValue = cardJsonObject.SelectToken("body[2].facts[0]");
        var userIdValue = cardJsonObject.SelectToken("body[2].facts[1]");
        var userTypeValue = cardJsonObject.SelectToken("body[2].facts[2]");
        var staffTypeValue = cardJsonObject.SelectToken("body[2].facts[3]");
        var helpTypeValue = cardJsonObject.SelectToken("body[2].facts[4]");
        var describeValue = cardJsonObject.SelectToken("body[2].facts[5]");


        userEmailValue["value"] = ticketProfile.emailInfo;
        userIdValue["value"] = ticketProfile.empIdInfo;
        userTypeValue["value"] = ticketProfile.userType;
        staffTypeValue["value"] = ticketProfile.staffType;
        helpTypeValue["value"] = ticketProfile.helpType;
        describeValue["value"] = ticketProfile.describeHelp;


        var attachment = new Attachment()
        {
            Content = cardJsonObject,
            ContentType = "application/vnd.microsoft.card.adaptive"
        };

         var reply = stepContext.Context.Activity.CreateReply();
        reply.Attachments = new List<Attachment>();

        reply.Attachments.Add(attachment);
        await stepContext.Context.SendActivityAsync(reply);
        Email($"Here you go{Environment.NewLine}{ticketProfile.screenShot}");



        return await stepContext.EndDialogAsync(cancellationToken: cancellationToken);
    }

the email function:

 public static void Email(string htmlString)
    {
        try
        {
            MailMessage mail = new MailMessage();
            SmtpClient SmtpServer = new SmtpClient();
            mail.From = new MailAddress("[email protected]");

            mail.Subject = "New Ticket";

            mail.Body = htmlString;
            SmtpServer.Port = 587;
            SmtpServer.Host = "smtp.gmail.com";
            SmtpServer.EnableSsl = true;
            SmtpServer.UseDefaultCredentials = false;
            SmtpServer.Credentials = new NetworkCredential("user Name, "password");
            SmtpServer.DeliveryMethod = SmtpDeliveryMethod.Network;
            mail.To.Add(new MailAddress("[email protected]"));
            mail.IsBodyHtml = true;

            SmtpServer.Send(mail);
        }

        catch (Exception e)
        {

            e.ToString();

        }
    }



 public class Ticket
{
    public string userType { get; set; }

    public string staffType { get; set; }

    public string helpType { get; set; }

    public string helpWith { get; set; }


    public string describeHelp { get; set; }

    public Attachment screenShot { get; set; }

    public string emailInfo { get; set; }

    public string empIdInfo { get; set; }
}

any help will be much appreciated...thanks in advance


Solution

  • thanks a lot for @Alphonso...appreciate your efforts to hep... i did the following to send the picture received from my chatbot as attachment as an email: 1-moved my email functionality method inside SummaryStepAsync method. 2-downloaded the image accepted from user using WebClient

     string contentURL = ticketProfile.screenShot.ContentUrl;
            string name = ticketProfile.screenShot.Name;
            using (var client = new WebClient())
            {
                client.DownloadFile(contentURL, name);
                client.DownloadData(contentURL);
                client.DownloadString(contentURL);
            }
    

    3-passed it to my email functionality

     try
            {
                HttpClient httpClient = new HttpClient();
    
    
    
                //Help Desk Email Settings
                MailMessage helpDeskMail = new MailMessage();
                if (ticketProfile.screenShot != null)
                {
                    System.Net.Mail.Attachment data = new System.Net.Mail.Attachment(ticketProfile.screenShot.Name);
                    helpDeskMail.Attachments.Add(data);
                }
    

    that's it :)