diff --git a/components/typeflowai/package.json b/components/typeflowai/package.json index 167fc4ce6447d..226dc9512cff4 100644 --- a/components/typeflowai/package.json +++ b/components/typeflowai/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/typeflowai", - "version": "0.0.1", + "version": "0.1.0", "description": "Pipedream TypeflowAI Components", "main": "typeflowai.app.mjs", "keywords": [ @@ -11,5 +11,8 @@ "author": "Pipedream (https://pipedream.com/)", "publishConfig": { "access": "public" + }, + "dependencies": { + "@pipedream/platform": "^3.0.0" } -} \ No newline at end of file +} diff --git a/components/typeflowai/sources/common/base.mjs b/components/typeflowai/sources/common/base.mjs new file mode 100644 index 0000000000000..b6c396d586741 --- /dev/null +++ b/components/typeflowai/sources/common/base.mjs @@ -0,0 +1,54 @@ +import typeflowai from "../../typeflowai.app.mjs"; + +export default { + props: { + typeflowai, + db: "$.service.db", + http: "$.interface.http", + workflowIds: { + propDefinition: [ + typeflowai, + "workflowIds", + ], + }, + }, + hooks: { + async activate() { + const { data: { id } } = await this.typeflowai.createWebhook({ + data: { + url: this.http.endpoint, + triggers: this.getTriggers(), + workflowIds: this.workflowIds, + }, + }); + this._setHookId(id); + }, + async deactivate() { + const hookId = this._getHookId(); + if (hookId) { + await this.typeflowai.deleteWebhook({ + hookId, + }); + } + }, + }, + methods: { + _getHookId() { + return this.db.get("hookId"); + }, + _setHookId(hookId) { + this.db.set("hookId", hookId); + }, + getTriggers() { + throw new Error("getTriggers is not implemented"); + }, + generateMeta() { + throw new Error("generateMeta is not implemented"); + }, + }, + async run(event) { + const { body } = event; + const meta = this.generateMeta(body.data); + this.$emit(body, meta); + }, +}; diff --git a/components/typeflowai/sources/new-response-created/new-response-created.mjs b/components/typeflowai/sources/new-response-created/new-response-created.mjs new file mode 100644 index 0000000000000..bb356a3c7a216 --- /dev/null +++ b/components/typeflowai/sources/new-response-created/new-response-created.mjs @@ -0,0 +1,28 @@ +import common from "../common/base.mjs"; +import sampleEmit from "./test-event.mjs"; + +export default { + ...common, + key: "typeflowai-new-response-created", + name: "New Response Created (Instant)", + description: "Emit new event when a response is created for a workflow in TypeflowAI. [See the documentation](https://typeflowai.com/docs/api/management/webhooks)", + version: "0.0.1", + type: "source", + dedupe: "unique", + methods: { + ...common.methods, + getTriggers() { + return [ + "responseCreated", + ]; + }, + generateMeta(data) { + return { + id: data.id, + summary: `New Response Created with ID: ${data.id}`, + ts: Date.parse(data.createdAt), + }; + }, + }, + sampleEmit, +}; diff --git a/components/typeflowai/sources/new-response-created/test-event.mjs b/components/typeflowai/sources/new-response-created/test-event.mjs new file mode 100644 index 0000000000000..6dbd546896db6 --- /dev/null +++ b/components/typeflowai/sources/new-response-created/test-event.mjs @@ -0,0 +1,34 @@ +export default { + "webhookId": "clysvncl1000h3zacrgownemj", + "event": "responseCreated", + "data": { + "id": "clysvvfoy00016uyngkpnkfa6", + "createdAt": "2024-07-19T15:57:13.138Z", + "updatedAt": "2024-07-19T15:57:13.138Z", + "workflowId": "clyovrgyj00001xs7dp1q82pn", + "person": null, + "personAttributes": null, + "finished": false, + "data": { + "inputType": "text", + "lead-name": "Bob Ross" + }, + "ttc": { + "lead-name": 202776.6000000238 + }, + "notes": [], + "tags": [], + "meta": { + "source": "", + "url": "https://dashboard.typeflowai.com/s/clyovrgyj00001xs7dp1q82pn", + "userAgent": { + "browser": "Chrome", + "os": "Mac OS", + "device": "desktop" + }, + "country": "US" + }, + "singleUseId": null, + "language": "default" + } +} \ No newline at end of file diff --git a/components/typeflowai/sources/new-response-finished/new-response-finished.mjs b/components/typeflowai/sources/new-response-finished/new-response-finished.mjs new file mode 100644 index 0000000000000..caec512793343 --- /dev/null +++ b/components/typeflowai/sources/new-response-finished/new-response-finished.mjs @@ -0,0 +1,28 @@ +import common from "../common/base.mjs"; +import sampleEmit from "./test-event.mjs"; + +export default { + ...common, + key: "typeflowai-new-response-finished", + name: "New Response Finished (Instant)", + description: "Emit new event when a response is marked as finished. [See the documentation](https://typeflowai.com/docs/api/management/webhooks)", + version: "0.0.1", + type: "source", + dedupe: "unique", + methods: { + ...common.methods, + getTriggers() { + return [ + "responseFinished", + ]; + }, + generateMeta(data) { + return { + id: data.id, + summary: `New Response Finished with ID: ${data.id}`, + ts: Date.now(), + }; + }, + }, + sampleEmit, +}; diff --git a/components/typeflowai/sources/new-response-finished/test-event.mjs b/components/typeflowai/sources/new-response-finished/test-event.mjs new file mode 100644 index 0000000000000..16fd830ab9133 --- /dev/null +++ b/components/typeflowai/sources/new-response-finished/test-event.mjs @@ -0,0 +1,35 @@ +export default { + "webhookId": "clysvosum000j3zacdfyu8214", + "event": "responseFinished", + "data": { + "id": "clysxxx5c000d6uynim7hydd4", + "createdAt": "2024-07-19T16:55:08.305Z", + "updatedAt": "2024-07-19T16:55:08.305Z", + "workflowId": "clysxvqnt0000147rgp14gxjs", + "person": null, + "personAttributes": null, + "finished": true, + "data": { + "inputType": "text", + "x45vvrnfd06yl46ay1iwtpj1": "hello world" + }, + "ttc": { + "_total": 9927.100000023842, + "x45vvrnfd06yl46ay1iwtpj1": 9927.100000023842 + }, + "notes": [], + "tags": [], + "meta": { + "source": "", + "url": "https://dashboard.typeflowai.com/s/clysxvqnt0000147rgp14gxjs", + "userAgent": { + "browser": "Chrome", + "os": "Mac OS", + "device": "desktop" + }, + "country": "US" + }, + "singleUseId": null, + "language": "default" + } +} \ No newline at end of file diff --git a/components/typeflowai/sources/new-response-updated/new-response-updated.mjs b/components/typeflowai/sources/new-response-updated/new-response-updated.mjs new file mode 100644 index 0000000000000..4f747e666a9e0 --- /dev/null +++ b/components/typeflowai/sources/new-response-updated/new-response-updated.mjs @@ -0,0 +1,29 @@ +import common from "../common/base.mjs"; +import sampleEmit from "./test-event.mjs"; + +export default { + ...common, + key: "typeflowai-new-response-updated", + name: "New Response Updated (Instant)", + description: "Emit new event when a response is updated within a workflow. [See the documentation](https://typeflowai.com/docs/api/management/webhooks)", + version: "0.0.1", + type: "source", + dedupe: "unique", + methods: { + ...common.methods, + getTriggers() { + return [ + "responseUpdated", + ]; + }, + generateMeta(data) { + const ts = Date.parse(data.updatedAt); + return { + id: `${data.id}-${ts}`, + summary: `New Response Updated with ID: ${data.id}`, + ts, + }; + }, + }, + sampleEmit, +}; diff --git a/components/typeflowai/sources/new-response-updated/test-event.mjs b/components/typeflowai/sources/new-response-updated/test-event.mjs new file mode 100644 index 0000000000000..de7f65e2f004f --- /dev/null +++ b/components/typeflowai/sources/new-response-updated/test-event.mjs @@ -0,0 +1,36 @@ +export default { + "webhookId": "clysvo37m000i3zacvkle85xz", + "event": "responseUpdated", + "data": { + "id": "clysvvfoy00016uyngkpnkfa6", + "createdAt": "2024-07-19T15:57:13.138Z", + "updatedAt": "2024-07-19T15:57:29.219Z", + "workflowId": "clyovrgyj00001xs7dp1q82pn", + "person": null, + "personAttributes": null, + "finished": false, + "data": { + "inputType": "text", + "lead-name": "Bob Ross", + "lead-company-do": "Art" + }, + "ttc": { + "lead-name": 202776.6000000238, + "lead-company-do": 17130.09999999404 + }, + "notes": [], + "tags": [], + "meta": { + "source": "", + "url": "https://dashboard.typeflowai.com/s/clyovrgyj00001xs7dp1q82pn", + "userAgent": { + "browser": "Chrome", + "os": "Mac OS", + "device": "desktop" + }, + "country": "US" + }, + "singleUseId": null, + "language": "default" + } +} \ No newline at end of file diff --git a/components/typeflowai/typeflowai.app.mjs b/components/typeflowai/typeflowai.app.mjs index d220f356faf37..2155b68c668f7 100644 --- a/components/typeflowai/typeflowai.app.mjs +++ b/components/typeflowai/typeflowai.app.mjs @@ -1,11 +1,63 @@ +import { axios } from "@pipedream/platform"; + export default { type: "app", app: "typeflowai", - propDefinitions: {}, + propDefinitions: { + workflowIds: { + type: "string[]", + label: "Workflow IDs", + description: "List of workflow IDs that will trigger the webhook. If not provided, the webhook will be triggered for all workflows.", + async options() { + const { data } = await this.listWorkflows(); + return data?.map(({ + id: value, name: label, + }) => ({ + value, + label, + })) || []; + }, + }, + }, methods: { - // this.$auth contains connected account data - authKeys() { - console.log(Object.keys(this.$auth)); + _baseUrl() { + return "https://dashboard.typeflowai.com/api/v1"; + }, + _makeRequest(opts = {}) { + const { + $ = this, + path, + ...otherOpts + } = opts; + return axios($, { + ...otherOpts, + url: `${this._baseUrl()}${path}`, + headers: { + "x-api-key": this.$auth.api_key, + }, + }); + }, + listWorkflows(opts = {}) { + return this._makeRequest({ + path: "/management/workflows", + ...opts, + }); + }, + createWebhook(opts = {}) { + return this._makeRequest({ + method: "POST", + path: "/webhooks", + ...opts, + }); + }, + deleteWebhook({ + hookId, ...opts + }) { + return this._makeRequest({ + method: "DELETE", + path: `/webhooks/${hookId}`, + ...opts, + }); }, }, -}; \ No newline at end of file +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 55908b64e245b..e9b0cb5ff42d8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9677,7 +9677,10 @@ importers: specifiers: {} components/typeflowai: - specifiers: {} + specifiers: + '@pipedream/platform': ^3.0.0 + dependencies: + '@pipedream/platform': 3.0.0 components/typeform: specifiers: