3

I created a listener page that receives the Docusign webhooks. Everything is working as far as pulling data from the webhook, but when I cycle through the DocumentPDF's, it creates the PDF files but they are corrupted and cannot be opened (when I try to open it in Acrobat, I receive the following message: Acrobat could not open ... because it is either not a supported file type or because the file has been damaged.")

Can anybody help me figure out why the created pdf files are corrupted?

My code for the page is as follows:

 protected void Page_Load(object sender, EventArgs e)
    {
        StreamReader sr = new StreamReader(Request.InputStream);
        string xml = sr.ReadToEnd();
        string fileName = HttpContext.Current.Server.MapPath("") + "\\Results\\" + DateTime.Now.Ticks + ".xml";
        File.WriteAllText(fileName, xml);


        try
        {
            XmlDocument xmldoc = new XmlDocument();
            xmldoc.LoadXml(xml);

            var mgr = new XmlNamespaceManager(xmldoc.NameTable);
            mgr.AddNamespace("a", "http://www.docusign.net/API/3.0");

            XmlNode envelopeStatus = xmldoc.SelectSingleNode("//a:EnvelopeStatus", mgr);
            XmlNode envelopeId = envelopeStatus.SelectSingleNode("//a:EnvelopeID", mgr);
            XmlNode status = envelopeStatus.SelectSingleNode("//a:Status", mgr);

            if (status.InnerText == "Completed")
            {
                LogException("Looking for DocPDF's_" + DateTime.Now.Ticks + ";");
                // Loop through the DocumentPDFs element, storing each document.

                XmlNode docs = xmldoc.SelectSingleNode("//a:DocumentPDFs", mgr);
                foreach (XmlNode doc in docs.ChildNodes)
                {
                    string documentName = doc.ChildNodes[0].InnerText; // pdf.SelectSingleNode("//a:Name", mgr).InnerText;
                    string documentId = doc.ChildNodes[2].InnerText; // pdf.SelectSingleNode("//a:DocumentID", mgr).InnerText;
                    string byteStr = doc.ChildNodes[1].InnerText; // pdf.SelectSingleNode("//a:PDFBytes", mgr).InnerText;

                    LogException("Writing Out PDF_" + HttpContext.Current.Server.MapPath("") + "\\Documents\\" + envelopeId.InnerText + "_" + documentId + "_" + documentName + "_" + DateTime.Now.Ticks + ";");

                    File.WriteAllText(HttpContext.Current.Server.MapPath("") + "\\Documents\\" + envelopeId.InnerText + "_" + documentId + "_" + documentName, byteStr);

                    LogException("Successfully wrote out PDF_" + DateTime.Now.Ticks + ";");
                }
            }
        }
        catch (Exception ex)
        {
            LogException("Exception: " + ex.Message + "; InnerException: " + ex.InnerException.ToString() + "_" + DateTime.Now.Ticks + ";");
        }
    }
RVille
  • 31
  • 4
  • 1
    I don't know the Docusign api but writing a pdf document as a text string can hardly be correct. Probably the `byteStr` is base64 encoded and you have to decode it to get the actual pdf? – mkl Dec 07 '16 at 05:48
  • Welcome to StackOverflow! Please upvote all useful answers, including those to others' questions. And please select / check the best answer to your own questions. – Larry K Dec 07 '16 at 14:00

2 Answers2

4

@mkl is correct. The Webhook (Connect) notification message's PDF content is base64 encoded. Decode it to obtain the PDF file.

An example: see line 402 of the recipe example webhook listener --

pdf_file.write(base64.b64decode(pdf.PDFBytes.string))
Larry K
  • 47,808
  • 15
  • 87
  • 140
  • mlk and Larry K, thank you very much. Was able to decode my base64 string and convert it to a pdf file. – RVille Dec 07 '16 at 21:41
  • @RVille If you like an answer, upvote it and "check" it (if it is the best answer.) – Larry K Dec 08 '16 at 11:13
  • I am sending word document(bytes) to docusign. I am getting email and i am signing that document.In listener I am getting xml response and i am able to get pdf byte but when i generate file from that , it's corrupted. – Sanjay Apr 03 '19 at 11:22
  • Hi @sanjay, Please ask a new question. – Larry K Apr 03 '19 at 17:06
0

I am using an Azure Function and using a Blob storage to save it. This worked for me:

var byteStr = doc.ChildNodes[1].InnerText;
outputBlob.Write(System.Convert.FromBase64String(byteStr));