diff --git a/components/agrello/actions/get-document/get-document.mjs b/components/agrello/actions/get-document/get-document.mjs new file mode 100644 index 0000000000000..918475503069a --- /dev/null +++ b/components/agrello/actions/get-document/get-document.mjs @@ -0,0 +1,35 @@ +import agrello from "../../agrello.app.mjs"; + +export default { + key: "agrello-get-document", + name: "Get Document", + description: "Get a document in Agrello. [See the documentation](https://api.agrello.io/public/webjars/swagger-ui/index.html)", + version: "0.0.1", + type: "action", + props: { + agrello, + folderId: { + propDefinition: [ + agrello, + "folderId", + ], + }, + documentId: { + propDefinition: [ + agrello, + "documentId", + ({ folderId }) => ({ + folderId, + }), + ], + }, + }, + async run({ $ }) { + const response = await this.agrello.getDocument({ + $, + documentId: this.documentId, + }); + $.export("$summary", `Successfully retrieved document with ID ${this.documentId}`); + return response; + }, +}; diff --git a/components/agrello/agrello.app.mjs b/components/agrello/agrello.app.mjs index 86b3689445f7a..a12c7c07fdd1c 100644 --- a/components/agrello/agrello.app.mjs +++ b/components/agrello/agrello.app.mjs @@ -1,11 +1,144 @@ +import { axios } from "@pipedream/platform"; + export default { type: "app", app: "agrello", - propDefinitions: {}, + propDefinitions: { + folderId: { + type: "string", + label: "Folder ID", + description: "The ID of the folder", + async options({ page }) { + return await this.listFolders({ + params: { + page, + }, + }); + }, + }, + documentId: { + type: "string", + label: "Document ID", + description: "The ID of the document", + async options({ + folderId, page, + }) { + const { content } = await this.listDocuments({ + folderId, + params: { + page, + }, + }); + return content.map(({ + id: value, name: label, + }) => ({ + label, + value, + })); + }, + }, + }, methods: { - // this.$auth contains connected account data - authKeys() { - console.log(Object.keys(this.$auth)); + _baseUrl() { + return "https://api.agrello.io/public/v3"; + }, + _headers(headers = {}) { + return { + ...headers, + Authorization: `Bearer ${this.$auth.oauth_access_token}`, + }; + }, + _makeRequest({ + $ = this, path, headers, ...opts + }) { + return axios($, { + url: this._baseUrl() + path, + headers: this._headers(headers), + ...opts, + }); + }, + async listFolders() { + const { content } = await this._makeRequest({ + path: "/folders", + }); + + const folders = []; + for (const parent of content) { + folders.push({ + label: `${parent.name}`, + value: parent.id, + }); + folders.push(...await this.getSubFolders(parent.name, parent.id)); + } + + return folders; + + }, + async getSubFolders(parentName, parentId) { + const folders = []; + const { subspaces } = await this._makeRequest({ + path: `/folders/${parentId}/folders`, + }); + for (const folder of subspaces) { + const label = `${parentName} - ${folder.name}`; + folders.push({ + label, + value: folder.id, + }); + folders.push(...await this.getSubFolders(label, folder.id)); + } + return folders; + }, + listDocuments({ + folderId, ...opts + }) { + return this._makeRequest({ + path: `/folders/${folderId}/containers`, + ...opts, + }); + }, + getDocument({ documentId }) { + return this._makeRequest({ + path: `/containers/${documentId}`, + }); + }, + createWebhook(opts = {}) { + return this._makeRequest({ + method: "POST", + path: "/webhooks", + ...opts, + }); + }, + deleteWebhook(hookId) { + return this._makeRequest({ + method: "DELETE", + path: `/webhooks/${hookId}`, + }); + }, + async *paginate({ + fn, params = {}, maxResults = null, ...opts + }) { + let hasMore = false; + let count = 0; + let page = 0; + + do { + params.page = page++; + const { content } = await fn({ + params, + ...opts, + }); + for (const d of content) { + yield d; + + if (maxResults && ++count === maxResults) { + return count; + } + } + + hasMore = content.length; + + } while (hasMore); }, }, -}; \ No newline at end of file +}; diff --git a/components/agrello/common/utils.mjs b/components/agrello/common/utils.mjs new file mode 100644 index 0000000000000..0cd1a12b6a4ba --- /dev/null +++ b/components/agrello/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/agrello/package.json b/components/agrello/package.json index e88166bb32ce1..ad8b43dc433d7 100644 --- a/components/agrello/package.json +++ b/components/agrello/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/agrello", - "version": "0.0.1", + "version": "0.1.0", "description": "Pipedream Agrello Components", "main": "agrello.app.mjs", "keywords": [ @@ -11,5 +11,9 @@ "author": "Pipedream (https://pipedream.com/)", "publishConfig": { "access": "public" + }, + "dependencies": { + "@pipedream/platform": "^3.0.1" } -} \ No newline at end of file +} + diff --git a/components/agrello/sources/common/base.mjs b/components/agrello/sources/common/base.mjs new file mode 100644 index 0000000000000..82aa089f5ecef --- /dev/null +++ b/components/agrello/sources/common/base.mjs @@ -0,0 +1,44 @@ +import agrello from "../../agrello.app.mjs"; + +export default { + props: { + agrello, + http: { + type: "$.interface.http", + customResponse: false, + }, + db: "$.service.db", + }, + methods: { + _setHookId(hookId) { + this.db.set("webhookId", hookId); + }, + _getHookId() { + return this.db.get("webhookId"); + }, + }, + hooks: { + async activate() { + const data = await this.agrello.createWebhook({ + data: { + event: this.getEvent(), + url: this.http.endpoint, + }, + }); + + this._setHookId(data.id); + }, + async deactivate() { + const webhookId = this._getHookId(); + await this.agrello.deleteWebhook(webhookId); + }, + }, + async run({ body: { event } }) { + const ts = Date.parse(new Date()); + this.$emit(event, { + id: `${event.containerId}-${ts}`, + summary: this.getSummary(event), + ts: ts, + }); + }, +}; diff --git a/components/agrello/sources/new-document/new-document.mjs b/components/agrello/sources/new-document/new-document.mjs new file mode 100644 index 0000000000000..d90003afb00f4 --- /dev/null +++ b/components/agrello/sources/new-document/new-document.mjs @@ -0,0 +1,78 @@ +import { DEFAULT_POLLING_SOURCE_TIMER_INTERVAL } from "@pipedream/platform"; +import agrello from "../../agrello.app.mjs"; +import sampleEmit from "./test-event.mjs"; + +export default { + key: "agrello-new-document", + name: "New Document Added to Folder", + description: "Emit new event when a user adds a document to a specific folder. [See the documentation](https://api.agrello.io/public/webjars/swagger-ui/index.html)", + version: "0.0.1", + type: "source", + dedupe: "unique", + props: { + agrello, + db: "$.service.db", + timer: { + type: "$.interface.timer", + default: { + intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, + }, + }, + folderId: { + propDefinition: [ + agrello, + "folderId", + ], + }, + }, + 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.agrello.paginate({ + fn: this.agrello.listDocuments, + folderId: this.folderId, + params: { + sort: "createdAt,DESC", + }, + maxResults, + }); + + let responseArray = []; + for await (const item of response) { + if (Date.parse(item.createdAt) <= lastDate) break; + responseArray.push(item); + } + + if (responseArray.length) { + if (maxResults && (responseArray.length > maxResults)) { + responseArray.length = maxResults; + } + this._setLastDate(Date.parse(responseArray[0].createdAt)); + } + + for (const item of responseArray.reverse()) { + this.$emit(item, { + id: item.id, + summary: `New Document: ${item.name}`, + ts: Date.parse(item.createdAt), + }); + } + }, + }, + hooks: { + async deploy() { + await this.emitEvent(25); + }, + }, + async run() { + await this.emitEvent(); + }, + sampleEmit, +}; diff --git a/components/agrello/sources/new-document/test-event.mjs b/components/agrello/sources/new-document/test-event.mjs new file mode 100644 index 0000000000000..20483cbb724ee --- /dev/null +++ b/components/agrello/sources/new-document/test-event.mjs @@ -0,0 +1,70 @@ +export default { + "id": "string", + "name": "string", + "status": "string", + "outputType": "PDF", + "size": 0, + "createdAt": "2024-09-09T21:28:21.391Z", + "updatedAt": "2024-09-09T21:28:21.391Z", + "parties": [ + { + "id": "string", + "createdAt": "2024-09-09T21:28:21.391Z", + "updatedAt": "2024-09-09T21:28:21.391Z", + "role": "VIEWER", + "identityId": "string", + "username": "string" + } + ], + "invitations": [ + { + "id": "string", + "createdAt": "2024-09-09T21:28:21.391Z", + "email": "string", + "expiresAt": "2024-09-09T21:28:21.391Z", + "role": "VIEWER" + } + ], + "files": [ + { + "id": "string", + "name": "string", + "mimeType": "string", + "size": 0, + "createdAt": "2024-09-09T21:28:21.391Z", + "updatedAt": "2024-09-09T21:28:21.391Z", + "variables": [ + { + "id": "string", + "name": "string", + "type": "TEXT", + "value": "string" + } + ] + } + ], + "signatures": [ + { + "id": "string", + "identityId": "string", + "username": "string", + "certificate": "string", + "certificateHash": "string", + "signature": "string", + "visualSignatureUrl": "string", + "contentHash": "string", + "signingTimestamp": "2024-09-09T21:28:21.391Z", + "type": "BASIC", + "signingMethod": "BARE", + "signatureProvider": "AGRELLO_ID", + "displayName": "string" + } + ], + "folderId": "string", + "workspaceId": "string", + "metadata": { + "additionalProp1": "string", + "additionalProp2": "string", + "additionalProp3": "string" + } +} \ No newline at end of file diff --git a/components/agrello/sources/new-signature-instant/new-signature-instant.mjs b/components/agrello/sources/new-signature-instant/new-signature-instant.mjs new file mode 100644 index 0000000000000..43f156fbc87c3 --- /dev/null +++ b/components/agrello/sources/new-signature-instant/new-signature-instant.mjs @@ -0,0 +1,22 @@ +import common from "../common/base.mjs"; +import sampleEmit from "./test-event.mjs"; + +export default { + ...common, + key: "agrello-new-signature-instant", + name: "New Signature Added to Document (Instant)", + description: "Emit new event when a signature is added to a container.", + version: "0.0.1", + type: "source", + dedupe: "unique", + methods: { + ...common.methods, + getEvent() { + return "DOCUMENT_SIGNATURE_ADDED"; + }, + getSummary(event) { + return `New signature added to container: ${event.containerId}`; + }, + }, + sampleEmit, +}; diff --git a/components/agrello/sources/new-signature-instant/test-event.mjs b/components/agrello/sources/new-signature-instant/test-event.mjs new file mode 100644 index 0000000000000..63e08339a8846 --- /dev/null +++ b/components/agrello/sources/new-signature-instant/test-event.mjs @@ -0,0 +1,10 @@ +export default { + "containerId": "068e7102-3565-4591-bf01-71f74e91dd1e", + "ownerId": "068e7102-3565-4591-bf01-71f74e91dd1e", + "userId": "068e7102-3565-4591-bf01-71f74e91dd1e", + "username": "email@test.com", + "spaceId": "068e7102-3565-4591-bf01-71f74e91dd1e", + "spaceOwnerId": "068e7102-3565-4591-bf01-71f74e91dd1e", + "workspaceId": "068e7102-3565-4591-bf01-71f74e91dd1e", + "workspaceOwnerId": "068e7102-3565-4591-bf01-71f74e91dd1e" +} \ No newline at end of file diff --git a/components/agrello/sources/new-signed-document-instant/new-signed-document-instant.mjs b/components/agrello/sources/new-signed-document-instant/new-signed-document-instant.mjs new file mode 100644 index 0000000000000..a53415dccb37d --- /dev/null +++ b/components/agrello/sources/new-signed-document-instant/new-signed-document-instant.mjs @@ -0,0 +1,22 @@ +import common from "../common/base.mjs"; +import sampleEmit from "./test-event.mjs"; + +export default { + ...common, + key: "agrello-new-signed-document-instant", + name: "New Signed Document (Instant)", + description: "Emit new event when a given document is signed by all parties.", + version: "0.0.1", + type: "source", + dedupe: "unique", + methods: { + ...common.methods, + getEvent() { + return "DOCUMENT_SIGNED"; + }, + getSummary(event) { + return `Document signed: ${event.containerId}`; + }, + }, + sampleEmit, +}; diff --git a/components/agrello/sources/new-signed-document-instant/test-event.mjs b/components/agrello/sources/new-signed-document-instant/test-event.mjs new file mode 100644 index 0000000000000..f30c2f5216387 --- /dev/null +++ b/components/agrello/sources/new-signed-document-instant/test-event.mjs @@ -0,0 +1,9 @@ +export default { + "containerId": "068e7102-3565-4591-bf01-71f74e91dd1e", + "userId": "068e7102-3565-4591-bf01-71f74e91dd1e", + "signerCount": 1, + "spaceId": "068e7102-3565-4591-bf01-71f74e91dd1e", + "spaceOwnerId": "068e7102-3565-4591-bf01-71f74e91dd1e", + "workspaceId": "068e7102-3565-4591-bf01-71f74e91dd1e", + "workspaceOwnerId": "068e7102-3565-4591-bf01-71f74e91dd1e" +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index eb4f815bd773b..bf362a2cf22d0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -316,7 +316,10 @@ importers: specifiers: {} components/agrello: - specifiers: {} + specifiers: + '@pipedream/platform': ^3.0.1 + dependencies: + '@pipedream/platform': 3.0.1 components/ahrefs: specifiers: {}