-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Box new action #18001
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Box new action #18001
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,113 @@ | ||
| import { ConfigurationError } from "@pipedream/platform"; | ||
| import app from "../../box.app.mjs"; | ||
| import utils from "../../common/utils.mjs"; | ||
|
|
||
| export default { | ||
| name: "Create Box Sign Request", | ||
| description: "Creates a signature request. This involves preparing a document for signing and sending the signature request to signers. [See the documentation](https://developer.box.com/reference/post-sign-requests/).", | ||
| key: "box-create-sign-request", | ||
| version: "0.0.1", | ||
| type: "action", | ||
| props: { | ||
| app, | ||
| signers: { | ||
| type: "string[]", | ||
| label: "Signers", | ||
| description: "Array of signers for the signature request. Each signer should be a JSON object with at least an email property. [See the documentation](https://developer.box.com/reference/post-sign-requests/#param-signers) for more information. Example: `{\"email\": \"[email protected]\", \"role\": \"signer\"}`", | ||
| }, | ||
| name: { | ||
| type: "string", | ||
| label: "Request Name", | ||
| description: "Name of the signature request", | ||
| optional: true, | ||
| }, | ||
| parentFolder: { | ||
| propDefinition: [ | ||
| app, | ||
| "parentId", | ||
| ], | ||
| label: "Parent Folder", | ||
| description: "The destination folder to place final, signed document and signing log. Uses root folder (0) if not specified", | ||
| optional: true, | ||
| }, | ||
| emailSubject: { | ||
| type: "string", | ||
| label: "Email Subject", | ||
| description: "Subject of sign request email. If not provided, a default subject will be used", | ||
| optional: true, | ||
| }, | ||
| emailMessage: { | ||
| type: "string", | ||
| label: "Email Message", | ||
| description: "Message to include in sign request email. If not provided, a default message will be used", | ||
| optional: true, | ||
| }, | ||
| redirectUrl: { | ||
| type: "string", | ||
| label: "Redirect URL", | ||
| description: "The URI that a signer will be redirected to after signing a document", | ||
| optional: true, | ||
| }, | ||
| declinedRedirectUrl: { | ||
| type: "string", | ||
| label: "Declined Redirect URL", | ||
| description: "The URI that a signer will be redirected to after declining to sign a document", | ||
| optional: true, | ||
| }, | ||
| additionalOptions: { | ||
| type: "object", | ||
| label: "Additional Options", | ||
| description: "Additional parameters to send in the request. See the [documentation](https://developer.box.com/reference/post-sign-requests/) for all available parameters. Values will be parsed as JSON where applicable", | ||
| optional: true, | ||
| }, | ||
| }, | ||
| async run({ $ }) { | ||
| const { | ||
| signers, | ||
| name, | ||
| parentFolder, | ||
| emailSubject, | ||
| emailMessage, | ||
| redirectUrl, | ||
| declinedRedirectUrl, | ||
| additionalOptions, | ||
| } = this; | ||
|
|
||
| const parsedSigners = signers.map((signer) => { | ||
| try { | ||
| return typeof signer === "string" | ||
| ? JSON.parse(signer) | ||
| : signer; | ||
| } catch (error) { | ||
| throw new ConfigurationError(`Error parsing signer as JSON: ${error}`); | ||
| } | ||
| }); | ||
|
|
||
| const data = { | ||
| signers: parsedSigners, | ||
| name, | ||
| email_subject: emailSubject, | ||
| email_message: emailMessage, | ||
| redirect_url: redirectUrl, | ||
| declined_redirect_url: declinedRedirectUrl, | ||
| ...(additionalOptions | ||
| ? utils.parseObjectEntries(additionalOptions) | ||
| : {}), | ||
| }; | ||
|
|
||
| if (parentFolder) { | ||
| data.parent_folder = { | ||
| id: parentFolder, | ||
| type: "folder", | ||
| }; | ||
| } | ||
|
|
||
| const response = await this.app.createSignRequest({ | ||
| $, | ||
| data, | ||
| }); | ||
|
|
||
| $.export("$summary", `Successfully created Box sign request (ID: ${response.id})`); | ||
| return response; | ||
| }, | ||
| }; | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,7 +1,29 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import constants from "./constants.mjs"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { getFileStreamAndMetadata } from "@pipedream/platform"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| function optionalParseAsJSON(value) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return JSON.parse(value); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } catch (e) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return value; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export default { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| parseObjectEntries(value = {}) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const obj = typeof value === "string" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ? JSON.parse(value) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| : value; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return Object.fromEntries( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Object.entries(obj).map(([ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| key, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| value, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ]) => [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| key, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| optionalParseAsJSON(value), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ]), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+13
to
+26
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Guard against invalid top-level JSON in parseObjectEntries. If -import constants from "./constants.mjs";
-import { getFileStreamAndMetadata } from "@pipedream/platform";
+import constants from "./constants.mjs";
+import { getFileStreamAndMetadata, ConfigurationError } from "@pipedream/platform";
@@
export default {
- parseObjectEntries(value = {}) {
- const obj = typeof value === "string"
- ? JSON.parse(value)
- : value;
+ parseObjectEntries(value = {}) {
+ let obj = value;
+ if (typeof value === "string") {
+ try {
+ obj = JSON.parse(value);
+ } catch (e) {
+ throw new ConfigurationError("Invalid JSON for Additional Options. Provide a valid JSON object.");
+ }
+ }
return Object.fromEntries(
Object.entries(obj).map(([
key,
value,
]) => [
key,
optionalParseAsJSON(value),
]),
);
},📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| async getFileData(filePath) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| stream, metadata, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing required
source_files— API will 400 without it.Box’s POST /sign_requests requires
source_files(or an alternative likeprefill_template/draft_id). The action doesn’t expose this, relying onadditionalOptions, which is easy to miss.Add a dedicated, required prop for source files and map to the payload:
@@ props: { app, signers: { type: "string[]", label: "Signers", description: "Array of signers for the signature request. Each signer should be a JSON object with at least an email property. [See the documentation](https://developer.box.com/reference/post-sign-requests/#param-signers) for more information. Example: `{\"email\": \"[email protected]\", \"role\": \"signer\"}`", }, + sourceFiles: { + type: "string[]", + label: "Source Files", + description: "Array of Box file IDs to include in the sign request.", + }, @@ async run({ $ }) { const { signers, + sourceFiles, name, parentFolder, emailSubject, emailMessage, redirectUrl, declinedRedirectUrl, additionalOptions, } = this; @@ - const data = { + if (!Array.isArray(sourceFiles) || sourceFiles.length === 0) { + throw new ConfigurationError("At least one source file is required (sourceFiles)."); + } + + const data = { signers: parsedSigners, + source_files: sourceFiles.map((id) => ({ + id, + type: "file", + })), name, email_subject: emailSubject, email_message: emailMessage, redirect_url: redirectUrl, declined_redirect_url: declinedRedirectUrl, ...(additionalOptions ? utils.parseObjectEntries(additionalOptions) : {}), };If you prefer to keep
additionalOptionsas the only path, at minimum validate thatadditionalOptions.source_filesexists and is non-empty, and throw a clearConfigurationErrorotherwise.📝 Committable suggestion
🤖 Prompt for AI Agents