From dc7ed3789be3d3ba1babe8b63d35ea6b82caa56c Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Tue, 16 Jul 2024 16:29:57 -0300 Subject: [PATCH 1/4] peach init --- .../send-template-message.mjs | 59 ++++++++++++ components/peach/package.json | 2 +- components/peach/peach.app.mjs | 95 ++++++++++++++++++- .../new-app-response-instant.mjs | 50 ++++++++++ 4 files changed, 200 insertions(+), 6 deletions(-) create mode 100644 components/peach/actions/send-template-message/send-template-message.mjs create mode 100644 components/peach/sources/new-app-response-instant/new-app-response-instant.mjs diff --git a/components/peach/actions/send-template-message/send-template-message.mjs b/components/peach/actions/send-template-message/send-template-message.mjs new file mode 100644 index 0000000000000..7672d7639ffcd --- /dev/null +++ b/components/peach/actions/send-template-message/send-template-message.mjs @@ -0,0 +1,59 @@ +import peach from "../../peach.app.mjs"; +import { axios } from "@pipedream/platform"; + +export default { + key: "peach-send-template-message", + name: "Send Template Message", + description: "Send a predefined message to a contact within the Peach app. [See the documentation](https://peach.apidocumentation.com/reference)", + version: "0.0.{{ts}}", + type: "action", + props: { + peach, + phoneNumber: { + propDefinition: [ + peach, + "phoneNumber", + ], + }, + templateName: { + propDefinition: [ + peach, + "templateName", + ], + optional: true, + }, + contactName: { + propDefinition: [ + peach, + "contactName", + ], + optional: true, + }, + contactEmail: { + propDefinition: [ + peach, + "contactEmail", + ], + optional: true, + }, + arguments: { + propDefinition: [ + peach, + "arguments", + ], + optional: true, + }, + }, + async run({ $ }) { + const response = await this.peach.sendTransactionalMessage({ + phoneNumber: this.phoneNumber, + templateName: this.templateName, + contactName: this.contactName, + contactEmail: this.contactEmail, + arguments: this.arguments, + }); + + $.export("$summary", `Message sent successfully to ${this.phoneNumber}`); + return response; + }, +}; diff --git a/components/peach/package.json b/components/peach/package.json index ed38312b58984..933cf65128f43 100644 --- a/components/peach/package.json +++ b/components/peach/package.json @@ -12,4 +12,4 @@ "publishConfig": { "access": "public" } -} \ No newline at end of file +} diff --git a/components/peach/peach.app.mjs b/components/peach/peach.app.mjs index 4c3eca5e6f6ef..214fa1f8dbeaf 100644 --- a/components/peach/peach.app.mjs +++ b/components/peach/peach.app.mjs @@ -1,11 +1,96 @@ +import { axios } from "@pipedream/platform"; + export default { type: "app", app: "peach", - propDefinitions: {}, + propDefinitions: { + phoneNumber: { + type: "string", + label: "Phone Number", + description: "The phone number of the contact to send the message to", + }, + templateName: { + type: "string", + label: "Template Name", + description: "WhatsApp approved utility template name", + optional: true, + }, + contactName: { + type: "string", + label: "Contact Name", + description: "The name of the contact", + optional: true, + }, + contactEmail: { + type: "string", + label: "Contact Email", + description: "The email of the contact", + optional: true, + }, + arguments: { + type: "object", + label: "Arguments", + description: "Arguments for the template", + optional: true, + }, + }, methods: { - // this.$auth contains connected account data - authKeys() { - console.log(Object.keys(this.$auth)); + _baseUrl() { + return "https://app.trypeach.io/api/v1"; + }, + async _makeRequest(opts = {}) { + const { + $ = this, + method = "GET", + path = "/", + headers, + ...otherOpts + } = opts; + return axios($, { + ...otherOpts, + method, + url: this._baseUrl() + path, + headers: { + ...headers, + "Authorization": `Bearer ${this.$auth.api_key}`, + "Content-Type": "application/json", + }, + }); + }, + async sendTransactionalMessage(opts = {}) { + const { + phoneNumber, + templateName, + contactName, + contactEmail, + arguments: args, + ...otherOpts + } = opts; + + const data = { + template_name: templateName, + to: { + name: contactName, + email: contactEmail, + phone_number: phoneNumber, + }, + arguments: args, + }; + + return this._makeRequest({ + method: "POST", + path: "/transactional_messages", + data, + ...otherOpts, + }); + }, + async emitNewAppResponseCreated() { + // Logic to emit new event when a new app response is created on Peach + // This is a placeholder function. Actual implementation would depend on the specific event system and API endpoints provided by Peach. + return this._makeRequest({ + method: "GET", + path: "/new_event_endpoint", // Replace with actual endpoint + }); }, }, -}; \ No newline at end of file +}; diff --git a/components/peach/sources/new-app-response-instant/new-app-response-instant.mjs b/components/peach/sources/new-app-response-instant/new-app-response-instant.mjs new file mode 100644 index 0000000000000..23f3e08dc643f --- /dev/null +++ b/components/peach/sources/new-app-response-instant/new-app-response-instant.mjs @@ -0,0 +1,50 @@ +import peach from "../../peach.app.mjs"; +import { axios } from "@pipedream/platform"; + +export default { + key: "peach-new-app-response-instant", + name: "New App Response Instant", + description: "Emit new event when a new app response is created on Peach. [See the documentation](https://peach.apidocumentation.com/reference)", + version: "0.0.{{ts}}", + type: "source", + dedupe: "unique", + props: { + peach: { + type: "app", + app: "peach", + }, + http: { + type: "$.interface.http", + customResponse: false, + }, + db: "$.service.db", + }, + hooks: { + async deploy() { + const responses = await this.peach.emitNewAppResponseCreated(); + for (const response of responses) { + this.$emit(response, { + id: response.id, + summary: `New response: ${response.id}`, + ts: Date.parse(response.created_at), + }); + } + }, + async activate() { + const hookId = await this.peach.createWebhook(); + this.db.set("webhookId", hookId); + }, + async deactivate() { + const hookId = this.db.get("webhookId"); + await this.peach.deleteWebhook(hookId); + }, + }, + async run(event) { + const response = event.body; + this.$emit(response, { + id: response.id, + summary: `New response: ${response.id}`, + ts: Date.parse(response.created_at), + }); + }, +}; From 5353d622fe55a5005a0f7455f480df823ae0ddbd Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Tue, 16 Jul 2024 17:55:19 -0300 Subject: [PATCH 2/4] [Components] peach #12735 Actions - Send Template Message --- .../send-template-message.mjs | 62 +++++++------ components/peach/common/utils.mjs | 16 ++++ components/peach/package.json | 6 +- components/peach/peach.app.mjs | 89 +++---------------- .../new-app-response-instant.mjs | 50 ----------- 5 files changed, 67 insertions(+), 156 deletions(-) create mode 100644 components/peach/common/utils.mjs delete mode 100644 components/peach/sources/new-app-response-instant/new-app-response-instant.mjs diff --git a/components/peach/actions/send-template-message/send-template-message.mjs b/components/peach/actions/send-template-message/send-template-message.mjs index 7672d7639ffcd..da69c240480c6 100644 --- a/components/peach/actions/send-template-message/send-template-message.mjs +++ b/components/peach/actions/send-template-message/send-template-message.mjs @@ -1,56 +1,60 @@ +import { clearObj } from "../../common/utils.mjs"; import peach from "../../peach.app.mjs"; -import { axios } from "@pipedream/platform"; export default { key: "peach-send-template-message", name: "Send Template Message", - description: "Send a predefined message to a contact within the Peach app. [See the documentation](https://peach.apidocumentation.com/reference)", - version: "0.0.{{ts}}", + description: "Send a predefined message to a contact within the Peach app. [See the documentation](https://peach.apidocumentation.com/reference#tag/messaging/post/transactional_messages)", + version: "0.0.1", type: "action", props: { peach, phoneNumber: { - propDefinition: [ - peach, - "phoneNumber", - ], + type: "string", + label: "Phone Number", + description: "The phone number of the contact to send the message to", }, templateName: { - propDefinition: [ - peach, - "templateName", - ], - optional: true, + type: "string", + label: "Template Name", + description: "WhatsApp approved utility template name", }, contactName: { - propDefinition: [ - peach, - "contactName", - ], + type: "string", + label: "Contact Name", + description: "The name of the contact", optional: true, }, contactEmail: { - propDefinition: [ - peach, - "contactEmail", - ], + type: "string", + label: "Contact Email", + description: "The email of the contact", optional: true, }, arguments: { - propDefinition: [ - peach, - "arguments", - ], + type: "object", + label: "Arguments", + description: "Arguments for the template", optional: true, }, }, async run({ $ }) { const response = await this.peach.sendTransactionalMessage({ - phoneNumber: this.phoneNumber, - templateName: this.templateName, - contactName: this.contactName, - contactEmail: this.contactEmail, - arguments: this.arguments, + $, + data: clearObj({ + template_name: this.templateName, + to: { + name: this.contactName, + email: this.contactEmail, + phone_number: this.phoneNumber, + }, + arguments: this.arguments + ? Object.keys(this.arguments).map((key) => ({ + key, + value: this.arguments[key], + })) + : {}, + }), }); $.export("$summary", `Message sent successfully to ${this.phoneNumber}`); diff --git a/components/peach/common/utils.mjs b/components/peach/common/utils.mjs new file mode 100644 index 0000000000000..816afd11fddb2 --- /dev/null +++ b/components/peach/common/utils.mjs @@ -0,0 +1,16 @@ +export const clearObj = (obj) => { + return Object.entries(obj) + .filter(([ + , + v, + ]) => (v != null && v != "" && JSON.stringify(v) != "{}")) + .reduce((acc, [ + k, + v, + ]) => ({ + ...acc, + [k]: (!Array.isArray(v) && v === Object(v)) + ? clearObj(v) + : v, + }), {}); +}; diff --git a/components/peach/package.json b/components/peach/package.json index 933cf65128f43..b44a64755861e 100644 --- a/components/peach/package.json +++ b/components/peach/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/peach", - "version": "0.0.1", + "version": "0.1.0", "description": "Pipedream Peach Components", "main": "peach.app.mjs", "keywords": [ @@ -11,5 +11,9 @@ "author": "Pipedream (https://pipedream.com/)", "publishConfig": { "access": "public" + }, + "dependencies": { + "@pipedream/platform": "^3.0.0" } } + diff --git a/components/peach/peach.app.mjs b/components/peach/peach.app.mjs index 214fa1f8dbeaf..059409d33cb36 100644 --- a/components/peach/peach.app.mjs +++ b/components/peach/peach.app.mjs @@ -3,93 +3,30 @@ import { axios } from "@pipedream/platform"; export default { type: "app", app: "peach", - propDefinitions: { - phoneNumber: { - type: "string", - label: "Phone Number", - description: "The phone number of the contact to send the message to", - }, - templateName: { - type: "string", - label: "Template Name", - description: "WhatsApp approved utility template name", - optional: true, - }, - contactName: { - type: "string", - label: "Contact Name", - description: "The name of the contact", - optional: true, - }, - contactEmail: { - type: "string", - label: "Contact Email", - description: "The email of the contact", - optional: true, - }, - arguments: { - type: "object", - label: "Arguments", - description: "Arguments for the template", - optional: true, - }, - }, methods: { _baseUrl() { return "https://app.trypeach.io/api/v1"; }, - async _makeRequest(opts = {}) { - const { - $ = this, - method = "GET", - path = "/", - headers, - ...otherOpts - } = opts; + _headers() { + return { + "Authorization": `${this.$auth.api_token}`, + "Content-Type": "application/json", + }; + }, + _makeRequest({ + $ = this, path, ...opts + }) { return axios($, { - ...otherOpts, - method, url: this._baseUrl() + path, - headers: { - ...headers, - "Authorization": `Bearer ${this.$auth.api_key}`, - "Content-Type": "application/json", - }, + headers: this._headers(), + ...opts, }); }, - async sendTransactionalMessage(opts = {}) { - const { - phoneNumber, - templateName, - contactName, - contactEmail, - arguments: args, - ...otherOpts - } = opts; - - const data = { - template_name: templateName, - to: { - name: contactName, - email: contactEmail, - phone_number: phoneNumber, - }, - arguments: args, - }; - + sendTransactionalMessage(opts = {}) { return this._makeRequest({ method: "POST", path: "/transactional_messages", - data, - ...otherOpts, - }); - }, - async emitNewAppResponseCreated() { - // Logic to emit new event when a new app response is created on Peach - // This is a placeholder function. Actual implementation would depend on the specific event system and API endpoints provided by Peach. - return this._makeRequest({ - method: "GET", - path: "/new_event_endpoint", // Replace with actual endpoint + ...opts, }); }, }, diff --git a/components/peach/sources/new-app-response-instant/new-app-response-instant.mjs b/components/peach/sources/new-app-response-instant/new-app-response-instant.mjs deleted file mode 100644 index 23f3e08dc643f..0000000000000 --- a/components/peach/sources/new-app-response-instant/new-app-response-instant.mjs +++ /dev/null @@ -1,50 +0,0 @@ -import peach from "../../peach.app.mjs"; -import { axios } from "@pipedream/platform"; - -export default { - key: "peach-new-app-response-instant", - name: "New App Response Instant", - description: "Emit new event when a new app response is created on Peach. [See the documentation](https://peach.apidocumentation.com/reference)", - version: "0.0.{{ts}}", - type: "source", - dedupe: "unique", - props: { - peach: { - type: "app", - app: "peach", - }, - http: { - type: "$.interface.http", - customResponse: false, - }, - db: "$.service.db", - }, - hooks: { - async deploy() { - const responses = await this.peach.emitNewAppResponseCreated(); - for (const response of responses) { - this.$emit(response, { - id: response.id, - summary: `New response: ${response.id}`, - ts: Date.parse(response.created_at), - }); - } - }, - async activate() { - const hookId = await this.peach.createWebhook(); - this.db.set("webhookId", hookId); - }, - async deactivate() { - const hookId = this.db.get("webhookId"); - await this.peach.deleteWebhook(hookId); - }, - }, - async run(event) { - const response = event.body; - this.$emit(response, { - id: response.id, - summary: `New response: ${response.id}`, - ts: Date.parse(response.created_at), - }); - }, -}; From c420999cfaac37b02a48444391a1189f5c95b512 Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Tue, 16 Jul 2024 18:03:33 -0300 Subject: [PATCH 3/4] [Components] peach #12735 Actions - Send Template Message - Create Contact --- .../actions/create-contact/create-contact.mjs | 46 +++++++++++++++++++ .../send-template-message.mjs | 21 +++++---- components/peach/peach.app.mjs | 24 ++++++++++ 3 files changed, 82 insertions(+), 9 deletions(-) create mode 100644 components/peach/actions/create-contact/create-contact.mjs diff --git a/components/peach/actions/create-contact/create-contact.mjs b/components/peach/actions/create-contact/create-contact.mjs new file mode 100644 index 0000000000000..eee0da3abb1aa --- /dev/null +++ b/components/peach/actions/create-contact/create-contact.mjs @@ -0,0 +1,46 @@ +import { clearObj } from "../../common/utils.mjs"; +import peach from "../../peach.app.mjs"; + +export default { + key: "peach-create-contact", + name: "Create Contact", + description: "Creates a contact in your account. [See the documentation](https://peach.apidocumentation.com/reference#tag/contacts/post/subscribers)", + version: "0.0.1", + type: "action", + props: { + peach, + phoneNumber: { + propDefinition: [ + peach, + "phoneNumber", + ], + }, + contactName: { + propDefinition: [ + peach, + "contactName", + ], + optional: true, + }, + contactEmail: { + propDefinition: [ + peach, + "contactEmail", + ], + optional: true, + }, + }, + async run({ $ }) { + const response = await this.peach.createContact({ + $, + data: clearObj({ + name: this.contactName, + email: this.contactEmail, + phone_number: this.phoneNumber, + }), + }); + + $.export("$summary", `Created the contact successfully with waId: ${this.phoneNumber}`); + return response; + }, +}; diff --git a/components/peach/actions/send-template-message/send-template-message.mjs b/components/peach/actions/send-template-message/send-template-message.mjs index da69c240480c6..b7f4ec0dbd664 100644 --- a/components/peach/actions/send-template-message/send-template-message.mjs +++ b/components/peach/actions/send-template-message/send-template-message.mjs @@ -10,9 +10,10 @@ export default { props: { peach, phoneNumber: { - type: "string", - label: "Phone Number", - description: "The phone number of the contact to send the message to", + propDefinition: [ + peach, + "phoneNumber", + ], }, templateName: { type: "string", @@ -20,15 +21,17 @@ export default { description: "WhatsApp approved utility template name", }, contactName: { - type: "string", - label: "Contact Name", - description: "The name of the contact", + propDefinition: [ + peach, + "contactName", + ], optional: true, }, contactEmail: { - type: "string", - label: "Contact Email", - description: "The email of the contact", + propDefinition: [ + peach, + "contactEmail", + ], optional: true, }, arguments: { diff --git a/components/peach/peach.app.mjs b/components/peach/peach.app.mjs index 059409d33cb36..df54b05c31088 100644 --- a/components/peach/peach.app.mjs +++ b/components/peach/peach.app.mjs @@ -3,6 +3,23 @@ import { axios } from "@pipedream/platform"; export default { type: "app", app: "peach", + propDefinitions: { + phoneNumber: { + type: "string", + label: "Phone Number", + description: "The phone number of the contact to send the message to", + }, + contactName: { + type: "string", + label: "Contact Name", + description: "The name of the contact", + }, + contactEmail: { + type: "string", + label: "Contact Email", + description: "The email of the contact", + }, + }, methods: { _baseUrl() { return "https://app.trypeach.io/api/v1"; @@ -29,5 +46,12 @@ export default { ...opts, }); }, + createContact(opts = {}) { + return this._makeRequest({ + method: "POST", + path: "/contacts", + ...opts, + }); + }, }, }; From a1432d265cd5f05193003b15849d885ca4403ee6 Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Tue, 16 Jul 2024 18:04:20 -0300 Subject: [PATCH 4/4] pnpm update --- pnpm-lock.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e63339c1d9a80..509b3aa852e5b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6548,7 +6548,10 @@ importers: specifiers: {} components/peach: - specifiers: {} + specifiers: + '@pipedream/platform': ^3.0.0 + dependencies: + '@pipedream/platform': 3.0.0 components/peaka: specifiers: