diff --git a/components/piggy/.gitignore b/components/piggy/.gitignore deleted file mode 100644 index ec761ccab7595..0000000000000 --- a/components/piggy/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*.js -*.mjs -dist \ No newline at end of file diff --git a/components/piggy/actions/common/constants.mjs b/components/piggy/actions/common/constants.mjs new file mode 100644 index 0000000000000..bf0f1c0069c93 --- /dev/null +++ b/components/piggy/actions/common/constants.mjs @@ -0,0 +1,88 @@ +export default { + DATA_TYPES: [ + { + label: "URL", + value: "url", + }, + { + label: "Text", + value: "text", + }, + { + label: "Date", + value: "date", + }, + { + label: "Phone", + value: "phone", + }, + { + label: "Float", + value: "float", + }, + { + label: "Color", + value: "color", + }, + { + label: "Email", + value: "email", + }, + { + label: "Number", + value: "number", + }, + { + label: "Select", + value: "select", + }, + { + label: "Boolean", + value: "boolean", + }, + { + label: "Rich Text", + value: "rich_text", + }, + { + label: "Date & Time", + value: "date_time", + }, + { + label: "Long Text", + value: "long_text", + }, + { + label: "Date Range", + value: "date_range", + }, + { + label: "Time Range", + value: "time_range", + }, + { + label: "Identifier", + value: "identifier", + }, + { + label: "Birth Date", + value: "birth_date", + }, + { + label: "File Upload", + value: "file_upload", + }, + { + label: "Media Upload", + value: "media_upload", + }, + { + label: "Multi-Select", + value: "multi_select", + }, + { + label: "License Plate", + value: "license_plate", + }, + ], +}; diff --git a/components/piggy/actions/create-contact-attribute/create-contact-attribute.mjs b/components/piggy/actions/create-contact-attribute/create-contact-attribute.mjs new file mode 100644 index 0000000000000..4ad8b2ac5b5f6 --- /dev/null +++ b/components/piggy/actions/create-contact-attribute/create-contact-attribute.mjs @@ -0,0 +1,51 @@ +import app from "../../piggy.app.mjs"; +import constants from "../common/constants.mjs"; + +export default { + name: "Create Contact Attribute", + version: "0.0.1", + key: "piggy-create-contact-attribute", + description: "Creates a contact attribute. [See the documentation](https://docs.piggy.eu/v3/oauth/contact-attributes#:~:text=Create%20Contact%20Attribute)", + type: "action", + props: { + app, + name: { + type: "string", + label: "Name", + description: "Name of the attribute", + }, + dataType: { + type: "string", + label: "Data type", + description: "Type of the attribute", + options: constants.DATA_TYPES, + }, + label: { + type: "string", + label: "Label", + description: "Label of the attribute", + }, + descripion: { + type: "string", + label: "Descripion", + description: "Description of the attribute", + }, + }, + async run({ $ }) { + const response = await this.app.createContactAttribute({ + $, + data: { + name: this.name, + data_type: this.dataType, + label: this.label, + description: this.description, + }, + }); + + if (response) { + $.export("$summary", `Successfully created contact attribute with name ${response.data.name}`); + } + + return response; + }, +}; diff --git a/components/piggy/actions/find-or-create-contact/find-or-create-contact.mjs b/components/piggy/actions/find-or-create-contact/find-or-create-contact.mjs new file mode 100644 index 0000000000000..16dfd568f2d80 --- /dev/null +++ b/components/piggy/actions/find-or-create-contact/find-or-create-contact.mjs @@ -0,0 +1,31 @@ +import app from "../../piggy.app.mjs"; + +export default { + name: "Find Or Create Contact", + version: "0.0.1", + key: "piggy-find-or-create-contact", + description: "Find or create a contact. [See the documentation](https://docs.piggy.eu/v3/oauth/contacts#:~:text=Possible%20errors-,Find%20or%20Create%20Contact,-Find%20Contact%20by)", + type: "action", + props: { + app, + email: { + type: "string", + label: "Email", + description: "Email of the contact", + }, + }, + async run({ $ }) { + const response = await this.app.findOrCreateContact({ + $, + data: { + email: this.email, + }, + }); + + if (response) { + $.export("$summary", "Successfully retrieved or created contact"); + } + + return response; + }, +}; diff --git a/components/piggy/app/piggy.app.ts b/components/piggy/app/piggy.app.ts deleted file mode 100644 index 9f8d28a54b484..0000000000000 --- a/components/piggy/app/piggy.app.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { defineApp } from "@pipedream/types"; - -export default defineApp({ - type: "app", - app: "piggy", - propDefinitions: {}, - methods: { - // this.$auth contains connected account data - authKeys() { - console.log(Object.keys(this.$auth)); - }, - }, -}); \ No newline at end of file diff --git a/components/piggy/package.json b/components/piggy/package.json index 257c339e70032..b0636b1fabe7c 100644 --- a/components/piggy/package.json +++ b/components/piggy/package.json @@ -1,16 +1,18 @@ { "name": "@pipedream/piggy", - "version": "0.0.1", + "version": "0.1.0", "description": "Pipedream Piggy Components", - "main": "dist/app/piggy.app.mjs", + "main": "piggy.app.mjs", "keywords": [ "pipedream", "piggy" ], - "files": ["dist"], "homepage": "https://pipedream.com/apps/piggy", "author": "Pipedream (https://pipedream.com/)", "publishConfig": { "access": "public" + }, + "dependencies": { + "@pipedream/platform": "^1.5.1" } -} \ No newline at end of file +} diff --git a/components/piggy/piggy.app.mjs b/components/piggy/piggy.app.mjs new file mode 100644 index 0000000000000..71a3746382fd4 --- /dev/null +++ b/components/piggy/piggy.app.mjs @@ -0,0 +1,72 @@ +import { axios } from "@pipedream/platform"; + +export default { + type: "app", + app: "piggy", + propDefinitions: { + contactId: { + label: "Contact ID", + description: "The contact ID", + type: "string", + async options({ page }) { + const { data: contacts } = await this.getContacts({ + params: { + page: page + 1, + }, + }); + + return contacts.map((contact) => ({ + label: contact.email, + value: contact.uuid, + })); + }, + }, + }, + methods: { + _apiKey() { + return this.$auth.api_key; + }, + _apiUrl() { + return "https://api.piggy.eu/api/v3/oauth"; + }, + async _makeRequest({ + $ = this, path, ...args + }) { + return axios($, { + url: `${this._apiUrl()}${path}`, + headers: { + Authorization: `Bearer ${this._apiKey()}`, + }, + ...args, + }); + }, + async findOrCreateContact(args = {}) { + return this._makeRequest({ + path: "/clients/contacts/find-or-create", + ...args, + }); + }, + async createContactAttribute(args = {}) { + return this._makeRequest({ + path: "/clients/contact-attributes", + method: "post", + ...args, + }); + }, + async getContacts(args = {}) { + return this._makeRequest({ + path: "/clients/contacts", + ...args, + }); + }, + async updateContact({ + contactId, ...args + }) { + return this._makeRequest({ + path: `/clients/contacts/${contactId}`, + method: "put", + ...args, + }); + }, + }, +}; diff --git a/components/piggy/sources/new-contact-created/new-contact-created.mjs b/components/piggy/sources/new-contact-created/new-contact-created.mjs new file mode 100644 index 0000000000000..deaf9d3aec599 --- /dev/null +++ b/components/piggy/sources/new-contact-created/new-contact-created.mjs @@ -0,0 +1,76 @@ +import app from "../../piggy.app.mjs"; +import { DEFAULT_POLLING_SOURCE_TIMER_INTERVAL } from "@pipedream/platform"; + +export default { + name: "New Contact Created", + version: "0.0.1", + key: "piggy-new-contact-created", + description: "Emit new event on each new contact.", + type: "source", + dedupe: "unique", + props: { + app, + db: "$.service.db", + timer: { + type: "$.interface.timer", + static: { + intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, + }, + }, + }, + methods: { + emitEvent(data) { + this.$emit(data, { + id: data.uuid, + summary: `New contact created with ID ${data.uuid}`, + ts: new Date(), + }); + }, + _setLastResourceId(id) { + this.db.set("lastResourceId", id); + }, + _getLastResourceId() { + return this.db.get("lastResourceId"); + }, + }, + hooks: { + async deploy() { + const { data: contacts } = await this.app.getContacts({ + params: { + limit: 20, + }, + }); + + contacts.forEach(this.emitEvent); + }, + }, + async run() { + const lastResourceId = this._getLastResourceId(); + + let page = 1; + + while (page >= 0) { + const { data: contacts } = await this.app.getContacts({ + params: { + page, + limit: 100, + }, + }); + + if (contacts.length) { + this._setLastResourceId(contacts[0].uuid); + } + + contacts.forEach(this.emitEvent); + + if ( + contacts.length < 100 || + contacts.filter((contact) => contact.uuid === lastResourceId) + ) { + return; + } + + page++; + } + }, +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 37515ca7ef412..cbae7b990e30c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4050,7 +4050,10 @@ importers: '@pipedream/platform': 1.5.1 components/piggy: - specifiers: {} + specifiers: + '@pipedream/platform': ^1.5.1 + dependencies: + '@pipedream/platform': 1.5.1 components/pikaso: specifiers: @@ -13590,7 +13593,7 @@ packages: dependencies: '@types/http-cache-semantics': 4.0.2 '@types/keyv': 3.1.4 - '@types/node': 20.8.0 + '@types/node': 17.0.45 '@types/responselike': 1.0.1 dev: false