{
  "id": "vca2Icaq6mJNY5pX",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Sync Beex ticket messages to HubSpot activities",
  "tags": [],
  "nodes": [
    {
      "id": "167e4d54-f34b-49f9-ab0d-073cbf9df00e",
      "name": "Beex Trigger",
      "type": "n8n-nodes-beex.beexTrigger",
      "notes": "Webhook",
      "position": [
        -1344,
        192
      ],
      "parameters": {
        "eventTypes": [
          "management_create"
        ]
      },
      "notesInFlow": true,
      "typeVersion": 1
    },
    {
      "id": "e33d37fc-71c9-4d11-87ef-20f1c19066eb",
      "name": "Get Phone",
      "type": "n8n-nodes-base.set",
      "position": [
        -896,
        192
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "a0186def-89ee-46af-a27f-932eec63f19a",
              "name": "country_code",
              "type": "string",
              "value": "*insert country_code*"
            },
            {
              "id": "2514e801-5d5f-4b0f-8651-d9cdcbd76a7c",
              "name": "phone",
              "type": "string",
              "value": "={{ $json.data.phone_number }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "1990cfdb-0484-4dbb-985a-4775bbab27d6",
      "name": "Search Contact",
      "type": "n8n-nodes-base.hubspot",
      "notes": "HubSpot",
      "maxTries": 2,
      "position": [
        -672,
        192
      ],
      "parameters": {
        "limit": 1,
        "operation": "search",
        "authentication": "appToken",
        "filterGroupsUi": {
          "filterGroupsValues": [
            {
              "filtersUi": {
                "filterValues": [
                  {
                    "value": "={{ $json.country_code }}{{ $json.phone }}",
                    "propertyName": "phone|string"
                  }
                ]
              }
            }
          ]
        },
        "additionalFields": {
          "properties": [
            "firstname",
            "phone"
          ]
        }
      },
      "credentials": {
        "hubspotAppToken": {
          "name": "<your credential>"
        }
      },
      "notesInFlow": true,
      "retryOnFail": true,
      "typeVersion": 2.2,
      "alwaysOutputData": false,
      "waitBetweenTries": 2500
    },
    {
      "id": "865d2f20-8719-4930-9cc9-3464cd0ab694",
      "name": "Get Messages",
      "type": "n8n-nodes-beex.beex",
      "notes": "Ticket",
      "position": [
        -448,
        192
      ],
      "parameters": {
        "id": "={{ $('Beex Trigger').item.json.data.ticket.id }}",
        "resource": "tickets",
        "operation": "get-messages"
      },
      "credentials": {
        "beexApi": {
          "name": "<your credential>"
        }
      },
      "notesInFlow": true,
      "retryOnFail": true,
      "typeVersion": 1,
      "waitBetweenTries": 2500
    },
    {
      "id": "2135aaa8-bb50-48e1-bc67-0f8ae6ea925e",
      "name": "Routes",
      "type": "n8n-nodes-base.switch",
      "position": [
        -224,
        176
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "Text",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "4a384b72-6132-4cb6-9e73-a7dc718eaf2c",
                    "operator": {
                      "type": "string",
                      "operation": "notEmpty",
                      "singleValue": true
                    },
                    "leftValue": "={{ $json.message }}",
                    "rightValue": ""
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Image",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "cbbd5016-5b93-4309-8872-82d3caee4d45",
                    "operator": {
                      "type": "string",
                      "operation": "regex"
                    },
                    "leftValue": "={{ $json.media_url }}",
                    "rightValue": "\\.(png|jpe?g|gif|bmp|webp|svg|tiff|avif|heic|ico)$"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Audio",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "e697c4f6-3d92-49af-acb4-9239597c9a0c",
                    "operator": {
                      "type": "string",
                      "operation": "regex"
                    },
                    "leftValue": "={{ $json.media_url }}",
                    "rightValue": "\\.(mp3|wav|ogg|flac|aac|m4a|wma|opus|aiff?|alac|midi?)$"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.3
    },
    {
      "id": "92c15f3e-0f63-46f5-af17-e920515e7c22",
      "name": "Format Text",
      "type": "n8n-nodes-base.set",
      "notes": "HTML",
      "position": [
        0,
        0
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "c8b22832-5c0d-4da6-9887-a23a9fba097a",
              "name": "message",
              "type": "string",
              "value": "={{    \n  time = $json.created_at.slice(11, 16),   \n  user = $json.person?.full_name ?? \"Unknown\",   \n  channel = $json.channel?.name ?? \"Unknown\",   \n  message = $json.message.replace(/[\\r\\n]+/g, \" \"),    \n\n  '<b>' + time + ' ' + user + ' (' + channel + ')' + ':</b><br/>'  \n  + message + \"<br/><br/>\" \n}}"
            },
            {
              "id": "dd6d746a-0ab9-4f43-9206-7a8929164814",
              "name": "created_at",
              "type": "string",
              "value": "={{ $json.created_at }}"
            }
          ]
        }
      },
      "notesInFlow": true,
      "typeVersion": 3.4
    },
    {
      "id": "3d669270-8d36-42ac-9383-4d169d8cc3af",
      "name": "Format Image",
      "type": "n8n-nodes-base.set",
      "notes": "HTML",
      "position": [
        0,
        192
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "d7d3023b-5262-439d-8afd-a337214723fe",
              "name": "message",
              "type": "string",
              "value": "={{    \n  time = $json.created_at.slice(11, 16),   \n  user = $json.person?.full_name ?? \"Unknown\",   \n  channel = $json.channel?.name ?? \"Unknown\",   \n  media_url = $json.media_url.trim(),    \n\n  '<b>' + time + ' ' + user + ' (' + channel + ')' + ':</b><br/>'  \n  + '<img src=' + media_url + ' width=350><br/><br/>' \n}}"
            },
            {
              "id": "8bf8d3b1-4259-45f5-b18e-97d38e3e91be",
              "name": "created_at",
              "type": "string",
              "value": "={{ $json.created_at }}"
            }
          ]
        }
      },
      "notesInFlow": true,
      "typeVersion": 3.4
    },
    {
      "id": "a34e65b7-6cd7-473f-858d-b61c09ed291a",
      "name": "Format Audio",
      "type": "n8n-nodes-base.set",
      "notes": "HTML",
      "position": [
        0,
        384
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "19742464-e12c-4a20-ad26-2c847eadd812",
              "name": "message",
              "type": "string",
              "value": "={{    \n  time = $json.created_at.slice(11, 16),   \n  user = $json.person?.full_name ?? \"Unknown\",   \n  channel = ($json.channel?.name ?? \"Unknown\") + \" Audio\",   \n  message = \"Audio-\" + $json.media_url.split(\"/\").last(),    \n  \n  '<b>' + time + ' ' + user + ' (' + channel + ')' + ':</b><br/>'    \n  + message + \"<br/><br/>\" \n}}"
            },
            {
              "id": "151a763c-c305-44d1-b437-c9d635922b98",
              "name": "created_at",
              "type": "string",
              "value": "={{ $json.created_at }}"
            }
          ]
        }
      },
      "notesInFlow": true,
      "typeVersion": 3.4
    },
    {
      "id": "116ff56f-a2be-4cd0-9300-99b18179fcf0",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "notes": "append",
      "position": [
        224,
        176
      ],
      "parameters": {
        "numberInputs": 3
      },
      "notesInFlow": true,
      "typeVersion": 3.2
    },
    {
      "id": "60d68e56-c11e-4169-907d-2e118676eb91",
      "name": "Sort Messages",
      "type": "n8n-nodes-base.sort",
      "notes": "created_at",
      "position": [
        448,
        192
      ],
      "parameters": {
        "options": {},
        "sortFieldsUi": {
          "sortField": [
            {
              "fieldName": "created_at"
            }
          ]
        }
      },
      "notesInFlow": true,
      "typeVersion": 1
    },
    {
      "id": "6257e5a4-4a4a-450a-9590-80625500b00d",
      "name": "Consolidate Chat",
      "type": "n8n-nodes-base.code",
      "notes": "JavaScript",
      "position": [
        672,
        192
      ],
      "parameters": {
        "jsCode": "let chat = \"\"\n\nfor (const item of $input.all()) {\n   if (item.json.message) {\n        chat += item.json.message.replaceAll('\"', '')\n   }\n}\n\nreturn {chat}\n"
      },
      "notesInFlow": true,
      "typeVersion": 2
    },
    {
      "id": "51cc123e-8a09-4e85-a9d0-a07a25e541fe",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -288,
        -128
      ],
      "parameters": {
        "color": 7,
        "width": 672,
        "height": 704,
        "content": "## Routing by message type\n- Depending on the type of message (text, image or audio) sent during the interaction, it will be given an equivalent HTML format. Then we consolidated."
      },
      "typeVersion": 1
    },
    {
      "id": "b8479e5f-4aa9-472a-861c-2be7a3dd220f",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1392,
        -128
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 704,
        "content": "## Beex Trigger Node + Filter\n- The trigger receives the `On Management Create` event\n- Currently, the workflow only accepts an event that uses WhatsApp messaging as its **channel**"
      },
      "typeVersion": 1
    },
    {
      "id": "1d458282-73c3-4cd1-b32f-c7b1e305656a",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        384,
        -128
      ],
      "parameters": {
        "color": 7,
        "width": 704,
        "height": 704,
        "content": "## Logging Activity in HubSpot\n- We proceed to sort the messages by creation.\n- We consolidate the messages into a single record.\n- We record the activity of type `WHATS_APP` in HubSpot."
      },
      "typeVersion": 1
    },
    {
      "id": "23ab178b-d25e-47cc-8db5-d10663eb557a",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -960,
        -128
      ],
      "parameters": {
        "color": 7,
        "width": 672,
        "height": 704,
        "content": "## Retrieving Messages from BeexCC\n- We strategically obtain a valid phone number (*insert* the **country code**)\n- We are looking for HubSpot's contact information using their **phone number**\n- We obtain the messages created through the given interaction in BeexCC (use the ticket id of the initial trigger node)"
      },
      "typeVersion": 1
    },
    {
      "id": "019f1c60-5857-4888-a7e4-1efa0d8c99fa",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2176,
        -336
      ],
      "parameters": {
        "width": 560,
        "height": 1088,
        "content": "# Sync Beex Ticket Messages to HubSpot Activities\n\n> **Requires:** Community node `n8n-nodes-beex`\n\n## Overview\nCaptures WhatsApp ticket classifications from Beex and syncs message history as HubSpot contact activities.\n\n## How it works \n1. **Beex Trigger** - Receives ticket classification events (On Management Create)\n2. **Filter** - Processes only WhatsApp Message channel events\n3. **Get Phone** - Extracts phone number (requires manual country code config)\n4. **Search Contact** - Locates HubSpot contact by phone number\n5. **Get Messages** - Retrieves all interaction messages using ticket ID\n6. **Route & Format** - Processes text/image/audio messages into HTML\n7. **Sort** - Orders messages by `created_at` timestamp\n8. **Consolidate** - Combines all messages into single HTML record for `hs_communication_body`\n9. **Register Activity** - Using the HubSpot API\n\n ## Setup steps\n\n### 1. Install Beex Package\n```\nn8n-nodes-beex\n```\n\n### 2. HubSpot Credentials\n- Create private app token with **Contacts** read/write permissions\n- Add credentials to HubSpot nodes\n\n### 3. Beex Configuration\n- Navigate to **Platform Settings \u2192 API Key and Callback**\n- Copy API key \u2192 paste into \"Get Messages\" node (`YOUR_TOKEN_HERE`)\n- Enable **Typing Registry in Callback Integration**\n\n### 4. Webhook Setup\n- Copy webhook URL from Beex trigger node (Test/Production)\n- Paste into Beex **Callback Integration** section\n- Save changes\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "c5e2672a-ffb5-4241-a8b2-1ec9161c9e68",
      "name": "Is WhatsApp Channel?",
      "type": "n8n-nodes-base.filter",
      "notes": "channel",
      "position": [
        -1120,
        192
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "445968c3-d85f-4ed7-81a7-8d6b36ee0c0b",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.data.ticket.channel.name }}",
              "rightValue": "WhatsApp Message"
            }
          ]
        }
      },
      "notesInFlow": true,
      "typeVersion": 2.2
    },
    {
      "id": "47b21b35-4fb5-4aa9-9e23-dcbae718abe7",
      "name": "Register Activity",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "HubSpot",
      "maxTries": 2,
      "position": [
        896,
        192
      ],
      "parameters": {
        "url": "https://api.hubapi.com/crm/v3/objects/communications",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"properties\": {\n    \"hs_communication_channel_type\": \"WHATS_APP\",\n    \"hs_communication_logged_from\": \"CRM\",\n    \"hs_communication_body\": \"{{ $json.chat }}\",\n    \"hs_timestamp\": \"{{ $now.toMillis() }}\"\n  },\n  \"associations\": [\n    {\n      \"to\": {\n        \"id\": {{ $('Search Contact').first().json.id }}\n      },\n      \"types\": [\n        {\n          \"associationCategory\": \"HUBSPOT_DEFINED\",\n          \"associationTypeId\": 81\n        }\n      ]\n    }\n  ]\n}\n",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "hubspotAppToken"
      },
      "credentials": {
        "hubspotAppToken": {
          "name": "<your credential>"
        }
      },
      "notesInFlow": true,
      "retryOnFail": true,
      "typeVersion": 4.3,
      "waitBetweenTries": 2500
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "9ecd04c9-7205-4b43-96b7-d94818610ce6",
  "connections": {
    "Merge": {
      "main": [
        [
          {
            "node": "Sort Messages",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Routes": {
      "main": [
        [
          {
            "node": "Format Text",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Format Image",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Format Audio",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Phone": {
      "main": [
        [
          {
            "node": "Search Contact",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Text": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Beex Trigger": {
      "main": [
        [
          {
            "node": "Is WhatsApp Channel?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Audio": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "Format Image": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Get Messages": {
      "main": [
        [
          {
            "node": "Routes",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sort Messages": {
      "main": [
        [
          {
            "node": "Consolidate Chat",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Search Contact": {
      "main": [
        [
          {
            "node": "Get Messages",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Consolidate Chat": {
      "main": [
        [
          {
            "node": "Register Activity",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is WhatsApp Channel?": {
      "main": [
        [
          {
            "node": "Get Phone",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}