diff --git a/components/v7_go/actions/create-entity/create-entity.mjs b/components/v7_go/actions/create-entity/create-entity.mjs new file mode 100644 index 0000000000000..30d3d01c1f72b --- /dev/null +++ b/components/v7_go/actions/create-entity/create-entity.mjs @@ -0,0 +1,56 @@ +import v7Go from "../../v7_go.app.mjs"; + +export default { + key: "v7_go-create-entity", + name: "Create Entity", + description: "Triggers the creation of a new entity. [See the documentation](https://docs.go.v7labs.com/reference/create-entities-programmatically)", + version: "0.0.1", + type: "action", + props: { + v7Go, + workspaceId: { + propDefinition: [ + v7Go, + "workspaceId", + ], + }, + projectId: { + propDefinition: [ + v7Go, + "projectId", + ({ workspaceId }) => ({ + workspaceId, + }), + ], + reloadProps: true, + }, + }, + async additionalProps() { + if (this.projectId) { + return await this.v7Go.prepareProps({ + workspaceId: this.workspaceId, + projectId: this.projectId, + }); + } + }, + async run({ $ }) { + const { + v7Go, + workspaceId, + projectId, + ...fields + } = this; + + const response = await v7Go.createEntity({ + $, + workspaceId, + projectId, + data: { + fields: v7Go.parseObject(fields), + }, + }); + + $.export("$summary", `Successfully created entity with ID ${response.id}`); + return response; + }, +}; diff --git a/components/v7_go/actions/create-project/create-project.mjs b/components/v7_go/actions/create-project/create-project.mjs new file mode 100644 index 0000000000000..7c5ffeb0e3459 --- /dev/null +++ b/components/v7_go/actions/create-project/create-project.mjs @@ -0,0 +1,34 @@ +import v7Go from "../../v7_go.app.mjs"; + +export default { + key: "v7_go-create-project", + name: "Create Project", + description: "Initiates the creation of a new project with a unique project identifier. [See the documentation](https://docs.go.v7labs.com/reference/project-create)", + version: "0.0.1", + type: "action", + props: { + v7Go, + workspaceId: { + propDefinition: [ + v7Go, + "workspaceId", + ], + }, + name: { + type: "string", + label: "Name", + description: "The name of the project.", + }, + }, + async run({ $ }) { + const response = await this.v7Go.createProject({ + $, + workspaceId: this.workspaceId, + data: { + name: this.name, + }, + }); + $.export("$summary", `Successfully created project with ID ${response.id}`); + return response; + }, +}; diff --git a/components/v7_go/actions/update-entity/update-entity.mjs b/components/v7_go/actions/update-entity/update-entity.mjs new file mode 100644 index 0000000000000..f945d7a19132a --- /dev/null +++ b/components/v7_go/actions/update-entity/update-entity.mjs @@ -0,0 +1,71 @@ +import v7Go from "../../v7_go.app.mjs"; + +export default { + key: "v7_go-update-entity", + name: "Update Entity", + description: "Executes an update on an existing entity. [See the documentation](https://docs.go.v7labs.com/reference/entity-update-values)", + version: "0.0.1", + type: "action", + props: { + v7Go, + workspaceId: { + propDefinition: [ + v7Go, + "workspaceId", + ], + }, + projectId: { + propDefinition: [ + v7Go, + "projectId", + ({ workspaceId }) => ({ + workspaceId, + }), + ], + }, + entityId: { + propDefinition: [ + v7Go, + "entityId", + ({ + workspaceId, projectId, + }) => ({ + workspaceId, + projectId, + }), + ], + reloadProps: true, + }, + }, + async additionalProps() { + if (this.entityId) { + return await this.v7Go.prepareProps({ + workspaceId: this.workspaceId, + projectId: this.projectId, + entityId: this.entityId, + }); + } + }, + async run({ $ }) { + const { + v7Go, + workspaceId, + projectId, + entityId, + ...fields + } = this; + + const response = await v7Go.updateEntity({ + $, + workspaceId, + projectId, + entityId, + data: { + fields: v7Go.parseObject(fields), + }, + }); + + $.export("$summary", `Successfully updated entity with ID ${response.id}`); + return response; + }, +}; diff --git a/components/v7_go/common/constants.mjs b/components/v7_go/common/constants.mjs new file mode 100644 index 0000000000000..ea830c15a04cb --- /dev/null +++ b/components/v7_go/common/constants.mjs @@ -0,0 +1 @@ +export const LIMIT = 100; diff --git a/components/v7_go/package.json b/components/v7_go/package.json index e4687af68787f..10257aacb4f1c 100644 --- a/components/v7_go/package.json +++ b/components/v7_go/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/v7_go", - "version": "0.0.1", + "version": "0.1.0", "description": "Pipedream V7 Go Components", "main": "v7_go.app.mjs", "keywords": [ @@ -11,5 +11,9 @@ "author": "Pipedream (https://pipedream.com/)", "publishConfig": { "access": "public" + }, + "dependencies": { + "@pipedream/platform": "^3.0.0" } -} \ No newline at end of file +} + diff --git a/components/v7_go/sources/common/base.mjs b/components/v7_go/sources/common/base.mjs new file mode 100644 index 0000000000000..4637d081dfda9 --- /dev/null +++ b/components/v7_go/sources/common/base.mjs @@ -0,0 +1,58 @@ +import v7Go from "../../v7_go.app.mjs"; + +export default { + props: { + v7Go, + http: { + type: "$.interface.http", + customResponse: false, + }, + db: "$.service.db", + workspaceId: { + propDefinition: [ + v7Go, + "workspaceId", + ], + }, + projectId: { + propDefinition: [ + v7Go, + "projectId", + ({ workspaceId }) => ({ + workspaceId, + }), + ], + }, + }, + hooks: { + async activate() { + const data = await this.v7Go.createWebhook({ + workspaceId: this.workspaceId, + data: { + action: { + type: "webhook", + url: this.http.endpoint, + }, + events: this.getEvents(), + project_id: this.projectId, + }, + }); + this.db.set("webhookId", data.id); + }, + async deactivate() { + const webhookId = this.db.get("webhookId"); + await this.v7Go.deleteWebhook({ + workspaceId: this.workspaceId, + webhookId, + }); + }, + }, + async run({ body }) { + const ts = Date.parse(new Date()); + this.$emit(body, { + id: `${body.entity.id}-${ts}`, + summary: this.getSummary(body), + ts: ts, + }); + }, +}; diff --git a/components/v7_go/sources/complete-entity-instant/complete-entity-instant.mjs b/components/v7_go/sources/complete-entity-instant/complete-entity-instant.mjs new file mode 100644 index 0000000000000..4d1ba5b2cc6ab --- /dev/null +++ b/components/v7_go/sources/complete-entity-instant/complete-entity-instant.mjs @@ -0,0 +1,24 @@ +import common from "../common/base.mjs"; +import sampleEmit from "./test-event.mjs"; + +export default { + ...common, + key: "v7_go-complete-entity-instant", + name: "New Complete Entity (Instant)", + description: "Emit new event when all fields of an entity are completed in V7 Go.", + version: "0.0.1", + type: "source", + dedupe: "unique", + methods: { + ...common.methods, + getEvents() { + return { + "entity.all_fields_completed": true, + }; + }, + getSummary({ entity }) { + return `Entity all fields completed: ${entity.id}`; + }, + }, + sampleEmit, +}; diff --git a/components/v7_go/sources/complete-entity-instant/test-event.mjs b/components/v7_go/sources/complete-entity-instant/test-event.mjs new file mode 100644 index 0000000000000..b8c4e359b951c --- /dev/null +++ b/components/v7_go/sources/complete-entity-instant/test-event.mjs @@ -0,0 +1,25 @@ +export default { + "type": "entity.all_fields_completed", + "entity": { + "id": "12345678-1234-1234-1234-123456789012", + "fields": { + "text-field-test": { + "data": { + "value": "field value", + "value_type": "manual", + "additional_value": null, + "additional_value_type": null + }, + "status": "complete", + "error_message": null, + "inserted_at": "2024-07-23T14:28:53.480497Z", + "updated_at": "2024-07-23T14:28:55.255082Z", + "property_id": "12345678-1234-1234-1234-123456789012", + "property_type": "text" + } + }, + "inserted_at": "2024-07-23T14:28:53.479981Z", + "updated_at": "2024-07-23T14:28:53.479981Z", + "project_id": "12345678-1234-1234-1234-123456789012" + } +} \ No newline at end of file diff --git a/components/v7_go/sources/complete-field-instant/complete-field-instant.mjs b/components/v7_go/sources/complete-field-instant/complete-field-instant.mjs new file mode 100644 index 0000000000000..7fe501692cb5b --- /dev/null +++ b/components/v7_go/sources/complete-field-instant/complete-field-instant.mjs @@ -0,0 +1,24 @@ +import common from "../common/base.mjs"; +import sampleEmit from "./test-event.mjs"; + +export default { + ...common, + key: "v7_go-complete-field-instant", + name: "New Field Completion (Instant)", + description: "Emit new event when a field within an entity is completed in V7 Go.", + version: "0.0.1", + type: "source", + dedupe: "unique", + methods: { + ...common.methods, + getEvents() { + return { + "entity.field_completed": true, + }; + }, + getSummary({ entity }) { + return `Field completed for entity ${entity.id}`; + }, + }, + sampleEmit, +}; diff --git a/components/v7_go/sources/complete-field-instant/test-event.mjs b/components/v7_go/sources/complete-field-instant/test-event.mjs new file mode 100644 index 0000000000000..073bb0ead5bc3 --- /dev/null +++ b/components/v7_go/sources/complete-field-instant/test-event.mjs @@ -0,0 +1,39 @@ +export default { + "type": "entity.field_completed", + "entity": { + "id": "12345678-1234-1234-1234-123456789012", + "fields": { + "text-field-test-1": { + "data": { + "value": "field value", + "value_type": "manual", + "additional_value": null, + "additional_value_type": null + }, + "status": "complete", + "error_message": null, + "inserted_at": "2024-07-23T14:35:21.061761Z", + "updated_at": "2024-07-23T14:35:37.057732Z", + "property_id": "12345678-1234-1234-1234-123456789012", + "property_type": "text" + }, + "text-field-test-2": { + "data": { + "value": "field value", + "value_type": "manual", + "additional_value": null, + "additional_value_type": null + }, + "status": "complete", + "error_message": null, + "inserted_at": "2024-07-23T14:28:53.480497Z", + "updated_at": "2024-07-23T14:28:55.255082Z", + "property_id": "12345678-1234-1234-1234-123456789012", + "property_type": "text" + } + }, + "inserted_at": "2024-07-23T14:28:53.479981Z", + "updated_at": "2024-07-23T14:28:53.479981Z", + "project_id": "12345678-1234-1234-1234-123456789012" + } +} \ No newline at end of file diff --git a/components/v7_go/sources/new-entity-instant/new-entity-instant.mjs b/components/v7_go/sources/new-entity-instant/new-entity-instant.mjs new file mode 100644 index 0000000000000..145e600432d58 --- /dev/null +++ b/components/v7_go/sources/new-entity-instant/new-entity-instant.mjs @@ -0,0 +1,24 @@ +import common from "../common/base.mjs"; +import sampleEmit from "./test-event.mjs"; + +export default { + ...common, + key: "v7_go-new-entity-instant", + name: "New Entity Created (Instant)", + description: "Emit new event when an entity is created.", + version: "0.0.1", + type: "source", + dedupe: "unique", + methods: { + ...common.methods, + getEvents() { + return { + "entity.created": true, + }; + }, + getSummary({ entity }) { + return `New entity created: ${entity.id}`; + }, + }, + sampleEmit, +}; diff --git a/components/v7_go/sources/new-entity-instant/test-event.mjs b/components/v7_go/sources/new-entity-instant/test-event.mjs new file mode 100644 index 0000000000000..b2744b64d59d9 --- /dev/null +++ b/components/v7_go/sources/new-entity-instant/test-event.mjs @@ -0,0 +1,72 @@ +export default { + "type": "entity.created", + "entity": { + "id": "12345678-1234-1234-1234-123456789012", + "fields": { + "text-field-test-1": { + "data": { + "value": null, + "value_type": null, + "additional_value": null, + "additional_value_type": null + }, + "status": "idle", + "error_message": null, + "inserted_at": "2024-07-23T14:39:40.528059Z", + "updated_at": "2024-07-23T14:39:40.528059Z", + "property_id": "12345678-1234-1234-1234-123456789012", + "property_type": "text" + }, + "text-field-test-2": { + "data": { + "value": null, + "value_type": null, + "additional_value": null, + "additional_value_type": null + }, + "status": "idle", + "error_message": null, + "inserted_at": "2024-07-23T14:39:40.527282Z", + "updated_at": "2024-07-23T14:39:40.527282Z", + "property_id": "12345678-1234-1234-1234-123456789012", + "property_type": "text" + } + }, + "inserted_at": "2024-07-23T14:39:40.526627Z", + "updated_at": "2024-07-23T14:39:40.526627Z", + "project_id": "12345678-1234-1234-1234-123456789012" + }, + "project": { + "id": "12345678-1234-1234-1234-123456789012", + "name": "Project test 01", + "inserted_at": "2024-07-22T16:24:26.921584Z", + "updated_at": "2024-07-23T14:35:21.101723Z", + "properties": { + "text-field-test-1": { + "id": "12345678-1234-1234-1234-123456789012", + "name": "New property", + "type": "text", + "description": null, + "inserted_at": "2024-07-23T14:35:21.064456Z", + "updated_at": "2024-07-23T14:35:21.064456Z", + "inputs": [], + "tool": "gpt_4o", + "input_ids": [], + "slug": "text-field-test-1" + }, + "text-field-test-2": { + "id": "12345678-1234-1234-1234-123456789012", + "name": "Text Field", + "type": "text", + "description": null, + "inserted_at": "2024-07-22T17:43:13.126685Z", + "updated_at": "2024-07-22T17:50:56.293517Z", + "inputs": [], + "tool": "gpt_4o", + "input_ids": [], + "slug": "text-field-test-2" + } + }, + "workspace_id": "12345678-1234-1234-1234-123456789012" + } +} \ No newline at end of file diff --git a/components/v7_go/v7_go.app.mjs b/components/v7_go/v7_go.app.mjs index d8fe18248065c..af0b8063e007c 100644 --- a/components/v7_go/v7_go.app.mjs +++ b/components/v7_go/v7_go.app.mjs @@ -1,11 +1,253 @@ +import { axios } from "@pipedream/platform"; +import { LIMIT } from "./common/constants.mjs"; + export default { type: "app", app: "v7_go", - propDefinitions: {}, + propDefinitions: { + workspaceId: { + type: "string", + label: "Workspace ID", + description: "The ID of the workspace", + async options() { + const { data } = await this.listWorkspaces(); + + return data.map(({ + id: value, name: label, + }) => ({ + label, + value, + })); + }, + }, + projectId: { + type: "string", + label: "Project ID", + description: "The ID of the project", + async options({ + page, workspaceId, + }) { + const { data } = await this.listProjects({ + workspaceId, + params: { + offset: LIMIT * page, + limit: LIMIT, + }, + }); + + return data.map(({ + id: value, name, + }) => ({ + label: name || value, + value, + })); + }, + }, + entityId: { + type: "string", + label: "Entity ID", + description: "The ID of the entity", + async options({ + page, workspaceId, projectId, + }) { + const { data } = await this.listEntities({ + workspaceId, + projectId, + params: { + offset: LIMIT * page, + limit: LIMIT, + }, + }); + + return data.map(({ id }) => id); + }, + }, + }, methods: { - // this.$auth contains connected account data - authKeys() { - console.log(Object.keys(this.$auth)); + _baseUrl() { + return "https://go.v7labs.com/api"; + }, + _headers() { + return { + "X-API-KEY": `${this.$auth.api_key}`, + }; + }, + _makeRequest({ + $ = this, path, ...opts + }) { + return axios($, { + url: this._baseUrl() + path, + headers: this._headers(), + ...opts, + }); + }, + createProject({ + workspaceId, ...opts + }) { + return this._makeRequest({ + method: "POST", + path: `/workspaces/${workspaceId}/projects`, + ...opts, + }); + }, + createEntity({ + workspaceId, projectId, ...opts + }) { + return this._makeRequest({ + method: "POST", + path: `/workspaces/${workspaceId}/projects/${projectId}/entities`, + ...opts, + }); + }, + getEntity({ + workspaceId, projectId, entityId, + }) { + return this._makeRequest({ + path: `/workspaces/${workspaceId}/projects/${projectId}/entities/${entityId}`, + }); + }, + getProject({ + workspaceId, projectId, + }) { + return this._makeRequest({ + path: `/workspaces/${workspaceId}/projects/${projectId}`, + }); + }, + updateEntity({ + workspaceId, projectId, entityId, ...opts + }) { + return this._makeRequest({ + method: "PUT", + path: `/workspaces/${workspaceId}/projects/${projectId}/entities/${entityId}`, + ...opts, + }); + }, + listEntities({ + workspaceId, projectId, ...opts + }) { + return this._makeRequest({ + method: "GET", + path: `/workspaces/${workspaceId}/projects/${projectId}/entities`, + ...opts, + }); + }, + listProjects({ + workspaceId, ...opts + }) { + return this._makeRequest({ + method: "GET", + path: `/workspaces/${workspaceId}/projects`, + ...opts, + }); + }, + listWorkspaces() { + return this._makeRequest({ + method: "GET", + path: "/workspaces", + }); + }, + parseObject(object) { + const arrayKeys = Object.keys(object); + return arrayKeys.reduce((prev, curr) => { + let value = object[curr]; + const prefix = curr.split("_"); + + switch (prefix[0]) { + case "SINGLE" : value = { + options: [ + value, + ], + }; break; + case "MULTI" : value = { + options: value, + }; break; + case "URL" : value = { + url: value, + }; break; + case "FILE" : value = { + file_url: value, + }; break; + } + + return { + ...prev, + [prefix[1]]: value, + }; + }, {}); + }, + async prepareProps({ + projectId, workspaceId, entityId, + }) { + const props = {}; + let fields; + const { properties } = await this.getProject({ + workspaceId, + projectId, + }); + + if (entityId) { + const entityProps = await this.getEntity({ + workspaceId, + projectId, + entityId, + }); + fields = entityProps.fields; + } + + for (const prop of properties) { + if (prop.type === "collection") continue; + + const type = prop.type === "multi_select" + ? "string[]" + : "string"; + + let responseType = "STRING"; + + switch (prop.type) { + case "single_select": responseType = "SINGLE"; break; + case "multi_select": responseType = "MULTI"; break; + case "url": responseType = "URL"; break; + case "file": responseType = "FILE"; break; + } + + props[`${responseType}_${prop.id}`] = { + type, + label: prop.name, + optional: true, + }; + + if (entityId) { + if (fields[prop.slug].manual_value?.value) { + const value = fields[prop.slug].manual_value.value; + const parsedValue = prop.type === "single_select" + ? value.join() + : value; + props[`${responseType}_${prop.id}`].default = parsedValue; + } + } + + if (prop.config?.options) { + props[`${responseType}_${prop.id}`].options = prop.config.options.map(({ value }) => value); + } + } + return props; + }, + createWebhook({ + workspaceId, ...opts + }) { + return this._makeRequest({ + method: "POST", + path: `/workspaces/${workspaceId}/triggers`, + ...opts, + }); + }, + deleteWebhook({ + workspaceId, webhookId, + }) { + return this._makeRequest({ + method: "DELETE", + path: `/workspaces/${workspaceId}/triggers/${webhookId}`, + }); }, }, -}; \ No newline at end of file +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 58c174547f5be..9fc18134a56ad 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9907,7 +9907,10 @@ importers: specifiers: {} components/v7_go: - specifiers: {} + specifiers: + '@pipedream/platform': ^3.0.0 + dependencies: + '@pipedream/platform': 3.0.0 components/vapi: specifiers: {}