diff --git a/components/connectwise_psa/actions/create-company/create-company.mjs b/components/connectwise_psa/actions/create-company/create-company.mjs new file mode 100644 index 0000000000000..a39f2cac87a18 --- /dev/null +++ b/components/connectwise_psa/actions/create-company/create-company.mjs @@ -0,0 +1,142 @@ +import connectwise from "../../connectwise_psa.app.mjs"; + +export default { + key: "connectwise_psa-create-company", + name: "Create Company", + description: "Creates a new company in Connectwise. [See the documentation](https://developer.connectwise.com/Products/ConnectWise_PSA/REST#/Companies/postCompanyCompanies)", + version: "0.0.1", + type: "action", + props: { + connectwise, + name: { + type: "string", + label: "Company Name", + description: "The name of the new company", + }, + identifier: { + type: "string", + label: "Identifier", + description: "A unique identifier for the company", + }, + types: { + propDefinition: [ + connectwise, + "companyTypes", + ], + }, + status: { + propDefinition: [ + connectwise, + "status", + ], + }, + site: { + type: "string", + label: "Site Name", + description: "The site name for the company", + }, + address1: { + type: "string", + label: "Address Line 1", + description: "First line of the company's address", + optional: true, + }, + address2: { + type: "string", + label: "Address Line 2", + description: "Second line of the company's address", + optional: true, + }, + city: { + type: "string", + label: "City", + description: "City of the company", + optional: true, + }, + state: { + type: "string", + label: "State", + description: "State of the company", + optional: true, + }, + zip: { + type: "string", + label: "Zip", + description: "Zip code of the company", + optional: true, + }, + country: { + propDefinition: [ + connectwise, + "country", + ], + }, + phone: { + type: "string", + label: "Phone", + description: "Phone number of the company", + optional: true, + }, + website: { + type: "string", + label: "Website", + description: "Website of the company", + optional: true, + }, + market: { + propDefinition: [ + connectwise, + "market", + ], + }, + territory: { + propDefinition: [ + connectwise, + "territory", + ], + }, + }, + async run({ $ }) { + const types = this.types.map((type) => ({ + id: type, + })); + const response = await this.connectwise.createCompany({ + $, + data: { + name: this.name, + identifier: this.identifier, + types, + status: { + id: this.status, + }, + site: { + name: this.site, + }, + addressLine1: this.address1, + addressLine2: this.address2, + city: this.city, + state: this.state, + zip: this.zip, + country: this.country + ? { + id: this.country, + } + : undefined, + phoneNumber: this.phone, + website: this.website, + market: this.market + ? { + id: this.market, + } + : undefined, + territory: this.territory + ? { + id: this.territory, + } + : undefined, + }, + }); + $.export("$summary", `Successfully created company with ID: ${response.id}`); + return response; + }, +}; diff --git a/components/connectwise_psa/actions/create-contact/create-contact.mjs b/components/connectwise_psa/actions/create-contact/create-contact.mjs new file mode 100644 index 0000000000000..4ac0d16d6d05b --- /dev/null +++ b/components/connectwise_psa/actions/create-contact/create-contact.mjs @@ -0,0 +1,153 @@ +import connectwise from "../../connectwise_psa.app.mjs"; + +export default { + key: "connectwise_psa-create-contact", + name: "Create Contact", + description: "Creates a new contact in Connectwise. [See the documentation](https://developer.connectwise.com/Products/ConnectWise_PSA/REST#/Contacts/postCompanyContacts)", + version: "0.0.1", + type: "action", + props: { + connectwise, + 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, + }, + types: { + propDefinition: [ + connectwise, + "contactTypes", + ], + }, + company: { + propDefinition: [ + connectwise, + "company", + ], + optional: true, + }, + relationship: { + propDefinition: [ + connectwise, + "relationship", + ], + }, + department: { + propDefinition: [ + connectwise, + "department", + ], + }, + phone: { + type: "string", + label: "Phone", + description: "Phone number of the contact", + optional: true, + }, + address1: { + type: "string", + label: "Address Line 1", + description: "First line of the contact's address", + optional: true, + }, + address2: { + type: "string", + label: "Address Line 2", + description: "Second line of the contact's address", + optional: true, + }, + city: { + type: "string", + label: "City", + description: "City of the contact", + optional: true, + }, + state: { + type: "string", + label: "State", + description: "State of the contact", + optional: true, + }, + zip: { + type: "string", + label: "Zip", + description: "Zip code of the contact", + optional: true, + }, + country: { + propDefinition: [ + connectwise, + "country", + ], + }, + }, + async run({ $ }) { + const communicationItems = []; + if (this.email) { + communicationItems.push({ + value: this.email, + type: { + id: 1, // email + }, + }); + } + if (this.phone) { + communicationItems.push({ + value: this.phone, + type: { + id: 2, // phone + }, + }); + } + const types = this.types.map((type) => ({ + id: type, + })); + const response = await this.connectwise.createContact({ + $, + data: { + firstName: this.firstName, + lastName: this.lastName, + addressLine1: this.address1, + addressLine2: this.address2, + city: this.city, + state: this.state, + zip: this.zip, + country: this.country + ? { + id: this.country, + } + : undefined, + communicationItems, + types, + company: this.company + ? { + id: this.company, + } + : undefined, + relationship: this.relationship + ? { + id: this.relationship, + } + : undefined, + department: this.department + ? { + id: this.department, + } + : undefined, + }, + }); + $.export("$summary", `Successfully created contact with ID: ${response.id}`); + return response; + }, +}; diff --git a/components/connectwise_psa/actions/create-ticket/create-ticket.mjs b/components/connectwise_psa/actions/create-ticket/create-ticket.mjs new file mode 100644 index 0000000000000..850a2d9d1f910 --- /dev/null +++ b/components/connectwise_psa/actions/create-ticket/create-ticket.mjs @@ -0,0 +1,58 @@ +import connectwise from "../../connectwise_psa.app.mjs"; + +export default { + key: "connectwise_psa-create-ticket", + name: "Create Ticket", + description: "Creates a new ticket in Connectwise. [See the documentation](https://developer.connectwise.com/Products/ConnectWise_PSA/REST#/Tickets/postServiceTickets)", + version: "0.0.1", + type: "action", + props: { + connectwise, + summary: { + type: "string", + label: "Summary", + description: "The subject line or description line for the ticket", + }, + company: { + propDefinition: [ + connectwise, + "company", + ], + }, + contact: { + propDefinition: [ + connectwise, + "contact", + ], + }, + priority: { + propDefinition: [ + connectwise, + "priority", + ], + }, + }, + async run({ $ }) { + const response = await this.connectwise.createTicket({ + $, + data: { + summary: this.summary, + company: { + id: this.company, + }, + contact: this.contact + ? { + id: this.contact, + } + : undefined, + priority: this.priority + ? { + id: this.priority, + } + : undefined, + }, + }); + $.export("$summary", `Successfully created ticket with ID: ${response.id}`); + return response; + }, +}; diff --git a/components/connectwise_psa/connectwise_psa.app.mjs b/components/connectwise_psa/connectwise_psa.app.mjs index b76bace0e7fbb..95104a7a06031 100644 --- a/components/connectwise_psa/connectwise_psa.app.mjs +++ b/components/connectwise_psa/connectwise_psa.app.mjs @@ -1,11 +1,364 @@ +import { axios } from "@pipedream/platform"; + export default { type: "app", app: "connectwise_psa", - propDefinitions: {}, + propDefinitions: { + company: { + type: "integer", + label: "Company", + description: "The identifier of a company", + async options({ page }) { + const companies = await this.listCompanies({ + params: { + page: page + 1, + }, + }); + return companies?.map(({ + id: value, name: label, + }) => ({ + value, + label, + })) || []; + }, + }, + contact: { + type: "integer", + label: "Contact", + description: "The identifier of a contact", + async options({ page }) { + const contacts = await this.listContacts({ + params: { + page: page + 1, + }, + }); + return contacts?.map(({ + id: value, firstName, lastName, + }) => ({ + value, + label: `${firstName} ${lastName}`, + })) || []; + }, + }, + companyTypes: { + type: "integer[]", + label: "Types", + description: "Select one or more company types", + async options({ page }) { + const types = await this.listCompanyTypes({ + params: { + page: page + 1, + }, + }); + return types?.map(({ + id: value, name: label, + }) => ({ + value, + label, + })) || []; + }, + }, + contactTypes: { + type: "integer[]", + label: "Types", + description: "Select one or more contact types", + async options({ page }) { + const types = await this.listContactTypes({ + params: { + page: page + 1, + }, + }); + return types?.map(({ + id: value, description: label, + }) => ({ + value, + label, + })) || []; + }, + }, + status: { + type: "integer", + label: "Status", + description: "The status of the company", + async options({ page }) { + const statuses = await this.listCompanyStatuses({ + params: { + page: page + 1, + }, + }); + return statuses?.map(({ + id: value, name: label, + }) => ({ + value, + label, + })) || []; + }, + }, + territory: { + type: "integer", + label: "Territory", + description: "The territory location the company", + optional: true, + async options({ page }) { + const territories = await this.listLocations({ + params: { + page: page + 1, + }, + }); + return territories?.map(({ + id: value, name: label, + }) => ({ + value, + label, + })) || []; + }, + }, + market: { + type: "integer", + label: "Market", + description: "The market of the company", + optional: true, + async options({ page }) { + const markets = await this.listMarkets({ + params: { + page: page + 1, + }, + }); + return markets?.map(({ + id: value, name: label, + }) => ({ + value, + label, + })) || []; + }, + }, + relationship: { + type: "integer", + label: "Relationship", + description: "The relationship of the contact", + optional: true, + async options({ page }) { + const relationships = await this.listRelationships({ + params: { + page: page + 1, + }, + }); + return relationships?.map(({ + id: value, name: label, + }) => ({ + value, + label, + })) || []; + }, + }, + department: { + type: "integer", + label: "Department", + description: "The department of the contact", + optional: true, + async options({ page }) { + const departments = await this.listDepartments({ + params: { + page: page + 1, + }, + }); + return departments?.map(({ + id: value, name: label, + }) => ({ + value, + label, + })) || []; + }, + }, + country: { + type: "integer", + label: "Country", + description: "The identifier of a country", + optional: true, + async options({ page }) { + const countries = await this.listCountries({ + params: { + page: page + 1, + }, + }); + return countries?.map(({ + id: value, name: label, + }) => ({ + value, + label, + })) || []; + }, + }, + priority: { + type: "integer", + label: "Priority", + description: "The priority of the ticket", + optional: true, + async options({ page }) { + const priorities = await this.listPriorities({ + params: { + page: page + 1, + }, + }); + return priorities?.map(({ + id: value, name: label, + }) => ({ + value, + label, + })) || []; + }, + }, + }, methods: { - // this.$auth contains connected account data - authKeys() { - console.log(Object.keys(this.$auth)); + _baseUrl() { + return `https://${this.$auth.environment}/v4_6_release/apis/3.0`; + }, + _headers() { + return { + clientId: this.$auth.client_id, + }; + }, + _auth() { + return { + username: `${this.$auth.company_id}+${this.$auth.public_key}`, + password: `${this.$auth.private_key}`, + }; + }, + _makeRequest({ + $ = this, + path, + ...opts + }) { + return axios($, { + url: `${this._baseUrl()}${path}`, + headers: this._headers(), + auth: this._auth(), + ...opts, + }); + }, + listCompanies(opts = {}) { + return this._makeRequest({ + path: "/company/companies", + ...opts, + }); + }, + listContacts(opts = {}) { + return this._makeRequest({ + path: "/company/contacts", + ...opts, + }); + }, + listProjects(opts = {}) { + return this._makeRequest({ + path: "/project/projects", + ...opts, + }); + }, + listTickets(opts = {}) { + return this._makeRequest({ + path: "/service/tickets", + ...opts, + }); + }, + listCompanyTypes(opts = {}) { + return this._makeRequest({ + path: "/company/companies/types", + ...opts, + }); + }, + listContactTypes(opts = {}) { + return this._makeRequest({ + path: "/company/contacts/types", + ...opts, + }); + }, + listCompanyStatuses(opts = {}) { + return this._makeRequest({ + path: "/company/companies/statuses", + ...opts, + }); + }, + listLocations(opts = {}) { + return this._makeRequest({ + path: "/system/locations", + ...opts, + }); + }, + listMarkets(opts = {}) { + return this._makeRequest({ + path: "/company/marketDescriptions", + ...opts, + }); + }, + listRelationships(opts = {}) { + return this._makeRequest({ + path: "/company/contacts/relationships", + ...opts, + }); + }, + listDepartments(opts = {}) { + return this._makeRequest({ + path: "/company/contacts/departments", + ...opts, + }); + }, + listPriorities(opts = {}) { + return this._makeRequest({ + path: "/service/priorities", + ...opts, + }); + }, + listCountries(opts = {}) { + return this._makeRequest({ + path: "/company/countries", + ...opts, + }); + }, + createContact(opts = {}) { + return this._makeRequest({ + method: "POST", + path: "/company/contacts", + ...opts, + }); + }, + createCompany(opts = {}) { + return this._makeRequest({ + method: "POST", + path: "/company/companies", + ...opts, + }); + }, + createTicket(opts = {}) { + return this._makeRequest({ + method: "POST", + path: "/service/tickets", + ...opts, + }); + }, + async *paginate({ + resourceFn, + params, + max, + }) { + params = { + ...params, + page: 1, + }; + let hasMore, count = 0; + do { + const items = await resourceFn({ + params, + }); + for (const item of items) { + yield item; + count++; + if (max && count >= max) { + return; + } + } + hasMore = items.length; + params.page++; + } while (hasMore); }, }, -}; \ No newline at end of file +}; diff --git a/components/connectwise_psa/package.json b/components/connectwise_psa/package.json index ba5d118b6cdbc..12cb51c301656 100644 --- a/components/connectwise_psa/package.json +++ b/components/connectwise_psa/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/connectwise_psa", - "version": "0.0.1", + "version": "0.1.1", "description": "Pipedream Connectwise PSA Components", "main": "connectwise_psa.app.mjs", "keywords": [ @@ -11,5 +11,8 @@ "author": "Pipedream (https://pipedream.com/)", "publishConfig": { "access": "public" + }, + "dependencies": { + "@pipedream/platform": "^2.0.0" } -} \ No newline at end of file +} diff --git a/components/connectwise_psa/sources/common/base.mjs b/components/connectwise_psa/sources/common/base.mjs new file mode 100644 index 0000000000000..f31b81aba1551 --- /dev/null +++ b/components/connectwise_psa/sources/common/base.mjs @@ -0,0 +1,70 @@ +import connectwise from "../../connectwise_psa.app.mjs"; +import { DEFAULT_POLLING_SOURCE_TIMER_INTERVAL } from "@pipedream/platform"; + +export default { + props: { + connectwise, + db: "$.service.db", + timer: { + type: "$.interface.timer", + default: { + intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, + }, + }, + }, + hooks: { + async deploy() { + await this.processEvent(25); + }, + }, + methods: { + _getLastId() { + return this.db.get("lastId") || 0; + }, + _setLastId(lastId) { + this.db.set("lastId", lastId); + }, + getParams() { + return {}; + }, + generateMeta(item) { + return { + id: item.id, + summary: this.getSummary(item), + ts: Date.now(), + }; + }, + async processEvent(max) { + const lastId = this._getLastId(); + const resourceFn = this.getResourceFn(); + const params = this.getParams(); + const results = this.connectwise.paginate({ + resourceFn, + params, + }); + let items = []; + for await (const item of results) { + if (item.id > lastId) { + items.push(item); + } + } + if (!items.length) { + return; + } + if (max) { + items = items.slice(-1 * max); + } + this._setLastId(items[items.length - 1].id); + items.forEach((item) => this.$emit(item, this.generateMeta(item))); + }, + getResourceFn() { + throw new Error("getResourceFn is not implemented"); + }, + getSummary() { + throw new Error("getSummary is not implemented"); + }, + }, + async run() { + await this.processEvent(); + }, +}; diff --git a/components/connectwise_psa/sources/new-contact-created/new-contact-created.mjs b/components/connectwise_psa/sources/new-contact-created/new-contact-created.mjs new file mode 100644 index 0000000000000..630191f34e289 --- /dev/null +++ b/components/connectwise_psa/sources/new-contact-created/new-contact-created.mjs @@ -0,0 +1,22 @@ +import common from "../common/base.mjs"; +import sampleEmit from "./test-event.mjs"; + +export default { + ...common, + key: "connectwise_psa-new-contact-created", + name: "New Contact Created", + description: "Emit new event when a new contact is created in Connectwise.", + version: "0.0.1", + type: "source", + dedupe: "unique", + methods: { + ...common.methods, + getResourceFn() { + return this.connectwise.listContacts; + }, + getSummary(item) { + return `New Contact Created: ${item.firstName} ${item.lastName}`; + }, + }, + sampleEmit, +}; diff --git a/components/connectwise_psa/sources/new-contact-created/test-event.mjs b/components/connectwise_psa/sources/new-contact-created/test-event.mjs new file mode 100644 index 0000000000000..5fd2b0a999e61 --- /dev/null +++ b/components/connectwise_psa/sources/new-contact-created/test-event.mjs @@ -0,0 +1,63 @@ +export default { + "id": 179, + "firstName": "Mike", + "lastName": "Evans", + "company": { + "id": 132, + "identifier": "EarthTrisolarisOrganization", + "name": "Earth-Trisolaris Organization", + "_info": { + "company_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//company/companies/132", + "mobileGuid": "74e4f32b-ebda-40d4-b25f-231d97e9dd28" + } + }, + "site": { + "id": 136, + "name": "Earth", + "_info": { + "site_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//company/companies/132/sites/136", + "mobileGuid": "77d95c91-bc33-4931-940a-22295abf42e3" + } + }, + "inactiveFlag": false, + "marriedFlag": false, + "childrenFlag": false, + "portalSecurityLevel": 1, + "disablePortalLoginFlag": true, + "unsubscribeFlag": false, + "mobileGuid": "8d6a547e-6a2e-43aa-9670-9907376e4f4f", + "defaultBillingFlag": false, + "defaultFlag": false, + "companyLocation": { + "id": 39, + "name": "My Accounts", + "_info": { + "location_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//system/locations/39" + } + }, + "types": [ + { + "id": 11, + "name": "No Longer Employed", + "_info": { + "type_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//company/contacts/types/11" + } + } + ], + "ignoreDuplicates": false, + "_info": { + "lastUpdated": "2024-05-31T18:18:16Z", + "updatedBy": "Admin1", + "communications_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//company/contacts/179/communications", + "notes_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//company/contacts/179/notes", + "tracks_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//company/contacts/179/tracks", + "portalSecurity_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//company/contacts/179/portalSecurity", + "activities_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//sales/activities?conditions=contact/id=179", + "documents_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//system/documents?recordType=Contact&recordId=179", + "configurations_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//company/configurations?conditions=contact/id=179", + "tickets_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//service/tickets?conditions=contact/id=179", + "opportunities_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//sales/opportunities?conditions=contact/id=179", + "projects_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//project/projects?conditions=contact/id=179", + "image_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//company/contacts/179/image?lastModified=2024-05-31T18:18:16Z" + } +} \ No newline at end of file diff --git a/components/connectwise_psa/sources/new-project-created/new-project-created.mjs b/components/connectwise_psa/sources/new-project-created/new-project-created.mjs new file mode 100644 index 0000000000000..ddd86b0c76b22 --- /dev/null +++ b/components/connectwise_psa/sources/new-project-created/new-project-created.mjs @@ -0,0 +1,22 @@ +import common from "../common/base.mjs"; +import sampleEmit from "./test-event.mjs"; + +export default { + ...common, + key: "connectwise_psa-new-project-created", + name: "New Project Created", + description: "Emit new event when a new project is created in Connectwise.", + version: "0.0.1", + type: "source", + dedupe: "unique", + methods: { + ...common.methods, + getResourceFn() { + return this.connectwise.listProjects; + }, + getSummary(item) { + return `New Project Created: ${item.name}`; + }, + }, + sampleEmit, +}; diff --git a/components/connectwise_psa/sources/new-project-created/test-event.mjs b/components/connectwise_psa/sources/new-project-created/test-event.mjs new file mode 100644 index 0000000000000..84899a49b7b15 --- /dev/null +++ b/components/connectwise_psa/sources/new-project-created/test-event.mjs @@ -0,0 +1,122 @@ +export default { + "id": 11, + "actualHours": 0, + "billExpenses": "NoDefault", + "billingAmount": 0, + "billingAttention": "", + "billingMethod": "ActualRates", + "billingRateType": "WorkRole", + "billProducts": "Billable", + "billProjectAfterClosedFlag": true, + "billTime": "NoDefault", + "billUnapprovedTimeAndExpense": false, + "board": { + "id": 3, + "name": "Projects-2-10", + "_info": { + "board_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//service/boards/3" + } + }, + "budgetAnalysis": "ActualHours", + "budgetFlag": false, + "company": { + "id": 2, + "identifier": "YourCompany", + "name": "Your Company", + "_info": { + "company_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//company/companies/2" + } + }, + "contact": { + "id": 77, + "name": "Arnie Bellini", + "_info": { + "contact_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//company/contacts/77" + } + }, + "customerPO": "", + "description": "", + "currency": { + "id": 7, + "symbol": "$", + "currencyCode": "USD", + "decimalSeparator": ".", + "numberOfDecimals": 2, + "thousandsSeparator": ",", + "negativeParenthesesFlag": false, + "displaySymbolFlag": false, + "currencyIdentifier": "Z-US$", + "displayIdFlag": false, + "rightAlign": false, + "name": "US Dollars", + "_info": { + "currency_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//finance/currencies/7" + } + }, + "downpayment": 0, + "estimatedEnd": "2007-07-27T00:00:00Z", + "estimatedExpenseRevenue": 0, + "estimatedHours": 0, + "estimatedProductRevenue": 0, + "estimatedStart": "2007-07-02T00:00:00Z", + "estimatedTimeRevenue": 0, + "includeDependenciesFlag": false, + "includeEstimatesFlag": false, + "location": { + "id": 2, + "name": "Tampa Office", + "_info": { + "location_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//system/locations/2" + } + }, + "department": { + "id": 10, + "identifier": "Services", + "name": "Professional Services", + "_info": { + "department_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//system/departments/10" + } + }, + "manager": { + "id": 150, + "identifier": "zAdmin", + "name": "zSys Admin", + "_info": { + "member_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//system/members/150" + } + }, + "name": "ConnectWise Implementation", + "restrictDownPaymentFlag": false, + "scheduledHours": 0, + "status": { + "id": 1, + "name": "Open", + "_info": { + "status_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//project/statuses/1" + } + }, + "closedFlag": false, + "type": { + "id": 8, + "name": "Implementations", + "_info": { + "projectType_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//project/projectTypes/8" + } + }, + "doNotDisplayInPortalFlag": false, + "poAmount": 0, + "estimatedTimeCost": 0, + "estimatedExpenseCost": 0, + "estimatedProductCost": 0, + "companyLocation": { + "id": 38, + "name": "Corporate", + "_info": { + "location_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//system/locations/38" + } + }, + "_info": { + "lastUpdated": "2007-07-17T17:26:02Z", + "updatedBy": "zadmin" + } +} \ No newline at end of file diff --git a/components/connectwise_psa/sources/new-ticket-created/new-ticket-created.mjs b/components/connectwise_psa/sources/new-ticket-created/new-ticket-created.mjs new file mode 100644 index 0000000000000..e9dec3f20ca97 --- /dev/null +++ b/components/connectwise_psa/sources/new-ticket-created/new-ticket-created.mjs @@ -0,0 +1,22 @@ +import common from "../common/base.mjs"; +import sampleEmit from "./test-event.mjs"; + +export default { + ...common, + key: "connectwise_psa-new-ticket-created", + name: "New Ticket Created", + description: "Emit new event when a new ticket is created in Connectwise.", + version: "0.0.1", + type: "source", + dedupe: "unique", + methods: { + ...common.methods, + getResourceFn() { + return this.connectwise.listTickets; + }, + getSummary(item) { + return `New Ticket Created: ${item.summary}`; + }, + }, + sampleEmit, +}; diff --git a/components/connectwise_psa/sources/new-ticket-created/test-event.mjs b/components/connectwise_psa/sources/new-ticket-created/test-event.mjs new file mode 100644 index 0000000000000..296bc6520be1f --- /dev/null +++ b/components/connectwise_psa/sources/new-ticket-created/test-event.mjs @@ -0,0 +1,183 @@ +export default { + "id": 493, + "summary": "Check Remote Backup", + "recordType": "ServiceTicket", + "board": { + "id": 1, + "name": "Professional Services", + "_info": { + "board_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//service/boards/1" + } + }, + "status": { + "id": 16, + "name": "New (not responded)", + "Sort": 0, + "_info": { + "status_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//service/boards/1/statuses/16" + } + }, + "company": { + "id": 16, + "identifier": "IndigoStrawberryCo", + "name": "IndigoStrawberry, Co.", + "_info": { + "company_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//company/companies/16", + "mobileGuid": "102830a1-479e-4a5f-bec1-fbc532e43c30" + } + }, + "site": { + "id": 20, + "name": "Main", + "_info": { + "site_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//company/companies/16/sites/20", + "mobileGuid": "caf531b0-1e63-4159-b429-642b6057a242" + } + }, + "siteName": "Main", + "addressLine1": "2106 SHADYHILL TER", + "city": "Harrells", + "stateIdentifier": "FL", + "zip": "34667", + "contact": { + "id": 48, + "name": "Ramon Stawiarz", + "_info": { + "mobileGuid": "57a19455-a9d7-4587-ac45-0f80f5387c31", + "contact_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//company/contacts/48" + } + }, + "contactName": "Ramon Stawiarz", + "contactPhoneNumber": "8133936413", + "contactEmailAddress": "ramon.stawiarz@indigostrawberry.com", + "type": { + "id": 14, + "name": "Proactive", + "_info": { + "type_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//service/boards/1/types/14" + } + }, + "team": { + "id": 25, + "name": "Service Team", + "_info": { + "team_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//service/boards/1/teams/25" + } + }, + "priority": { + "id": 4, + "name": "Priority 3 - Normal Response", + "sort": 6, + "_info": { + "priority_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//service/priorities/4", + "image_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//service/priorities/4/image?lm=2005-05-27T14:58:21Z" + } + }, + "serviceLocation": { + "id": 2, + "name": "In-house", + "_info": { + "location_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//service/locations/2" + } + }, + "source": { + "id": 2, + "name": "Phone", + "_info": { + "source_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//service/sources/2" + } + }, + "severity": "Medium", + "impact": "Medium", + "allowAllClientsPortalView": false, + "customerUpdatedFlag": false, + "automaticEmailContactFlag": false, + "automaticEmailResourceFlag": false, + "automaticEmailCcFlag": false, + "automaticEmailCc": "", + "closedFlag": false, + "approved": true, + "estimatedExpenseCost": 0, + "estimatedExpenseRevenue": 0, + "estimatedProductCost": 0, + "estimatedProductRevenue": 0, + "estimatedTimeCost": 0, + "estimatedTimeRevenue": 0, + "billingMethod": "ActualRates", + "subBillingMethod": "ActualRates", + "resolveMinutes": 0, + "resPlanMinutes": 0, + "respondMinutes": 0, + "isInSla": false, + "hasChildTicket": false, + "hasMergedChildTicketFlag": false, + "billTime": "NoDefault", + "billExpenses": "NoDefault", + "billProducts": "Billable", + "location": { + "id": 2, + "name": "Tampa Office", + "_info": { + "location_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//system/locations/2" + } + }, + "department": { + "id": 10, + "identifier": "Services", + "name": "Professional Services", + "_info": { + "department_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//system/departments/10" + } + }, + "mobileGuid": "25bdf3ce-b284-470b-a13d-0ffcea6aa922", + "sla": { + "id": 1, + "name": "Standard SLA", + "_info": { + "sla_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//service/SLAs/1" + } + }, + "slaStatus": "Respond by Mon 07/04 1:00 PM UTC-04", + "requestForChangeFlag": false, + "currency": { + "id": 7, + "symbol": "$", + "currencyCode": "USD", + "decimalSeparator": ".", + "numberOfDecimals": 2, + "thousandsSeparator": ",", + "negativeParenthesesFlag": false, + "displaySymbolFlag": false, + "currencyIdentifier": "Z-US$", + "displayIdFlag": false, + "rightAlign": false, + "name": "US Dollars", + "_info": { + "currency_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//finance/currencies/7" + } + }, + "_info": { + "lastUpdated": "2022-07-02T04:20:41Z", + "updatedBy": "template3", + "dateEntered": "2022-07-02T04:20:41Z", + "enteredBy": "template3", + "activities_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//sales/activities?conditions=ticket/id=493", + "scheduleentries_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//schedule/entries?conditions=type/id=4 AND objectId=493", + "documents_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//system/documents?recordType=Ticket&recordId=493", + "configurations_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//service/tickets/493/configurations", + "tasks_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//service/tickets/493/tasks", + "notes_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//service/tickets/493/notes", + "products_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//procurement/products?conditions=chargeToType='Ticket' AND chargeToId=493", + "timeentries_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//time/entries?conditions=(chargeToType='ServiceTicket' OR chargeToType='ProjectTicket') AND chargeToId=493", + "expenseEntries_href": "https://api-staging.connectwisedev.com/v4_6_release/apis/3.0//expense/entries?conditions=(chargeToType='ServiceTicket' OR chargeToType='ProjectTicket') AND chargeToId=493" + }, + "escalationStartDateUTC": "2022-07-04T13:00:00Z", + "escalationLevel": 0, + "minutesBeforeWaiting": 0, + "respondedSkippedMinutes": 0, + "resplanSkippedMinutes": 0, + "respondedHours": 4, + "resplanHours": 24, + "resolutionHours": 48, + "minutesWaiting": 0 +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 171ac0de2fb85..b0439e37dccc1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1785,7 +1785,10 @@ importers: specifiers: {} components/connectwise_psa: - specifiers: {} + specifiers: + '@pipedream/platform': ^2.0.0 + dependencies: + '@pipedream/platform': 2.0.0 components/constant_contact: specifiers: