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

2024-05-07

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

工作流程:

  • 有一个包含一堆字段的模板
  • 使用 API:

    • 从模板创建一个信封/文档,并指定一个新用户进行签名(该文档将成为注册服务的协议)

      • 创建新角色
      • 在模板上将 roleName 设置为假签名者(因为我无法在模板上没有至少一个签名者的情况下配置字段)
      • 添加文本选项卡以尝试填充某些字段。
    • 检索收件人

    • 创建一个收件人视图,以便我获取要放入 iframe 中的 URL

这有点令人讨厌,因为我不关心第一个签名者不是注册该服务的用户。然而,我希望在签名后将文档复制给某人,但 docusign 似乎不支持这一点(无论如何我都发现了)。

以下是用于创建信封的 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将每个相应字段的标签显示为field1, field2, etc.

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

仅供参考,这里是创建 api 连接并获取视图 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 创建一个模板并定义两个收件人角色:

  • Signer1(这将是注册您的服务的人)--Action=“签名”
  • 复写1(一旦获得完整/签署的文件副本的人Signer1标志)——Action=“接收副本”

(注意:这些角色可以随意命名——我将它们命名为“Signer1”和“CarbonCopy1”,这样每个角色代表谁就很清楚了。)

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

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

现在,如果我想通过使用此模板的 API 创建一个信封,并为一个或多个收件人预填充字段,那么关键是在 API 请求中使用“复合模板”结构。 (参见复合模板的部分这一页 https://docs.docusign.com/esign/restapi/Envelopes/Envelopes/create/了解详细信息。)在上述示例中,您的复合模板API 请求中的对象将包含一个服务器模板对象(指定模板ID and sequence=1), 和一个内联模板对象(指定sequence=2 和收件人信息,包括您想要预填充的任何选项卡(字段)的值。

在上面描述的示例中,创建信封的 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": "[email protected] /cdn-cgi/l/email-protection",
                        "clientUserId": "1234",
                        "tabs": {
                            "textTabs": [
                                {
                                    "tabLabel": "field1",
                                    "value": "TEST-123"
                                }
                            ]
                        }
                    },
                    {
                      "roleName": "CarbonCopy1",
                      "recipientId": "2",
                      "name": "Jane Doe",
                      "email": "[email protected] /cdn-cgi/l/email-protection"
                    }
                ]
            }
        }]
    }],
    "status": "sent"
}

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

然后,当我随后使用该响应中返回的 URL 来启动签名会话时Signer1(约翰·多伊),我看到field1选项卡确实预先填充了我在“创建信封”API 请求中指定的值(TEST-123):

此外,一旦约翰·多伊(Signer1) 完成签名并提交完整的文件,Jane Doe (复写1)将发送一份副本。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 Docusign 的 REST API 预填充从模板创建的信封中的字段? 的相关文章

  • Nodejs:带有 URL 列表的异步请求

    我正在研究爬虫 我有一个需要请求的 URL 列表 如果我不将其设置为异步 则会同时有数百个请求 我担心它会爆炸我的带宽或产生对目标网站的大量网络访问 我应该怎么办 这是我正在做的事情 urlList forEach url index gt
  • Node.js:如何将流读入缓冲区?

    我编写了一个非常简单的函数 从给定的 URL 下载图像 调整其大小并上传到 S3 使用 gm 和 knox 我不知道我是否正确地将流读取到缓冲区 一切正常 但这是正确的方法吗 另外 我想了解有关事件循环的一些信息 我如何知道函数的一次调用不
  • 如何触发应用程序通过 REST 服务获取数据?

    我正在寻找一种方法来触发应用程序从远程 REST 服务获取数据 该方法不需要轮询 iOS 推送通知似乎不是一个选项 因为它可以被用户停用 然而 我可能是错的 是否有最佳实践来完成此任务 实际上 推送通知是可行的方法 在 ios8 及更高版本
  • REST - 获取随机数 GET 还是 POST?

    应该如何在 REST 中正确实现随机数生成器 GET RANDOM or POST RANDOM 服务器每次返回不同的随机数 我可以看到这两种方式的论点 我想说这与返回的包含当前时间的页面相同 其中许多都是使用 GET 完成的 抽象地说 获
  • 将 jQuery 集成到电子应用程序中

    我正在尝试将 jquery 功能添加到用 Electron 编写的桌面应用程序中 使用电子快速启动存储库 我将下载的 jquery 文件添加到main html像这样的文件 or so 然后在index js我正在文件中添加代码create
  • 在spawn中使用两个命令(使用管道|)

    我正在内存中将文档转换为 pdf unoconv 并在终端中打印 pdftotext unoconv f pdf stdout sample doc pdftotext layout enc UTF 8 out txt 工作中 现在我想使用
  • 为什么我在 Intellij IDEA 11 中调试 Nodejs 应用程序失败?

    我有一个单进程 node js 应用程序 我希望使用 Intellij IDEA 11 32 位进行调试 node js 也是 32 位 因此 我放置一个初始断点并运行 调试器在断点处停止 但随后拒绝执行以下任何操作 步入 转到另一个断点
  • 如何在没有 baseUrl 的情况下设置 Retrofit

    我的 apiPath 是完全动态的 我有包含 ipAddress 和 SSLprotocol 等字段的项目 基于它们我可以构建我的网址 private String urlBuilder Server server String proto
  • 访问 Node.js 全局模块

    npm 文档是这样说的 如果您正在安装想要在程序中使用的东西 请使用 require whatever 然后将其安装在本地项目的根目录下 如果您要安装要在 shell 中使用的东西 请在命令行或 某些东西 全局安装它 以便它的二进制文件最终
  • setInterval 可以随时间漂移吗?

    我有 2 个 Node js 网络服务器 我在网络服务器内缓存数据 我根据系统时间同步缓存加载 清除 我已经完成了所有主机的时间同步 现在我使用以下代码每 15 分钟清除一次缓存 millisTillNexthour Calculate m
  • RESTful API:仅用于验证的方法/标头组合

    我希望我的 API 有一个仅验证请求 例如 如果我有一个 URL 例如 http api somesite com users 12345 用户正在客户端上填写一份信息表单 我最终会将其修补 放置 发布到该资源 当用户填写表单时 我可能希望
  • Express/node.js 204 HTTP 代码响应问题

    这是我的代码 put function req res User findById req params user id function err user if err return res send err user dateEdite
  • 如何在 Codeigniter 中我自己的控制器中生成 API 密钥

    只是想提一下 我确实是 API 开发 概念 结构 最佳实践 方面的新手 我对它一点也不熟悉 所以如果您发现我正在使用 Phil 请原谅我可悲的愚蠢问题Sturgeon 的 REST API 服务器 Curl 库和 REST API 客户端这
  • 使用 Post 以 REST 方式更新值

    我对 REST 很陌生 所以如果这是一个愚蠢的问题 请原谅我 这样 我就有了客户资源 一个客户有很多信用 所以 我想获取客户积分的 URL 是 客户 21 积分 其中 21 是客户 ID 现在 如果我没有全额积分 如何添加积分 例如 客户有
  • LinkedIn Groups API - 在单个 API 请求中获取多个群组的群组徽标

    Using LinkedIn 群组 API http developer linkedin com documents groups api 我正在显示用户在 LinkedIn 上所属的组列表 使用以下命令可以清楚地在一次调用中获取组列表
  • Visual Studio 代码断点在使用 TypeScript 的 Node.js 上不起作用

    我尝试了很多解决方案 但没有人适合我 代码执行 但我无法放置断点并调试它 请你帮助我好吗 我尝试过以下 VSCode 配置脚本 type node request launch name Typescript Node JS program
  • 如何检测和测量 Node.js 中的事件循环阻塞?

    我想监视 node js 中事件循环每次运行需要多长时间 但是我不确定衡量这一点的最佳方法 我能想到的最好的方法是这样的 var interval 500 var interval setInterval function var last
  • RESTful API,如果查询字符串不够长怎么办?

    我们有产品资源集合 products 我们希望过滤此集合以仅返回具有特定列表之一的成员class id的 例如 GET products classes 100 101 102 这应该返回具有列出的任何类的产品成员的集合 我们遇到的问题是
  • Child_process 处理带有回车符 (\r) 的 STDOUT 流

    我正在编写一个简单的应用程序 它允许工作中的内部系统请求从远程服务器到使用 REST 调用发起的另一个远程服务器的复制过程 使用 rsync 我已经对express框架足够熟悉 并且刚刚开始尝试child process库 并偶然发现了一个
  • socket.io 作为客户端

    有什么方法可以将socketio作为客户端运行 不是浏览器 而是nodejs脚本 我需要将数据从服务器广播到一些客户端 浏览器 和另一台linux机器 仅运行nodejs来获取变量 没有浏览器 欢迎任何想法 Regards github上有

随机推荐