With the REST api, I am trying to get the documents out of a completed envelope. My header is using X-DocuSign-Authentication.
EnvelopesApi ap = new EnvelopesApi();
Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
EnvelopeDocumentsResult edr = ap.ListDocuments((AccountId, "xxx-xx-xxx");
List<EnvelopeDocument> docs = edr.EnvelopeDocuments;
foreach(EnvelopeDocument doc in docs)
{
Stream stream1 = ap.GetDocument(AccountId, "xxx-xx-xxx", doc.DocumentId);
StreamReader reader = new System.IO.StreamReader(stream1, encode);
var data = reader.ReadToEnd();
StreamWriter writer = new StreamWriter(#"C:\mysigneddoc.pdf");
writer.Write(data);
writer.Close();
}
When I try to open the completed pdf, I get the error stating that
the signers identity has not been verified.
Any ideas where I might be going wrong?
Please look at the API recipe here to download the documents from an envelope.
var ap = new EnvelopesApi();
var edr = ap.ListDocuments((AccountId, "xxx-xx-xxx");
List<EnvelopeDocument> docs = edr.EnvelopeDocuments;
foreach(EnvelopeDocument doc in docs)
{
// GetDocument() API call returns a MemoryStream
var docStream = (MemoryStream)envelopesApi.GetDocument(accountId, envelopeId, doc.DocumentId);
// let's save the document to local file system
filePath = #"C:\temp\" + Path.GetRandomFileName() + ".pdf";
fs = new FileStream(filePath, FileMode.Create);
docStream.Seek(0, SeekOrigin.Begin);
docStream.CopyTo(fs);
fs.Close();
}
You can also download the combined documents in an envelope using the GetEnvelopeDocuments api. You are not required to query for each individual document.
Combined PDF
Pass the string combined as the documentId.
Retrieve a PDF that contains the combined content of all documents and the certificate.
string envelopeId = "XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX";
string accountId = "XXXXXX";
var envApi = new EnvelopesApi();
// GetDocument() API call returns a MemoryStream
var docStream = (MemoryStream)envApi.GetDocument(accountId, envelopeId, "combined");
// let's save the document to local file system
string filePath = #"C:\temp\" + Path.GetRandomFileName() + ".pdf";
var fs = new FileStream(filePath, FileMode.Create);
docStream.Seek(0, SeekOrigin.Begin);
docStream.CopyTo(fs);
fs.Close();
ZIP file
Pass the string archive as documentId
Retrieve a ZIP archive that contains all of the PDF documents, the certificate, and any .WAV files used for voice authentication.
var envApi = new EnvelopesApi();
// GetDocument() API call returns a MemoryStream
var docStream = (FileStream)envApi.GetDocument(accountId, envelopeId, "archive");
// let's save the document to local file system
string filePath = #"C:\temp\" + Path.GetRandomFileName() + ".zip";
var fs = new FileStream(filePath, FileMode.Create);
docStream.Seek(0, SeekOrigin.Begin);
docStream.CopyTo(fs);
fs.Close();
Related
This link (https://developers.docusign.com/docs/esign-rest-api/how-to/download-envelope-documents/) mentions how I can download separate documents using their document IDs. Also found a way to download the documents as a zip file. But is there a way to download them as a combined PDF using the API?
Thanks.
Not sure what lang you're using but C# code will be this (note "combined" option).
For other langs - check my blog post
// You would need to obtain an accessToken using your chosen auth flow
var apiClient = new ApiClient(basePath);
apiClient.Configuration.DefaultHeader.Add("Authorization", "Bearer " + accessToken);
var envelopesApi = new EnvelopesApi(apiClient);
string accountId; // accountId for your DocuSign account
string envelopeId; // envelopeId that you are working on
// produce a ZIP file with all documents including the CoC
Stream results1 = envelopesApi.GetDocument(accountId, envelopeId, "archive");
// produce a PDF combining all signed documents as well as the CoC
Stream results2 = envelopesApi.GetDocument(accountId, envelopeId, "combined");
// produce a particular document with documentId "1"
Stream results3 = envelopesApi.GetDocument(accountId, envelopeId, "1");
//TODO - use Stream to write or send the file for your use
I'm getting a list view threshold issue when attempting to upload a document to a document library. Let me give you the back story.
My site is on SPO and I'm using CSOM to create a folder and then add a uploaded document to that folder.
The service account I'm using to authentication to SPO is a site collection admin.
My CSOM code can create the folder, but cannot upload a document to that folder because SharePoint says that we've hit the list view threshold.
The document library that we're trying to upload a document to has over 20K items in it.
The default view that we're using only has one column selected, we have the Title and Created field indexed and the document library uses the modern experience.
We've been using the same code for a while, but as of October 2019 things stopped working.
Any ideas ? Provided below is the code that I'm using
using (ClientContext ctx = new ClientContext(SPUrl))
{
ctx.Credentials = new SharePointOnlineCredentials(spuser, securePassword);
Web webSite = ctx.Web;
ctx.Load(webSite);
ctx.ExecuteQuery();
List list = ctx.Web.Lists.GetByTitle("TempDoc");
ctx.Load(list);
var lst = ctx.Web.Lists.GetByTitle("TempDoc");
var fld1 = lst.RootFolder.Folders.Add(FolderName);
fld1.Update();
ctx.ExecuteQuery();
foldersatus = true;
try
{
int FileLen;
FileLen = Request.Files[upload].ContentLength;
byte[] input = new byte[FileLen];
System.IO.Stream fileStream;
// Initialize the stream.
fileStream = Request.Files[upload].InputStream;
// Read the file into the byte array.
fileStream.Read(input, 0, FileLen);
FileCreationInformation newFile = new FileCreationInformation();
newFile.Content = input;
newFile.Url = filename;
List docs = webSite.Lists.GetByTitle("TempDoc");
ctx.Load(docs.RootFolder);
ctx.Load(docs.RootFolder.Folders);
Microsoft.SharePoint.Client.File uploadFile1 = docs.RootFolder.Folders[0].Files.Add(newFile);
ctx.ExecuteQuery();
}
I found out the problem. The issue was the call ctx.Load(docs.RootFolder.Folders); I had removed this piece of code, I was now able to upload documents.
My sample test code(the lib has more than 10k files).
List docs = context.Web.Lists.GetByTitle("largeLib1");
var filePath = #"C:\Lee\template.xlsx";
using (FileStream fs = new FileStream(filePath, FileMode.Open))
{
FileCreationInformation flciNewFile = new FileCreationInformation();
flciNewFile.ContentStream = fs;
flciNewFile.Url = System.IO.Path.GetFileName(filePath);
flciNewFile.Overwrite = true;
Microsoft.SharePoint.Client.File uploadFile = docs.RootFolder.Files.Add(flciNewFile);
context.Load(uploadFile);
context.ExecuteQuery();
}
Or(the folder has more than 10k files)
Folder folder = context.Web.GetFolderByServerRelativeUrl("/sites/xxx/largeLib1/set2");
var filePath = #"C:\Lee\template.xlsx";
using (FileStream fs = new FileStream(filePath, FileMode.Open))
{
FileCreationInformation flciNewFile = new FileCreationInformation();
flciNewFile.ContentStream = fs;
flciNewFile.Url = System.IO.Path.GetFileName(filePath);
flciNewFile.Overwrite = true;
Microsoft.SharePoint.Client.File uploadFile = folder.Files.Add(flciNewFile);
context.Load(uploadFile);
context.ExecuteQuery();
}
I need to update orientation tag(EXIF data) for the uploaded image. I am using "PIEXIF" for this. I am not using express but swagger. The code I've written is:
//Get the uploaded buffer
var _originalBuffer = req.swagger.params.uploadedFile.value.buffer;
let Duplex = require('stream').Duplex;
//Create stream from buffer. This stream is required later to send to cloud.
let _uploadedFileStream = new Duplex();
_uploadedFileStream.push(_originalBuffer);
_uploadedFileStream.push(null);
//Create base 64 string so that "PIEXIF" can read exif data from it.
const jpegData = "data:image/jpeg;base64, " + createStringFromBuffer(_originalBuffer, 'base64');
//Read exif data.
var _exifData = piexif.load(jpegData);
//Create a copy of exif data. Will be used to create a new image with updated orientation tag.
var _exifDataCopied = {};
for (var key in _exifData) {
_exifDataCopied[key] = _exifData[key];
}
//Update orientation tag.
if (_exifDataCopied["0th"][piexif.ImageIFD.Orientation])
_exifDataCopied["0th"][piexif.ImageIFD.Orientation] = 1;
//Example taken from https://www.npmjs.com/package/piexifjs
//From here onwards, there seems to be an issue.
var exifbytes = piexif.dump(_exifDataCopied);
var newData = piexif.insert(exifbytes, createStringFromBuffer(_originalBuffer, 'binary'));
var newJpeg = new Buffer(newData);
//Create a new stream and save it as image back.
let _updatedFileStream = new Duplex();
_updatedFileStream.push(newJpeg);
_updatedFileStream.push(null);
var fs = require('fs');
var writeStream = fs.createWriteStream("./uploads/" + "Whatever.jpg")
The issue is there is no error thrown by the code. The image is also getting saved in the directory but it is corrupted. I can not preview it. Since, the code does not breaks anywhere, I am confused what could be the issue? The function to convert buffer to string with different encoding(since I need it a lot) is:
var createStringFromBuffer = function(_buffer, _encoding) {
return Buffer.from(_buffer).toString(_encoding);
}
Can someone point out where I am mistaking? I am using the example given Here
I am uploading an attachment in BOT emulator, after uploading an attachment I am converting it to base64, to pass it to our service.
I pick this attachment from path D:\Images\MobileRequest.PNG, but after uploading it to BOT app it shows the path of attachment as http://127.0.0.1:44185/v3/attachments/ne7djbemc9f40bifi/views/original/MobileRequest.PNG, as the image is not available on this path, So while converting the image to base64, it throws an error as "URI formats are not supported.".
How to get actual physical path i.e "D:\Images\MobileRequest.PNG" in BOT app.
Below is code from my BOT app
var dialog = new PromptDialog.PromptAttachment("Please attach screenshot ", "Sorry, I didn't get the attachment. Try again please.", 2);
context.Call(dialog, afterUpload);
private async Task afterUpload(IDialogContext context, IAwaitable<IEnumerable<Attachment>> result)
{
IEnumerable<Attachment> attach = await result;
string filePath = attach.FirstOrDefault().ContentUrl + "/" + attach.FirstOrDefault().Name;
context.UserData.SetValue("filePath", filePath);
}
string filePath = string.Empty;
context.UserData.TryGetValue("filePath", out filePath);
using (System.Drawing.Image image = System.Drawing.Image.FromFile(filePath))
{
using (MemoryStream m = new MemoryStream())
{
image.Save(m, image.RawFormat);
byte[] imageBytes = m.ToArray();
attach1 = Convert.ToBase64String(imageBytes);
}
}
Your bot will be deployed so you will not have access to local files.
You can easily convert your image located at a URL by doing the following:
using (var client = new HttpClient())
{
var bytes = await client.GetByteArrayAsync(imageUrl);
var imageInBase64String = "image/jpeg;base64," + Convert.ToBase64String(bytes);
// Do what you want with your converted image
}
i'm trying to stream a newly generated pdf (using itext) directly to the body of lotus notes email as an attachment. but i'm getting following error while setting body of the email from bytes
"com.ibm.jscript.types.GeneratedWrapperObject$StaticField incompatible with com.ibm.jscript.types.FBSValue"
following is my completed code(placed in a button of an xpage). Any help would be greatly appreciated
session.setConvertMIME(false);
outputStream:java.io.ByteArrayOutputStream = new java.io.ByteArrayOutputStream();
writePdf(outputStream);
var bytes = outputStream.toByteArray();
var inputStream:java.io.ByteArrayInputStream = new java.io.ByteArrayInputStream(bytes);
var db:NotesDatabase= session.getDatabase("","mail.box")
if (!db.isOpen()) {
print ("No mailbox!")
}
else
{
var doc:NotesDocument=db.createDocument()
doc.replaceItemValue("Form","Memo")
doc.replaceItemValue("From",context.getUser().getCommonName())
doc.replaceItemValue("Principal",context.getUser().getCommonName())
doc.replaceItemValue("SendTo","a#b.com");
doc.replaceItemValue("Recipients","a#b.com");
doc.replaceItemValue("CopyTo","a#b.com");
doc.replaceItemValue("INetFrom","b#c.com");
var strFileName="temp.pdf"
var body:NotesMIMEEntity = doc.createMIMEEntity('Body');
var hdr:NotesMIMEHeader = body.createHeader("Subject");
hdr.setHeaderValAndParams("Subject")
hdr=body.createHeader("MIME-Version")
hdr.setHeaderValAndParams("1.0")
body.setPreamble("multipart message in MIME")
var child1:NotesMIMEEntity= body.createChildEntity()
hdr = child1.createHeader("Content-Disposition")
hdr.setHeaderValAndParams('attachment; filename="test.pdf"')
var stream:NotesStream = session.createStream();
stream.setContents(inputStream)
child1.setContentFromBytes(stream, "application/pdf", body.ENC_IDENTITY_BINARY)
child1.encodeContent(body.ENC_BASE64)
doc.closeMIMEEntities(true,"Body")
doc.save(true, true);
// Restore conversion
session.setConvertMIME(true);
}
function writePdf(outputStream) {
var document:com.itextpdf.text.Document = new com.itextpdf.text.Document();
var writer = com.itextpdf.text.pdf.PdfWriter.getInstance(document,outputStream);
document.open();
document.addTitle("Test PDF");
document.addSubject("Testing email PDF");
document.addKeywords("iText, email");
document.addAuthor("Author");
document.addCreator("Creator");
var passChunk:com.itextpdf.text.Chunk = new com.itextpdf.text.Chunk("Hello");
document.add(new com.itextpdf.text.Paragraph(passChunk));
document.close();
}
you probably would be better off writing a small Java wrapper class.
For starters you need:
var stream:NotesStream = session.createStream();
stream.setContents(inputStream);
stream.setPosition(0);
so the stream is at the beginning.
Update:
Also you have:
var bytes = outputStream.toByteArray();
var inputStream:java.io.ByteArrayInputStream = new java.io.ByteArrayInputStream(bytes);
stream.setContents(inputStream);
where I would write:
var bytes = outputStream.toByteArray();
stream.write(bytes);
Still, make a helper in Java.
Note: iText is GPL licenced. Unless the application you build is internal use only, you either need to buy a commercial license or GPL your code as well. Look at Apache PDFBox for an alternative