diff --git a/components/benchmarkone/actions/add-note/add-note.mjs b/components/benchmarkone/actions/add-note/add-note.mjs new file mode 100644 index 0000000000000..0e2d14aeaed6f --- /dev/null +++ b/components/benchmarkone/actions/add-note/add-note.mjs @@ -0,0 +1,54 @@ +import { ConfigurationError } from "@pipedream/platform"; +import benchmarkone from "../../benchmarkone.app.mjs"; + +export default { + key: "benchmarkone-add-note", + name: "Add Note to Contact", + description: "Adds a note to a BenchmarkONE contact. [See the documentation](https://sandbox.hatchbuck.com/api/dist/#!/Notes/post_contact_email_address_or_contact_ID_notes).", + version: "0.0.1", + type: "action", + props: { + benchmarkone, + contactId: { + propDefinition: [ + benchmarkone, + "contactId", + ], + }, + subject: { + type: "string", + label: "Subject", + description: "Subject line for the note.", + }, + body: { + type: "string", + label: "Body", + description: "Body of the note.", + }, + copyToCompany: { + type: "boolean", + label: "Copy To Company", + description: "Copy this note to the contact's associated company record.", + optional: true, + }, + }, + async run({ $ }) { + try { + const response = await this.benchmarkone.addNoteToContact({ + $, + contactId: this.contactId, + data: { + subject: this.subject, + body: this.body, + copyToCompany: this.copyToCompany, + }, + }); + + $.export("$summary", `Added note to contact with ID ${this.contactId}`); + + return response; + } catch (error) { + throw new ConfigurationError(error.message); + } + }, +}; diff --git a/components/benchmarkone/actions/add-tag/add-tag.mjs b/components/benchmarkone/actions/add-tag/add-tag.mjs new file mode 100644 index 0000000000000..4623da7c20b1e --- /dev/null +++ b/components/benchmarkone/actions/add-tag/add-tag.mjs @@ -0,0 +1,35 @@ +import benchmarkone from "../../benchmarkone.app.mjs"; +import { parseObject } from "../../common/utils.mjs"; + +export default { + key: "benchmarkone-add-tag", + name: "Add Tag to Contact", + description: "Adds tags to a contact. If the contact does not exist, it will be created first. [See the documentation](https://sandbox.hatchbuck.com/api/dist/#/Tags).", + version: "0.0.1", + type: "action", + props: { + benchmarkone, + contactId: { + propDefinition: [ + benchmarkone, + "contactId", + ], + }, + tags: { + type: "string[]", + label: "Tags", + description: "A list of tags to add to the contact.", + }, + }, + async run({ $ }) { + const response = await this.benchmarkone.addTagToContact({ + contactId: this.contactId, + data: parseObject(this.tags)?.map((item) => ({ + name: item, + })), + }); + + $.export("$summary", `Succcessfully added tags to contact ID ${this.contactId}`); + return response; + }, +}; diff --git a/components/benchmarkone/actions/create-contact/create-contact.mjs b/components/benchmarkone/actions/create-contact/create-contact.mjs new file mode 100644 index 0000000000000..0f571b288de33 --- /dev/null +++ b/components/benchmarkone/actions/create-contact/create-contact.mjs @@ -0,0 +1,183 @@ +import { ConfigurationError } from "@pipedream/platform"; +import benchmarkone from "../../benchmarkone.app.mjs"; +import { parseObject } from "../../common/utils.mjs"; + +export default { + key: "benchmarkone-create-contact", + name: "Create Contact", + description: "Creates a new contact in BenchmarkONE. [See the documentation](https://sandbox.hatchbuck.com/api/dist/#!/Contacts/post_contact)", + version: "0.0.1", + type: "action", + props: { + benchmarkone, + firstName: { + propDefinition: [ + benchmarkone, + "firstName", + ], + optional: true, + }, + lastName: { + propDefinition: [ + benchmarkone, + "lastName", + ], + optional: true, + }, + title: { + propDefinition: [ + benchmarkone, + "title", + ], + optional: true, + }, + company: { + propDefinition: [ + benchmarkone, + "company", + ], + optional: true, + }, + workEmail: { + propDefinition: [ + benchmarkone, + "workEmail", + ], + optional: true, + }, + homeEmail: { + propDefinition: [ + benchmarkone, + "homeEmail", + ], + optional: true, + }, + workPhone: { + propDefinition: [ + benchmarkone, + "workPhone", + ], + optional: true, + }, + homePhone: { + propDefinition: [ + benchmarkone, + "homePhone", + ], + optional: true, + }, + workAddress: { + propDefinition: [ + benchmarkone, + "workAddress", + ], + optional: true, + }, + homeAddress: { + propDefinition: [ + benchmarkone, + "homeAddress", + ], + optional: true, + }, + status: { + propDefinition: [ + benchmarkone, + "status", + ], + }, + temperature: { + propDefinition: [ + benchmarkone, + "temperature", + ], + optional: true, + }, + website: { + propDefinition: [ + benchmarkone, + "website", + ], + optional: true, + }, + }, + async run({ $ }) { + try { + const emails = []; + if (this.workEmail) { + emails.push({ + address: this.workEmail, + type: "Work", + }); + } + if (this.homeEmail) { + emails.push({ + address: this.homeEmail, + type: "Home", + }); + } + const phones = []; + if (this.workPhone) { + phones.push({ + number: this.workPhone, + type: "Work", + }); + } + if (this.homePhone) { + phones.push({ + number: this.homePhone, + type: "Home", + }); + } + const addresses = []; + if (this.workAddress) { + addresses.push({ + ...parseObject(this.workAddress), + type: "Work", + }); + } + if (this.homeAddress) { + addresses.push({ + ...parseObject(this.homeAddress), + type: "Home", + }); + } + + const data = { + contactId: this.contactId, + firstName: this.firstName, + lastName: this.lastName, + emails, + phones, + addresses, + }; + if (this.status) { + data.status = { + name: this.status.label, + id: this.status.value, + }; + } + if (this.temperature) { + data.temperature = { + name: this.temperature.label, + id: this.temperature.value, + }; + } + if (this.website) { + data.website = [ + { + websiteUrl: this.website, + }, + ]; + } + const response = await this.benchmarkone.createContact({ + $, + data, + }); + $.export("$summary", `Created contact with ID: ${response.contactId}`); + return response; + } catch (error) { + throw new ConfigurationError(`Failed to create contact: ${error.message}`); + } + }, +}; diff --git a/components/benchmarkone/actions/update-contact/update-contact.mjs b/components/benchmarkone/actions/update-contact/update-contact.mjs new file mode 100644 index 0000000000000..2f45edc32a059 --- /dev/null +++ b/components/benchmarkone/actions/update-contact/update-contact.mjs @@ -0,0 +1,191 @@ +import { ConfigurationError } from "@pipedream/platform"; +import benchmarkone from "../../benchmarkone.app.mjs"; +import { parseObject } from "../../common/utils.mjs"; + +export default { + key: "benchmarkone-update-contact", + name: "Update Contact", + description: "Updates an existing contact. [See the documentation](https://sandbox.hatchbuck.com/api/dist/#!/Contacts/put_contact)", + version: "0.0.1", + type: "action", + props: { + benchmarkone, + contactId: { + propDefinition: [ + benchmarkone, + "contactId", + ], + }, + firstName: { + propDefinition: [ + benchmarkone, + "firstName", + ], + optional: true, + }, + lastName: { + propDefinition: [ + benchmarkone, + "lastName", + ], + optional: true, + }, + title: { + propDefinition: [ + benchmarkone, + "title", + ], + optional: true, + }, + company: { + propDefinition: [ + benchmarkone, + "company", + ], + optional: true, + }, + workEmail: { + propDefinition: [ + benchmarkone, + "workEmail", + ], + optional: true, + }, + homeEmail: { + propDefinition: [ + benchmarkone, + "homeEmail", + ], + optional: true, + }, + workPhone: { + propDefinition: [ + benchmarkone, + "workPhone", + ], + optional: true, + }, + homePhone: { + propDefinition: [ + benchmarkone, + "homePhone", + ], + optional: true, + }, + workAddress: { + propDefinition: [ + benchmarkone, + "workAddress", + ], + optional: true, + }, + homeAddress: { + propDefinition: [ + benchmarkone, + "homeAddress", + ], + optional: true, + }, + status: { + propDefinition: [ + benchmarkone, + "status", + ], + optional: true, + }, + temperature: { + propDefinition: [ + benchmarkone, + "temperature", + ], + optional: true, + }, + website: { + propDefinition: [ + benchmarkone, + "website", + ], + optional: true, + }, + }, + async run({ $ }) { + try { + const emails = []; + if (this.workEmail) { + emails.push({ + address: this.workEmail, + type: "Work", + }); + } + if (this.homeEmail) { + emails.push({ + address: this.homeEmail, + type: "Home", + }); + } + const phones = []; + if (this.workPhone) { + phones.push({ + number: this.workPhone, + type: "Work", + }); + } + if (this.homePhone) { + phones.push({ + number: this.homePhone, + type: "Home", + }); + } + const addresses = []; + if (this.workAddress) { + addresses.push({ + ...parseObject(this.workAddress), + type: "Work", + }); + } + if (this.homeAddress) { + addresses.push({ + ...parseObject(this.homeAddress), + type: "Home", + }); + } + + const data = { + contactId: this.contactId, + firstName: this.firstName, + lastName: this.lastName, + emails, + phones, + addresses, + }; + if (this.status) { + data.status = { + name: this.status.label, + id: this.status.value, + }; + } + if (this.temperature) { + data.temperature = { + name: this.temperature.label, + id: this.temperature.value, + }; + } + if (this.website) { + data.website = [ + { + websiteUrl: this.website, + }, + ]; + } + + const response = await this.benchmarkone.updateContact({ + $, + data, + }); + $.export("$summary", "Contact updated successfully."); + return response; + } catch (error) { + throw new ConfigurationError(`Failed to create contact: ${error.message}`); + } + }, +}; diff --git a/components/benchmarkone/benchmarkone.app.mjs b/components/benchmarkone/benchmarkone.app.mjs index 6e9058b2fe7af..67e31bae14d1c 100644 --- a/components/benchmarkone/benchmarkone.app.mjs +++ b/components/benchmarkone/benchmarkone.app.mjs @@ -1,11 +1,181 @@ +import { axios } from "@pipedream/platform"; + export default { type: "app", app: "benchmarkone", - propDefinitions: {}, + propDefinitions: { + contactId: { + type: "string", + label: "Contact ID", + description: "The unique identifier of the contact.", + }, + firstName: { + type: "string", + label: "First Name", + description: "Contact's first name.", + }, + lastName: { + type: "string", + label: "Last Name", + description: "Contact's last name.", + }, + status: { + type: "string", + label: "Status", + description: "Contact's status.", + withLabel: true, + async options() { + const data = await this.listContactStatuses(); + return data.map(({ + id: value, name: label, + }) => ({ + label, + value, + })); + }, + }, + temperature: { + type: "string", + label: "Temperature", + description: "Contact's temperature.", + withLabel: true, + async options() { + const data = await this.listTemperatures(); + return data.map(({ + id: value, name: label, + }) => ({ + label, + value, + })); + }, + }, + title: { + type: "string", + label: "Title", + description: "The contact's title.", + }, + company: { + type: "string", + label: "Company", + description: "The contact's company name.", + }, + workEmail: { + type: "string", + label: "Work Email Address", + description: "A contact's work email address.", + }, + homeEmail: { + type: "string", + label: "Home Email Address", + description: "A contact's home email address.", + }, + workPhone: { + type: "string", + label: "Work Phone", + description: "A contact's work phone number.", + }, + homePhone: { + type: "string", + label: "Home Phone", + description: "A contact's home phone number.", + }, + workAddress: { + type: "object", + label: "Work Address", + description: "An object of contact's work address.", + default: { + street: "", + city: "", + state: "", + zip: "", + country: "", + }, + }, + homeAddress: { + type: "object", + label: "Home Address", + description: "An object of contact's home address.", + default: { + street: "", + city: "", + state: "", + zip: "", + country: "", + }, + }, + website: { + type: "string", + label: "Website", + description: "The contact's website.", + }, + }, methods: { - // this.$auth contains connected account data - authKeys() { - console.log(Object.keys(this.$auth)); + _baseUrl() { + return "https://api.hatchbuck.com/api/v1"; + }, + _params(params = {}) { + return { + api_key: this.$auth.api_key, + ...params, + }; + }, + _makeRequest({ + $ = this, path, params, ...opts + }) { + return axios($, { + url: this._baseUrl() + path, + params: this._params(params), + ...opts, + }); + }, + listContactStatuses() { + return this._makeRequest({ + path: "/settings/contactStatus", + }); + }, + listTemperatures() { + return this._makeRequest({ + path: "/settings/temperature", + }); + }, + createContact(opts = {}) { + return this._makeRequest({ + method: "POST", + path: "/contact", + ...opts, + }); + }, + updateContact(opts = {}) { + return this._makeRequest({ + method: "PUT", + path: "/contact", + ...opts, + }); + }, + addNoteToContact({ + contactId, ...opts + }) { + return this._makeRequest({ + method: "POST", + path: `/contact/${contactId}/notes`, + ...opts, + }); + }, + addTagToContact({ + contactId, ...opts + }) { + return this._makeRequest({ + method: "POST", + path: `/contact/${contactId}/tags`, + ...opts, + }); + }, + createWebhook(opts = {}) { + return this._makeRequest({ + method: "POST", + path: "/Webhook/Addwebhook", + ...opts, + }); }, }, }; diff --git a/components/benchmarkone/common/utils.mjs b/components/benchmarkone/common/utils.mjs new file mode 100644 index 0000000000000..dcc9cc61f6f41 --- /dev/null +++ b/components/benchmarkone/common/utils.mjs @@ -0,0 +1,24 @@ +export const parseObject = (obj) => { + if (!obj) return undefined; + + if (Array.isArray(obj)) { + return obj.map((item) => { + if (typeof item === "string") { + try { + return JSON.parse(item); + } catch (e) { + return item; + } + } + return item; + }); + } + if (typeof obj === "string") { + try { + return JSON.parse(obj); + } catch (e) { + return obj; + } + } + return obj; +}; diff --git a/components/benchmarkone/package.json b/components/benchmarkone/package.json index 3c09a92341b72..b3db1a868e73b 100644 --- a/components/benchmarkone/package.json +++ b/components/benchmarkone/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/benchmarkone", - "version": "0.0.1", + "version": "0.1.0", "description": "Pipedream BenchmarkONE Components", "main": "benchmarkone.app.mjs", "keywords": [ @@ -11,5 +11,8 @@ "author": "Pipedream (https://pipedream.com/)", "publishConfig": { "access": "public" + }, + "dependencies": { + "@pipedream/platform": "^3.0.3" } } diff --git a/components/benchmarkone/sources/new-webhook-automation-event-instant/new-webhook-automation-event-instant.mjs b/components/benchmarkone/sources/new-webhook-automation-event-instant/new-webhook-automation-event-instant.mjs new file mode 100644 index 0000000000000..41bfbf1f33e2d --- /dev/null +++ b/components/benchmarkone/sources/new-webhook-automation-event-instant/new-webhook-automation-event-instant.mjs @@ -0,0 +1,48 @@ +import benchmarkone from "../../benchmarkone.app.mjs"; +import sampleEmit from "./test-event.mjs"; + +export default { + key: "benchmarkone-new-webhook-automation-event-instant", + name: "New Webhook Automation Event (Instant)", + description: "Emit new event when a webhook automation step is triggered in BenchmarkONE.", + version: "0.0.1", + type: "source", + dedupe: "unique", + props: { + benchmarkone, + http: "$.interface.http", + db: "$.service.db", + alert: { + type: "alert", + alertType: "warning", + content: "BenchmarkONE does not provide a way to delete webhooks through API. If you want to stop receiving events, you'll need to delete this source and the webhook from the [BenchmarkONE UI > Account Settings > Data > Webhooks](https://app.hatchbuck.com/account/setting#Webhooks)", + }, + webhookName: { + type: "string", + label: "Webhook Name", + description: "Webhook name for display in the BenchmarkONE UI.", + optional: true, + }, + }, + methods: {}, + hooks: { + async activate() { + await this.benchmarkone.createWebhook({ + data: { + URL: this.http.endpoint, + WebHookName: this.webhookName, + Trigger: "all triggers", + }, + }); + }, + }, + async run({ body }) { + const ts = Date.parse(body.Data.createdDt || new Date()); + this.$emit(body, { + id: `${body.Data.contactId}-${ts}`, + summary: "New Automation Event", + ts: ts, + }); + }, + sampleEmit, +}; diff --git a/components/benchmarkone/sources/new-webhook-automation-event-instant/test-event.mjs b/components/benchmarkone/sources/new-webhook-automation-event-instant/test-event.mjs new file mode 100644 index 0000000000000..c71056e7938b5 --- /dev/null +++ b/components/benchmarkone/sources/new-webhook-automation-event-instant/test-event.mjs @@ -0,0 +1,116 @@ +export default { + "Data":[ + { + "contactId":"QmNXLWlfVk0zN1dOaERKYU45c0pEZzdxSUZTaE1ZanNvUmpySjc3eGxYYzE1", + "firstName":"Eric", + "lastName":"Weiss", + "title":"Customer Support Rep", + "company":"The Real Hatchbuck", + "createdDt":"2017-03-16T19:24:19.327", + "contactUrl":"https://app.hatchbuck.com//Contact/ContactDetail?eid=QmNXLWlfVk0zN1dOaERKYU45c0pEZzdxSUZTaE1ZanNvUmpySjc3eGxYYzE1", + "emails":[ + { + "id":"dVRyQlRfLU1GZ3J1ZXBRUk4zSnZWRjd5ZUtpVy1oaW1vWThSV2EtOXBVczE1", + "address":"eweiss@hatchbuck.com", + "type":"Work", + "typeId":"VmhlQU1pZVJSUFFJSjZfMHRmT1laUmwtT0FMNW9hbnBuZHd2Q1JTdE0tYzE1", + "isPrimary":true + } + ], + "phones":[ + { + "id":"Y211cTRiTVRSZElqUGY4NVVRY1lFV1FQaS1aY2JOeEZBUEd2Xzc4ejZ5VTE1", + "number":"3142880399", + "type":"Work", + "typeId":"QTBncHV0dndnaGNnRVMzLTR0SGtFRmRvZjdqNm4zcVphQi1XX1Z2MXVtRTE1", + "isPrimary":true + }, + { + "id":"UkhBQ19RTDdnaU1NY09OMWVvYldiQU5zQTU2Umx4VkJBX3czSDhpTi1OUTE1", + "number":"(866) 991-4888", + "type":"Work", + "typeId":"QTBncHV0dndnaGNnRVMzLTR0SGtFRmRvZjdqNm4zcVphQi1XX1Z2MXVtRTE1", + "isPrimary":false + } + ], + "tags":[ + { + "name":"met my dad", + "score":3, + "id":"Yno4aWRiXzFKTUNkcE10cEtBLUQ4eUM4SWRfWlJLWmNCY1dBeXBRLU1kWTE1" + }, + { + "name":"visited website", + "score":1, + "id":"TWs0U1hXeDJzdDk5ZHBIcVhzZzVQV3hxOHE1X2IydE9KXy01bGFMU0E4QTE1" + } + ], + "campaigns":[ + { + "name":"ad timers", + "step":3, + "id":"1066365" + }, + { + "name":"Basic A - Tags Basic B copy copy", + "step":3, + "id":"288854" + } + ], + "status":{ + "name":"Investigator", + "id":"VnFMcmNUMXFfT0tXM1RYZ3FWQUdSRkVra1ZDZG1IajZucEo0UzZ3ZkF5VTE1" + }, + "temperature":{ + "name":"Colder", + "id":"d0ZFT3NTdENxMTNjWFZESkdiSWtubGhWWjA0cUpVcy1BWWwzTUdJaVNDRTE1" + }, + "salesRep":{ + "username":"tholt576@yahoo.com1", + "id":"TWpHRE14dFBERVY3c3hQaG9lZ2ZsdkhoWDZLanVYYUk5MktQbEhxRHZZVTE1" + }, + "addresses":[ + { + "id":"N3cwanMxVjBTVERCcDZUeTh3MmVEemZKNzIwZ0FCUzRHLS1HczJPbkpHYzE1", + "street":"911 Washington Avenue", + "city":"St. Louis", + "state":"MO", + "zip":"63129", + "countryId":"LS1qcWZaeVFGdkRXNnZpcTlkclVORHNLMTVnMWhObkFQVnItdmM0RTlTczE1", + "type":"Work", + "typeId":"SjFENlU0Y2s2RDFpM0NKWEExRmVvSjZ4T3NJMG5pLWNYZjRseDBSaTVfVTE1", + "isPrimary":true + } + ], + "timezone":"Central Standard Time", + "socialNetworks":[ ], + "instantMessaging":[ ], + "website":[ + ], + "source":{ + "name":"Facebook", + "id":"UkRGdHA3YkpiYVYzN3JqVzVhWWxaMlkyejlhd3FxLWxuTmlXZ3pKaE54RTE1" + }, + "referredBy":"Katie Culp", + "customFields":[ + { + "name":"Office Location", + "type":"Text", + "value":"IDK" + }, + { + "name":"Original Source", + "type":"Text", + "value":"Maybe" + }, + { + "name":"BOA / Jr. Ins Agent Email", + "type":"Text", + "value":"" + } + ], + "subscribed":true + } + ], + "StatusCode":0 +} \ No newline at end of file diff --git a/components/bitbucket_data_center/bitbucket_data_center.app.mjs b/components/bitbucket_data_center/bitbucket_data_center.app.mjs index 922ead122293b..a193358cf0c4a 100644 --- a/components/bitbucket_data_center/bitbucket_data_center.app.mjs +++ b/components/bitbucket_data_center/bitbucket_data_center.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/frontify/frontify.app.mjs b/components/frontify/frontify.app.mjs index 35b602820c598..f7902b68e5e75 100644 --- a/components/frontify/frontify.app.mjs +++ b/components/frontify/frontify.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/membership_io/membership_io.app.mjs b/components/membership_io/membership_io.app.mjs index 16dad612f6a0e..0ff214f8ca984 100644 --- a/components/membership_io/membership_io.app.mjs +++ b/components/membership_io/membership_io.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/portabilling/portabilling.app.mjs b/components/portabilling/portabilling.app.mjs index e2de504d416df..9d2b0ae23fadc 100644 --- a/components/portabilling/portabilling.app.mjs +++ b/components/portabilling/portabilling.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0c2c55850ceca..8d00235ded427 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1346,7 +1346,11 @@ importers: specifier: ^3.0.0 version: 3.0.3 - components/benchmarkone: {} + components/benchmarkone: + dependencies: + '@pipedream/platform': + specifier: ^3.0.3 + version: 3.0.3 components/benzinga: dependencies: @@ -1479,8 +1483,7 @@ importers: specifier: ^0.0.4 version: 0.0.4 - components/bitbucket_data_center: - specifiers: {} + components/bitbucket_data_center: {} components/bitdefender_gravityzone: {} @@ -4732,8 +4735,7 @@ importers: specifier: ^1.6.0 version: 1.6.6 - components/frontify: - specifiers: {} + components/frontify: {} components/ftrack: dependencies: @@ -7595,8 +7597,7 @@ importers: specifier: ^9.0.0 version: 9.0.1 - components/membership_io: - specifiers: {} + components/membership_io: {} components/memberspot: dependencies: @@ -9535,8 +9536,7 @@ importers: components/popupsmart: {} - components/portabilling: - specifiers: {} + components/portabilling: {} components/portfolio_optimizer: {}