|
| 1 | +// <copyright file="FocusedView.cs" company="DocuSign"> |
| 2 | +// Copyright (c) DocuSign. All rights reserved. |
| 3 | +// </copyright> |
| 4 | + |
| 5 | +namespace ESignature.Examples |
| 6 | +{ |
| 7 | + using System; |
| 8 | + using System.Collections.Generic; |
| 9 | + using DocuSign.eSign.Api; |
| 10 | + using DocuSign.eSign.Client; |
| 11 | + using DocuSign.eSign.Model; |
| 12 | + using Org.BouncyCastle.Asn1; |
| 13 | + using static System.Net.WebRequestMethods; |
| 14 | + |
| 15 | + /// <summary> |
| 16 | + /// Used to generate an envelope and allow user to sign it directly from the app without having to open an email. |
| 17 | + /// </summary> |
| 18 | + public static class FocusedView |
| 19 | + { |
| 20 | + /// <summary> |
| 21 | + /// Creates a new envelope, adds a single document and a signle recipient (signer) and generates a url that is used for embedded signing. |
| 22 | + /// </summary> |
| 23 | + /// <param name="signerEmail">Email address for the signer</param> |
| 24 | + /// <param name="signerName">Full name of the signer</param> |
| 25 | + /// <param name="signerClientId">A unique ID for the embedded signing session for this signer</param> |
| 26 | + /// <param name="accessToken">Access Token for API call (OAuth)</param> |
| 27 | + /// <param name="basePath">BasePath for API calls (URI)</param> |
| 28 | + /// <param name="accountId">The DocuSign Account ID (GUID or short version) for which the APIs call would be made</param> |
| 29 | + /// <param name="docPdf">String of bytes representing the document (pdf)</param> |
| 30 | + /// <param name="returnUrl">URL user will be redirected to after they sign</param> |
| 31 | + /// <param name="pingUrl">URL that DocuSign will be able to ping to incdicate signing session is active</param> |
| 32 | + /// <returns>The envelopeId (GUID) of the resulting Envelope and the URL for the embedded signing</returns> |
| 33 | + public static (string, string) SendEnvelopeWithFocusedView( |
| 34 | + string signerEmail, |
| 35 | + string signerName, |
| 36 | + string signerClientId, |
| 37 | + string accessToken, |
| 38 | + string basePath, |
| 39 | + string accountId, |
| 40 | + string docPdf, |
| 41 | + string returnUrl, |
| 42 | + string pingUrl = null) |
| 43 | + { |
| 44 | + //ds-snippet-start:eSign44Step3 |
| 45 | + EnvelopeDefinition envelope = MakeEnvelope(signerEmail, signerName, signerClientId, docPdf); |
| 46 | + |
| 47 | + var docuSignClient = new DocuSignClient(basePath); |
| 48 | + docuSignClient.Configuration.DefaultHeader.Add("Authorization", "Bearer " + accessToken); |
| 49 | + |
| 50 | + EnvelopesApi envelopesApi = new EnvelopesApi(docuSignClient); |
| 51 | + EnvelopeSummary results = envelopesApi.CreateEnvelope(accountId, envelope); |
| 52 | + string envelopeId = results.EnvelopeId; |
| 53 | + //ds-snippet-end:eSign44Step3 |
| 54 | + |
| 55 | + //ds-snippet-start:eSign44Step5 |
| 56 | + RecipientViewRequest viewRequest = MakeRecipientViewRequest(signerEmail, signerName, returnUrl, signerClientId, pingUrl); |
| 57 | + |
| 58 | + // call the CreateRecipientView API |
| 59 | + ViewUrl results1 = envelopesApi.CreateRecipientView(accountId, envelopeId, viewRequest); |
| 60 | + |
| 61 | + // State can be stored/recovered using the framework's session or a |
| 62 | + // query parameter on the returnUrl (see the makeRecipientViewRequest method) |
| 63 | + string redirectUrl = results1.Url; |
| 64 | + |
| 65 | + // returning both the envelopeId as well as the url to be used for embedded signing |
| 66 | + return (envelopeId, redirectUrl); |
| 67 | + //ds-snippet-end:eSign44Step5 |
| 68 | + } |
| 69 | + |
| 70 | + //ds-snippet-start:eSign44Step4 |
| 71 | + public static RecipientViewRequest MakeRecipientViewRequest(string signerEmail, string signerName, string returnUrl, string signerClientId, string pingUrl = null) |
| 72 | + { |
| 73 | + // Data for this method |
| 74 | + // signerEmail |
| 75 | + // signerName |
| 76 | + // dsPingUrl -- class global |
| 77 | + // signerClientId -- class global |
| 78 | + // dsReturnUrl -- class global |
| 79 | + RecipientViewRequest viewRequest = new RecipientViewRequest(); |
| 80 | + |
| 81 | + // Set the url where you want the recipient to go once they are done signing |
| 82 | + // should typically be a callback route somewhere in your app. |
| 83 | + // The query parameter is included as an example of how |
| 84 | + // to save/recover state information during the redirect to |
| 85 | + // the DocuSign signing ceremony. It's usually better to use |
| 86 | + // the session mechanism of your web framework. Query parameters |
| 87 | + // can be changed/spoofed very easily. |
| 88 | + viewRequest.ReturnUrl = returnUrl + "?state=123"; |
| 89 | + |
| 90 | + // How has your app authenticated the user? In addition to your app's |
| 91 | + // authentication, you can include authenticate steps from DocuSign. |
| 92 | + // Eg, SMS authentication |
| 93 | + viewRequest.AuthenticationMethod = "none"; |
| 94 | + |
| 95 | + // Recipient information must match embedded recipient info |
| 96 | + // we used to create the envelope. |
| 97 | + viewRequest.Email = signerEmail; |
| 98 | + viewRequest.UserName = signerName; |
| 99 | + viewRequest.ClientUserId = signerClientId; |
| 100 | + |
| 101 | + // DocuSign recommends that you redirect to DocuSign for the |
| 102 | + // Signing Ceremony. There are multiple ways to save state. |
| 103 | + // To maintain your application's session, use the pingUrl |
| 104 | + // parameter. It causes the DocuSign Signing Ceremony web page |
| 105 | + // (not the DocuSign server) to send pings via AJAX to your |
| 106 | + // app, |
| 107 | + // NOTE: The pings will only be sent if the pingUrl is an https address |
| 108 | + if (pingUrl != null) |
| 109 | + { |
| 110 | + viewRequest.PingFrequency = "600"; // seconds |
| 111 | + viewRequest.PingUrl = pingUrl; // optional setting |
| 112 | + } |
| 113 | + |
| 114 | + // The FrameAncestors should include the links https://apps-d.docusign.com |
| 115 | + // for demo environments and https://apps.docusign.com for prod environments, |
| 116 | + // and the site where the document should be embedded. |
| 117 | + // The site must have a valid SSL protocol for the embed to work. |
| 118 | + // MessageOrigins includes the demo or prod link and only |
| 119 | + // takes a single string. |
| 120 | + viewRequest.FrameAncestors = new List<string> { "https://localhost:44333", "https://apps-d.docusign.com" }; |
| 121 | + viewRequest.MessageOrigins = new List<string> { "https://apps-d.docusign.com" }; |
| 122 | + |
| 123 | + return viewRequest; |
| 124 | + } |
| 125 | + //ds-snippet-end:eSign44Step4 |
| 126 | + |
| 127 | + //ds-snippet-start:eSign44Step2 |
| 128 | + public static EnvelopeDefinition MakeEnvelope(string signerEmail, string signerName, string signerClientId, string docPdf) |
| 129 | + { |
| 130 | + // Data for this method |
| 131 | + // signerEmail |
| 132 | + // signerName |
| 133 | + // signerClientId -- class global |
| 134 | + // Config.docPdf |
| 135 | + byte[] buffer = System.IO.File.ReadAllBytes(docPdf); |
| 136 | + |
| 137 | + EnvelopeDefinition envelopeDefinition = new EnvelopeDefinition(); |
| 138 | + envelopeDefinition.EmailSubject = "Please sign this document"; |
| 139 | + Document doc1 = new Document(); |
| 140 | + |
| 141 | + string doc1b64 = Convert.ToBase64String(buffer); |
| 142 | + |
| 143 | + doc1.DocumentBase64 = doc1b64; |
| 144 | + doc1.Name = "Lorem Ipsum"; // can be different from actual file name |
| 145 | + doc1.FileExtension = "pdf"; |
| 146 | + doc1.DocumentId = "3"; |
| 147 | + |
| 148 | + // The order in the docs array determines the order in the envelope |
| 149 | + envelopeDefinition.Documents = new List<Document> { doc1 }; |
| 150 | + |
| 151 | + // Create a signer recipient to sign the document, identified by name and email |
| 152 | + // We set the clientUserId to enable embedded signing for the recipient |
| 153 | + // We're setting the parameters via the object creation |
| 154 | + Signer signer1 = new Signer |
| 155 | + { |
| 156 | + Email = signerEmail, |
| 157 | + Name = signerName, |
| 158 | + ClientUserId = signerClientId, |
| 159 | + RecipientId = "1", |
| 160 | + }; |
| 161 | + |
| 162 | + // Create signHere fields (also known as tabs) on the documents, |
| 163 | + // We're using anchor (autoPlace) positioning |
| 164 | + // |
| 165 | + // The DocuSign platform searches throughout your envelope's |
| 166 | + // documents for matching anchor strings. |
| 167 | + SignHere signHere1 = new SignHere |
| 168 | + { |
| 169 | + AnchorString = "/sn1/", |
| 170 | + AnchorUnits = "pixels", |
| 171 | + AnchorXOffset = "10", |
| 172 | + AnchorYOffset = "20", |
| 173 | + }; |
| 174 | + |
| 175 | + // Tabs are set per recipient / signer |
| 176 | + Tabs signer1Tabs = new Tabs |
| 177 | + { |
| 178 | + SignHereTabs = new List<SignHere> { signHere1 }, |
| 179 | + }; |
| 180 | + signer1.Tabs = signer1Tabs; |
| 181 | + |
| 182 | + // Add the recipient to the envelope object |
| 183 | + Recipients recipients = new Recipients |
| 184 | + { |
| 185 | + Signers = new List<Signer> { signer1 }, |
| 186 | + }; |
| 187 | + envelopeDefinition.Recipients = recipients; |
| 188 | + |
| 189 | + // Request that the envelope be sent by setting |status| to "sent". |
| 190 | + // To request that the envelope be created as a draft, set to "created" |
| 191 | + envelopeDefinition.Status = "sent"; |
| 192 | + |
| 193 | + return envelopeDefinition; |
| 194 | + } |
| 195 | + //ds-snippet-end:eSign44Step2 |
| 196 | + } |
| 197 | +} |
0 commit comments