From a0a90cba0496651e90380e9dd4040eabbb39c50f Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Tue, 17 Dec 2024 19:35:15 -0300 Subject: [PATCH 1/9] boldsign init --- .../send-document-template.mjs | 186 +++++++++ components/boldsign/boldsign.app.mjs | 361 +++++++++++++++++- components/boldsign/package.json | 2 +- .../new-document-completed.mjs | 147 +++++++ .../new-document-declined.mjs | 163 ++++++++ .../new-document-sent/new-document-sent.mjs | 129 +++++++ 6 files changed, 985 insertions(+), 3 deletions(-) create mode 100644 components/boldsign/actions/send-document-template/send-document-template.mjs create mode 100644 components/boldsign/sources/new-document-completed/new-document-completed.mjs create mode 100644 components/boldsign/sources/new-document-declined/new-document-declined.mjs create mode 100644 components/boldsign/sources/new-document-sent/new-document-sent.mjs diff --git a/components/boldsign/actions/send-document-template/send-document-template.mjs b/components/boldsign/actions/send-document-template/send-document-template.mjs new file mode 100644 index 0000000000000..5c8274f6268aa --- /dev/null +++ b/components/boldsign/actions/send-document-template/send-document-template.mjs @@ -0,0 +1,186 @@ +import boldsign from "../../boldsign.app.mjs"; +import { axios } from "@pipedream/platform"; + +export default { + key: "boldsign-send-document-template", + name: "Send Document Using Template", + description: "Send documents for e-signature using a BoldSign template. [See the documentation](https://developers.boldsign.com/documents/send-document-from-template/?region=us)", + version: "0.0.{{ts}}", + type: "action", + props: { + boldsign, + templateId: { + propDefinition: [ + boldsign, + "templateId", + ], + }, + title: { + propDefinition: [ + boldsign, + "title", + ], + }, + message: { + propDefinition: [ + boldsign, + "message", + ], + }, + roles: { + propDefinition: [ + boldsign, + "roles", + ], + }, + brandId: { + propDefinition: [ + boldsign, + "brandId", + ], + }, + labels: { + propDefinition: [ + boldsign, + "labels", + ], + }, + disableEmails: { + propDefinition: [ + boldsign, + "disableEmails", + ], + }, + disableSMS: { + propDefinition: [ + boldsign, + "disableSMS", + ], + }, + hitDocumentId: { + propDefinition: [ + boldsign, + "hitDocumentId", + ], + }, + enableAutoReminder: { + propDefinition: [ + boldsign, + "enableAutoReminder", + ], + }, + reminderDays: { + propDefinition: [ + boldsign, + "reminderDays", + ], + }, + reminderCount: { + propDefinition: [ + boldsign, + "reminderCount", + ], + }, + cc: { + propDefinition: [ + boldsign, + "cc", + ], + }, + expiryDays: { + propDefinition: [ + boldsign, + "expiryDays", + ], + }, + enablePrintAndSign: { + propDefinition: [ + boldsign, + "enablePrintAndSign", + ], + }, + enableReassign: { + propDefinition: [ + boldsign, + "enableReassign", + ], + }, + enableSigningOrder: { + propDefinition: [ + boldsign, + "enableSigningOrder", + ], + }, + disableExpiryAlert: { + propDefinition: [ + boldsign, + "disableExpiryAlert", + ], + }, + documentInfo: { + propDefinition: [ + boldsign, + "documentInfo", + ], + }, + onBehalfOf: { + propDefinition: [ + boldsign, + "onBehalfOf", + ], + }, + roleRemovalIndices: { + propDefinition: [ + boldsign, + "roleRemovalIndices", + ], + }, + documentDownloadOption: { + propDefinition: [ + boldsign, + "documentDownloadOption", + ], + }, + formGroups: { + propDefinition: [ + boldsign, + "formGroups", + ], + }, + files: { + propDefinition: [ + boldsign, + "files", + ], + }, + fileUrls: { + propDefinition: [ + boldsign, + "fileUrls", + ], + }, + recipientNotificationSettings: { + propDefinition: [ + boldsign, + "recipientNotificationSettings", + ], + }, + removeFormfields: { + propDefinition: [ + boldsign, + "removeFormfields", + ], + }, + enableAuditTrailLocalization: { + propDefinition: [ + boldsign, + "enableAuditTrailLocalization", + ], + }, + }, + async run({ $ }) { + const response = await this.boldsign.sendDocument(); + $.export("$summary", `Document sent successfully using template ${this.templateId}`); + return response; + }, +}; diff --git a/components/boldsign/boldsign.app.mjs b/components/boldsign/boldsign.app.mjs index e3c1b11cb2149..8ab2b97c04a9b 100644 --- a/components/boldsign/boldsign.app.mjs +++ b/components/boldsign/boldsign.app.mjs @@ -1,11 +1,368 @@ +import { axios } from "@pipedream/platform"; + export default { type: "app", app: "boldsign", - propDefinitions: {}, + version: "0.0.{{ts}}", + propDefinitions: { + // Required Props + templateId: { + type: "string", + label: "Template ID", + description: "The ID of the BoldSign template to use.", + }, + // Optional Props + title: { + type: "string", + label: "Title", + description: "The title of the document.", + optional: true, + }, + message: { + type: "string", + label: "Message", + description: "A message to include with the document.", + optional: true, + }, + roles: { + type: "string[]", + label: "Roles", + description: "Roles assigned to the signers.", + optional: true, + }, + brandId: { + type: "string", + label: "Brand ID", + description: "The brand ID for customizing the document.", + optional: true, + async options() { + const brands = await this.listBrands(); + return brands.map((brand) => ({ + label: brand.name, + value: brand.id, + })); + }, + }, + labels: { + type: "string[]", + label: "Labels", + description: "Labels for categorizing documents.", + optional: true, + }, + disableEmails: { + type: "boolean", + label: "Disable Emails", + description: "Disable sending emails to recipients.", + optional: true, + }, + disableSMS: { + type: "boolean", + label: "Disable SMS", + description: "Disable sending SMS to recipients.", + optional: true, + }, + hitDocumentId: { + type: "string", + label: "Hit Document ID", + description: "Hit Document ID.", + optional: true, + }, + enableAutoReminder: { + type: "boolean", + label: "Enable Auto Reminder", + description: "Enable automatic reminders.", + optional: true, + }, + reminderDays: { + type: "integer", + label: "Reminder Days", + description: "Number of days between reminders.", + optional: true, + }, + reminderCount: { + type: "integer", + label: "Reminder Count", + description: "Number of reminder attempts.", + optional: true, + }, + cc: { + type: "string[]", + label: "CC", + description: "CC recipients for the document.", + optional: true, + }, + expiryDays: { + type: "integer", + label: "Expiry Days", + description: "Number of days before document expires.", + optional: true, + }, + enablePrintAndSign: { + type: "boolean", + label: "Enable Print and Sign", + description: "Allow signers to print and sign document.", + optional: true, + }, + enableReassign: { + type: "boolean", + label: "Enable Reassign", + description: "Allow signers to reassign the document.", + optional: true, + }, + enableSigningOrder: { + type: "boolean", + label: "Enable Signing Order", + description: "Enable signing order for the document.", + optional: true, + }, + disableExpiryAlert: { + type: "boolean", + label: "Disable Expiry Alert", + description: "Disable alerts before document expiry.", + optional: true, + }, + documentInfo: { + type: "string[]", + label: "Document Info", + description: "Custom information fields for the document.", + optional: true, + }, + onBehalfOf: { + type: "string", + label: "On Behalf Of", + description: "Send document on behalf of another user.", + optional: true, + }, + roleRemovalIndices: { + type: "integer[]", + label: "Role Removal Indices", + description: "Indices of roles to remove from the template.", + optional: true, + }, + documentDownloadOption: { + type: "string", + label: "Document Download Option", + description: "Option for document download configuration.", + optional: true, + }, + formGroups: { + type: "string[]", + label: "Form Groups", + description: "Groups of form fields in the document.", + optional: true, + }, + files: { + type: "string[]", + label: "Files", + description: "Files to include in the document.", + optional: true, + }, + fileUrls: { + type: "string[]", + label: "File URLs", + description: "URLs of files to include in the document.", + optional: true, + }, + recipientNotificationSettings: { + type: "string", + label: "Recipient Notification Settings", + description: "Settings for recipient notifications.", + optional: true, + }, + removeFormfields: { + type: "boolean", + label: "Remove Formfields", + description: "Remove existing form fields from the document.", + optional: true, + }, + enableAuditTrailLocalization: { + type: "boolean", + label: "Enable Audit Trail Localization", + description: "Enable localization for audit trails.", + optional: true, + }, + // Event Props + sentBy: { + type: "string", + label: "Sent By", + description: "The sender of the document.", + optional: true, + async options() { + const sentByOptions = await this.listSenderIdentities(); + return sentByOptions.map((item) => ({ + label: item.name, + value: item.id, + })); + }, + }, + recipients: { + type: "string[]", + label: "Recipients", + description: "Recipients of the document.", + optional: true, + }, + searchKey: { + type: "string", + label: "Search Key", + description: "Search key for documents.", + optional: true, + }, + brandIds: { + type: "string[]", + label: "Brand IDs", + description: "Brand IDs associated with the document.", + optional: true, + async options() { + const brandIdsOptions = await this.listBrands(); + return brandIdsOptions.map((item) => ({ + label: item.name, + value: item.id, + })); + }, + }, + status: { + type: "string", + label: "Status", + description: "Status of the document.", + optional: false, + }, + transmitType: { + type: "string", + label: "Transmit Type", + description: "Type of transmission for the document.", + optional: false, + }, + }, methods: { - // this.$auth contains connected account data + // Log authentication keys authKeys() { console.log(Object.keys(this.$auth)); }, + // Base URL for BoldSign API + _baseUrl() { + return "https://api.boldsign.com/v1"; + }, + // Generic method to make API requests + async _makeRequest(opts = {}) { + const { + $ = this, method = "GET", path = "/", headers, ...otherOpts + } = opts; + return axios($, { + ...otherOpts, + method, + url: this._baseUrl() + path, + headers: { + ...headers, + "X-API-KEY": this.$auth.api_key, + "Content-Type": "application/json;odata.metadata=minimal;odata.streaming=true", + "accept": "application/json", + }, + }); + }, + // Fetch options for 'sentBy' prop + async listSenderIdentities(opts = {}) { + return this._makeRequest({ + path: "/sender-identities/list-identities", + ...opts, + }); + }, + // Fetch options for 'brandIds' and 'brandId' props + async listBrands(opts = {}) { + return this._makeRequest({ + path: "/branding/list-brands", + ...opts, + }); + }, + // Method to send document for e-signature using a template + async sendDocument() { + const data = { + template_id: this.templateId, + title: this.title, + message: this.message, + roles: this.roles, + brandid: this.brandId, + labels: this.labels, + disableemails: this.disableEmails, + disablesms: this.disableSMS, + hitdocumentid: this.hitDocumentId, + enableautoreminder: this.enableAutoReminder, + reminderdays: this.reminderDays, + remindercount: this.reminderCount, + cc: this.cc, + expirydays: this.expiryDays, + enableprintandsign: this.enablePrintAndSign, + enablereassign: this.enableReassign, + enablesigningorder: this.enableSigningOrder, + disableexpiryalert: this.disableExpiryAlert, + documentinfo: this.documentInfo, + onbehalfof: this.onBehalfOf, + roleremovalindices: this.roleRemovalIndices, + documentdownloadoption: this.documentDownloadOption, + formgroups: this.formGroups, + files: this.files, + fileurls: this.fileUrls, + recipientnotificationsettings: this.recipientNotificationSettings, + removeformfields: this.removeFormfields, + enableaudittraillocalization: this.enableAuditTrailLocalization, + }; + + // Ensure that at least one of 'files' or 'fileUrls' is provided + if (!this.files && !this.fileUrls) { + throw new Error("At least one of 'files' or 'fileUrls' must be provided."); + } + + // Remove undefined properties + Object.keys(data).forEach( + (key) => data[key] === undefined && delete data[key], + ); + + return this._makeRequest({ + method: "POST", + path: "/template/send", + data, + params: { + templateId: this.templateId, + }, + }); + }, + // Emit event when document status changes to 'completed' + async emitDocumentCompleted() { + if (this.status === "completed") { + this.$emit("documentCompleted", { + sentBy: this.sentBy, + recipients: this.recipients, + searchKey: this.searchKey, + labels: this.labels, + brandIds: this.brandIds, + status: this.status, + }); + } + }, + // Emit event when document is sent + async emitDocumentSent() { + if (this.transmitType === "sent") { + this.$emit("documentSent", { + sentBy: this.sentBy, + recipients: this.recipients, + searchKey: this.searchKey, + labels: this.labels, + brandIds: this.brandIds, + transmitType: this.transmitType, + }); + } + }, + // Emit event when document status changes to 'declined' + async emitDocumentDeclined() { + if (this.status === "declined") { + this.$emit("documentDeclined", { + sentBy: this.sentBy, + recipients: this.recipients, + searchKey: this.searchKey, + labels: this.labels, + brandIds: this.brandIds, + status: this.status, + }); + } + }, }, }; diff --git a/components/boldsign/package.json b/components/boldsign/package.json index b69400671ddd9..2276850c6d5c3 100644 --- a/components/boldsign/package.json +++ b/components/boldsign/package.json @@ -12,4 +12,4 @@ "publishConfig": { "access": "public" } -} \ No newline at end of file +} diff --git a/components/boldsign/sources/new-document-completed/new-document-completed.mjs b/components/boldsign/sources/new-document-completed/new-document-completed.mjs new file mode 100644 index 0000000000000..0fb848fe80ff0 --- /dev/null +++ b/components/boldsign/sources/new-document-completed/new-document-completed.mjs @@ -0,0 +1,147 @@ +import { + axios, DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, +} from "@pipedream/platform"; +import boldsign from "../../boldsign.app.mjs"; + +export default { + key: "boldsign-new-document-completed", + name: "BoldSign New Document Completed", + description: "Emit a new event when a document is completed by all the signers. [See the documentation]()", + version: "0.0.{{ts}}", + type: "source", + dedupe: "unique", + props: { + boldsign, + db: "$.service.db", + timer: { + type: "$.interface.timer", + default: { + intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, + }, + }, + status: { + type: "string", + label: "Status", + description: "Status of the document.", + default: "completed", + }, + sentBy: { + propDefinition: [ + "boldsign", + "sentBy", + ], + optional: true, + }, + recipients: { + propDefinition: [ + "boldsign", + "recipients", + ], + optional: true, + }, + searchKey: { + propDefinition: [ + "boldsign", + "searchKey", + ], + optional: true, + }, + labels: { + propDefinition: [ + "boldsign", + "labels", + ], + optional: true, + }, + brandIds: { + propDefinition: [ + "boldsign", + "brandIds", + ], + optional: true, + }, + }, + methods: { + async listDocuments() { + const params = { + status: this.status, + sentby: this.sentBy, + recipients: this.recipients, + searchkey: this.searchKey, + labels: this.labels, + brandids: this.brandIds, + perpage: 50, + }; + Object.keys(params).forEach((key) => params[key] === undefined && delete params[key]); + const response = await this.boldsign._makeRequest({ + path: "/documents/list-documents", + method: "GET", + params, + }); + return response.result; + }, + getCursorKey() { + return "lastRunTs"; + }, + }, + hooks: { + async deploy() { + const documents = await this.listDocuments(); + const sortedDocuments = documents.sort((a, b) => b.activityDate - a.activityDate).slice(0, 50); + for (const document of sortedDocuments) { + this.$emit(document, { + id: document.documentId || document.activityDate, + summary: `Document Completed: ${document.messageTitle}`, + ts: document.activityDate * 1000, + }); + } + if (sortedDocuments.length > 0) { + const latestDocument = sortedDocuments[0]; + this.db.set(this.getCursorKey(), latestDocument.activityDate); + } + }, + async activate() { + // No activation logic required + }, + async deactivate() { + // No deactivation logic required + }, + }, + async run() { + const lastRunTs = (await this.db.get(this.getCursorKey())) || 0; + const params = { + status: this.status, + sentby: this.sentBy, + recipients: this.recipients, + searchkey: this.searchKey, + labels: this.labels, + brandids: this.brandIds, + since: lastRunTs, + perpage: 50, + }; + Object.keys(params).forEach((key) => params[key] === undefined && delete params[key]); + const documents = await this.boldsign._makeRequest({ + path: "/documents/list-documents", + method: "GET", + params, + }).then((response) => response.result); + + const newDocuments = documents.filter((doc) => doc.activityDate > lastRunTs); + for (const document of newDocuments) { + this.$emit(document, { + id: document.documentId || document.activityDate, + summary: `Document Completed: ${document.messageTitle}`, + ts: document.activityDate + ? document.activityDate * 1000 + : Date.now(), + }); + } + + if (newDocuments.length > 0) { + const latestDocument = newDocuments.reduce((prev, current) => (prev.activityDate > current.activityDate) + ? prev + : current); + this.db.set(this.getCursorKey(), latestDocument.activityDate); + } + }, +}; diff --git a/components/boldsign/sources/new-document-declined/new-document-declined.mjs b/components/boldsign/sources/new-document-declined/new-document-declined.mjs new file mode 100644 index 0000000000000..11aa1b1960336 --- /dev/null +++ b/components/boldsign/sources/new-document-declined/new-document-declined.mjs @@ -0,0 +1,163 @@ +import { + axios, DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, +} from "@pipedream/platform"; +import boldsign from "../../boldsign.app.mjs"; + +export default { + key: "boldsign-new-document-declined", + name: "New Document Declined", + description: "Emit new event when a document is declined by a signer. [See the documentation](https://developers.boldsign.com)", + version: "0.0.{{ts}}", + type: "source", + dedupe: "unique", + props: { + boldsign: { + type: "app", + app: "boldsign", + }, + sentby: { + propDefinition: [ + boldsign, + "sentBy", + ], + optional: true, + }, + recipients: { + propDefinition: [ + boldsign, + "recipients", + ], + optional: true, + }, + searchkey: { + propDefinition: [ + boldsign, + "searchKey", + ], + optional: true, + }, + labels: { + propDefinition: [ + boldsign, + "labels", + ], + optional: true, + }, + brandids: { + propDefinition: [ + boldsign, + "brandIds", + ], + optional: true, + }, + status: { + type: "string", + label: "Status", + description: "The status of the document. Must be 'declined'.", + default: "declined", + }, + db: "$.service.db", + timer: { + type: "$.interface.timer", + default: { + intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, + }, + }, + }, + hooks: { + async deploy() { + const params = { + status: this.status, + }; + if (this.sentby) params.sentby = this.sentby; + if (this.recipients) params.recipients = this.recipients; + if (this.searchkey) params.searchkey = this.searchkey; + if (this.labels) params.labels = this.labels; + if (this.brandids) params.brandids = this.brandids; + + let page = 1; + const perPage = 50; + let emitted = 0; + + while (emitted < 50) { + const documents = await this.boldsign._makeRequest({ + method: "GET", + path: "/documents/list-documents", + params: { + ...params, + page, + perpage: Math.min(perPage - emitted, 50 - emitted), + }, + }); + + const docs = documents.result; + if (!docs.length) break; + + for (const doc of docs.reverse()) { + this.$emit(doc, { + id: doc.documentId, + summary: `Document Declined: ${doc.messageTitle}`, + ts: doc.activityDate * 1000, + }); + emitted++; + if (emitted >= 50) break; + } + + if (docs.length < perPage || emitted >= 50) break; + page++; + } + }, + async activate() { + // No activation steps needed for polling source + }, + async deactivate() { + // No deactivation steps needed for polling source + }, + }, + async run() { + const lastTs = this.db.get("lastTs") ?? 0; + const params = { + status: this.status, + activityDate_gte: Math.floor(lastTs / 1000), + }; + if (this.sentby) params.sentby = this.sentby; + if (this.recipients) params.recipients = this.recipients; + if (this.searchkey) params.searchkey = this.searchkey; + if (this.labels) params.labels = this.labels; + if (this.brandids) params.brandids = this.brandids; + + let page = 1; + const perPage = 100; + let maxTs = lastTs; + + while (true) { + const documents = await this.boldsign._makeRequest({ + method: "GET", + path: "/documents/list-documents", + params: { + ...params, + page, + perpage: perPage, + }, + }); + + const docs = documents.result; + if (!docs.length) break; + + for (const doc of docs) { + const docTs = doc.activityDate * 1000; + if (docTs > maxTs) maxTs = docTs; + this.$emit(doc, { + id: doc.documentId, + summary: `Document Declined: ${doc.messageTitle}`, + ts: docTs, + }); + } + + if (docs.length < perPage) break; + page++; + } + + this.db.set("lastTs", maxTs); + }, +}; diff --git a/components/boldsign/sources/new-document-sent/new-document-sent.mjs b/components/boldsign/sources/new-document-sent/new-document-sent.mjs new file mode 100644 index 0000000000000..aa9fbbf680118 --- /dev/null +++ b/components/boldsign/sources/new-document-sent/new-document-sent.mjs @@ -0,0 +1,129 @@ +import { + axios, DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, +} from "@pipedream/platform"; +import boldsign from "../../boldsign.app.mjs"; + +export default { + key: "boldsign-new-document-sent", + name: "New Document Sent", + description: "Emit a new event when a document is sent to a signer. [See the documentation]()", + version: "0.0.{{ts}}", + type: "source", + dedupe: "unique", + props: { + boldsign: { + type: "app", + app: "boldsign", + }, + db: "$.service.db", + timer: { + type: "$.interface.timer", + default: { + intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, + }, + }, + sentBy: { + propDefinition: [ + "boldsign", + "sentBy", + ], + optional: true, + }, + recipients: { + type: "string[]", + label: "Recipients", + description: "Recipients of the document.", + optional: true, + }, + searchKey: { + type: "string", + label: "Search Key", + description: "Search key for documents.", + optional: true, + }, + labels: { + type: "string[]", + label: "Labels", + description: "Labels for categorizing documents.", + optional: true, + }, + brandIds: { + propDefinition: [ + "boldsign", + "brandIds", + ], + optional: true, + }, + }, + methods: { + getLastTimestamp() { + return this.db.get("lastTimestamp") ?? 0; + }, + setLastTimestamp(timestamp) { + this.db.set("lastTimestamp", timestamp); + }, + buildQueryParams() { + const params = { + transmitType: "sent", + perpage: 50, + sort: "activityDate", + order: "DESC", + }; + if (this.sentBy) params.sentBy = this.sentBy; + if (this.recipients && this.recipients.length > 0) + params.recipients = this.recipients.join(","); + if (this.searchKey) params.searchKey = this.searchKey; + if (this.labels && this.labels.length > 0) + params.labels = this.labels.join(","); + if (this.brandIds && this.brandIds.length > 0) + params.brandIds = this.brandIds.join(","); + return params; + }, + }, + hooks: { + async deploy() { + const params = this.buildQueryParams(); + const documents = await this.boldsign.listDocuments(params); + for (const document of documents.result) { + this.$emit(document, { + id: document.documentId, + summary: `New Document Sent: ${document.messageTitle || document.title}`, + ts: document.activityDate * 1000, + }); + if (document.activityDate > this.getLastTimestamp()) { + this.setLastTimestamp(document.activityDate); + } + } + }, + async activate() { + // No activation steps needed for polling source + }, + async deactivate() { + // No deactivation steps needed for polling source + }, + }, + async run() { + const lastTimestamp = this.getLastTimestamp(); + const params = { + ...this.buildQueryParams(), + from_ts: lastTimestamp + 1, + }; + const documents = await this.boldsign.listDocuments(params); + let newLastTimestamp = lastTimestamp; + for (const document of documents.result) { + if (document.activityDate > lastTimestamp) { + this.$emit(document, { + id: document.documentId, + summary: `New Document Sent: ${document.messageTitle || document.title}`, + ts: document.activityDate * 1000, + }); + if (document.activityDate > newLastTimestamp) { + newLastTimestamp = document.activityDate; + } + } + } + if (newLastTimestamp > lastTimestamp) { + this.setLastTimestamp(newLastTimestamp); + } + }, +}; From 3693a5600a39dd034067bb99111db371f39c202d Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Thu, 19 Dec 2024 11:58:10 -0300 Subject: [PATCH 2/9] [Components] boldsign #14976 Sources - New Document Completed - New Document Sent - New Document Declined Actions - Send Document Template --- .../send-document-template.mjs | 292 +++++++----- components/boldsign/boldsign.app.mjs | 417 +++++------------- components/boldsign/common/constants.mjs | 4 + components/boldsign/common/utils.mjs | 31 ++ components/boldsign/package.json | 5 +- components/boldsign/sources/common/base.mjs | 104 +++++ .../new-document-completed.mjs | 152 +------ .../new-document-completed/test-event.mjs | 47 ++ .../new-document-declined.mjs | 166 +------ .../new-document-declined/test-event.mjs | 47 ++ .../new-document-sent/new-document-sent.mjs | 131 +----- .../sources/new-document-sent/test-event.mjs | 47 ++ 12 files changed, 626 insertions(+), 817 deletions(-) create mode 100644 components/boldsign/common/constants.mjs create mode 100644 components/boldsign/common/utils.mjs create mode 100644 components/boldsign/sources/common/base.mjs create mode 100644 components/boldsign/sources/new-document-completed/test-event.mjs create mode 100644 components/boldsign/sources/new-document-declined/test-event.mjs create mode 100644 components/boldsign/sources/new-document-sent/test-event.mjs diff --git a/components/boldsign/actions/send-document-template/send-document-template.mjs b/components/boldsign/actions/send-document-template/send-document-template.mjs index 5c8274f6268aa..2e45cb4939fce 100644 --- a/components/boldsign/actions/send-document-template/send-document-template.mjs +++ b/components/boldsign/actions/send-document-template/send-document-template.mjs @@ -1,11 +1,17 @@ +import { ConfigurationError } from "@pipedream/platform"; +import fs from "fs"; import boldsign from "../../boldsign.app.mjs"; -import { axios } from "@pipedream/platform"; +import { + checkTmp, + parseObject, +} from "../../common/utils.mjs"; +import { DOCUMENT_DOWNLOAD_OPTIONS } from "./common/constants.mjs"; export default { key: "boldsign-send-document-template", name: "Send Document Using Template", description: "Send documents for e-signature using a BoldSign template. [See the documentation](https://developers.boldsign.com/documents/send-document-from-template/?region=us)", - version: "0.0.{{ts}}", + version: "0.0.1", type: "action", props: { boldsign, @@ -16,171 +22,249 @@ export default { ], }, title: { - propDefinition: [ - boldsign, - "title", - ], + type: "string", + label: "Title", + description: "The title of the document.", + optional: true, }, message: { - propDefinition: [ - boldsign, - "message", - ], + type: "string", + label: "Message", + description: "A message to include with the document.", + optional: true, }, roles: { - propDefinition: [ - boldsign, - "roles", - ], + type: "string[]", + label: "Roles", + description: "Roles assigned to the signers. [See the documentation](https://developers.boldsign.com/documents/send-document-from-template) for further information.", }, brandId: { propDefinition: [ boldsign, "brandId", ], + optional: true, }, labels: { propDefinition: [ boldsign, "labels", ], + optional: true, }, disableEmails: { - propDefinition: [ - boldsign, - "disableEmails", - ], + type: "boolean", + label: "Disable Emails", + description: "Disable sending emails to recipients.", + optional: true, }, disableSMS: { - propDefinition: [ - boldsign, - "disableSMS", - ], + type: "boolean", + label: "Disable SMS", + description: "Disable sending SMS to recipients.", + optional: true, }, - hitDocumentId: { - propDefinition: [ - boldsign, - "hitDocumentId", - ], + hideDocumentId: { + type: "boolean", + label: "Hide Document ID", + description: "Decides whether the document ID should be hidden or not.", + optional: true, }, enableAutoReminder: { - propDefinition: [ - boldsign, - "enableAutoReminder", - ], + type: "boolean", + label: "Enable Auto Reminder", + description: "Enable automatic reminders.", + reloadProps: true, + optional: true, }, reminderDays: { - propDefinition: [ - boldsign, - "reminderDays", - ], + type: "integer", + label: "Reminder Days", + description: "Number of days between reminders.", + hidden: true, + optional: true, }, reminderCount: { - propDefinition: [ - boldsign, - "reminderCount", - ], + type: "integer", + label: "Reminder Count", + description: "Number of reminder attempts.", + hidden: true, + optional: true, }, cc: { propDefinition: [ boldsign, "cc", ], + optional: true, }, expiryDays: { - propDefinition: [ - boldsign, - "expiryDays", - ], + type: "integer", + label: "Expiry Days", + description: "Number of days before document expires.", + optional: true, }, enablePrintAndSign: { - propDefinition: [ - boldsign, - "enablePrintAndSign", - ], + type: "boolean", + label: "Enable Print and Sign", + description: "Allow signers to print and sign document.", + optional: true, }, enableReassign: { - propDefinition: [ - boldsign, - "enableReassign", - ], + type: "boolean", + label: "Enable Reassign", + description: "Allow signers to reassign the document.", + optional: true, }, enableSigningOrder: { - propDefinition: [ - boldsign, - "enableSigningOrder", - ], + type: "boolean", + label: "Enable Signing Order", + description: "Enable signing order for the document.", + optional: true, }, disableExpiryAlert: { - propDefinition: [ - boldsign, - "disableExpiryAlert", - ], + type: "boolean", + label: "Disable Expiry Alert", + description: "Disable alerts before document expiry.", + optional: true, }, documentInfo: { - propDefinition: [ - boldsign, - "documentInfo", - ], - }, - onBehalfOf: { - propDefinition: [ - boldsign, - "onBehalfOf", - ], + type: "string[]", + label: "Document Info", + description: "Custom information fields for the document. [See the documentation](https://developers.boldsign.com/documents/send-document-from-template) for further information.", + optional: true, }, roleRemovalIndices: { - propDefinition: [ - boldsign, - "roleRemovalIndices", - ], + type: "integer[]", + label: "Role Removal Indices", + description: "Removes the roles present in the template with their indices given in this property.", + optional: true, }, documentDownloadOption: { - propDefinition: [ - boldsign, - "documentDownloadOption", - ], + type: "string", + label: "Document Download Option", + description: "Option for document download configuration.", + options: DOCUMENT_DOWNLOAD_OPTIONS, + optional: true, }, formGroups: { - propDefinition: [ - boldsign, - "formGroups", - ], + type: "string[]", + label: "Form Groups", + description: "Manages the rules and configuration of grouped form fields. [See the documentation](https://developers.boldsign.com/documents/send-document-from-template) for further information.", + optional: true, }, files: { - propDefinition: [ - boldsign, - "files", - ], + type: "string[]", + label: "Files", + description: "Files to include in the document.", + optional: true, }, fileUrls: { - propDefinition: [ - boldsign, - "fileUrls", - ], + type: "string[]", + label: "File URLs", + description: "URLs of files to include in the document.", + optional: true, }, recipientNotificationSettings: { - propDefinition: [ - boldsign, - "recipientNotificationSettings", - ], + type: "object", + label: "Recipient Notification Settings", + description: "Settings for recipient notifications. [See the documentation](https://developers.boldsign.com/documents/send-document-from-template) for further information.", + optional: true, }, removeFormfields: { - propDefinition: [ - boldsign, - "removeFormfields", - ], + type: "string[]", + label: "Remove Formfields", + description: "The removeFormFields property in API allows you to exclude specific form fields from a document before sending it. You provide a string array with the IDs of the existing form fields you want to remove. One or more values can be specified.", + optional: true, }, enableAuditTrailLocalization: { - propDefinition: [ - boldsign, - "enableAuditTrailLocalization", - ], + type: "boolean", + label: "Enable Audit Trail Localization", + description: "Enable localization for audit trail based on the signer's language. If null is provided, the value will be inherited from the Business Profile settings. Only one additional language can be specified in the signer's languages besides English.", + optional: true, }, }, + async additionalProps(props) { + props.reminderDays.hidden = !this.enableAutoReminder; + props.reminderCount.hidden = !this.enableAutoReminder; + return {}; + }, async run({ $ }) { - const response = await this.boldsign.sendDocument(); - $.export("$summary", `Document sent successfully using template ${this.templateId}`); - return response; + try { + const files = []; + if (this.files) { + for (const file of parseObject(this.files)) { + const filePath = fs.readFileSync(checkTmp(file), "base64"); + files.push(`data:application/${file.substr(file.length - 3)};base64,${filePath}`); + } + } + + const additionalData = {}; + if (this.enableAutoReminder) { + additionalData.reminderSettings = { + enableAutoReminder: this.enableAutoReminder, + reminderDays: this.reminderDays, + reminderCount: this.reminderCount, + }; + } + + const response = await this.boldsign.sendDocument({ + $, + headers: { + "Content-Type": "application/json;odata.metadata=minimal;odata.streaming=true", + }, + params: { + templateId: this.templateId, + }, + data: { + title: this.title, + message: this.message, + roles: parseObject(this.roles), + brandId: this.brandId, + labels: parseObject(this.labels), + disableEmails: this.disableEmails, + disableSMS: this.disableSMS, + hideDocumentId: this.hideDocumentId, + reminderSettings: { + enableAutoReminder: this.enableAutoReminder, + reminderDays: this.reminderDays, + reminderCount: this.reminderCount, + }, + cc: this.cc ?? parseObject(this.cc)?.map((item) => ({ + emailAddress: item, + })), + expiryDays: this.expiryDays, + enablePrintAndSign: this.enablePrintAndSign, + enableReassign: this.enableReassign, + enableSigningOrder: this.enableSigningOrder, + disableExpiryAlert: this.disableExpiryAlert, + documentInfo: parseObject(this.documentInfo), + roleRemovalIndices: parseObject(this.roleRemovalIndices), + documentDownloadOption: this.documentDownloadOption, + formGroups: parseObject(this.formGroups), + files, + fileUrls: parseObject(this.fileUrls), + recipientNotificationSettings: parseObject(this.recipientNotificationSettings), + removeFormfields: parseObject(this.removeFormfields), + enableAuditTrailLocalization: this.enableAuditTrailLocalization, + ...additionalData, + }, + }); + $.export("$summary", `Document sent successfully using template ${this.templateId}`); + return response; + } catch ({ message }) { + const parsedMessage = JSON.parse(message); + let errorMessage = ""; + if (parsedMessage.error) errorMessage = parsedMessage.error; + if (parsedMessage.errors) { + Object.entries(parsedMessage.errors).map(([ + , + value, + ]) => { + errorMessage += `- ${value[0]}\n`; + }); + } + throw new ConfigurationError(errorMessage); + } }, }; diff --git a/components/boldsign/boldsign.app.mjs b/components/boldsign/boldsign.app.mjs index 8ab2b97c04a9b..7259dc2ef3fea 100644 --- a/components/boldsign/boldsign.app.mjs +++ b/components/boldsign/boldsign.app.mjs @@ -3,43 +3,37 @@ import { axios } from "@pipedream/platform"; export default { type: "app", app: "boldsign", - version: "0.0.{{ts}}", propDefinitions: { - // Required Props templateId: { type: "string", label: "Template ID", description: "The ID of the BoldSign template to use.", - }, - // Optional Props - title: { - type: "string", - label: "Title", - description: "The title of the document.", - optional: true, - }, - message: { - type: "string", - label: "Message", - description: "A message to include with the document.", - optional: true, - }, - roles: { - type: "string[]", - label: "Roles", - description: "Roles assigned to the signers.", - optional: true, + async options({ page }) { + const { result } = await this.listTemplates({ + params: { + page: page + 1, + }, + }); + + return result.map(({ + documentId: value, templateName: label, + }) => ({ + label, + value, + })); + }, }, brandId: { type: "string", label: "Brand ID", description: "The brand ID for customizing the document.", - optional: true, async options() { - const brands = await this.listBrands(); - return brands.map((brand) => ({ - label: brand.name, - value: brand.id, + const { result } = await this.listBrands(); + return result.map(({ + brandId: value, brandName: label, + }) => ({ + label, + value, })); }, }, @@ -47,322 +41,127 @@ export default { type: "string[]", label: "Labels", description: "Labels for categorizing documents.", - optional: true, - }, - disableEmails: { - type: "boolean", - label: "Disable Emails", - description: "Disable sending emails to recipients.", - optional: true, - }, - disableSMS: { - type: "boolean", - label: "Disable SMS", - description: "Disable sending SMS to recipients.", - optional: true, - }, - hitDocumentId: { - type: "string", - label: "Hit Document ID", - description: "Hit Document ID.", - optional: true, - }, - enableAutoReminder: { - type: "boolean", - label: "Enable Auto Reminder", - description: "Enable automatic reminders.", - optional: true, - }, - reminderDays: { - type: "integer", - label: "Reminder Days", - description: "Number of days between reminders.", - optional: true, - }, - reminderCount: { - type: "integer", - label: "Reminder Count", - description: "Number of reminder attempts.", - optional: true, }, cc: { type: "string[]", label: "CC", - description: "CC recipients for the document.", - optional: true, - }, - expiryDays: { - type: "integer", - label: "Expiry Days", - description: "Number of days before document expires.", - optional: true, - }, - enablePrintAndSign: { - type: "boolean", - label: "Enable Print and Sign", - description: "Allow signers to print and sign document.", - optional: true, - }, - enableReassign: { - type: "boolean", - label: "Enable Reassign", - description: "Allow signers to reassign the document.", - optional: true, - }, - enableSigningOrder: { - type: "boolean", - label: "Enable Signing Order", - description: "Enable signing order for the document.", - optional: true, - }, - disableExpiryAlert: { - type: "boolean", - label: "Disable Expiry Alert", - description: "Disable alerts before document expiry.", - optional: true, - }, - documentInfo: { - type: "string[]", - label: "Document Info", - description: "Custom information fields for the document.", - optional: true, - }, - onBehalfOf: { - type: "string", - label: "On Behalf Of", - description: "Send document on behalf of another user.", - optional: true, - }, - roleRemovalIndices: { - type: "integer[]", - label: "Role Removal Indices", - description: "Indices of roles to remove from the template.", - optional: true, - }, - documentDownloadOption: { - type: "string", - label: "Document Download Option", - description: "Option for document download configuration.", - optional: true, - }, - formGroups: { - type: "string[]", - label: "Form Groups", - description: "Groups of form fields in the document.", - optional: true, - }, - files: { - type: "string[]", - label: "Files", - description: "Files to include in the document.", - optional: true, - }, - fileUrls: { - type: "string[]", - label: "File URLs", - description: "URLs of files to include in the document.", - optional: true, - }, - recipientNotificationSettings: { - type: "string", - label: "Recipient Notification Settings", - description: "Settings for recipient notifications.", - optional: true, - }, - removeFormfields: { - type: "boolean", - label: "Remove Formfields", - description: "Remove existing form fields from the document.", - optional: true, - }, - enableAuditTrailLocalization: { - type: "boolean", - label: "Enable Audit Trail Localization", - description: "Enable localization for audit trails.", - optional: true, + description: "A list of CC recipients for the document.", + async options({ page }) { + const { result } = await this.listContacts({ + params: { + page: page + 1, + }, + }); + + return result.map(({ + id: value, email: label, + }) => ({ + label, + value, + })); + }, }, - // Event Props sentBy: { type: "string", label: "Sent By", description: "The sender of the document.", - optional: true, - async options() { - const sentByOptions = await this.listSenderIdentities(); - return sentByOptions.map((item) => ({ - label: item.name, - value: item.id, - })); - }, - }, - recipients: { - type: "string[]", - label: "Recipients", - description: "Recipients of the document.", - optional: true, - }, - searchKey: { - type: "string", - label: "Search Key", - description: "Search key for documents.", - optional: true, - }, - brandIds: { - type: "string[]", - label: "Brand IDs", - description: "Brand IDs associated with the document.", - optional: true, - async options() { - const brandIdsOptions = await this.listBrands(); - return brandIdsOptions.map((item) => ({ - label: item.name, - value: item.id, - })); + async options({ page }) { + const { result } = await this.listSenderIdentities({ + params: { + page: page + 1, + }, + }); + + return result.map(({ email }) => email); }, }, - status: { - type: "string", - label: "Status", - description: "Status of the document.", - optional: false, - }, - transmitType: { - type: "string", - label: "Transmit Type", - description: "Type of transmission for the document.", - optional: false, - }, }, methods: { - // Log authentication keys - authKeys() { - console.log(Object.keys(this.$auth)); - }, - // Base URL for BoldSign API _baseUrl() { return "https://api.boldsign.com/v1"; }, - // Generic method to make API requests - async _makeRequest(opts = {}) { - const { - $ = this, method = "GET", path = "/", headers, ...otherOpts - } = opts; + _headers(headers = {}) { + return { + ...headers, + "Authorization": `Bearer ${this.$auth.oauth_access_token}`, + "accept": "application/json", + }; + }, + _makeRequest({ + $ = this, path, headers, ...opts + }) { return axios($, { - ...otherOpts, - method, - url: this._baseUrl() + path, - headers: { - ...headers, - "X-API-KEY": this.$auth.api_key, - "Content-Type": "application/json;odata.metadata=minimal;odata.streaming=true", - "accept": "application/json", - }, + url: `${this._baseUrl()}${path}`, + headers: this._headers(headers), + ...opts, }); }, - // Fetch options for 'sentBy' prop - async listSenderIdentities(opts = {}) { + listTemplates(opts = {}) { return this._makeRequest({ - path: "/sender-identities/list-identities", + path: "/template/list", ...opts, }); }, - // Fetch options for 'brandIds' and 'brandId' props - async listBrands(opts = {}) { + listBrands(opts = {}) { return this._makeRequest({ - path: "/branding/list-brands", + path: "/brand/list", ...opts, }); }, - // Method to send document for e-signature using a template - async sendDocument() { - const data = { - template_id: this.templateId, - title: this.title, - message: this.message, - roles: this.roles, - brandid: this.brandId, - labels: this.labels, - disableemails: this.disableEmails, - disablesms: this.disableSMS, - hitdocumentid: this.hitDocumentId, - enableautoreminder: this.enableAutoReminder, - reminderdays: this.reminderDays, - remindercount: this.reminderCount, - cc: this.cc, - expirydays: this.expiryDays, - enableprintandsign: this.enablePrintAndSign, - enablereassign: this.enableReassign, - enablesigningorder: this.enableSigningOrder, - disableexpiryalert: this.disableExpiryAlert, - documentinfo: this.documentInfo, - onbehalfof: this.onBehalfOf, - roleremovalindices: this.roleRemovalIndices, - documentdownloadoption: this.documentDownloadOption, - formgroups: this.formGroups, - files: this.files, - fileurls: this.fileUrls, - recipientnotificationsettings: this.recipientNotificationSettings, - removeformfields: this.removeFormfields, - enableaudittraillocalization: this.enableAuditTrailLocalization, - }; - - // Ensure that at least one of 'files' or 'fileUrls' is provided - if (!this.files && !this.fileUrls) { - throw new Error("At least one of 'files' or 'fileUrls' must be provided."); - } - - // Remove undefined properties - Object.keys(data).forEach( - (key) => data[key] === undefined && delete data[key], - ); - + listContacts(opts = {}) { return this._makeRequest({ - method: "POST", - path: "/template/send", - data, - params: { - templateId: this.templateId, - }, + path: "/contacts/list", + ...opts, }); }, - // Emit event when document status changes to 'completed' - async emitDocumentCompleted() { - if (this.status === "completed") { - this.$emit("documentCompleted", { - sentBy: this.sentBy, - recipients: this.recipients, - searchKey: this.searchKey, - labels: this.labels, - brandIds: this.brandIds, - status: this.status, - }); - } + listDocuments(opts = {}) { + return this._makeRequest({ + path: "/document/list", + ...opts, + }); }, - // Emit event when document is sent - async emitDocumentSent() { - if (this.transmitType === "sent") { - this.$emit("documentSent", { - sentBy: this.sentBy, - recipients: this.recipients, - searchKey: this.searchKey, - labels: this.labels, - brandIds: this.brandIds, - transmitType: this.transmitType, - }); - } + listSenderIdentities(opts = {}) { + return this._makeRequest({ + path: "/senderIdentities/list", + ...opts, + }); }, - // Emit event when document status changes to 'declined' - async emitDocumentDeclined() { - if (this.status === "declined") { - this.$emit("documentDeclined", { - sentBy: this.sentBy, - recipients: this.recipients, - searchKey: this.searchKey, - labels: this.labels, - brandIds: this.brandIds, - status: this.status, + sendDocument(opts = {}) { + return this._makeRequest({ + method: "POST", + path: "/template/send", + ...opts, + }); + }, + async *paginate({ + fn, params = {}, maxResults = null, ...opts + }) { + let hasMore = false; + let count = 0; + let page = 0; + + do { + params.page = ++page; + const { + result, + pageDetails: { + page: currentPage, totalPages, + }, + } = await fn({ + params, + ...opts, }); - } + for (const d of result) { + yield d; + + if (maxResults && ++count === maxResults) { + return count; + } + } + + hasMore = currentPage < totalPages; + + } while (hasMore); }, }, }; diff --git a/components/boldsign/common/constants.mjs b/components/boldsign/common/constants.mjs new file mode 100644 index 0000000000000..412c03323c14c --- /dev/null +++ b/components/boldsign/common/constants.mjs @@ -0,0 +1,4 @@ +export const DOCUMENT_DOWNLOAD_OPTIONS = [ + "Combined", + "Individually", +]; diff --git a/components/boldsign/common/utils.mjs b/components/boldsign/common/utils.mjs new file mode 100644 index 0000000000000..0cd1a12b6a4ba --- /dev/null +++ b/components/boldsign/common/utils.mjs @@ -0,0 +1,31 @@ +export const checkTmp = (filename) => { + if (!filename.startsWith("/tmp")) { + return `/tmp/${filename}`; + } + return filename; +}; + +export const parseObject = (obj) => { + if (!obj) return undefined; + + if (Array.isArray(obj)) { + return obj.map((item) => { + if (typeof item === "string") { + try { + return JSON.parse(item); + } catch (e) { + return item; + } + } + return item; + }); + } + if (typeof obj === "string") { + try { + return JSON.parse(obj); + } catch (e) { + return obj; + } + } + return obj; +}; diff --git a/components/boldsign/package.json b/components/boldsign/package.json index 2276850c6d5c3..214d46128b487 100644 --- a/components/boldsign/package.json +++ b/components/boldsign/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/boldsign", - "version": "0.0.1", + "version": "0.1.0", "description": "Pipedream BoldSign Components", "main": "boldsign.app.mjs", "keywords": [ @@ -11,5 +11,8 @@ "author": "Pipedream (https://pipedream.com/)", "publishConfig": { "access": "public" + }, + "dependencies": { + "@pipedream/platform": "^3.0.3" } } diff --git a/components/boldsign/sources/common/base.mjs b/components/boldsign/sources/common/base.mjs new file mode 100644 index 0000000000000..c5d7665097945 --- /dev/null +++ b/components/boldsign/sources/common/base.mjs @@ -0,0 +1,104 @@ +import { DEFAULT_POLLING_SOURCE_TIMER_INTERVAL } from "@pipedream/platform"; +import boldsign from "../../boldsign.app.mjs"; +import { parseObject } from "../../common/utils.mjs"; + +export default { + props: { + boldsign, + db: "$.service.db", + timer: { + type: "$.interface.timer", + default: { + intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, + }, + }, + sentBy: { + propDefinition: [ + boldsign, + "sentBy", + ], + optional: true, + }, + recipients: { + type: "string[]", + label: "Recipients", + description: "Recipients of the document.", + optional: true, + }, + searchKey: { + type: "string", + label: "Search Key", + description: "Search key for documents.", + optional: true, + }, + labels: { + propDefinition: [ + boldsign, + "labels", + ], + optional: true, + }, + brandIds: { + propDefinition: [ + boldsign, + "brandId", + ], + type: "string[]", + label: "Brand IDs", + description: "Brand IDs associated with the document.", + optional: true, + }, + }, + methods: { + _getLastDate() { + return this.db.get("lastDate") || 0; + }, + _setLastDate(lastDate) { + this.db.set("lastDate", lastDate); + }, + async emitEvent(maxResults = false) { + const lastDate = this._getLastDate(); + + const response = this.boldsign.paginate({ + fn: this.getFunction(), + params: { + ...this.getParams(), + sentBy: this.sentBy, + recipients: this.recipients, + searchKey: this.searchKey, + labels: this.labels, + brandIds: parseObject(this.brandIds), + }, + }); + + let responseArray = []; + for await (const item of response) { + if (item.activityDate <= lastDate) break; + responseArray.push(item); + } + + if (responseArray.length) { + if (maxResults && (responseArray.length > maxResults)) { + responseArray.length = maxResults; + } + this._setLastDate(responseArray[0].activityDate); + } + + for (const item of responseArray.reverse()) { + this.$emit(item, { + id: `${item.documentId}-${item.activityDate}`, + summary: this.getSummary(item), + ts: Date.parse(item.activityDate || new Date()), + }); + } + }, + }, + hooks: { + async deploy() { + await this.emitEvent(25); + }, + }, + async run() { + await this.emitEvent(); + }, +}; diff --git a/components/boldsign/sources/new-document-completed/new-document-completed.mjs b/components/boldsign/sources/new-document-completed/new-document-completed.mjs index 0fb848fe80ff0..96b6916bb6ca8 100644 --- a/components/boldsign/sources/new-document-completed/new-document-completed.mjs +++ b/components/boldsign/sources/new-document-completed/new-document-completed.mjs @@ -1,147 +1,27 @@ -import { - axios, DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, -} from "@pipedream/platform"; -import boldsign from "../../boldsign.app.mjs"; +import common from "../common/base.mjs"; +import sampleEmit from "./test-event.mjs"; export default { + ...common, key: "boldsign-new-document-completed", - name: "BoldSign New Document Completed", - description: "Emit a new event when a document is completed by all the signers. [See the documentation]()", - version: "0.0.{{ts}}", + name: "New Document Completed", + description: "Emit new event when a document is completed by all the signers.", + version: "0.0.1", type: "source", dedupe: "unique", - props: { - boldsign, - db: "$.service.db", - timer: { - type: "$.interface.timer", - default: { - intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, - }, - }, - status: { - type: "string", - label: "Status", - description: "Status of the document.", - default: "completed", - }, - sentBy: { - propDefinition: [ - "boldsign", - "sentBy", - ], - optional: true, - }, - recipients: { - propDefinition: [ - "boldsign", - "recipients", - ], - optional: true, - }, - searchKey: { - propDefinition: [ - "boldsign", - "searchKey", - ], - optional: true, - }, - labels: { - propDefinition: [ - "boldsign", - "labels", - ], - optional: true, - }, - brandIds: { - propDefinition: [ - "boldsign", - "brandIds", - ], - optional: true, - }, - }, methods: { - async listDocuments() { - const params = { - status: this.status, - sentby: this.sentBy, - recipients: this.recipients, - searchkey: this.searchKey, - labels: this.labels, - brandids: this.brandIds, - perpage: 50, - }; - Object.keys(params).forEach((key) => params[key] === undefined && delete params[key]); - const response = await this.boldsign._makeRequest({ - path: "/documents/list-documents", - method: "GET", - params, - }); - return response.result; - }, - getCursorKey() { - return "lastRunTs"; - }, - }, - hooks: { - async deploy() { - const documents = await this.listDocuments(); - const sortedDocuments = documents.sort((a, b) => b.activityDate - a.activityDate).slice(0, 50); - for (const document of sortedDocuments) { - this.$emit(document, { - id: document.documentId || document.activityDate, - summary: `Document Completed: ${document.messageTitle}`, - ts: document.activityDate * 1000, - }); - } - if (sortedDocuments.length > 0) { - const latestDocument = sortedDocuments[0]; - this.db.set(this.getCursorKey(), latestDocument.activityDate); - } + ...common.methods, + getFunction() { + return this.boldsign.listDocuments; }, - async activate() { - // No activation logic required + getSummary(item) { + return `Document Completed: ${item.documentId}`; }, - async deactivate() { - // No deactivation logic required + getParams() { + return { + status: "Completed", + }; }, }, - async run() { - const lastRunTs = (await this.db.get(this.getCursorKey())) || 0; - const params = { - status: this.status, - sentby: this.sentBy, - recipients: this.recipients, - searchkey: this.searchKey, - labels: this.labels, - brandids: this.brandIds, - since: lastRunTs, - perpage: 50, - }; - Object.keys(params).forEach((key) => params[key] === undefined && delete params[key]); - const documents = await this.boldsign._makeRequest({ - path: "/documents/list-documents", - method: "GET", - params, - }).then((response) => response.result); - - const newDocuments = documents.filter((doc) => doc.activityDate > lastRunTs); - for (const document of newDocuments) { - this.$emit(document, { - id: document.documentId || document.activityDate, - summary: `Document Completed: ${document.messageTitle}`, - ts: document.activityDate - ? document.activityDate * 1000 - : Date.now(), - }); - } - - if (newDocuments.length > 0) { - const latestDocument = newDocuments.reduce((prev, current) => (prev.activityDate > current.activityDate) - ? prev - : current); - this.db.set(this.getCursorKey(), latestDocument.activityDate); - } - }, + sampleEmit, }; diff --git a/components/boldsign/sources/new-document-completed/test-event.mjs b/components/boldsign/sources/new-document-completed/test-event.mjs new file mode 100644 index 0000000000000..e2ab71be6dac3 --- /dev/null +++ b/components/boldsign/sources/new-document-completed/test-event.mjs @@ -0,0 +1,47 @@ +export default { + "documentId": "755195d8-xxxx-xxxx-xxxx-88ff77d35419", + "senderDetail": { + "name": "Richard", + "privateMessage": null, + "emailAddress": "richard@cubeflakes.com", + "isViewed": false + }, + "ccDetails": [ + { + "emailAddress": "alexgayle@cubeflakes.com", + "isViewed": false + } + ], + "createdDate": 1664961706, + "activityDate": 1665989290, + "activityBy": "alexgayle@cubeflakes.com", + "messageTitle": "565", + "status": "Completed", + "signerDetails": [ + { + "signerName": "Richard", + "signerRole": "", + "signerEmail": "", + "status": "NotCompleted", + "enableAccessCode": false, + "isAuthenticationFailed": null, + "enableEmailOTP": false, + "authenticationType": "None", + "isDeliveryFailed": false, + "isViewed": false, + "order": 1, + "signerType": "Signer", + "hostEmail": "", + "hostName": "", + "isReassigned": true, + "privateMessage": "", + "formFields": [], + "language": 0 + } + ], + "expiryDate": 1670178599, + "enableSigningOrder": false, + "isDeleted": false, + "labels": [], + "nextCursor": 1665989290 +} \ No newline at end of file diff --git a/components/boldsign/sources/new-document-declined/new-document-declined.mjs b/components/boldsign/sources/new-document-declined/new-document-declined.mjs index 11aa1b1960336..d190ea58ab1eb 100644 --- a/components/boldsign/sources/new-document-declined/new-document-declined.mjs +++ b/components/boldsign/sources/new-document-declined/new-document-declined.mjs @@ -1,163 +1,27 @@ -import { - axios, DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, -} from "@pipedream/platform"; -import boldsign from "../../boldsign.app.mjs"; +import common from "../common/base.mjs"; +import sampleEmit from "./test-event.mjs"; export default { + ...common, key: "boldsign-new-document-declined", name: "New Document Declined", - description: "Emit new event when a document is declined by a signer. [See the documentation](https://developers.boldsign.com)", - version: "0.0.{{ts}}", + description: "Emit new event when a document is declined by a signer.", + version: "0.0.1", type: "source", dedupe: "unique", - props: { - boldsign: { - type: "app", - app: "boldsign", + methods: { + ...common.methods, + getFunction() { + return this.boldsign.listDocuments; }, - sentby: { - propDefinition: [ - boldsign, - "sentBy", - ], - optional: true, + getSummary(item) { + return `Document Declined: ${item.documentId}`; }, - recipients: { - propDefinition: [ - boldsign, - "recipients", - ], - optional: true, - }, - searchkey: { - propDefinition: [ - boldsign, - "searchKey", - ], - optional: true, - }, - labels: { - propDefinition: [ - boldsign, - "labels", - ], - optional: true, - }, - brandids: { - propDefinition: [ - boldsign, - "brandIds", - ], - optional: true, - }, - status: { - type: "string", - label: "Status", - description: "The status of the document. Must be 'declined'.", - default: "declined", - }, - db: "$.service.db", - timer: { - type: "$.interface.timer", - default: { - intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, - }, - }, - }, - hooks: { - async deploy() { - const params = { - status: this.status, + getParams() { + return { + status: "Declined", }; - if (this.sentby) params.sentby = this.sentby; - if (this.recipients) params.recipients = this.recipients; - if (this.searchkey) params.searchkey = this.searchkey; - if (this.labels) params.labels = this.labels; - if (this.brandids) params.brandids = this.brandids; - - let page = 1; - const perPage = 50; - let emitted = 0; - - while (emitted < 50) { - const documents = await this.boldsign._makeRequest({ - method: "GET", - path: "/documents/list-documents", - params: { - ...params, - page, - perpage: Math.min(perPage - emitted, 50 - emitted), - }, - }); - - const docs = documents.result; - if (!docs.length) break; - - for (const doc of docs.reverse()) { - this.$emit(doc, { - id: doc.documentId, - summary: `Document Declined: ${doc.messageTitle}`, - ts: doc.activityDate * 1000, - }); - emitted++; - if (emitted >= 50) break; - } - - if (docs.length < perPage || emitted >= 50) break; - page++; - } - }, - async activate() { - // No activation steps needed for polling source - }, - async deactivate() { - // No deactivation steps needed for polling source }, }, - async run() { - const lastTs = this.db.get("lastTs") ?? 0; - const params = { - status: this.status, - activityDate_gte: Math.floor(lastTs / 1000), - }; - if (this.sentby) params.sentby = this.sentby; - if (this.recipients) params.recipients = this.recipients; - if (this.searchkey) params.searchkey = this.searchkey; - if (this.labels) params.labels = this.labels; - if (this.brandids) params.brandids = this.brandids; - - let page = 1; - const perPage = 100; - let maxTs = lastTs; - - while (true) { - const documents = await this.boldsign._makeRequest({ - method: "GET", - path: "/documents/list-documents", - params: { - ...params, - page, - perpage: perPage, - }, - }); - - const docs = documents.result; - if (!docs.length) break; - - for (const doc of docs) { - const docTs = doc.activityDate * 1000; - if (docTs > maxTs) maxTs = docTs; - this.$emit(doc, { - id: doc.documentId, - summary: `Document Declined: ${doc.messageTitle}`, - ts: docTs, - }); - } - - if (docs.length < perPage) break; - page++; - } - - this.db.set("lastTs", maxTs); - }, + sampleEmit, }; diff --git a/components/boldsign/sources/new-document-declined/test-event.mjs b/components/boldsign/sources/new-document-declined/test-event.mjs new file mode 100644 index 0000000000000..5bb5b3269b125 --- /dev/null +++ b/components/boldsign/sources/new-document-declined/test-event.mjs @@ -0,0 +1,47 @@ +export default { + "documentId": "755195d8-xxxx-xxxx-xxxx-88ff77d35419", + "senderDetail": { + "name": "Richard", + "privateMessage": null, + "emailAddress": "richard@cubeflakes.com", + "isViewed": false + }, + "ccDetails": [ + { + "emailAddress": "alexgayle@cubeflakes.com", + "isViewed": false + } + ], + "createdDate": 1664961706, + "activityDate": 1665989290, + "activityBy": "alexgayle@cubeflakes.com", + "messageTitle": "565", + "status": "Declined", + "signerDetails": [ + { + "signerName": "Richard", + "signerRole": "", + "signerEmail": "", + "status": "NotCompleted", + "enableAccessCode": false, + "isAuthenticationFailed": null, + "enableEmailOTP": false, + "authenticationType": "None", + "isDeliveryFailed": false, + "isViewed": false, + "order": 1, + "signerType": "Signer", + "hostEmail": "", + "hostName": "", + "isReassigned": true, + "privateMessage": "", + "formFields": [], + "language": 0 + } + ], + "expiryDate": 1670178599, + "enableSigningOrder": false, + "isDeleted": false, + "labels": [], + "nextCursor": 1665989290 +} \ No newline at end of file diff --git a/components/boldsign/sources/new-document-sent/new-document-sent.mjs b/components/boldsign/sources/new-document-sent/new-document-sent.mjs index aa9fbbf680118..30259ca9aa4b2 100644 --- a/components/boldsign/sources/new-document-sent/new-document-sent.mjs +++ b/components/boldsign/sources/new-document-sent/new-document-sent.mjs @@ -1,129 +1,28 @@ -import { - axios, DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, -} from "@pipedream/platform"; -import boldsign from "../../boldsign.app.mjs"; +import common from "../common/base.mjs"; +import sampleEmit from "./test-event.mjs"; export default { + ...common, key: "boldsign-new-document-sent", name: "New Document Sent", - description: "Emit a new event when a document is sent to a signer. [See the documentation]()", - version: "0.0.{{ts}}", + description: "Emit new event when a document is sent to a signer.", + version: "0.0.1", type: "source", dedupe: "unique", - props: { - boldsign: { - type: "app", - app: "boldsign", - }, - db: "$.service.db", - timer: { - type: "$.interface.timer", - default: { - intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, - }, - }, - sentBy: { - propDefinition: [ - "boldsign", - "sentBy", - ], - optional: true, - }, - recipients: { - type: "string[]", - label: "Recipients", - description: "Recipients of the document.", - optional: true, - }, - searchKey: { - type: "string", - label: "Search Key", - description: "Search key for documents.", - optional: true, - }, - labels: { - type: "string[]", - label: "Labels", - description: "Labels for categorizing documents.", - optional: true, - }, - brandIds: { - propDefinition: [ - "boldsign", - "brandIds", - ], - optional: true, - }, - }, methods: { - getLastTimestamp() { - return this.db.get("lastTimestamp") ?? 0; + ...common.methods, + getFunction() { + return this.boldsign.listDocuments; }, - setLastTimestamp(timestamp) { - this.db.set("lastTimestamp", timestamp); + getSummary(item) { + return `New Document Sent: ${item.documentId}`; }, - buildQueryParams() { - const params = { - transmitType: "sent", - perpage: 50, - sort: "activityDate", - order: "DESC", + getParams() { + return { + status: "None", + transmitType: "Sent", }; - if (this.sentBy) params.sentBy = this.sentBy; - if (this.recipients && this.recipients.length > 0) - params.recipients = this.recipients.join(","); - if (this.searchKey) params.searchKey = this.searchKey; - if (this.labels && this.labels.length > 0) - params.labels = this.labels.join(","); - if (this.brandIds && this.brandIds.length > 0) - params.brandIds = this.brandIds.join(","); - return params; - }, - }, - hooks: { - async deploy() { - const params = this.buildQueryParams(); - const documents = await this.boldsign.listDocuments(params); - for (const document of documents.result) { - this.$emit(document, { - id: document.documentId, - summary: `New Document Sent: ${document.messageTitle || document.title}`, - ts: document.activityDate * 1000, - }); - if (document.activityDate > this.getLastTimestamp()) { - this.setLastTimestamp(document.activityDate); - } - } }, - async activate() { - // No activation steps needed for polling source - }, - async deactivate() { - // No deactivation steps needed for polling source - }, - }, - async run() { - const lastTimestamp = this.getLastTimestamp(); - const params = { - ...this.buildQueryParams(), - from_ts: lastTimestamp + 1, - }; - const documents = await this.boldsign.listDocuments(params); - let newLastTimestamp = lastTimestamp; - for (const document of documents.result) { - if (document.activityDate > lastTimestamp) { - this.$emit(document, { - id: document.documentId, - summary: `New Document Sent: ${document.messageTitle || document.title}`, - ts: document.activityDate * 1000, - }); - if (document.activityDate > newLastTimestamp) { - newLastTimestamp = document.activityDate; - } - } - } - if (newLastTimestamp > lastTimestamp) { - this.setLastTimestamp(newLastTimestamp); - } }, + sampleEmit, }; diff --git a/components/boldsign/sources/new-document-sent/test-event.mjs b/components/boldsign/sources/new-document-sent/test-event.mjs new file mode 100644 index 0000000000000..7cbc93bc10a7f --- /dev/null +++ b/components/boldsign/sources/new-document-sent/test-event.mjs @@ -0,0 +1,47 @@ +export default { + "documentId": "755195d8-xxxx-xxxx-xxxx-88ff77d35419", + "senderDetail": { + "name": "Richard", + "privateMessage": null, + "emailAddress": "richard@cubeflakes.com", + "isViewed": false + }, + "ccDetails": [ + { + "emailAddress": "alexgayle@cubeflakes.com", + "isViewed": false + } + ], + "createdDate": 1664961706, + "activityDate": 1665989290, + "activityBy": "alexgayle@cubeflakes.com", + "messageTitle": "565", + "status": "WaitingForOthers", + "signerDetails": [ + { + "signerName": "Richard", + "signerRole": "", + "signerEmail": "", + "status": "NotCompleted", + "enableAccessCode": false, + "isAuthenticationFailed": null, + "enableEmailOTP": false, + "authenticationType": "None", + "isDeliveryFailed": false, + "isViewed": false, + "order": 1, + "signerType": "Signer", + "hostEmail": "", + "hostName": "", + "isReassigned": true, + "privateMessage": "", + "formFields": [], + "language": 0 + } + ], + "expiryDate": 1670178599, + "enableSigningOrder": false, + "isDeleted": false, + "labels": [], + "nextCursor": 1665989290 +} \ No newline at end of file From 0b9d934f9a2982195d8d6189433ccb719d9d57a9 Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Thu, 19 Dec 2024 11:59:11 -0300 Subject: [PATCH 3/9] pnpm update --- pnpm-lock.yaml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 39ba56f95f156..7c85606ee1e06 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1239,7 +1239,11 @@ importers: specifier: ^1.6.0 version: 1.6.6 - components/boldsign: {} + components/boldsign: + dependencies: + '@pipedream/platform': + specifier: ^3.0.3 + version: 3.0.3 components/boloforms: dependencies: @@ -24525,22 +24529,22 @@ packages: superagent@3.8.1: resolution: {integrity: sha512-VMBFLYgFuRdfeNQSMLbxGSLfmXL/xc+OO+BZp41Za/NRDBet/BNbkRJrYzCUu0u4GU0i/ml2dtT8b9qgkw9z6Q==} engines: {node: '>= 4.0'} - deprecated: Please upgrade to v7.0.2+ of superagent. We have fixed numerous issues with streams, form-data, attach(), filesystem errors not bubbling up (ENOENT on attach()), and all tests are now passing. See the releases tab for more information at . + deprecated: Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net superagent@4.1.0: resolution: {integrity: sha512-FT3QLMasz0YyCd4uIi5HNe+3t/onxMyEho7C3PSqmti3Twgy2rXT4fmkTz6wRL6bTF4uzPcfkUCa8u4JWHw8Ag==} engines: {node: '>= 6.0'} - deprecated: Please upgrade to v7.0.2+ of superagent. We have fixed numerous issues with streams, form-data, attach(), filesystem errors not bubbling up (ENOENT on attach()), and all tests are now passing. See the releases tab for more information at . + deprecated: Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net superagent@5.3.1: resolution: {integrity: sha512-wjJ/MoTid2/RuGCOFtlacyGNxN9QLMgcpYLDQlWFIhhdJ93kNscFonGvrpAHSCVjRVj++DGCglocF7Aej1KHvQ==} engines: {node: '>= 7.0.0'} - deprecated: Please upgrade to v7.0.2+ of superagent. We have fixed numerous issues with streams, form-data, attach(), filesystem errors not bubbling up (ENOENT on attach()), and all tests are now passing. See the releases tab for more information at . + deprecated: Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net superagent@7.1.6: resolution: {integrity: sha512-gZkVCQR1gy/oUXr+kxJMLDjla434KmSOKbx5iGD30Ql+AkJQ/YlPKECJy2nhqOsHLjGHzoDTXNSjhnvWhzKk7g==} engines: {node: '>=6.4.0 <13 || >=14'} - deprecated: Please downgrade to v7.1.5 if you need IE/ActiveXObject support OR upgrade to v8.0.0 as we no longer support IE and published an incorrect patch version (see https://github.com/visionmedia/superagent/issues/1731) + deprecated: Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net supports-color@2.0.0: resolution: {integrity: sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==} From a4952151845db2cdb3949d492009eed978940e78 Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Thu, 19 Dec 2024 12:03:02 -0300 Subject: [PATCH 4/9] fix import --- .../actions/send-document-template/send-document-template.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/boldsign/actions/send-document-template/send-document-template.mjs b/components/boldsign/actions/send-document-template/send-document-template.mjs index 2e45cb4939fce..d9aa57135f212 100644 --- a/components/boldsign/actions/send-document-template/send-document-template.mjs +++ b/components/boldsign/actions/send-document-template/send-document-template.mjs @@ -1,11 +1,11 @@ import { ConfigurationError } from "@pipedream/platform"; import fs from "fs"; import boldsign from "../../boldsign.app.mjs"; +import { DOCUMENT_DOWNLOAD_OPTIONS } from "../../common/constants.mjs"; import { checkTmp, parseObject, } from "../../common/utils.mjs"; -import { DOCUMENT_DOWNLOAD_OPTIONS } from "./common/constants.mjs"; export default { key: "boldsign-send-document-template", From d8b30933c7a9257de532dfab6c4d66e5e07ed567 Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Thu, 19 Dec 2024 15:59:08 -0300 Subject: [PATCH 5/9] some adjusts --- components/boldsign/sources/common/base.mjs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/components/boldsign/sources/common/base.mjs b/components/boldsign/sources/common/base.mjs index c5d7665097945..112e52108f74a 100644 --- a/components/boldsign/sources/common/base.mjs +++ b/components/boldsign/sources/common/base.mjs @@ -58,17 +58,19 @@ export default { }, async emitEvent(maxResults = false) { const lastDate = this._getLastDate(); + const params = { + ...this.getParams(), + }; + + if (this.sentBy) params.sentBy = this.sentBy; + if (this.recipients) params.recipients = parseObject(this.recipients); + if (this.searchKey) params.searchKey = this.searchKey; + if (this.labels) params.labels = parseObject(this.labels); + if (this.brandIds) params.brandIds = parseObject(this.brandIds); const response = this.boldsign.paginate({ fn: this.getFunction(), - params: { - ...this.getParams(), - sentBy: this.sentBy, - recipients: this.recipients, - searchKey: this.searchKey, - labels: this.labels, - brandIds: parseObject(this.brandIds), - }, + params, }); let responseArray = []; @@ -86,7 +88,7 @@ export default { for (const item of responseArray.reverse()) { this.$emit(item, { - id: `${item.documentId}-${item.activityDate}`, + id: item.documentId, summary: this.getSummary(item), ts: Date.parse(item.activityDate || new Date()), }); From d3e872bb1936873c67c51d8557915cee2e1028d4 Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Mon, 23 Dec 2024 20:00:04 -0300 Subject: [PATCH 6/9] some adjusts --- .../send-document-template/send-document-template.mjs | 6 +++--- components/boldsign/boldsign.app.mjs | 7 +------ 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/components/boldsign/actions/send-document-template/send-document-template.mjs b/components/boldsign/actions/send-document-template/send-document-template.mjs index d9aa57135f212..6aae2961da60f 100644 --- a/components/boldsign/actions/send-document-template/send-document-template.mjs +++ b/components/boldsign/actions/send-document-template/send-document-template.mjs @@ -36,7 +36,7 @@ export default { roles: { type: "string[]", label: "Roles", - description: "Roles assigned to the signers. [See the documentation](https://developers.boldsign.com/documents/send-document-from-template) for further information.", + description: "A role is simply a placeholder for a real person. For example, if we have a purchase order that will always be signed by two people, one from the company and one from the customer, we can create a template with two roles Customer and Representative. Example: **[{\"roleIndex\": 50,\"signerName\": \"Richard\",\"signerOrder\": 1,\"signerEmail\": \"richard@cubeflakes.com\",\"privateMessage\": \"Please check and sign the document.\",\"authenticationCode\": \"281028\",\"enableEmailOTP\": false,\"signerType\": \"Signer\",\"signerRole\": \"Manager\",\"formFields\": [{\"id\": \"SignField\",\"fieldType\": \"Signature\",\"pageNumber\": 1,\"bounds\": {\"x\": 100,\"y\": 100,\"width\": 100,\"height\": 50},\"isRequired\": true}]**.", }, brandId: { propDefinition: [ @@ -156,7 +156,7 @@ export default { files: { type: "string[]", label: "Files", - description: "Files to include in the document.", + description: "A list of paths to files in the `/tmp` directory. [See the documentation on working with files](https://pipedream.com/docs/code/nodejs/working-with-files/#writing-a-file-to-tmp).", optional: true, }, fileUrls: { @@ -230,7 +230,7 @@ export default { reminderDays: this.reminderDays, reminderCount: this.reminderCount, }, - cc: this.cc ?? parseObject(this.cc)?.map((item) => ({ + cc: parseObject(this.cc)?.map((item) => ({ emailAddress: item, })), expiryDays: this.expiryDays, diff --git a/components/boldsign/boldsign.app.mjs b/components/boldsign/boldsign.app.mjs index 7259dc2ef3fea..cd0328e46d266 100644 --- a/components/boldsign/boldsign.app.mjs +++ b/components/boldsign/boldsign.app.mjs @@ -53,12 +53,7 @@ export default { }, }); - return result.map(({ - id: value, email: label, - }) => ({ - label, - value, - })); + return result.map(({ email }) => email); }, }, sentBy: { From 51ffafd3245d90a0ab9ea989127c1d0595042471 Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Mon, 23 Dec 2024 20:03:34 -0300 Subject: [PATCH 7/9] pnpm update --- pnpm-lock.yaml | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7c85606ee1e06..2d263c749412c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12186,10 +12186,10 @@ importers: version: 14.2.19(@babel/core@8.0.0-alpha.13)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) nextra: specifier: latest - version: 3.2.5(@types/react@18.3.12)(acorn@8.14.0)(next@14.2.19(@babel/core@8.0.0-alpha.13)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + version: 3.3.0(@types/react@18.3.12)(acorn@8.14.0)(next@14.2.19(@babel/core@8.0.0-alpha.13)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) nextra-theme-docs: specifier: latest - version: 3.2.5(next@14.2.19(@babel/core@8.0.0-alpha.13)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(nextra@3.2.5(@types/react@18.3.12)(acorn@8.14.0)(next@14.2.19(@babel/core@8.0.0-alpha.13)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 3.3.0(next@14.2.19(@babel/core@8.0.0-alpha.13)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(nextra@3.3.0(@types/react@18.3.12)(acorn@8.14.0)(next@14.2.19(@babel/core@8.0.0-alpha.13)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: specifier: ^18.3.1 version: 18.3.1 @@ -22381,16 +22381,16 @@ packages: sass: optional: true - nextra-theme-docs@3.2.5: - resolution: {integrity: sha512-eF0j1VNNS1rFjZOfYqlrXISaCU3+MhZ9hhXY+TUydRlfELrFWpGzrpW6MiL7hq4JvUR7OBtHHs8+A+8AYcETBQ==} + nextra-theme-docs@3.3.0: + resolution: {integrity: sha512-4JSbDmsbtaYa2eKHsNymWy6So4/fAAXuNPSkjgQ3S+aLRiC730mR9djdkTd1iRca4+czetzBWaqxu+HwTVSSCA==} peerDependencies: next: '>=13' - nextra: 3.2.5 + nextra: 3.3.0 react: '>=18' react-dom: '>=18' - nextra@3.2.5: - resolution: {integrity: sha512-n665DRpI/brjHXM83G5LdlbYA2nOtjaLcWJs7mZS3gkuRDmEXpJj4XJ860xrhkYZW2iYoUMu32zzhPuFByU7VA==} + nextra@3.3.0: + resolution: {integrity: sha512-//+bQW3oKrpLrrIFD5HJow310+YcNYhGIgdM4y+EjYuIXScJcgp6Q4Upsq8c2s2fQKEJjeuf+hXKusx9fvH/2w==} engines: {node: '>=18'} peerDependencies: next: '>=13' @@ -23442,6 +23442,12 @@ packages: '@types/react': '>=18' react: '>=18' + react-medium-image-zoom@5.2.12: + resolution: {integrity: sha512-BbQ9jLBFxu6z+viH5tzQzAGqHOJQoYUM7iT1KUkamWKOO6vR1pC33os7LGLrHvOcyySMw74rUdoUCXFdeglwCQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-select@5.8.3: resolution: {integrity: sha512-lVswnIq8/iTj1db7XCG74M/3fbGB6ZaluCzvwPGT5ZOjCdL/k0CLWhEK0vCBLuU5bHTEf6Gj8jtSvi+3v+tO1w==} peerDependencies: @@ -39716,7 +39722,7 @@ snapshots: - '@babel/core' - babel-plugin-macros - nextra-theme-docs@3.2.5(next@14.2.19(@babel/core@8.0.0-alpha.13)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(nextra@3.2.5(@types/react@18.3.12)(acorn@8.14.0)(next@14.2.19(@babel/core@8.0.0-alpha.13)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + nextra-theme-docs@3.3.0(next@14.2.19(@babel/core@8.0.0-alpha.13)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(nextra@3.3.0(@types/react@18.3.12)(acorn@8.14.0)(next@14.2.19(@babel/core@8.0.0-alpha.13)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@headlessui/react': 2.2.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) clsx: 2.1.1 @@ -39724,13 +39730,13 @@ snapshots: flexsearch: 0.7.43 next: 14.2.19(@babel/core@8.0.0-alpha.13)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) next-themes: 0.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - nextra: 3.2.5(@types/react@18.3.12)(acorn@8.14.0)(next@14.2.19(@babel/core@8.0.0-alpha.13)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + nextra: 3.3.0(@types/react@18.3.12)(acorn@8.14.0)(next@14.2.19(@babel/core@8.0.0-alpha.13)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) scroll-into-view-if-needed: 3.1.0 zod: 3.23.8 - nextra@3.2.5(@types/react@18.3.12)(acorn@8.14.0)(next@14.2.19(@babel/core@8.0.0-alpha.13)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3): + nextra@3.3.0(@types/react@18.3.12)(acorn@8.14.0)(next@14.2.19(@babel/core@8.0.0-alpha.13)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3): dependencies: '@formatjs/intl-localematcher': 0.5.8 '@headlessui/react': 2.2.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -39757,6 +39763,7 @@ snapshots: p-limit: 6.1.0 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + react-medium-image-zoom: 5.2.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1) rehype-katex: 7.0.1 rehype-pretty-code: 0.14.0(shiki@1.24.0) rehype-raw: 7.0.0 @@ -41194,6 +41201,11 @@ snapshots: transitivePeerDependencies: - supports-color + react-medium-image-zoom@5.2.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-select@5.8.3(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@babel/runtime': 7.26.0 From a9baeace11b347d598da7740840133e68673aca7 Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Mon, 30 Dec 2024 10:42:34 -0300 Subject: [PATCH 8/9] pnpm update --- pnpm-lock.yaml | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f7e0425d765e8..ce53749759b36 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1338,8 +1338,7 @@ importers: components/braze: {} - components/breathe: - specifiers: {} + components/breathe: {} components/brevo: dependencies: @@ -1629,8 +1628,7 @@ importers: specifier: ^1.5.1 version: 1.6.6 - components/change_photos: - specifiers: {} + components/change_photos: {} components/changenow: {} @@ -5399,8 +5397,7 @@ importers: specifier: ^1.5.1 version: 1.6.6 - components/kafka: - specifiers: {} + components/kafka: {} components/kajabi: {} @@ -8949,8 +8946,7 @@ importers: specifier: ^1.4.1 version: 1.6.6 - components/scrapegraphai: - specifiers: {} + components/scrapegraphai: {} components/scrapein_: {} @@ -10239,8 +10235,7 @@ importers: components/taggun: {} - components/taleez: - specifiers: {} + components/taleez: {} components/talend: {} From 52cfccbf01ee81cbafdfb7323d256a24777a4289 Mon Sep 17 00:00:00 2001 From: michelle0927 Date: Mon, 30 Dec 2024 10:48:00 -0500 Subject: [PATCH 9/9] pnpm-lock.yaml --- pnpm-lock.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f8f13046c98b4..91a3dfc899c0a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -24576,22 +24576,22 @@ packages: superagent@3.8.1: resolution: {integrity: sha512-VMBFLYgFuRdfeNQSMLbxGSLfmXL/xc+OO+BZp41Za/NRDBet/BNbkRJrYzCUu0u4GU0i/ml2dtT8b9qgkw9z6Q==} engines: {node: '>= 4.0'} - deprecated: Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net + deprecated: Please upgrade to v7.0.2+ of superagent. We have fixed numerous issues with streams, form-data, attach(), filesystem errors not bubbling up (ENOENT on attach()), and all tests are now passing. See the releases tab for more information at . superagent@4.1.0: resolution: {integrity: sha512-FT3QLMasz0YyCd4uIi5HNe+3t/onxMyEho7C3PSqmti3Twgy2rXT4fmkTz6wRL6bTF4uzPcfkUCa8u4JWHw8Ag==} engines: {node: '>= 6.0'} - deprecated: Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net + deprecated: Please upgrade to v7.0.2+ of superagent. We have fixed numerous issues with streams, form-data, attach(), filesystem errors not bubbling up (ENOENT on attach()), and all tests are now passing. See the releases tab for more information at . superagent@5.3.1: resolution: {integrity: sha512-wjJ/MoTid2/RuGCOFtlacyGNxN9QLMgcpYLDQlWFIhhdJ93kNscFonGvrpAHSCVjRVj++DGCglocF7Aej1KHvQ==} engines: {node: '>= 7.0.0'} - deprecated: Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net + deprecated: Please upgrade to v7.0.2+ of superagent. We have fixed numerous issues with streams, form-data, attach(), filesystem errors not bubbling up (ENOENT on attach()), and all tests are now passing. See the releases tab for more information at . superagent@7.1.6: resolution: {integrity: sha512-gZkVCQR1gy/oUXr+kxJMLDjla434KmSOKbx5iGD30Ql+AkJQ/YlPKECJy2nhqOsHLjGHzoDTXNSjhnvWhzKk7g==} engines: {node: '>=6.4.0 <13 || >=14'} - deprecated: Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net + deprecated: Please downgrade to v7.1.5 if you need IE/ActiveXObject support OR upgrade to v8.0.0 as we no longer support IE and published an incorrect patch version (see https://github.com/visionmedia/superagent/issues/1731) supports-color@2.0.0: resolution: {integrity: sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==}