From bbfc537780a60f629a1a52d2f5fa0d93f695f4d8 Mon Sep 17 00:00:00 2001 From: michelle0927 Date: Wed, 16 Apr 2025 14:02:35 -0400 Subject: [PATCH 1/3] new components --- .../actions/create-contact/create-contact.mjs | 95 ++++++++++ .../actions/create-deal/create-deal.mjs | 75 ++++++++ .../actions/create-task/create-task.mjs | 72 +++++++ components/cogmento/cogmento.app.mjs | 178 +++++++++++++++++- components/cogmento/package.json | 7 +- components/cogmento/sources/common/base.mjs | 82 ++++++++ .../new-contact-created.mjs | 20 ++ .../new-deal-created/new-deal-created.mjs | 20 ++ .../new-task-created/new-task-created.mjs | 20 ++ 9 files changed, 562 insertions(+), 7 deletions(-) create mode 100644 components/cogmento/actions/create-contact/create-contact.mjs create mode 100644 components/cogmento/actions/create-deal/create-deal.mjs create mode 100644 components/cogmento/actions/create-task/create-task.mjs create mode 100644 components/cogmento/sources/common/base.mjs create mode 100644 components/cogmento/sources/new-contact-created/new-contact-created.mjs create mode 100644 components/cogmento/sources/new-deal-created/new-deal-created.mjs create mode 100644 components/cogmento/sources/new-task-created/new-task-created.mjs diff --git a/components/cogmento/actions/create-contact/create-contact.mjs b/components/cogmento/actions/create-contact/create-contact.mjs new file mode 100644 index 0000000000000..6e8c580fd0841 --- /dev/null +++ b/components/cogmento/actions/create-contact/create-contact.mjs @@ -0,0 +1,95 @@ +import cogmento from "../../cogmento.app.mjs"; + +export default { + key: "cogmento-create-contact", + name: "Create Contact", + description: "Create a new contact in Cogmento CRM. [See the documentation](https://api.cogmento.com/static/swagger/index.html#/Contacts/post_contacts_)", + version: "0.0.1", + type: "action", + props: { + cogmento, + firstName: { + type: "string", + label: "First Name", + description: "First name of the contact", + }, + lastName: { + type: "string", + label: "Last Name", + description: "Last name of the contact", + }, + email: { + type: "string", + label: "Email", + description: "Email address of the contact", + optional: true, + }, + phone: { + type: "string", + label: "Phone", + description: "Phone number of the contact", + optional: true, + }, + description: { + type: "string", + label: "Description", + description: "Description of the contact", + optional: true, + }, + tags: { + type: "string[]", + label: "Tags", + description: "Array of tags associated with the contact", + optional: true, + }, + doNotCall: { + type: "boolean", + label: "Do Not Call", + description: "Set to `true` to mark the contact as Do Not Call", + optional: true, + }, + doNotText: { + type: "boolean", + label: "Do Not Text", + description: "Set to `true` to mark the contact as Do Not Text", + optional: true, + }, + doNotEmail: { + type: "boolean", + label: "Do Not Email", + description: "Set to `true` to mark the contact as Do Not Email", + optional: true, + }, + }, + async run({ $ }) { + const channels = []; + if (this.email) { + channels.push({ + channel_type: "Email", + value: this.email, + }); + } + if (this.phone) { + channels.push({ + channel_type: "Phone", + value: this.phone, + }); + } + + const response = await this.cogmento.createContact({ + $, + data: { + first_name: this.firstName, + last_name: this.lastName, + channels, + description: this.description, + tags: this.tags, + do_not_call: this.doNotCall, + do_not_text: this.doNotText, + do_not_email: this.doNotEmail, + }, + }); + $.export("$summary", `Successfully created contact: ${this.firstName} ${this.lastName}`); + return response; + }, +}; diff --git a/components/cogmento/actions/create-deal/create-deal.mjs b/components/cogmento/actions/create-deal/create-deal.mjs new file mode 100644 index 0000000000000..654abaafae1a1 --- /dev/null +++ b/components/cogmento/actions/create-deal/create-deal.mjs @@ -0,0 +1,75 @@ +import cogmento from "../../cogmento.app.mjs"; + +export default { + key: "cogmento-create-deal", + name: "Create Deal", + description: "Create a new deal in Cogmento CRM. [See the documentation](https://api.cogmento.com/static/swagger/index.html#/Deals/post_deals_)", + version: "0.0.1", + type: "action", + props: { + cogmento, + title: { + type: "string", + label: "Title", + description: "The title of the deal", + }, + description: { + type: "string", + label: "Description", + description: "A description of the deal", + optional: true, + }, + assigneeIds: { + propDefinition: [ + cogmento, + "userIds", + ], + optional: true, + }, + tags: { + type: "string[]", + label: "Tags", + description: "Array of tags associated with the deal", + optional: true, + }, + closeDate: { + type: "string", + label: "Close Date", + description: "The date the deal was completed (format: YYYY-MM-DD)", + optional: true, + }, + productIds: { + propDefinition: [ + cogmento, + "productIds", + ], + optional: true, + }, + amount: { + type: "string", + label: "Amount", + description: "The final deal value", + optional: true, + }, + }, + async run({ $ }) { + const response = await this.cogmento.createDeal({ + $, + data: { + title: this.title, + description: this.description, + assigned_to: this.assigneeIds?.map((id) => ({ + id, + })) || undefined, + tags: this.tags, + close_date: this.closeDate, + products: this.productIds?.map((id) => ({ + id, + })) || undefined, + amount: this.amount && +this.amount, + }, + }); + $.export("$summary", `Successfully created deal: ${this.title}`); + return response; + }, +}; diff --git a/components/cogmento/actions/create-task/create-task.mjs b/components/cogmento/actions/create-task/create-task.mjs new file mode 100644 index 0000000000000..2dee9054992ae --- /dev/null +++ b/components/cogmento/actions/create-task/create-task.mjs @@ -0,0 +1,72 @@ +import cogmento from "../../cogmento.app.mjs"; + +export default { + key: "cogmento-create-task", + name: "Create Task", + description: "Create a new task in Cogmento CRM. [See the documentation](https://api.cogmento.com/static/swagger/index.html#/Tasks/post_tasks_)", + version: "0.0.1", + type: "action", + props: { + cogmento, + title: { + type: "string", + label: "Title", + description: "The title of the task", + }, + description: { + type: "string", + label: "Description", + description: "A description of the task", + optional: true, + }, + dueDate: { + type: "string", + label: "Due Date", + description: "The task's deadline(format: YYYY-MM-DD)", + optional: true, + }, + assigneeIds: { + propDefinition: [ + cogmento, + "userIds", + ], + description: "An array of user IDs to assign to the task", + optional: true, + }, + dealId: { + propDefinition: [ + cogmento, + "dealId", + ], + optional: true, + }, + contactId: { + propDefinition: [ + cogmento, + "contactId", + ], + optional: true, + }, + }, + async run({ $ }) { + const response = await this.cogmento.createTask({ + $, + data: { + title: this.title, + description: this.description, + due_date: this.dueDate, + assigned_to: this.assigneeIds?.map((id) => ({ + id, + })) || undefined, + deal: this.dealId && { + id: this.dealId, + }, + contact: this.contactId && { + id: this.contactId, + }, + }, + }); + $.export("$summary", `Successfully created task: ${this.title}`); + return response; + }, +}; diff --git a/components/cogmento/cogmento.app.mjs b/components/cogmento/cogmento.app.mjs index 1f43a645cb769..4deeb171176cb 100644 --- a/components/cogmento/cogmento.app.mjs +++ b/components/cogmento/cogmento.app.mjs @@ -1,11 +1,179 @@ +import { axios } from "@pipedream/platform"; +const LIMIT = 100; + export default { type: "app", app: "cogmento", - propDefinitions: {}, + propDefinitions: { + userIds: { + type: "string[]", + label: "User IDs", + description: "An array of user IDs to assign to the deal", + async options() { + const { response: { user } } = await this.getUser(); + return [ + { + label: (`${user?.first_name} ${user?.last_name}`).trim(), + value: user.id, + }, + ]; + }, + }, + productIds: { + type: "string[]", + label: "Product IDs", + description: "An array of product IDs to include in the deal", + async options({ page }) { + const { response: { results } } = await this.listProducts({ + params: { + limit: LIMIT, + start: page * LIMIT, + }, + }); + return results?.map(({ + id: value, name: label, + }) => ({ + label, + value, + })) || []; + }, + }, + dealId: { + type: "string", + label: "Deal ID", + description: "Identifier of a deal to associate with the task", + async options({ page }) { + const { response: { results } } = await this.listDeals({ + params: { + limit: LIMIT, + start: page * LIMIT, + }, + }); + return results?.map(({ + id: value, title: label, + }) => ({ + label, + value, + })) || []; + }, + }, + contactId: { + type: "string", + label: "Contact ID", + description: "Identifier of a contact to associate with the task", + async options({ page }) { + const { response: { results } } = await this.listContacts({ + params: { + limit: LIMIT, + start: page * LIMIT, + }, + }); + return results?.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.cogmento.com/api/1"; + }, + _makeRequest({ + $ = this, + path, + ...opts + }) { + return axios($, { + url: `${this._baseUrl()}${path}`, + headers: { + Accept: "application/json", + Authorization: `Token ${this.$auth.oauth_access_token}`, + }, + ...opts, + }); + }, + getUser(opts = {}) { + return this._makeRequest({ + path: "/auth/user", + ...opts, + }); + }, + listContacts(opts = {}) { + return this._makeRequest({ + path: "/contacts/", + ...opts, + }); + }, + listDeals(opts = {}) { + return this._makeRequest({ + path: "/deals/", + ...opts, + }); + }, + listTasks(opts = {}) { + return this._makeRequest({ + path: "/tasks/", + ...opts, + }); + }, + listProducts(opts = {}) { + return this._makeRequest({ + path: "/products/", + ...opts, + }); + }, + createContact(opts = {}) { + return this._makeRequest({ + method: "POST", + path: "/contacts/", + ...opts, + }); + }, + createDeal(opts = {}) { + return this._makeRequest({ + method: "POST", + path: "/deals/", + ...opts, + }); + }, + createTask(opts = {}) { + return this._makeRequest({ + method: "POST", + path: "/tasks/", + ...opts, + }); + }, + async *paginate({ + fn, args = {}, max, + }) { + args = { + ...args, + params: { + ...args?.params, + limit: LIMIT, + start: 0, + }, + }; + let hasMore, count = 0; + do { + const { + response: { + results, total, + }, + } = await fn(args); + for (const item of results) { + yield item; + count++; + if (max && count >= max) { + return; + } + } + args.params.start += args.params.limit; + hasMore = count < total; + } while (hasMore); }, }, -}; \ No newline at end of file +}; diff --git a/components/cogmento/package.json b/components/cogmento/package.json index 09f133fe2d8c6..4d03179a61d4c 100644 --- a/components/cogmento/package.json +++ b/components/cogmento/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/cogmento", - "version": "0.0.1", + "version": "0.1.0", "description": "Pipedream Cogmento Components", "main": "cogmento.app.mjs", "keywords": [ @@ -11,5 +11,8 @@ "author": "Pipedream (https://pipedream.com/)", "publishConfig": { "access": "public" + }, + "dependencies": { + "@pipedream/platform": "^3.0.3" } -} \ No newline at end of file +} diff --git a/components/cogmento/sources/common/base.mjs b/components/cogmento/sources/common/base.mjs new file mode 100644 index 0000000000000..fe12bdd0f476f --- /dev/null +++ b/components/cogmento/sources/common/base.mjs @@ -0,0 +1,82 @@ +import cogmento from "../../cogmento.app.mjs"; +import { DEFAULT_POLLING_SOURCE_TIMER_INTERVAL } from "@pipedream/platform"; + +export default { + props: { + cogmento, + db: "$.service.db", + timer: { + label: "Polling interval", + description: "Pipedream will poll the Trello API on this schedule", + type: "$.interface.timer", + default: { + intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, + }, + }, + }, + methods: { + _getLastTs() { + return this.db.get("lastTs") || 0; + }, + _setLastTs(lastTs) { + this.db.set("lastTs", lastTs); + }, + getArgs() { + return { + params: { + sort: `-${this.getTsField()}`, + }, + }; + }, + getTsField() { + return "created_at"; + }, + generateMeta(item) { + return { + id: item.id, + summary: this.getSummary(item), + ts: Date.parse(item[this.getTsField()]), + }; + }, + async processEvent(max) { + const lastTs = this._getLastTs(); + let maxTs = lastTs; + const resourceFn = this.getResourceFn(); + const args = this.getArgs(); + const tsField = this.getTsField(); + + const items = this.cogmento.paginate({ + fn: resourceFn, + args, + max, + }); + + for await (const item of items) { + const ts = Date.parse(item[tsField]); + if (ts >= lastTs) { + const meta = this.generateMeta(item); + this.$emit(item, meta); + maxTs = Math.max(ts, maxTs); + } else { + break; + } + } + + this._setLastTs(maxTs); + }, + getResourceFn() { + throw new Error("getResourceFn is not implemented"); + }, + getSummary() { + throw new Error("getSummary is not implemented"); + }, + }, + hooks: { + async deploy() { + await this.processEvent(25); + }, + }, + async run() { + await this.processEvent(); + }, +}; diff --git a/components/cogmento/sources/new-contact-created/new-contact-created.mjs b/components/cogmento/sources/new-contact-created/new-contact-created.mjs new file mode 100644 index 0000000000000..8ec92815cb680 --- /dev/null +++ b/components/cogmento/sources/new-contact-created/new-contact-created.mjs @@ -0,0 +1,20 @@ +import common from "../common/base.mjs"; + +export default { + ...common, + key: "cogmento-new-contact-created", + name: "New Contact Created", + description: "Emit new event when a new contact is added in Cogmento. [See the documentation](https://api.cogmento.com/static/swagger/index.html#/Contacts/get_contacts_)", + version: "0.0.1", + type: "source", + dedupe: "unique", + methods: { + ...common.methods, + getResourceFn() { + return this.cogmento.listContacts; + }, + getSummary(item) { + return `New Contact Created: ${item.name}`; + }, + }, +}; diff --git a/components/cogmento/sources/new-deal-created/new-deal-created.mjs b/components/cogmento/sources/new-deal-created/new-deal-created.mjs new file mode 100644 index 0000000000000..a0d36e5b5b850 --- /dev/null +++ b/components/cogmento/sources/new-deal-created/new-deal-created.mjs @@ -0,0 +1,20 @@ +import common from "../common/base.mjs"; + +export default { + ...common, + key: "cogmento-new-deal-created", + name: "New Deal Created", + description: "Emit new event when a new deal is created in Cogmento. [See the documentation](https://api.cogmento.com/static/swagger/index.html#/Deals/get_deals_)", + version: "0.0.1", + type: "source", + dedupe: "unique", + methods: { + ...common.methods, + getResourceFn() { + return this.cogmento.listDeals; + }, + getSummary(item) { + return `New Deal Created: ${item.title}`; + }, + }, +}; diff --git a/components/cogmento/sources/new-task-created/new-task-created.mjs b/components/cogmento/sources/new-task-created/new-task-created.mjs new file mode 100644 index 0000000000000..196dea160bfea --- /dev/null +++ b/components/cogmento/sources/new-task-created/new-task-created.mjs @@ -0,0 +1,20 @@ +import common from "../common/base.mjs"; + +export default { + ...common, + key: "cogmento-new-task-created", + name: "New Task Created", + description: "Emit new event when a new task is created in Cogmento. [See the documentation](https://api.cogmento.com/static/swagger/index.html#/Tasks/get_tasks_)", + version: "0.0.1", + type: "source", + dedupe: "unique", + methods: { + ...common.methods, + getResourceFn() { + return this.cogmento.listTasks; + }, + getSummary(item) { + return `New Task Created: ${item.title}`; + }, + }, +}; From 8bc826a06f9ae1c2a414d207ab7d0b0b28c35d01 Mon Sep 17 00:00:00 2001 From: michelle0927 Date: Wed, 16 Apr 2025 14:05:00 -0400 Subject: [PATCH 2/3] pnpm-lock.yaml --- pnpm-lock.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ce810ce2a1a92..29cf56b442505 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2715,7 +2715,11 @@ importers: specifier: ^1.5.1 version: 1.6.6 - components/cogmento: {} + components/cogmento: + dependencies: + '@pipedream/platform': + specifier: ^3.0.3 + version: 3.0.3 components/cohere_platform: dependencies: From 9c505eccd648e487ccab3b05850c440240ffb773 Mon Sep 17 00:00:00 2001 From: michelle0927 Date: Wed, 16 Apr 2025 14:20:53 -0400 Subject: [PATCH 3/3] update --- components/cogmento/sources/common/base.mjs | 2 -- 1 file changed, 2 deletions(-) diff --git a/components/cogmento/sources/common/base.mjs b/components/cogmento/sources/common/base.mjs index fe12bdd0f476f..d2363fe6b982e 100644 --- a/components/cogmento/sources/common/base.mjs +++ b/components/cogmento/sources/common/base.mjs @@ -6,8 +6,6 @@ export default { cogmento, db: "$.service.db", timer: { - label: "Polling interval", - description: "Pipedream will poll the Trello API on this schedule", type: "$.interface.timer", default: { intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL,