From 3e36073f3c4efa80d9acafbc2ee224a6e00b8d26 Mon Sep 17 00:00:00 2001 From: Cobalt0s Date: Thu, 16 Jul 2026 00:15:38 +0300 Subject: [PATCH 1/2] [ENG-4125] feat(connectwise): Support Custom fields --- src/provider-guides/connectWise.mdx | 99 +++++++++++++++++++++++++---- 1 file changed, 88 insertions(+), 11 deletions(-) diff --git a/src/provider-guides/connectWise.mdx b/src/provider-guides/connectWise.mdx index 8d0ce36d..0ccf4cb0 100644 --- a/src/provider-guides/connectWise.mdx +++ b/src/provider-guides/connectWise.mdx @@ -251,20 +251,97 @@ Write payload example for the `contacts` object: } ``` -### Example integration - -To define an integration for ConnectWise, create a manifest file that looks like this: +### Custom Fields +The ConnectWise connector **supports reading and writing custom fields** on supported objects. +For reads, custom fields are available through scheduled reads, historical backfills, and subscriptions. +Each ConnectWise custom field is exposed as `customField` -- for example, +a field with ID `59` might represent a marketing email preference and be selected as `customField59`, while +a field with ID `83` might represent a hobby and be selected as `customField83`. +You can then map those fields to more readable names in your connector configuration, such as `marketingEmailOn` or `hobby`. ```YAML -# amp.yaml -specVersion: 1.0.0 -integrations: - - name: connectWise-integration - displayName: My ConnectWise Integration - provider: connectWise - proxy: - enabled: true +read: + objects: + - objectName: contacts + destination: connectWiseWebhook + requiredFields: + - fieldName: customField59 + mapToName: marketingEmailOn + - fieldName: customField83 + mapToName: hobby +``` +This produces output that is easier to work with: +```JSON +[ + { + "mappedFields":{ + "hobby": "Traveling", + "marketingEmailOn": true, + "firstName": "Estella" + } + } +] +``` + +**For writes**, custom fields can be provided as if it was a native standard field. +The connector translates these values into the ConnectWise API format automatically. + +To create a record with custom fields: +```JSON +{ + "groupRef": "{{connectWiseGroupID}}", + "type": "create", + "record": { + "firstName": "Estella", + "customField59": true, + "customField83": "Traveling" + } +} +``` +To update a record with custom fields using `PUT`: +```JSON +{ + "groupRef": "{{connectWiseGroupID}}", + "type": "update", + "record": { + "id": "58117", + "firstName": "Estella (UPDATED)", + "customField59": false, + "customField83": "Swimming" + } +} ``` +To update a record with custom fields using `PATCH`: +```JSON +{ + "groupRef": "{{connectWiseGroupID}}", + "type": "update", + "record": { + "id": "58117", + "patch": [ + {"op": "replace", "path": "/firstName", "value": "Jeniffer"}, + {"op": "replace", "path": "/customField59", "value": true}, + {"op": "replace", "path": "/customField83", "value": "Skiing"} + ] + } +} +``` + +When updating records, you only need to provide the custom fields you want to set or change. +You **do not** need to list **every** custom field exhaustively. +However, if you want to clear a field, then set its value to `null`, for example: +```JSON +{ + "customField83": null +} +``` + +When you are unsure of a **custom field ID**, check a **read response** for that object. +Custom fields are returned with their ConnectWise IDs in the `customFields` array. + +### Example integration + +For an example manifest file of a ConnectWise integration, visit our [samples repo on Github](https://github.com/amp-labs/samples/blob/main/connectwise/amp.yaml). ## Using the connector From a5a122d11cdbb8677e342733059b4615d8f8b07b Mon Sep 17 00:00:00 2001 From: Constantin Koval <60330780+Cobalt0s@users.noreply.github.com> Date: Wed, 22 Jul 2026 04:45:04 +0300 Subject: [PATCH 2/2] [ENG-4127] feat(connectwise): Communication items (#654) --- src/provider-guides/connectWise.mdx | 156 +++++++++++++++++----------- 1 file changed, 96 insertions(+), 60 deletions(-) diff --git a/src/provider-guides/connectWise.mdx b/src/provider-guides/connectWise.mdx index 0ccf4cb0..b56634e1 100644 --- a/src/provider-guides/connectWise.mdx +++ b/src/provider-guides/connectWise.mdx @@ -253,95 +253,131 @@ Write payload example for the `contacts` object: ### Custom Fields -The ConnectWise connector **supports reading and writing custom fields** on supported objects. -For reads, custom fields are available through scheduled reads, historical backfills, and subscriptions. -Each ConnectWise custom field is exposed as `customField` -- for example, -a field with ID `59` might represent a marketing email preference and be selected as `customField59`, while -a field with ID `83` might represent a hobby and be selected as `customField83`. -You can then map those fields to more readable names in your connector configuration, such as `marketingEmailOn` or `hobby`. -```YAML +The connector supports reading and writing custom fields on supported objects, and they behave like native fields. +For reads, they're available through scheduled reads, historical backfills, and subscriptions. + +Each custom field is exposed as `customField`. Map it to a more readable name in your configuration with `mapToName`. + +> Example: a field with ID `59` representing a marketing preference is selected as `customField59` and can be mapped to `marketingEmailOn`. + +```yaml read: objects: - objectName: contacts - destination: connectWiseWebhook requiredFields: - fieldName: customField59 mapToName: marketingEmailOn - fieldName: customField83 mapToName: hobby ``` -This produces output that is easier to work with: -```JSON -[ - { - "mappedFields":{ - "hobby": "Traveling", - "marketingEmailOn": true, - "firstName": "Estella" - } - } -] + +For writes, provide custom fields as if they were native fields; the connector converts them to the ConnectWise format automatically: + +```json +{ + "firstName": "Estella", + "customField59": true, + "customField83": "Traveling" +} +``` + +You only need to include the custom fields you want to set or change. To clear a field, set its value to `null`. + +To find a custom field's ID, check a read response, custom fields are returned with their IDs in the `customFields` array. + + +### Example integration + +For an example manifest file of a ConnectWise integration, visit our [samples repo on Github](https://github.com/amp-labs/samples/blob/main/connectwise/amp.yaml). + +### Contact Communication Items + +ConnectWise stores a contact's email, phone, and fax numbers inside a nested `communicationItems` array, which isn't directly mappable. +To make these easy to read and write, the connector exposes the **default** email, phone, and fax of a contact +as flat fields, which you can map like any other contact field. + +| Field | Description | +|----------------------------|------------------------------------------| +| `AMPERSAND-defaultEmail` | The contact's default email address | +| `AMPERSAND-defaultEmailId` | The communication type of that email | +| `AMPERSAND-defaultPhone` | The contact's default phone number | +| `AMPERSAND-defaultPhoneId` | The communication type of that phone | +| `AMPERSAND-defaultFax` | The contact's default fax number | +| `AMPERSAND-defaultFaxId` | The communication type of that fax | + +Only the **default** item of each category is exposed. If a contact has several emails, only the one marked as default appears in `AMPERSAND-defaultEmail`. + +#### Reading + +Map these fields in a read action just like standard contact fields: + +```yaml +read: + objects: + - objectName: contacts + requiredFields: + - fieldName: AMPERSAND-defaultEmail ``` -**For writes**, custom fields can be provided as if it was a native standard field. -The connector translates these values into the ConnectWise API format automatically. +A contact whose default email is `john@example.com` reads back as: -To create a record with custom fields: -```JSON +```json { - "groupRef": "{{connectWiseGroupID}}", - "type": "create", - "record": { - "firstName": "Estella", - "customField59": true, - "customField83": "Traveling" - } + "AMPERSAND-defaultEmail": "john@example.com", + "AMPERSAND-defaultEmailId": "15" } ``` -To update a record with custom fields using `PUT`: -```JSON + +The `...Id` field identifies which communication type the default value belongs to. This matters when a contact has more than one item in the same category. + +#### Writing + +Map a value to `AMPERSAND-defaultEmail` (or phone/fax) to set it when creating or updating a contact: + +- Set just the value, and the connector uses the customer's default type for that category. +- Set the matching `...Id` field too if you want to target a specific type (for example, a Work email vs a Home email). +The value is applied to that type and marked as the default. + +Updates replace the fields you send. Any fields you omit will be cleared. +For partial updates, see the [JSON Patch section below](#advanced-partial-updates-with-json-patch). + +Example -- replace a contact: + +```json { - "groupRef": "{{connectWiseGroupID}}", - "type": "update", - "record": { - "id": "58117", - "firstName": "Estella (UPDATED)", - "customField59": false, - "customField83": "Swimming" - } + "firstName": "John", + "lastName": "Smith", + "AMPERSAND-defaultEmail": "john@example.com" } ``` -To update a record with custom fields using `PATCH`: -```JSON + + +The `...Id` fields refer to ConnectWise "communication types" configured in the customer's ConnectWise account. + You only need them when a contact has more than one email, phone, or fax and you want to target a specific one. + + +#### Advanced: partial updates with JSON Patch + +If you call the write API directly, you can send a JSON Patch to change a single field, including these virtual fields: + +```json { - "groupRef": "{{connectWiseGroupID}}", "type": "update", "record": { "id": "58117", "patch": [ - {"op": "replace", "path": "/firstName", "value": "Jeniffer"}, - {"op": "replace", "path": "/customField59", "value": true}, - {"op": "replace", "path": "/customField83", "value": "Skiing"} + { "op": "replace", "path": "/AMPERSAND-defaultEmail", "value": "john@example.com" } ] } } ``` -When updating records, you only need to provide the custom fields you want to set or change. -You **do not** need to list **every** custom field exhaustively. -However, if you want to clear a field, then set its value to `null`, for example: -```JSON -{ - "customField83": null -} -``` - -When you are unsure of a **custom field ID**, check a **read response** for that object. -Custom fields are returned with their ConnectWise IDs in the `customFields` array. +- `replace` on a value updates the current default item. +- `replace` on an `...Id` field switches which communication type is the default, +(used together with `AMPERSAND-defaultEmail`, etc.) +- `remove` deletes the current default item for that category. -### Example integration - -For an example manifest file of a ConnectWise integration, visit our [samples repo on Github](https://github.com/amp-labs/samples/blob/main/connectwise/amp.yaml). +The connector translates these into the correct changes on the underlying `communicationItems` array. ## Using the connector