Node.js Docusign从模板发送信封不显示选项卡(节点)

Node.js Docusign从模板发送信封不显示选项卡(节点),node.js,docusignapi,webhooks,Node.js,Docusignapi,Webhooks,我正在尝试从webhook侦听器中的模板发送信封。我将node.js与.mjs文件一起使用。当我通过docusign仪表板发送信封时,它有标签-全名、SSN、电话号码、地址。但是当API发送信封时,它有这些单词,但旁边没有字段。这是一个问题,因为我们需要这些信息,而签名者无处输入这些信息。从api发送信封时,是什么导致选项卡不显示 以下是创建信封和使用模板(基于文档)的代码: 下面是我调用useTemplate的webhook侦听器的代码(请原谅注释掉的代码和控制台日志-我仍在弄清楚这一切):

我正在尝试从webhook侦听器中的模板发送信封。我将node.js与.mjs文件一起使用。当我通过docusign仪表板发送信封时,它有标签-全名、SSN、电话号码、地址。但是当API发送信封时,它有这些单词,但旁边没有字段。这是一个问题,因为我们需要这些信息,而签名者无处输入这些信息。从api发送信封时,是什么导致选项卡不显示

以下是创建信封和使用模板(基于文档)的代码:

下面是我调用useTemplate的webhook侦听器的代码(请原谅注释掉的代码和控制台日志-我仍在弄清楚这一切):


Inbar Gazit解决了这个问题-结果是我在模板中使用了student作为角色名,在代码中使用了signer作为角色名,这就是它不起作用的原因。

Inbar Gazit解决了这个问题-结果是我在模板中使用student作为角色名,在代码中使用signer作为角色名,这就是它不起作用的原因。

模板使用“签名者”作为角色名?占位符收件人有一个名称,它必须与您在代码中使用templateRoles时使用的名称相匹配,这就是全部!谢谢Bunch您的模板使用“签名者”作为角色名吗?占位符收件人有一个名称,它必须与您在代码中使用templateRoles时使用的名称相匹配—这完全是它!谢谢你,不客气…不客气。。。
import docusign from 'docusign-esign';

export function makeEnvelope(args){

  // Create the envelope definition
    let env = new docusign.EnvelopeDefinition();
    env.templateId = args.templateId;

  // Create template role elements to connect the signer and cc recipients
  // to the template
  // We're setting the parameters via the object creation
    let signer1 = docusign.TemplateRole.constructFromObject({
        email: args.signerEmail,
        name: args.signerName,
        roleName: 'signer'});

  // Create a cc template role.
  // We're setting the parameters via setters
    let cc1 = new docusign.TemplateRole();
    cc1.email = args.ccEmail;
    cc1.name = args.ccName;
    cc1.roleName = 'cc';

  // Add the TemplateRole objects to the envelope object
    env.templateRoles = [signer1, cc1];
    env.status = 'sent'; // We want the envelope to be sent

    return env;
}

export async function useTemplate(args) {


    let dsApiClient = new docusign.ApiClient();
    dsApiClient.setBasePath(args.basePath);
    dsApiClient.addDefaultHeader('Authorization', 'Bearer ' + args.accessToken);
    let envelopesApi = new docusign.EnvelopesApi(dsApiClient);
  
  // Make the envelope request body
    let envelope = makeEnvelope(args.envelopeArgs);

  // Call Envelopes::create API method
  // Exceptions will be caught by the calling function
    let results = await envelopesApi.createEnvelope(
      args.accountId, {envelopeDefinition: envelope});

    return results;
};
import express from 'express';
import { useTemplate } from '../request/docusign/docusign-methods.mjs';
import opportunities from '../request/prosperworks/opportunities.mjs';
import people from '../request/prosperworks/people.js';
import customFields from '../request/prosperworks/custom-fields.mjs';
import { findTemplateIdByCohortName } from '../request/docusign/templates.mjs';
import { findSentEnvelopesByStudentEmail, voidEnvelope, findTemplateFromEnvelopeTemplateUri } from '../request/docusign/envelopes.mjs';
import { createJWT, getAccessTokenFromJWT } from '../request/docusign/token.mjs';
import { getAccessToken } from '../request/quickbooks/tokens.mjs';
import { findCustomerByEmail } from '../request/quickbooks/customer.mjs';
import { createCustomer } from '../request/quickbooks/customer.mjs';
import { createInvoice, sendInvoice } from '../request/quickbooks/invoice.mjs';
import { findItemByName } from '../request/quickbooks/item.mjs';

const router = express.Router();

export default router
  .post('/copper/opportunity/updated', express.json(), async (req, res, next) => {
    const { body } = req;
    console.log('webhook received', body);
    if(!Object.keys(body.updated_attributes).length) return res.send('irrelevant webhook');
    const cohortChanged = !!body.updated_attributes?.custom_fields?.['94620']
    console.log('cohort changed?', cohortChanged);
    const interviewScheduledToAccepted = !!(body.updated_attributes?.stage?.[0] === 'Interview Scheduled' && body.updated_attributes?.stage?.[1] === 'Accepted')
    console.log('interview scheduled to accepted?', interviewScheduledToAccepted);
    const fullConditional = cohortChanged || interviewScheduledToAccepted;
    console.log('full conditional', fullConditional);
    if(fullConditional) {
        try {
            const jwt = await createJWT();
            const docusign_access_token = await getAccessTokenFromJWT(jwt);
            const opportunity = await opportunities.get(body.ids[0]);
            const cohortId = opportunity?.custom_fields?.find(field => field.custom_field_definition_id === 94620)?.value || null;
            const cohortName = customFields.getCohortNameById(cohortId);
            console.log('cohort name', cohortName);
            const templateId = await findTemplateIdByCohortName(cohortName, docusign_access_token);    
            const person = await people.findById(opportunity.primary_contact_id);
            const email = person.emails[0].email;
            console.log('email', email);
            const { name } = person;
            // if(interviewScheduledToAccepted) {
            //     const quickbooks_access_token = await getAccessToken();
            //     let customer = await findCustomerByEmail(email, quickbooks_access_token);
            //     if(customer === null) {
            //         customer = await createCustomer(cohortName, person, quickbooks_access_token);
            //     };
            //     console.log('customer', customer);
            //     const product = await findItemByName('Deposit', quickbooks_access_token);
            //     const invoice =  await createInvoice(customer, product, cohortName, quickbooks_access_token);
            //     const sentInvoice = await sendInvoice(email, invoice.Invoice.Id, quickbooks_access_token)
            //     console.log('sent invoice', sentInvoice);
            // }  
            const sentEnvelopes = await findSentEnvelopesByStudentEmail(email, docusign_access_token);
            await Promise.all(
            sentEnvelopes.filter(envelope => {
                return envelope.emailSubject.includes('Enrollment Agreement');
            })
            .map(envelope => {
                if(envelope.status === 'sent') return voidEnvelope(envelope.envelopeId, docusign_access_token);
            })
            );
            const sentEnvelopesTemplates = await Promise.all(
                sentEnvelopes
                .filter(envelope => {
                    return envelope.status !== 'voided'
                })
                .map(envelope => {
                    return findTemplateFromEnvelopeTemplateUri(envelope.templatesUri, docusign_access_token);
                })
            );
            const templateAlreadyUsedCheck = sentEnvelopesTemplates.reduce((outerAcc, templateArr) => {
                if(templateArr.reduce((innerAcc, template) => {
                    if(template.templateId === templateId) innerAcc=true;
                    return innerAcc;
                }, false)) {
                    outerAcc=true;
                }
                return outerAcc;
            }, false);
            if(templateAlreadyUsedCheck) return res.send('envelope already sent');
            const envelopeArgs = {
            templateId: templateId,
            signerEmail: email,
            signerName: name
            }
            console.log(envelopeArgs);
            const envelope = await useTemplate({
                basePath: process.env.DOCUSIGN_BASE_PATH,
                accessToken: docusign_access_token,
                accountId: process.env.DOCUSIGN_ACCOUNT_ID,
                envelopeArgs
            });
            return res.send(envelope);
        }
        catch(err) {
            console.log(err.message);
            next(err);
        }
    } else {
        return res.send('irrelevant webhook');
    }
  });