Coder Social home page Coder Social logo

hellosign-nodejs-sdk's People

Contributors

alexmac05 avatar asolberg avatar bhspitmonkey avatar dannypaz avatar elizabethkilson avatar framinus avatar gabegorelick avatar georules avatar hazemhamedhs avatar jacobpgn avatar josiahwiebe avatar jtreminio-dropbox avatar jyoung488 avatar latoyazamill avatar marchah avatar nathanbuchar avatar npbee avatar radhack avatar renderf0x avatar taylorkrusen avatar trevoro avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hellosign-nodejs-sdk's Issues

1.1.9 issue data become to null: null

After update on 1.1.9 I got error "You must either upgrade to a paid API plan (https://www.hellosign.com/api/pricing) or use the test_mode=1 parameter"

details

send code

  addDeal(deal) {
   // ...
    const message = {
      title: `Deal [${deal._id}]`,
      use_text_tags: 1,
      hide_text_tags: 0,
      message: 'Please review and sign this document.',
      signing_redirect_url: this.config.uri + this.config.postSign(deal._id, deal.customer._id),
      signers: [
        {
          email_address: deal.customer.email_address,
          name: `${deal.customer.first_name} ${deal.customer.last_name}`
        }
      ],
      files: [fileName], // <------------- files there!
      metadata: {
        delaId: deal._id,
        customerId: deal.customer._id,
        salesmanagerId: deal.user._id,
      }
    };

    if (!!this.config.testMode) {
      message.test_mode = 1; // <-- test mode inculded
    }

    return pdf.make(deal, true)
      // ....
      .then(() => this.hSign.signatureRequest.send(message))
      // ...
      .catch(err => this.triggerError('deal-added', err, {deal: deal, message: message})); //eslint-disable-line
  }

message after convert

looks wrong:

  1. files property gone
  2. test_mode exists but please looks to error!
   { title: 'Deal [d100]',
     use_text_tags: 1,
     hide_text_tags: 0,
     message: 'Please review and sign this document.',
     signing_redirect_url: 'https://alpha.taxliencloud.com/deals/d100/signed?customerId=41dd3f8d-9aee-48c1-be99-916aeadc4b77',
     test_mode: 1, // <-- test mode inculded
     'signers[0][email_address]': '[email protected]',
     'signers[0][name]': 'Abraham Vayheses',
     'metadata[delaId]': 'd100',
     'metadata[customerId]': '41dd3f8d-9aee-48c1-be99-916aeadc4b77',
     'metadata[salesmanagerId]': '32c69356-022f-4cae-8651-c831fb9e8cae' } }

response - error

 { [Error: You must either upgrade to a paid API plan (https://www.hellosign.com/api/pricing) or use the test_mode=1 parameter.]
  type: 'payment_required',

reasons

message received on hellosign side

{
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: {
        null: null
    },
    null: null,
    null: null,
    "\u0016\t_": null,
    null: {
        null: null
    },
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    "v\u0017\u000f": null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: {
        null: null
    },
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: {
        null: null
    },
    null: null,
    null: {
        null: null
    },
    null: {
        null: null
    },
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: [null],
    null: null,
    null: null,
    null: {
        null: null
    },
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    null: null,
    "module": "v3",
    "action": "signatureRequestSend"
}

Error: This request cannot be signed yet

We are experiencing this error in our application:

{ Error: This request cannot be signed yet 
  message: 'This request cannot be signed yet', 
  stack: 'Error: This request cannot be signed yet
    at _Error (/app/node_modules/hellosign-sdk/lib/Error.js:36:19)
    at Function.HelloSignError.generate (/app/node_modules/hellosign-sdk/lib/Error.js:79:12)
    at IncomingMessage.<anonymous> (/app/node_modules/hellosign-sdk/lib/HelloSignResource.js:173:56)
    at emitNone (events.js:91:20)
    at IncomingMessage.emit (events.js:188:7)
    at endReadableNT (_stream_readable.js:974:12)
    at _combinedTickCallback (internal/process/next_tick.js:80:11)
    at process._tickDomainCallback (internal/process/next_tick.js:128:9)' } 

Not sure exactly which function call triggers this as the stack doesn't include the exact origin

Support setting callback_url on a per-request basis.

Currently, the callback_url can only be set at the account or app level. This does not allow for dynamic callbacks in which the callback_url is decided at runtime.

For my specific use case, we would like to set the callback url to different URLs based on whether we're in a local, review, staging, or production environment.

This is currently not possible, AFAIK.

Facing issue while integrating hellosign embedded request API using Node.js

Hi there,
We have our own template created and there is "Customer" role who will sign.
We have tried a lot to integrate hellosign embedded create request API using Node.js, but i was not able to create any request by using the same. So i tried with 'Curl' on terminal and successfully created embedded signature request id. I installed 'curlrequest' module to create request using curl, but i got following error response:

We tried with following code:

curl.request({
url: 'https://api.hellosign.com/v3/signature_request/create_embedded_with_template',
user: '--------------API key----------------------:',
data: {
client_id: '-----------------client id --------------------------------',
template_id: '--------------------template id-----------------------',
subject: 'My First embedded Signature Request',
message: 'Awesome, right?',
signers: [
{
email_address: '----------------email address------------------',
role: 'Customer',
name: 'Test'
}],
test_mode: 1
}
}, function (err, parts) {
console.log("================================", err, data);
});

{"error":{"error_msg":"Malformed signers parameter(s)","error_name":"bad_request"}}

Please suggest, this is kinda urgent. What is wrong, or what is missing or how we can specify signers at least in the request?

Thanks.

How can I set the merge_fields in sendWithTemplate option?

I'm using this nodejs-sdk to send the eSign document to users who attempts to register to our platform. But I should send them document with pre-filled form. Such as their name and email address and don't allow them to change this at document.
But seems merge_fields parameter is not working properly.

Any help please

signatureRequest.cancel promise never resolves on success

hellosign-sdk version: 1.6.0

Using the code snippet in the example:

hellosign.signatureRequest.cancel(request_id)
 .then(function(response){
  console.log(response.statusCode);
  console.log(response.statusMessage);
})
.catch(function(err){
  // Handle errors
});

with a valid request_id successfully cancels the request but the promise is never resolved, in the example console.log(response.statusCode); and console.log(response.statusMessage); are never called. An invalid request_id does reject the promise.

API silently fails on downloading files with `{ file_type: "zip" }`

The SDK fails silently when requesting to download files for a signature request with:
{ file_type: "zip" }

Here is the function I am using to download the files.

  const createDownloadStream = (
    signatureRequestId,
    { file_type = 'pdf' } = { file_type: 'pdf' }
  ) => {
    console.log('Downloading stream');

    return new Promise((resolve, reject) =>
      helloSignClient.signatureRequest.download(
        signatureRequestId,
        { file_type: fileType },
        function callback(err, responseStream) {
          console.log('Downloaded', err, response); // <-- This line is never reached, because the callback is never called.

          if (err) {
            reject(err);
          }

          resolve(responseStream);
        }
      )
    );
  };

This has been working for over a year now, and just started failing last week.

Err Object

When using IIS/Azure functions, errors are returned when trying to return the err object as json http output so it'll return this type of error:
Error: ENOENT: no such file or directory, open 'D:\home\site\wwwroot\node_modules\hellosign-sdk\node_modules\when\when.js'

However, a workaround would be parse the err using this function:
JSON.parse(JSON.stringify(err))

Provide TypeScript definitions

It will be nice if you provide TypeScript definitions for this package.

This is what I wrote as a good start if you are interested:

declare module "hellosign-sdk" {
  // Configuration
  type Configuration =
    | { key: string }
    | { username: string; password: string }
    | {
        key: string;
        client_id: string;
        client_secret: string;
      };
  function Hellosign(options: Configuration): Hellosign.Api;

  namespace Hellosign {
    export type Flag = 0 | 1;

    // Api response base
    type BasicResponse = {
      warnings: any;
      statusCode: number;
      statusMessage: string;
    };

    // Account Api
    export namespace Account {
      export type Account = {
        account_id: string;
        email_address: string;
        callback_url: string;
        is_locked: boolean;
        is_paid_hs: boolean;
        is_paid_hf: boolean;
        quotas: {
          api_signature_requests_left: number;
          documents_left: number;
          templates_left: number;
        };
        role_code: string;
      };

      export type AccountResponse = BasicResponse & {
        account: Account;
      };

      export type Api = {
        get: () => Promise<AccountResponse>;
        update: (payload: { callback_url: string }) => Promise<AccountResponse>;
        create: (payload: {
          email_address: string;
        }) => Promise<AccountResponse>;
        verify: (payload: {
          email_address: string;
        }) => Promise<AccountResponse>;
      };
    }

    // Signature Request Api
    export namespace SignatureRequest {
      export type SignatureRequest = {
        test_mode: Flag;
        signature_request_id: string;
        requester_email_address: string;
        title: string;
        subject: string;
        message: string;
        is_complete: boolean;
        is_declined: boolean;
        has_error: boolean;
        files_url: string;
        signing_url: string;
        details_url: string;
        cc_email_addresses: Array<string>;
        signing_redirect_url: string;
        custom_fields: Array<{
          name: string;
          type: FieldType;
          value: string;
          required: boolean;
          editor: string;
        }>;
        response_data: Array<{
          api_id: string;
          signature_id: string;
          name: string;
          value: boolean;
          required: boolean;
          type: string;
        }>;
        metadata?: { [key: string]: string };
        signatures: Array<Signature>;
      };

      export type SignatureStatusCode =
        | "awaiting_signature"
        | "signed"
        | "declined";

      export type Signature = {
        signature_id: string;
        signer_email_address: string;
        signer_name: string;
        signer_role: string;
        order: number;
        status_code: SignatureStatusCode;
        decline_reason: string;
        signed_at: number;
        last_viewed_at: number;
        last_reminded_at: number;
        has_pin: boolean;
        reassigned_by: string;
        reassignment_reason: string;
        error: string;
      };

      export type ListOptions = {
        page?: number;
        page_size?: number;
      };

      export type ListResponse = BasicResponse & {
        list_info: {
          page: number;
          num_pages: number;
          num_results: number;
          page_size: number;
        };
        signature_requests: Array<SignatureRequest>;
      };

      export type SignatureRequestResponse = BasicResponse & {
        signature_request: SignatureRequest;
      };

      export type FieldType =
        | "text"
        | "checkbox"
        | "date_signed"
        | "executiondate"
        | "initials"
        | "signature"
        | "text-merge"
        | "checkbox-merge";

      export type ValidationTypeBase =
        | "numbers_only"
        | "letters_only"
        | "phone_number"
        | "bank_routing_number"
        | "bank_account_number"
        | "email_address"
        | "zip_code"
        | "social_security_number"
        | "employer_identification_number";

      export type ValidationTypeRegex = "custom_regex";

      export type ValidationType = ValidationTypeBase | ValidationTypeRegex;

      export type DocumentFieldBaseValidation = {
        api_id: string;
        name: string;
        type: FieldType;
        x: number;
        y: number;
        width: number;
        height: number;
        required?: boolean;
        signer: number | string;
        page?: number;
        validation_type?: ValidationTypeBase;
      };

      export type DocumentFieldRegexpValidation = DocumentFieldBaseValidation & {
        validation_type: "custom_regex";
        validation_custom_regex: string;
        validation_custom_regex_format_label: string;
      };

      export type DocumentField =
        | DocumentFieldBaseValidation
        | DocumentFieldRegexpValidation;

      export type SigningOptions = {
        draw: boolean;
        type: boolean;
        upload: boolean;
        phone: boolean;
        default: boolean;
      };

      export type Payload = {
        test_mode?: Flag;
        clientId: string;
        title?: string;
        subject?: string;
        message?: string;
        signers?: Array<{
          email_address: string;
          name: string;
          role: string;
          order?: number;
        }>;
        ccs?: Array<{
          email_address: string;
          role: string;
        }>;
        custom_fields?: Array<{
          name: string;
          value: string;
          editor?: string;
          required?: boolean;
        }>;
        cc_email_addresses?: Array<string>;
        metadata?: { [key: string]: string };
        allow_decline?: Flag;
        signing_options?: SigningOptions;
      };

      export type TemplatePayload = Payload & {
        template_id: string;
      };

      export type FilePayload = Payload & {
        files: Array<string>;
        use_text_tags?: Flag;
        hide_text_tags?: Flag;
        allow_reassign?: Flag;
        form_fields_per_document?: Array<Array<DocumentField>>;
      };

      export type Api = {
        get: (id: string) => Promise<SignatureRequestResponse>;
        list: (options?: ListOptions) => Promise<ListResponse>;
        send: (data: FilePayload) => Promise<SignatureRequestResponse>;
        sendWithTemplate: (
          data: TemplatePayload
        ) => Promise<SignatureRequestResponse>;
        createEmbeddedWithTemplate: (
          data: TemplatePayload
        ) => Promise<SignatureRequestResponse>;
        createEmbedded: (
          data: FilePayload
        ) => Promise<SignatureRequestResponse>;
        remind: (
          request_id: string,
          options: { email_address: string }
        ) => Promise<SignatureRequestResponse>;
        download: (
          request_id: string,
          options: { file_type: string },
          callback: (err: Error, response: ReadableStream) => void
        ) => void;
        cancel: (request_id: string) => Promise<SignatureRequestResponse>;
      };
    }

    export namespace Embedded {
      export type Data = {
        sign_url: string;
        expires_at: number;
      };
      export type Response = BasicResponse & {
        embedded: Data;
      };
      type Api = {
        getSignUrl: (signatureId: string) => Promise<Response>;
        getEditUrl: (templateId: string) => Promise<Response>;
      };
    }

    // Api
    export type Api = {
      account: Account.Api;
      signatureRequest: SignatureRequest.Api;
      embedded: Embedded.Api;
    };

    // Http callbacks
    export namespace Callback {
      export type EventSignature =
        | "signature_request_viewed"
        | "signature_request_downloadable"
        | "signature_request_sent"
        | "signature_request_declined"
        | "signature_request_reassigned"
        | "signature_request_remind"
        | "signature_request_all_signed"
        | "signature_request_email_bounce"
        | "signature_request_invalid"
        | "signature_request_canceled"
        | "signature_request_prepared"
        | "signature_request_declined"
        | "signature_request_signed";

      export type EventTest = "callback_test";

      export type EventSignUrlInvalid = "sign_url_invalid";

      export type EventTemplate = "template_created" | "template_error";

      type Event<T extends string> = {
        event_time: string;
        event_hash: string;
        event_type: T;
      };

      type Base<T extends string> = {
        event: Event<T>;
      };

      export type Signature = Base<EventSignature> & {
        signature_request: SignatureRequest.SignatureRequest;
      };

      export type Test = Base<EventTest>;

      export type SignUrlInvalid = Base<EventSignUrlInvalid>;

      export type Template = Base<EventTemplate>;

      export type Data = Signature | Test | SignUrlInvalid | Template;
    }
  }
  export = Hellosign;
}

When creating a template with a cc_role, and then trying to edit the template, the cc_role doesn't appear

Here's what I did:

  1. In our app, I create a new template... here's what it looks like on our end: https://www.evernote.com/l/AAY_ARo9KVNF4JEGDitzdZuUkMGhJJJwp3sB/image.png
  2. Our app makes an API request using the NODE SDK endpoint hellosign.template.createEmbeddedDraft() with the following options:
    { test_mode: 1,
    clientId: 'CLIENT ID',
    title: 'Testing CC Roles',
    subject: 'A nice subject',
    use_preexisting_fields: 1,
    message: 'Message',
    signer_roles: [ { name: 'A Role Name' } ],
    cc_roles: [ '[email protected]' ],
    file_url: [ 'https://signature-requests.s3.amazonaws.com/8a8939c3-c450-dbdf-52a2-7547bc70fdfa.pdf' ] }
  3. We receive an EDIT_URL from hellosign which we use to create the template and then pressing continue on the hellosign modal returns the following event_data: {"template_status_id":" ","template_id":" ","template_info":{"title":"A nice subject","message":"Message","signer_roles":[{"name":"A Role Name","order":0}],"cc_roles":["[email protected]"]},"success":true,"event":"template_created"}
  4. NOTE the cc_role of '[email protected]' in the hellosign event data.
  5. I then call hellosign.embedded.getEditUrl() from the Node SDK to retrieve the edit_url of the template.
  6. upon opening the edit_url from an embedded hellosign modal, it looks like this: https://www.evernote.com/l/AAb4iY7dYb5DEo74wOvVeVp5fCyjq5bSYRAB/image.png
  7. NOTE that the cc_role is not there...and it should be

Thanks,
Ray

HelloSign-sdk is broken when upgrading to nock 13.x

I just upgraded my project from nock 12.0.3 to nock 13.0.4 and my tests break.

Here's an example project using nock 12.0.3 and I can easily stub out the response from the hellosign-sdk client https://repl.it/@TomCaflisch/HelplessWorthlessCell#index.js

Here's an example project using nock 13.0.4 and you can see the hellosign-sdk error
https://repl.it/@TomCaflisch/UnrealisticPopularGlueware#index.js

err =  Error: write after end
    at Constructor._Error (/home/runner/UnrealisticPopularGlueware/node_modules/hellosign-sdk/lib/Error.js:36:19)
    at new Constructor (/home/runner/UnrealisticPopularGlueware/node_modules/hellosign-sdk/lib/utils.js:112:19)
    at OverriddenClientRequest.<anonymous> (/home/runner/UnrealisticPopularGlueware/node_modules/hellosign-sdk/lib/HelloSignResource.js:213:17)
    at OverriddenClientRequest.emit (events.js:315:20)
    at OverriddenClientRequest.EventEmitter.emit (domain.js:483:12)
    at /home/runner/UnrealisticPopularGlueware/node_modules/nock/lib/intercepted_request_router.js:145:34
    at processTicksAndRejections (internal/process/task_queues.js:79:11) {
  type: 'HelloSignError',
  rawType: undefined,
  code: 'ERR_STREAM_WRITE_AFTER_END',
  param: undefined,
  detail: undefined,
  raw: Error: write after end
      at InterceptedRequestRouter.handleWrite (/home/runner/UnrealisticPopularGlueware/node_modules/nock/lib/intercepted_request_router.js:143:19)
      at OverriddenClientRequest.req.write (/home/runner/UnrealisticPopularGlueware/node_modules/nock/lib/intercepted_request_router.js:90:35)
      at InterceptedRequestRouter.handleEnd (/home/runner/UnrealisticPopularGlueware/node_modules/nock/lib/intercepted_request_router.js:198:9)
      at OverriddenClientRequest.req.end (/home/runner/UnrealisticPopularGlueware/node_modules/nock/lib/intercepted_request_router.js:91:33)
      at OverriddenClientRequest.<anonymous> (/home/runner/UnrealisticPopularGlueware/node_modules/hellosign-sdk/lib/HelloSignResource.js:422:21)
      at OverriddenClientRequest.emit (events.js:315:20)
      at OverriddenClientRequest.EventEmitter.emit (domain.js:483:12)
      at InterceptedRequestRouter.startPlayback (/home/runner/UnrealisticPopularGlueware/node_modules/nock/lib/intercepted_request_router.js:302:11)
      at InterceptedRequestRouter.maybeStartPlayback (/home/runner/UnrealisticPopularGlueware/node_modules/nock/lib/intercepted_request_router.js:253:12)
      at InterceptedRequestRouter.handleEnd (/home/runner/UnrealisticPopularGlueware/node_modules/nock/lib/intercepted_request_router.js:200:10) {
    code: 'ERR_STREAM_WRITE_AFTER_END'
  }
}
res =  null

I'm assuming the issue is with something that hellosign-sdk is doing since the other hundreds of tests I have are still working after upgrading to nock 13.

DeprecationWarning

Hi team,

I got the following warning message while using the endpoints of create template, signature request, and embedded signing.

(node:1) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.

Can you please look into the issue? Thank you.

"Client IDs" should be accepted as snake case or camel case

I'm working on a Node demo, going off this example: Embedded Signing Example. Some options are snake case (like test_mode) while others, specifically Client ID, must strictly be camelcase. client_id will return:

{ [Error: No client id provided]
  type: 'bad_request',
  message: 'No client id provided',
  stack: 'Error: No client id provided
at Error._Error (/Users/freddyrangel/repositories/sandbox/embedded_signing_node/node_modules/hellosign-sdk/lib/Error.js:36:19)
at Function.HelloSignError.generate (/Users/freddyrangel/repositories/sandbox/embedded_signing_node/node_modules/hellosign-sdk/lib/Error.js:79:12)
at IncomingMessage.<anonymous> (/Users/freddyrangel/repositories/sandbox/embedded_signing_node/node_modules/hellosign-sdk/lib/HelloSignResource.js:172:56)\
at emitNone (events.js:72:20)
at IncomingMessage.emit (events.js:166:7)
at endReadableNT (_stream_readable.js:893:12)
at doNTCallback2 (node.js:429:9)
at process._tickCallback (node.js:343:17)' }

using pin number unclaimed draft throwing invalid param error.

When using the hellosign.unclaimedDraft.createEmbeddedWithTemplate method with signers in the format:

    signers: [
        {
            name: 'Sherlock',
            role: 'Signer',
            email_address: '[email protected]',
            pin: 3645
        }
    ]

it works fine, however, if I try to use hellosign.unclaimedDraft.createEmbedded with the same signers. it breaks with an error of Invalid parameter: 'pin'. I verified with Hellosign that this is indeed a bug and that it should work (and does work via CURL). So it must be the node-sdk that is causing the error.

Invalid parameter: custom_fields

Hi everyone,
I got this error: { statusCode: 400, I20160811-16:02:10.019(2)? content: '{"error":{"error_msg":"Invalid parameter: custom_fields","error_name":"bad_request"}}' while attempting to create a new draft template with custom fields.

Add signer groups functionality

Signer group parameters need to be added to the signatureRequest.send() and signatureRequest.sendWithTemplate() functions:

For .send():
signers[0][group]=Authorized signatory
signers[0][0][name]=Jack
signers[0][0][email_address]=[email protected]
signers[0][1][name]=Jill
signers[0][1][email_address]=[email protected]

For .sendWithTemplate():

signers[HR][group]=Authorized signatory
signers[HR][0][name]=Jack
signers[HR][0][email_address]=[email protected]
signers[HR][1][name]=Jill
signers[HR][1][email_address]=[email protected]

Add Editable Merge Fields support

When updating the SDKs to include editable merge fields, please also update the SDK git repos README examples (if necessary) and the following in the API docs:

  • "Send with Template" endpoint example
  • "Send Embedded Signature Request with Template" endpoint example
  • Templates Walkthrough
  • Signature Request Walkthrough -> Using Templates

Is this library interfering with nock in some way?

I'm trying to use nock to intercept requests to your services and mock out a response, however i seem to be receiving this from your library when i do:

Error: write after end
    at Constructor._Error (/Users/jared/Projects/scratch/js-server/node_modules/hellosign-sdk/lib/Error.js:36:19)
    at new Constructor (/Users/jared/Projects/scratch/js-server/node_modules/hellosign-sdk/lib/utils.js:112:19)
    at OverriddenClientRequest.<anonymous> (/Users/jared/Projects/scratch/js-server/node_modules/hellosign-sdk/lib/HelloSignResource.js:214:17)
    at OverriddenClientRequest.emit (events.js:210:5)
    at /Users/jared/Projects/scratch/js-server/node_modules/nock/lib/intercepted_request_router.js:145:34
    at processTicksAndRejections (internal/process/task_queues.js:75:11) {
  type: 'HelloSignError',
  stack: 'Error: write after end\n' +
    '    at Constructor._Error (/Users/jared/Projects/scratch/js-server/node_modules/hellosign-sdk/lib/Error.js:36:19)\n' +
    '    at new Constructor (/Users/jared/Projects/scratch/js-server/node_modules/hellosign-sdk/lib/utils.js:112:19)\n' +
    '    at OverriddenClientRequest.<anonymous> (/Users/jared/Projects/scratch/js-server/node_modules/hellosign-sdk/lib/HelloSignResource.js:214:17)\n' +
    '    at OverriddenClientRequest.emit (events.js:210:5)\n' +
    '    at /Users/jared/Projects/scratch/js-server/node_modules/nock/lib/intercepted_request_router.js:145:34\n' +
    '    at processTicksAndRejections (internal/process/task_queues.js:75:11)',
  rawType: undefined,
  code: 'ERR_STREAM_WRITE_AFTER_END',
  param: undefined,
  message: 'write after end',
  detail: undefined,
  raw: Error: write after end
      at InterceptedRequestRouter.handleWrite (/Users/jared/Projects/scratch/js-server/node_modules/nock/lib/intercepted_request_router.js:143:19)
      at OverriddenClientRequest.req.write (/Users/jared/Projects/scratch/js-server/node_modules/nock/lib/intercepted_request_router.js:90:35)
      at InterceptedRequestRouter.handleEnd (/Users/jared/Projects/scratch/js-server/node_modules/nock/lib/intercepted_request_router.js:198:9)
      at OverriddenClientRequest.req.end (/Users/jared/Projects/scratch/js-server/node_modules/nock/lib/intercepted_request_router.js:91:33)
      at OverriddenClientRequest.<anonymous> (/Users/jared/Projects/scratch/js-server/node_modules/hellosign-sdk/lib/HelloSignResource.js:423:21)
      at OverriddenClientRequest.emit (events.js:210:5)
      at InterceptedRequestRouter.startPlayback (/Users/jared/Projects/scratch/js-server/node_modules/nock/lib/intercepted_request_router.js:302:11)
      at InterceptedRequestRouter.maybeStartPlayback (/Users/jared/Projects/scratch/js-server/node_modules/nock/lib/intercepted_request_router.js:253:12)
      at InterceptedRequestRouter.handleEnd (/Users/jared/Projects/scratch/js-server/node_modules/nock/lib/intercepted_request_router.js:200:10)
      at OverriddenClientRequest.req.end (/Users/jared/Projects/scratch/js-server/node_modules/nock/lib/intercepted_request_router.js:91:33)
      at Socket.<anonymous> (/Users/jared/Projects/scratch/js-server/node_modules/hellosign-sdk/lib/HelloSignResource.js:417:29)
      at Socket.emit (events.js:210:5)
      at InterceptedRequestRouter.connectSocket (/Users/jared/Projects/scratch/js-server/node_modules/nock/lib/intercepted_request_router.js:128:14)
      at /Users/jared/Projects/scratch/js-server/node_modules/nock/lib/intercepted_request_router.js:69:33
      at processTicksAndRejections (internal/process/task_queues.js:75:11) {
    code: 'ERR_STREAM_WRITE_AFTER_END'
  }
}

This is based on the code:

const helloAPI = require('hellosign-sdk')({key: process.env.API_KEY});
class CreateLive {
  constructor() {

  }

  async acknowledge(header, body) {
    const contractFile = await this._download(body)
      .catch((err) => {
        throw err;
      });
  }

  async _download(body) {
    const requestID = body.signature_request.signature_request_id;
    const downloadedData = await helloAPI.signatureRequest.download(requestID, {file_type: 'pdf'})
      .then((res) => {
        return new Promise((resolve, reject) => {
          let downloadData = Buffer.from('');
          res.on('data', (data) => {
            downloadData = Buffer.concat([downloadData, data]);
          });
          res.on('end', () => {
            resolve(downloadData);
          });
        });
      })
      .catch((err) => {
        console.log(err);
        throw err;
      });
    console.log(downloadedData)
    return downloadedData;
  }
}
module.exports = CreateLive;

then using nock in my tests here:

// common.js
'use strict';

global.chai = require('chai');
global.chai.should();

global.expect = global.chai.expect;
global.sinon = require('sinon');

global.sinonChai = require('sinon-chai');
global.chai.use(global.sinonChai);

global.nock = require('nock');
// .mocharc.js
'use strict';

module.exports = {
  require: '/Users/jared/Projects/scratch/js-server/test/common.js',
  harmony: true,
  recursive: true,
  bail: true
};
const CreateLive = require('../src/Events/Event/CreateLive');
describe('CreateLive', () => {
  describe('acknowledge', function() {
    it('should call _download', async () => {
      const event = getEvent() // code to get a mocked out hellosign event
      const contract = getContract() // code to get a contract (.pdf file)
      nock('https://api.hellosign.com:443', {"encodedQueryParams":true})
          .get('/v3/signature_request/files/' + event.body.signature_request.signature_request_id, "file_type=pdf")
          .query({"file_type":"pdf"})
          .reply(200, contract, [
            'Access-Control-Allow-Headers',
            'Authorization, Origin, X-Requested-With, Content-Type, Accept',
            'Access-Control-Allow-Methods',
            'GET, POST, OPTIONS',
            'Access-Control-Allow-Origin',
            '*',
            'Cache-Control',
            'cache-control=must-revalidate',
            'Content-Description',
            'File Transfer',
            'Content-Disposition',
            'attachment; filename="abcd"',
            'Content-Transfer-Encoding',
            'binary',
            'Content-Type',
            'application/pdf',
            'Date',
            'Fri, 26 Jun 2020 16:39:49 GMT',
            'ETag',
            '"57c83-0"',
            'Expires',
            'Sat, 26 Jul 1997 05:00:00 GMT',
            'Last-Modified',
            'Fri, 26 Jun 2020 16:39:50 GMT',
            'P3P',
            'CP="NOP3PPOLICY"',
            'Pragma',
            'public: 1',
            'Server',
            'Apache',
            'Strict-Transport-Security',
            'max-age=15768000',
            'Content-Length',
            '359555',
            'Connection',
            'Close'
          ]);
        const createEvent = new CreateLive();
        const actual = await createEvent.acknowledge(event.headers, event.body)
          .catch(function(err) {
            console.log(err);
            expect(function() { throw err })
              .to.not.throw();
          });
    });
  });
});

Dependencies:

"chai": "^4.2.0",
    "mocha": "^8.1.1",
    "nock": "^13.0.4",
    "sinon": "^9.0.3",
    "sinon-chai": "^3.5.0"
"hellosign-sdk": "^1.6.0",

List methods trigger 500 error when a search string with multiple parameters is provided

Following the documentation [1], I'm constructing and sending my search query as follows:

let queryParams = {
    to: signerEmail,
    title: titleKeyword,
    complete: complete ? 'true' : 'false',
};

let query = [];
for (let key in queryParams) {
    if (queryParams[key]) {
        query.push(key + ':' + queryParams[key].replace(/\s+/g, '+'));
    }
}

let searchQuery = query.join('+AND+);
return hellosign.signatureRequest.list({ query: searchQuery }); 

Which always triggers a 500 error. Intercepting the request URL on the SDK, I see that the request data is always urlencoded [2], which provides a URL of the form:

"https://api.hellosign.com/v3/signature_request/list?query=to%3Aemail%40example.com%2BAND%2Btitle%3AKeyword"

With the help of Hellosign support we discovered that the API fails when the "+" around the "AND" are encoded. On the other hand, if a query value has a "+" sign (as in [email protected]) the API will fail to parse the query, and thus return incorrect results.

It'd be nice to adapt the list methods to accept the query as an object, in which the developers can define the different filters. If the API is working as designed (in spite of the 500), it'd be nice if the nodejs request examples on the API reference showed how to construct the query correctly (issue #8)

Cheers!

[1] https://www.hellosign.com/api/reference#Search
[2] https://github.com/HelloFax/hellosign-nodejs-sdk/blob/v3/lib/utils.js#L46

Query parameter issues

I'm having a difficult time with a date query for completed docs.

I'm using the node hellosign-sdk (1.1.8 running on node v4.2.1)

If I run a query like this:

'complete:true'

I get 34 results. That's how many completed signed docs I have. OK, no problem.

If I set a query to:

'created:{2014-01-01 TO 2016-12-31}'

I get 68 results. (That time span covers all my docs, so you can see that roughly 1/2 have been completed.)

But if I change that query to:

'completed:{2014-01-01 TO 2016-12-31}'

I get zero results. I'm not sure I understand that at all.

In fact, I don't think I've gotten a query with "completed" in it to return any results. It doesn't appear to work at all. The docs say this about "completed":

completed The date (and optional time) of the final signature SignatureRequest only Date

From this I would gather that I should be a able to query on completion date/time.

Well, let me suggest that the documentation around queries can be improved quite a bit.
For example, I just figured out that the '+' signs needed by the query string to separate 'TO' and 'AND', etc are inserted by the SDK and should be spaces instead. How could I work that out except through experimentation. There are ZERO complete examples of a query with date ranges.

Best,
Dave J

Multiple content-type headers are sent on HTTP request

Hello,

Submitting forms with v3 HEAD sets two values for content-type. They are currently being set using two different key values.

In most parts of the lib the header value Content-Type is set (note the uppercase), but later in the library, you're transposing header values from the form-data npm module which has a lower case content-type value set. Because of the way this works we end up with multiple content-type headers, and this breaks other things.

For example, I'm trying to get this to work with a other apps that do a lower case comparison on header values, as it's not part of the standard.

The fix is simple, but I wanted to make sure I knew which content-type value to accept;
Either multipart/form-data; boundary=-..... or
application/x-www-form-urlencoded.

Thanks

Update dependencies to work with React Native

We make some calls to a few libraries that are incompatible with React Native ( child_process and fs for instance ) and others that need to be explicitly required for the dependency manager to find them (http, https).

Projects for React Native won't build with these dependencies missing.

Allow Response Handling with Delete Template Endpoint

const hellosign = require('hellosign-sdk')({ key: 'SIGN_IN_AND_CREATE_API_KEY_FIRST' });

hellosign.template.delete(templateId).then((res) => {
// Handle response -------> NEVER GETS CALLED.
}).catch((err) => {
// Handle error
});

Allow the response of 200 OK to get proper handling in the above block of code. At the moment nothing gets handled with the positive response.

MessageListener not being called

Hello.
For some reason, messageListener is not being called.
I am successfully seeing the document and able to sign it.
I have tried - unsuccessfully - to put eventListeners on the Window...
I am not sure what else to try?

const opts = {
      this.props.url,
      allowCancel: true,
      uxVersion: 2,
      messageListener: function(eventData) {
        console.log('hello!?')
        if (eventData.event === window.HelloSign.EVENT_SIGNED) {
          this.props.onSign(eventData['signature_id'])
        }
      }
    }
window.HelloSign.init('API_KEY')
window.HelloSign.open(opts)

The allow_reassign parameter does not work on non-embedded endpoints.

When an embedded signature request is passed the parameter "allow_reassign": true, the signer is able to reassign the signature request in the embedded editor.

However, when passing the same allow_reassign parameter to either the signatureRequest.send() or signatureRequest.sendWithTemplate() methods, the parameter does not get included in the request. I confirmed that is not getting passed in the request logs, and the option to reassign is not available when the signer opens the editor.

Functional test suite missing required packages to run.

The README.md instructions for testing include a functional test suite, which can be run by creating a dummy HelloSign account, copying the required account variables into testparams.js, and using the command node_modules/mocha/bin/mocha to run them.

When these tests are run, the following error is thrown:

Error: Cannot find module 'express'

/test/hellosign-sdk-test-server/server.js requires the following packages: express, body-parser, multer and morgan.

However, these packages are not listed in the package.json as either regular or dev dependencies.

Custom fields code snippets on hellosign.com are wrong

Hello, I spent some time today being very confused because HelloSign's API was rejecting the payload I was providing, which was based on the following snippet on Using a Template with Custom Fields:

const hellosign = require('hellosign-sdk')({ key: 'ba92b3085265d6bb9729c1e2efcb39c614d91373b15acfd6fdde7e90a0867c7f' });

const opts = {
  test_mode: 1,
  template_id: '5eb54aaaa71ce8dcaec5d06e93a2754af1712606',
  title: 'NDA with Acme Co.',
  subject: 'The NDA we talked about',
  message: 'Please sign this NDA and then we can discuss more.',
  signers: [
    {
      email_address: '[email protected]',
      name: 'Alice',
      role: 'Manager'
    },
    {
      email_address: '[email protected]',
      name: 'Bob',
      role: 'Employee'
    }
  ],
  custom_fields: [
    {
      contract_number: 'DD21'
    }
  ]
};

hellosign.signatureRequest.sendWithTemplate(opts).then((res) => {
  // handle response
}).catch((err) => {
  // handle error
});

Your API was rejecting my request with Invalid custom fields parameters, but as far as I knew, the custom fields information I was providing was correct.

It wasn't until I stumbled on your Using Editable Merge Fields aka Custom Fields article that I noticed an entirely different format for custom_fields was expected:

image

Based on this format, the documentation for custom_fields in your example snippet should be something along the lines of:

  custom_fields: [
    {
      name: 'contract_number',
      value: 'DD21'
    }
  ]

Once I started submitting my payload in this format, everything worked. Please update your documentation snippets on your API walkthroughs on app.hellosign.com to use the correct format, as it will save a lot of needless frustration for new developers!

Replace Request Lib

Request is deprecated and should be replaced with an alternative like fetch or node-fetch.

Canceling Signature Request hangs

Hi. I sent this to support@hellosign. Nic said post the issue here so I could get notifications when it was fixed, etc, and what not.

It would appear that the node SDK function hellosign.signatureRequest.cancel(signatureRequestId) never fires/calls the .then() or .catch() promise callbacks

I attempted one just now in debug mode and my breakpoints on either were never encountered.
When I look in the dashboard the signature request still shows "out for signature" but when when I click on it I get the error: The content you requested was not found, or you do not have permission to access it.

If I do a Postman post to https://api.hellosign.com/v3/signature_request/cancel/{signatureid}
I get back no response body but the http code is 200.

In either case, the signature request does seem to get canceled and is no longer accessible to click on from the dashboard nor from the email notification the user received. However the dashboard still shows that it is "out for signature"

So, my current issues are,

  1. The HelloSign Node SDK (1.1.12) never calls/returns on the .then or .catch promise methods when canceling signature requests.
  2. The dashboard shows a status of "out for signature" rather than canceled.

Thanks.

Allow the passing of signing_options

Add signing_options to non-embedded and embedded signature request endpoints
signing_options = {"draw": true, "type": true, "upload": true, "phone": false, "default": "draw"}

Add support for Decline to Sign

The following changes have been made to the API:

  • There is a new parameter allow_decline for declining to sign signature requests
  • There is a new API status_code for declined requests
  • There is a new API variable is_declined on SignatureRequest objects
  • There is a new API variable decline_reason on Signature objects

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.