diff --git a/docs/Bulk actions/sign-requests/sign-requests-create.csv b/docs/Bulk actions/sign-requests/sign-requests-create.csv new file mode 100644 index 00000000..c5a49b80 --- /dev/null +++ b/docs/Bulk actions/sign-requests/sign-requests-create.csv @@ -0,0 +1,3 @@ +signer,source-files,parent-folder +"email=userA@email.com,role=approver","2468135790,2468135791","1357902468" +"email=userB@email.com,role=signer","2468135799","1357902460" \ No newline at end of file diff --git a/docs/Bulk actions/sign-requests/sign-requests.md b/docs/Bulk actions/sign-requests/sign-requests.md new file mode 100644 index 00000000..aababe19 --- /dev/null +++ b/docs/Bulk actions/sign-requests/sign-requests.md @@ -0,0 +1,67 @@ +`box sign-requests` +=========== + +Manage sign requests + +* [`box sign-requests:create`](#box-sign-requests:create) + + +## `box sign-requests:create` + +Create sign request + +``` +USAGE + $ box sign-requests:create + +OPTIONS + -h, --help Show CLI help + -q, --quiet Suppress any non-error output to stderr + -s, --save Save report to default reports folder on disk + -t, --token=token Provide a token to perform this call + -v, --verbose Show verbose output, which can be helpful for debugging + -y, --yes Automatically respond yes to all confirmation prompts + --as-user=as-user Provide an ID for a user + --bulk-file-path=bulk-file-path File path to bulk .csv or .json objects + --csv Output formatted CSV + --days-valid=days-valid Number of days after which this request will automatically expire if not completed + --declined-redirect-url=declined-redirect-url The URL that a signer will be redirected to after declining to sign a document. Defining this URL overrides the default redirect URL for all signers. + --[no-]document-preparation-needed Indicates if the sender should receive a `prepare_url` in the response to complete document preparation via UI. + + --email-message=email-message Message to include in sign request email. The field is cleaned through sanitization of specific characters. However, some html tags are allowed. Links included in the message are also converted to hyperlinks in the email. The message + may contain the following html tags including `a`, `abbr`, `acronym`, `b`, `blockquote`, `code`, `em`, `i`, `ul`, `li`, `ol`, and `strong`. Be aware that when the text to html ratio is too high, the email may end up in spam filters. + Custom styles on these tags are not allowed. If this field is not passed, a default message will be used. + + --email-subject=email-subject Subject of sign request email. This is cleaned by sign request. If this field is not passed, a default subject will be used. + + --external-id=external-id This can be used to reference an ID in an external system that the sign request is related to. + + --fields=fields Comma separated list of fields to show + + --json Output formatted JSON + + --no-color Turn off colors for logging + + --parent-folder=parent-folder (required) The destination folder to place final, signed document and signing log + + --prefill-tag=prefill-tag Prefills a sign related tag in the content. Pass in a comma-separated dictionary of fields: id,text,checkbox,date. Can be added multiple times. + + --redirect-url=redirect-url The URL that a signer will be redirected to after signing a document. Defining this URL overrides the default redirect URL for all signers. If no declined redirect URL is specified, this URL will be used for decline actions as well. + + --[no-]reminders-enabled Reminds signers to sign a document on day 3, 8, 13 and 18. Reminders are only sent to outstanding signers. + + --save-to-file-path=save-to-file-path Override default file path to save report + + --signer=signer (required) A signer for the sign request. 35 is the max number of signers permitted. Can be added multiple times. Allowed (recommended) properties: + email,role,is-in-person,order,embed-url-external-user-id,redirect-url,declined-redirect-url,group-id but snake case is also supported for: is_in_person,order,embed_url_external_user_id,redirect_url,declined_redirect_url,group_id + + --source-files=source-files (required) Comma separated list of files to create a signing document from. This is currently limited to 10 files, e.g. 12345 + + --[no-]text-signatures-enabled Disables the usage of signatures generated by typing (text) + +EXAMPLE + box sign-requests:create --bulk-file-path path/to/csv/create-sign-requests.csv +``` + +- _See documentation [sign-requests.md](https://github.com/box/boxcli/blob/main/docs/sign-requests.md#box-sign-requestscreate)_ +- _See example: [sign-requests-create.csv](sign-requests-create.csv)_ diff --git a/src/box-command.js b/src/box-command.js index 6c84d885..6b5df8b4 100644 --- a/src/box-command.js +++ b/src/box-command.js @@ -282,8 +282,8 @@ class BoxCommand extends Command { * @returns {void} */ async bulkOutputRun() { - const allPossibleArgs = this.constructor.args.map((arg) => arg.name); - const allPossibleFlags = Object.keys(this.constructor.flags); + const allPossibleArgs = (this.constructor.args || []).map((arg) => arg.name); + const allPossibleFlags = Object.keys(this.constructor.flags || []); // Map from matchKey (arg/flag name in all lower-case characters) => {type, fieldKey} let fieldMapping = Object.assign( {}, @@ -649,12 +649,17 @@ class BoxCommand extends Command { * @returns {void} */ disableRequiredArgsAndFlags() { - Object.keys(this.constructor.args).forEach((key) => { - this.constructor.args[key].required = false; - }); - Object.keys(this.constructor.flags).forEach((key) => { - this.constructor.flags[key].required = false; - }); + if (this.constructor.args !== undefined) { + Object.keys(this.constructor.args).forEach((key) => { + this.constructor.args[key].required = false; + }); + } + + if (this.constructor.flags !== undefined) { + Object.keys(this.constructor.flags).forEach((key) => { + this.constructor.flags[key].required = false; + }); + } } /** diff --git a/test/commands/bulk.test.js b/test/commands/bulk.test.js index 62dddabc..c8a9e8ff 100644 --- a/test/commands/bulk.test.js +++ b/test/commands/bulk.test.js @@ -35,7 +35,9 @@ describe('Bulk', () => { multipleFlagValuesInputFilePath = path.join(__dirname, '../fixtures/bulk/input_multiple_same_flag.csv'), emptyStringInputFilePath = path.join(__dirname, '../fixtures/bulk/input_with_empty_string.csv'), metadataUpdateInputFilePath = path.join(__dirname, '../fixtures/bulk/input_metadata_update.csv'), - tableOutput = getFixture('bulk/post_collaborations_table.txt'); + signRequestCreateInputFilePath = path.join(__dirname, '../fixtures/bulk/input_sign_request_create.csv'), + tableOutput = getFixture('bulk/post_collaborations_table.txt'), + createSignRequestFixture = getFixture('bulk/post_sign_requests'); let addCollaborationBody1 = { item: { @@ -600,6 +602,25 @@ describe('Bulk', () => { expectedOutput.push(JSON.parse(terminateSessionFixture)); assert.deepEqual(JSON.parse(ctx.stdout), expectedOutput); }); + + test + .nock(TEST_API_ROOT, api => api + .post('/2.0/sign_requests') + .reply(200, createSignRequestFixture) + ) + .stdout() + .stderr() + .command([ + 'sign-requests:create', + `--bulk-file-path=${signRequestCreateInputFilePath}`, + '--json', + '--token=test' + ]) + .it('should correctly process commands that do not contain argument parameters', ctx => { + let expectedOutput = []; + expectedOutput.push(JSON.parse(createSignRequestFixture)); + assert.deepEqual(JSON.parse(ctx.stdout), expectedOutput); + }); }); describe('JSON Input', () => { diff --git a/test/fixtures/bulk/input_sign_request_create.csv b/test/fixtures/bulk/input_sign_request_create.csv new file mode 100644 index 00000000..981a6da4 --- /dev/null +++ b/test/fixtures/bulk/input_sign_request_create.csv @@ -0,0 +1,2 @@ +signer,source-files,parent-folder +"email=userA@email.com,role=approver","2468135790,2468135791","1357902468" diff --git a/test/fixtures/bulk/post_sign_requests.json b/test/fixtures/bulk/post_sign_requests.json new file mode 100644 index 00000000..7760e212 --- /dev/null +++ b/test/fixtures/bulk/post_sign_requests.json @@ -0,0 +1,127 @@ +{ + "is_document_preparation_needed": false, + "redirect_url": null, + "declined_redirect_url": null, + "are_text_signatures_enabled": true, + "signature_color": null, + "is_phone_verification_required_to_view": false, + "email_subject": null, + "email_message": null, + "are_reminders_enabled": false, + "signers": [ + { + "email": "user@email.com", + "role": "final_copy_reader", + "is_in_person": false, + "order": 0, + "verification_phone_number": null, + "embed_url_external_user_id": null, + "redirect_url": null, + "declined_redirect_url": null, + "login_required": false, + "has_viewed_document": false, + "signer_decision": null, + "signer_group_id": null, + "inputs": [], + "embed_url": null, + "iframeable_embed_url": null, + "suppress_notifications": false + }, + { + "email": "userA@email.com", + "role": "approver", + "is_in_person": false, + "order": 0, + "verification_phone_number": null, + "embed_url_external_user_id": null, + "redirect_url": null, + "declined_redirect_url": null, + "login_required": false, + "has_viewed_document": false, + "signer_decision": null, + "signer_group_id": null, + "inputs": [], + "embed_url": null, + "iframeable_embed_url": null, + "suppress_notifications": false + } + ], + "id": "ce25caf8-54e5-4860-8006-f9f6886551c5", + "prefill_tags": [], + "days_valid": null, + "prepare_url": null, + "source_files": [ + { + "id": "2468135790", + "etag": "0", + "type": "file", + "sequence_id": "0", + "name": "report1.xlsx", + "sha1": "2150fa7e04d87e776ee8fc04fc098b6d977c0ca5", + "file_version": { + "id": "1702075180104", + "type": "file_version", + "sha1": "2150fa7e04d87e776ee8fc04fc098b6d977c0ca5" + } + }, + { + "id": "2468135791", + "etag": "0", + "type": "file", + "sequence_id": "0", + "name": "report2.xlsx", + "sha1": "f75575f090598f46fbde405e3ea4424c1e7fd6c8", + "file_version": { + "id": "1702075180105", + "type": "file_version", + "sha1": "f75575f090598f46fbde405e3ea4424c1e7fd6c8" + } + } + ], + "parent_folder": { + "id": "1357902468", + "etag": "0", + "type": "folder", + "sequence_id": "0", + "name": "myReports" + }, + "name": "sign1", + "external_id": null, + "type": "sign-request", + "signing_log": null, + "status": "converting", + "sign_files": { + "files": [ + { + "id": "4568135987", + "etag": "0", + "type": "file", + "sequence_id": "0", + "name": "report1.xlsx", + "sha1": "2150fa7e04d87e776ee8fc04fc098b6d977c0ca5", + "file_version": { + "id": "1702075180104", + "type": "file_version", + "sha1": "2150fa7e04d87e776ee8fc04fc098b6d977c0ca5" + } + }, + { + "id": "4568135988", + "etag": "0", + "type": "file", + "sequence_id": "0", + "name": "report2.xlsx", + "sha1": "f75575f090598f46fbde405e3ea4424c1e7fd6c8", + "file_version": { + "id": "1702075180105", + "type": "file_version", + "sha1": "f75575f090598f46fbde405e3ea4424c1e7fd6c8" + } + } + ], + "is_ready_for_download": true + }, + "auto_expire_at": null, + "template_id": null, + "external_system_name": null +}