如何预先填充使用Docusign的REST API从模板创build的信封中的字段?

注意:我使用的是“经典”体验,因为新界面没有办法让模板为将来的签名人设置必填字段。

工作stream程:

  • 有一堆领域的模板
  • 使用api:

    • 从模板创build一个信封/文档,并分配一个新用户签名(这个文档将是一个注册服务的协议)

      • 创造新的angular色
      • 将roleName设置为模板上的伪造签名者(因为我无法configuration在模板上没有至less一个签名者的字段)
      • 添加textTabs来尝试填充一些字段。
    • 检索收件人

    • 创build一个收件人视图,以便我可以将url放入iframe

这是一种令人厌恶的行为,因为我不在意第一个签名者是否是注册服务的用户。 然而,我会喜欢在签名后将文档复制到某个人,但是docusign似乎不支持这个(反正我find了)。

这里是创build信封的node.js代码(我认为我的API用法出错了):

function createEnvelopeDefinition(templateId, userData) { var envDef = new docusign.EnvelopeDefinition(); envDef.setEmailSubject('Signup Agreement'); envDef.setTemplateId(templateId); var tRole = new docusign.TemplateRole(); tRole.setRoleName('RoleOne'); tRole.setName(userData.fullName); tRole.setEmail(userData.email); tRole.setClientUserId('2'); tRole.setTabs(new docusign.Tabs()); tRole.getTabs().setTextTabs([]); const fieldsToPreFill = [ 'field1', 'field2', 'field3', 'field4']; fieldsToPreFill.forEach(fieldName => { let textTab = new docusign.Text(); let value = userData[fieldName]; if (value === null || value === undefined) { value = 'not null'; } textTab.setTabLabel(fieldName); textTab.setValue(value); tRole.getTabs().getTextTabs().push(textTab); }); tRole = removeNulls(tRole); envDef.setTemplateRoles([tRole]); // send the envelope by setting |status| to 'sent'. // To save as a draft set to 'created' // sent is required for getting view URLs envDef.setStatus('sent'); return envDef; } 

在docusign的模板编辑器中,“ Data Field Tag Properties ”将每个相应字段的标签显示为field1field2

当我把新的信封放在iframe中时,这些字段现在用提供的值填充。

这里仅供参考是创buildapi连接的其他代码,并获取视图URL

 import ENV from 'environment/backend'; const accountId = ENV.docusign.accountId; var Promise = require('bluebird'); var docusign = require('docusign-esign'); export function newApiClient() { let apiClient = new docusign.ApiClient(); apiClient.setBasePath(ENV.docusign.endpoint); // create JSON formatted auth header let creds = JSON.stringify({ Username: ENV.docusign.email, Password: ENV.docusign.password, IntegratorKey: ENV.docusign.integratorKey }); apiClient.addDefaultHeader('X-DocuSign-Authentication', creds); // assign api client to the Configuration object // this probably doesn't need to be set every time... docusign.Configuration.default.setDefaultApiClient(apiClient); return apiClient; } const defaultApiClient = newApiClient(); const envelopesApi = new docusign.EnvelopesApi(); const createEnvelope = Promise.promisify(envelopesApi.createEnvelope, { context: envelopesApi }); const listRecipients = Promise.promisify(envelopesApi.listRecipients, { context: envelopesApi }); const createRecipientView = Promise.promisify(envelopesApi.createRecipientView, { context: envelopesApi }); export default defaultApiClient; // promise resolves to the view URL, envelopeId for the user. // returns a recipientView export function setupDocumentForEmbeddedSigning(templateId, userData) { let envDefinition = createEnvelopeDefinition(templateId, userData); return createEnvelope(accountId, envDefinition, null) .then(envelopeSummary => { const envelopeId = envelopeSummary.envelopeId; return createViewFromEnvelope(envelopeId); }); } export function createViewFromEnvelope(envelopeId) { return getRecipients(envelopeId).then(recipients => { // the last signer is the one we added in the // createEnvelopeDefinition step let signers = recipients.signers; let lastSigner = signers[signers.length - 1]; return createView(envelopeId, lastSigner) .then(recipientView => [recipientView.url, envelopeId]); }); } function getRecipients(envelopeId) { return listRecipients(accountId, envelopeId); } function createView(envelopeId, signerData) { var viewRequest = new docusign.RecipientViewRequest(); viewRequest.setReturnUrl(ENV.host); viewRequest.setAuthenticationMethod('email'); // recipient information must match embedded recipient info // from the createEnvelopeDefinition method viewRequest.setEmail(signerData.email); viewRequest.setUserName(signerData.name); viewRequest.setRecipientId('2'); viewRequest.setClientUserId('2'); return createRecipientView(accountId, envelopeId, viewRequest); } // bug with the api wrapper // https://github.com/docusign/docusign-node-client/issues/47 const removeNulls = function(obj) { var isArray = obj instanceof Array; for (var k in obj) { if (obj[k] === null) isArray ? obj.splice(k, 1) : delete obj[k]; else if (typeof obj[k] == 'object') removeNulls(obj[k]); if (isArray && obj.length == k) removeNulls(obj); } return obj; }; 

所以,我可能不完全明白你卡在哪里,但是我会在这方面采取一些措施。

假设我使用DocuSign UI创build了一个模板并定义了两个收件人angular色:

  • 签名者1 (这将是注册您的服务的人) – 行动 =“签名”
  • CarbonCopy1 (一旦Signer1签署,将获得已完成/签署的文档的副本) – Action =“接收副本”

(注意:这些angular色可以用任何名称来命名 – 我将它们命名为“Signer1”和“CarbonCopy1”,这样就可以明确每个angular色代表什么。)

假设上述情况,您的模板的收件人angular色(在DocuSign UI中)将如下所示:

在这里输入图像说明

接下来,让我们假设您在模板的文档中定义了一些字段(标签)(即,使用DocuSign UI), 签名者在签名文档时需要填写Signer1收件人。 对于这个例子,我们假设其中一个Text选项卡的标签 (名称)是field1 。 请注意,该字段已分配给Signer1收件人:

在这里输入图像说明

现在,如果要通过使用此模板的API创build信封,并为一个或多个收件人预填充字段,则要使用API​​请求中的“合成模板”结构。 (请参阅本页面的复合模板一节以了解详细信息。)在上述示例中,API请求中的compositeTemplates对象将包含一个serverTemplate对象(它指定templateIdsequence = 1)和一个inlineTemplate对象指定序列 = 2和收件人信息,包括要预填充的任何制表符(字段)的值。

在上面描述的例子中,创buildEnvelope的JSON API请求看起来像这样(假设我们只是预先填充Signer1的一个字段 – 显然你可以通过简单地将它们包含在tabs对象中来预填充其他字段请求与field1一起 ):

 POST https://{{env}}.docusign.net/restapi//v2/accounts/{{accountId}}/envelopes { "emailSubject": "Test Pre-fill Tabs", "emailBlurb": "This is a test.", "compositeTemplates": [{ "serverTemplates": [{ "sequence": "1", "templateId": "CD0E6D53-3447-4A9E-BBAF-0EB2C78E8310" }], "inlineTemplates":[{ "sequence": "2", "recipients": { "signers": [ { "roleName": "Signer1", "recipientId": "1", "name": "John Doe", "email": "johndoe@test.com", "clientUserId": "1234", "tabs": { "textTabs": [ { "tabLabel": "field1", "value": "TEST-123" } ] } }, { "roleName": "CarbonCopy1", "recipientId": "2", "name": "Jane Doe", "email": "janedoe@test.com" } ] } }] }], "status": "sent" } 

使用上述请求创build信封后,我执行“POST收件人视图”请求以获取第一个收件人的签名URL( https://{{env}}.docusign.net/restapi//v2/accounts/{{accountId}}/envelopes/{{envelopeId/views/recipient )。

然后,当我随后使用该响应中返回的URL为Signer1 (John Doe)启动签名会话时,我发现field1选项卡确实预先填充了我在“Create Envelope”API请求中指定的值( TEST-123 ):

在这里输入图像说明

此外,一旦John Doe( Signer1 )完成签署并提交完成的文件,Jane Doe( CarbonCopy1 )将被发送一份副本。

我不熟悉DocuSign Node SDK,但想象一下,您可以找出使用复合模板的语法,如上例所示。 希望这可以帮助!