From 400b10fd828eb7780b7e3ede4a48957ad670d5d4 Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Tue, 25 Feb 2025 11:55:54 -0300 Subject: [PATCH 1/3] opnform init --- components/opnform/opnform.app.mjs | 95 ++++++++++++++++++- .../new-submission-instant.mjs | 92 ++++++++++++++++++ 2 files changed, 185 insertions(+), 2 deletions(-) create mode 100644 components/opnform/sources/new-submission-instant/new-submission-instant.mjs diff --git a/components/opnform/opnform.app.mjs b/components/opnform/opnform.app.mjs index 5d7a7fb15c1ce..a4b537a0ab2f8 100644 --- a/components/opnform/opnform.app.mjs +++ b/components/opnform/opnform.app.mjs @@ -1,11 +1,102 @@ +import { axios } from "@pipedream/platform"; + export default { type: "app", app: "opnform", - propDefinitions: {}, + version: "0.0.{{ts}}", + propDefinitions: { + workspaceId: { + type: "string", + label: "Workspace ID", + description: "The ID of the workspace containing the forms.", + }, + formId: { + type: "string", + label: "Form", + description: "Select the form to monitor for new submissions.", + async options() { + const { workspaceId } = this; + const forms = await this.listForms({ + workspaceId, + }); + return forms.map((form) => ({ + label: form.name, + value: form.id, + })); + }, + }, + }, methods: { - // this.$auth contains connected account data authKeys() { console.log(Object.keys(this.$auth)); }, + _baseUrl() { + return "https://api.opnform.com/external/zapier"; + }, + async _makeRequest(opts = {}) { + const { + $ = this, method = "GET", path = "/", headers, params, data, ...otherOpts + } = opts; + return axios($, { + method, + url: this._baseUrl() + path, + headers: { + ...headers, + Authorization: `Bearer ${this.$auth.api_key}`, + }, + params, + data, + ...otherOpts, + }); + }, + async listForms({ + workspaceId, ...opts + } = {}) { + if (!workspaceId) { + throw new Error("workspaceId is required to list forms."); + } + return this._makeRequest({ + method: "GET", + path: "/forms", + params: { + workspace_id: workspaceId, + }, + ...opts, + }); + }, + async createWebhook({ + hookUrl, formId, ...opts + } = {}) { + return this._makeRequest({ + method: "POST", + path: "/webhook", + data: { + hookUrl, + form_id: formId, + }, + ...opts, + }); + }, + async paginate(fn, ...opts) { + let results = []; + let response; + let hasMore = true; + let page = 1; + + while (hasMore) { + response = await fn({ + page, + ...opts, + }); + if (Array.isArray(response) && response.length > 0) { + results = results.concat(response); + page += 1; + } else { + hasMore = false; + } + } + + return results; + }, }, }; diff --git a/components/opnform/sources/new-submission-instant/new-submission-instant.mjs b/components/opnform/sources/new-submission-instant/new-submission-instant.mjs new file mode 100644 index 0000000000000..ca6261dcc1738 --- /dev/null +++ b/components/opnform/sources/new-submission-instant/new-submission-instant.mjs @@ -0,0 +1,92 @@ +import { axios } from "@pipedream/platform"; +import opnform from "../../opnform.app.mjs"; + +export default { + key: "opnform-new-submission-instant", + name: "New Submission Instant", + description: "Emit a new event when a form receives a submission. [See the documentation]()", + version: "0.0.{{ts}}", + type: "source", + dedupe: "unique", + props: { + opnform: { + type: "app", + app: "opnform", + }, + workspaceId: { + propDefinition: [ + "opnform", + "workspaceId", + ], + }, + formId: { + propDefinition: [ + "opnform", + "formId", + ], + }, + http: { + type: "$.interface.http", + customResponse: true, + }, + db: "$.service.db", + }, + hooks: { + async activate() { + const hookUrl = this.http.endpoint; + const webhook = await this.opnform.createWebhook({ + hookUrl, + formId: this.formId, + }); + await this.db.set("webhookId", webhook.id); + }, + async deactivate() { + const webhookId = await this.db.get("webhookId"); + if (webhookId) { + await this.opnform._makeRequest({ + method: "DELETE", + path: `/webhook/${webhookId}`, + }); + await this.db.delete("webhookId"); + } + }, + async deploy() { + const submissions = await this.opnform.paginate( + this.opnform._makeRequest.bind(this.opnform), + { + method: "GET", + path: `/forms/${this.formId}/submissions`, + params: { + limit: 50, + }, + }, + ); + + submissions.reverse().forEach((submission) => { + this.$emit( + submission, + { + id: submission.id || Date.now().toString(), + summary: `New submission for form ${submission.formName}`, + ts: submission.createdAt + ? Date.parse(submission.createdAt) + : Date.now(), + }, + ); + }); + }, + }, + async run(event) { + const submission = event.body; + const id = submission.id || Date.now().toString(); + const summary = `New submission for form ${submission.formName}`; + const ts = submission.createdAt + ? Date.parse(submission.createdAt) + : Date.now(); + this.$emit(submission, { + id, + summary, + ts, + }); + }, +}; From fe1cacd35f3cfe583d7cb5d69600cc638c8483e0 Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Wed, 26 Feb 2025 11:50:50 -0300 Subject: [PATCH 2/3] [Components] opnform #15639 Sources - New Submission (Instant) --- components/opnform/opnform.app.mjs | 93 ++++++++----------- components/opnform/package.json | 5 +- .../new-submission-instant.mjs | 86 ++++++----------- .../new-submission-instant/test-event.mjs | 24 +++++ 4 files changed, 91 insertions(+), 117 deletions(-) create mode 100644 components/opnform/sources/new-submission-instant/test-event.mjs diff --git a/components/opnform/opnform.app.mjs b/components/opnform/opnform.app.mjs index a4b537a0ab2f8..2f182b96df28f 100644 --- a/components/opnform/opnform.app.mjs +++ b/components/opnform/opnform.app.mjs @@ -3,21 +3,30 @@ import { axios } from "@pipedream/platform"; export default { type: "app", app: "opnform", - version: "0.0.{{ts}}", propDefinitions: { workspaceId: { type: "string", label: "Workspace ID", description: "The ID of the workspace containing the forms.", + async options() { + const worspaces = await this.listWorkspaces(); + return worspaces.map(({ + id: value, name: label, + }) => ({ + label, + value, + })); + }, }, formId: { type: "string", label: "Form", description: "Select the form to monitor for new submissions.", - async options() { - const { workspaceId } = this; + async options({ workspaceId }) { const forms = await this.listForms({ - workspaceId, + params: { + workspace_id: workspaceId, + }, }); return forms.map((form) => ({ label: form.name, @@ -27,76 +36,48 @@ export default { }, }, methods: { - authKeys() { - console.log(Object.keys(this.$auth)); - }, _baseUrl() { return "https://api.opnform.com/external/zapier"; }, - async _makeRequest(opts = {}) { - const { - $ = this, method = "GET", path = "/", headers, params, data, ...otherOpts - } = opts; + _headers() { + return { + Authorization: `Bearer ${this.$auth.api_key}`, + }; + }, + _makeRequest({ + $ = this, path, ...opts + }) { return axios($, { - method, url: this._baseUrl() + path, - headers: { - ...headers, - Authorization: `Bearer ${this.$auth.api_key}`, - }, - params, - data, - ...otherOpts, + headers: this._headers(), + ...opts, }); }, - async listForms({ - workspaceId, ...opts - } = {}) { - if (!workspaceId) { - throw new Error("workspaceId is required to list forms."); - } + listForms(opts = {}) { return this._makeRequest({ - method: "GET", path: "/forms", - params: { - workspace_id: workspaceId, - }, ...opts, }); }, - async createWebhook({ - hookUrl, formId, ...opts - } = {}) { + listWorkspaces(opts = {}) { + return this._makeRequest({ + path: "/workspaces", + ...opts, + }); + }, + createWebhook(opts = {}) { return this._makeRequest({ method: "POST", path: "/webhook", - data: { - hookUrl, - form_id: formId, - }, ...opts, }); }, - async paginate(fn, ...opts) { - let results = []; - let response; - let hasMore = true; - let page = 1; - - while (hasMore) { - response = await fn({ - page, - ...opts, - }); - if (Array.isArray(response) && response.length > 0) { - results = results.concat(response); - page += 1; - } else { - hasMore = false; - } - } - - return results; + deleteWebhook(opts = {}) { + return this._makeRequest({ + method: "DELETE", + path: "/webhook", + ...opts, + }); }, }, }; diff --git a/components/opnform/package.json b/components/opnform/package.json index 5aa0ca20c8e7e..bdb9666195ab1 100644 --- a/components/opnform/package.json +++ b/components/opnform/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/opnform", - "version": "0.0.1", + "version": "0.1.0", "description": "Pipedream OpnForm Components", "main": "opnform.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/opnform/sources/new-submission-instant/new-submission-instant.mjs b/components/opnform/sources/new-submission-instant/new-submission-instant.mjs index ca6261dcc1738..e37adeb66f873 100644 --- a/components/opnform/sources/new-submission-instant/new-submission-instant.mjs +++ b/components/opnform/sources/new-submission-instant/new-submission-instant.mjs @@ -1,92 +1,58 @@ -import { axios } from "@pipedream/platform"; import opnform from "../../opnform.app.mjs"; +import sampleEmit from "./test-event.mjs"; export default { key: "opnform-new-submission-instant", name: "New Submission Instant", - description: "Emit a new event when a form receives a submission. [See the documentation]()", - version: "0.0.{{ts}}", + description: "Emit new event when a form receives a submission.", + version: "0.0.1", type: "source", dedupe: "unique", props: { - opnform: { - type: "app", - app: "opnform", - }, + opnform, + http: "$.interface.http", + db: "$.service.db", workspaceId: { propDefinition: [ - "opnform", + opnform, "workspaceId", ], }, formId: { propDefinition: [ - "opnform", + opnform, "formId", + ({ workspaceId }) => ({ + workspaceId, + }), ], }, - http: { - type: "$.interface.http", - customResponse: true, - }, - db: "$.service.db", }, hooks: { async activate() { - const hookUrl = this.http.endpoint; - const webhook = await this.opnform.createWebhook({ - hookUrl, - formId: this.formId, + await this.opnform.createWebhook({ + data: { + hookUrl: this.http.endpoint, + form_id: this.formId, + }, }); - await this.db.set("webhookId", webhook.id); }, async deactivate() { - const webhookId = await this.db.get("webhookId"); - if (webhookId) { - await this.opnform._makeRequest({ - method: "DELETE", - path: `/webhook/${webhookId}`, - }); - await this.db.delete("webhookId"); - } - }, - async deploy() { - const submissions = await this.opnform.paginate( - this.opnform._makeRequest.bind(this.opnform), - { - method: "GET", - path: `/forms/${this.formId}/submissions`, - params: { - limit: 50, - }, + await this.opnform.deleteWebhook({ + data: { + hookUrl: this.http.endpoint, + form_id: this.formId, }, - ); - - submissions.reverse().forEach((submission) => { - this.$emit( - submission, - { - id: submission.id || Date.now().toString(), - summary: `New submission for form ${submission.formName}`, - ts: submission.createdAt - ? Date.parse(submission.createdAt) - : Date.now(), - }, - ); }); }, }, - async run(event) { - const submission = event.body; - const id = submission.id || Date.now().toString(); - const summary = `New submission for form ${submission.formName}`; - const ts = submission.createdAt - ? Date.parse(submission.createdAt) - : Date.now(); - this.$emit(submission, { - id, - summary, + async run({ body }) { + const ts = Date.now(); + this.$emit(body, { + id: `${body.form_slug}-${ts}`, + summary: `New submission for "${body.form_title}"`, ts, }); }, + sampleEmit, }; diff --git a/components/opnform/sources/new-submission-instant/test-event.mjs b/components/opnform/sources/new-submission-instant/test-event.mjs new file mode 100644 index 0000000000000..4f17754a4ce18 --- /dev/null +++ b/components/opnform/sources/new-submission-instant/test-event.mjs @@ -0,0 +1,24 @@ +export default { + "form_title": "My Form", + "form_slug": "my-form-dtewbq", + "submission": { + "Name": "User Name", + "Email": "user@email.com", + "Message": "User Message" + }, + "data": { + "3cc8fbba-1234-1234-979d-0e81d8f6845c": { + "value": "USer Name", + "name": "Name" + }, + "9a1778ff-1234-1234-a62c-197dae1ed3c0": { + "value": "user@email.com", + "name": "Email" + }, + "ddd28630-1234-1234-bbe5-4f58c485d470": { + "value": "USer Message", + "name": "Message" + } + }, + "message": "Please do not use the `submission` field. It is deprecated and will be removed in the future." +} \ No newline at end of file From b1aeb773be0758960122d3a5e78d94a4ba755909 Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Wed, 26 Feb 2025 11:51:47 -0300 Subject: [PATCH 3/3] pnpm update --- pnpm-lock.yaml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 25f2f4f8316b0..4c982a0f5efbe 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6660,8 +6660,7 @@ importers: specifier: ^1.5.1 version: 1.6.6 - components/kindo: - specifiers: {} + components/kindo: {} components/kingsumo: dependencies: @@ -7871,8 +7870,7 @@ importers: components/mindmeister: {} - components/mindstudio: - specifiers: {} + components/mindstudio: {} components/minio: {} @@ -8787,7 +8785,11 @@ importers: specifier: ^0.9.0 version: 0.9.0 - components/opnform: {} + components/opnform: + dependencies: + '@pipedream/platform': + specifier: ^3.0.3 + version: 3.0.3 components/opsgenie: dependencies: @@ -12295,8 +12297,7 @@ importers: components/synthflow: {} - components/systeme_io: - specifiers: {} + components/systeme_io: {} components/t2m_url_shortener: {}