APIs & Integrations

GJakobTriad
Participant

Custom code and Company deduplication

SOLVE

Hey guys. I'm looking for some help with this. I'm trying to unlock the potential of the custom code element present in workflows, the one granted by Operations Hub.

 

I'm basically trying to adapt the following sample code to work with Companies, and use their names as the deduplication property:

https://github.com/HubSpot/sample-workflow-custom-code/blob/main/samples/dedupe_contact.js

 

But I get the following, basic-looking error pointing at line 20, which is the first time the code tries to search by ID. For some reason, it fails.

ERROR Invoke Error {"errorType":"TypeError","errorMessage":"Cannot read properties of undefined (reading 'getById')","stack":["TypeError: Cannot read properties of undefined (reading 'getById')"," at Object.exports.main (/var/task/file.js:20:6)"," at Runtime.exports.hubspot_handler [as handler] (/var/task/hubspotHandler.js:6:21)"," at Runtime.handleOnceNonStreaming (file:///var/runtime/index.mjs:1173:29)"]}

 

Here's the full code. I tried both referencing the ID using the sample's "event.object.objectId" and also feeding it as an input field on the workflow. The error remains the same.

 

/**
 * Searches for another company with the same value of DEDUPE_PROPERTY.
 * - If no matches are found, nothing happens
 * - If one match is found, the enrolled company is merged into the matching company
 * - If more than one match is found, the action fails
 */

const DEDUPE_PROPERTY = 'name';

const hubspot = require('@hubspot/api-client');

exports.main = (event, callback) => {

  // Make sure to add your API key under "Secrets" above.
  const hubspotClient = new hubspot.Client({
    accessToken: process.env.CompanyAssocCreateToken
  });

  hubspotClient.crm.companies.defaultApi
    .getById(event.object.objectId, [DEDUPE_PROPERTY])
    .then(companyResult => {
      let dedupePropValue = companyResult.body.properties[DEDUPE_PROPERTY];

      console.log(`Looking for duplicates based on ${DEDUPE_PROPERTY} = ${dedupePropValue}`);
      hubspotClient.crm.companies.defaultApi
        .doSearch({
          filterGroups: [{
            filters: [{
              propertyName: DEDUPE_PROPERTY,
              operator: 'EQ',
              value: dedupePropValue
            }]
          }]
        })
        .then(searchResults => {
          let idsToMerge = searchResults.body.results
            .map(object => object.id)
            .filter(vid => Number(vid) !== Number(event.object.objectId));

          if (idsToMerge.length == 0) {
            console.log('No matching company, nothing to merge');
            return;
          } else if (idsToMerge.length > 1) {
            console.log(`Found multiple potential company IDs ${idsToMerge.join(', ')} to merge`);
            throw new Error("Ambiguous merge; more than one matching company");
          }

          let idToMerge = idsToMerge[0];
          console.log(`Merging enrolled company id=${event.object.objectId} into company id=${idToMerge}`);
          hubspotClient
            .apiRequest({
              method: 'POST',
              path: `/crm/v3/objects/companies/merge`,
              body: {
                objectIdToMerge: idToMerge,
                primaryObjectId: event.object.objectId
              }
            })
            .then(mergeResult => {
              console.log('Companies merged!');
            });
        });
    });

    callback({
      outputFields: {
        company_id: event.object.objectId
      }
    });

};

 

1 Accepted solution
GJakobTriad
Solution
Participant

Custom code and Company deduplication

SOLVE

After a bunch of troubleshooting, I found the two issues which were breaking the code:

 

  1. I was calling the wrong APIs, which should be basicApi and searchApi instead of DefaultApi. The Company Endpoints documentation was misleading in this regard.

  2. The sample code refers to "body.properties" when trying to look into the properties clause of a response, and "body" throws it off, so that's inaccurate too. The reference should only be "properties", as in companyResult.properties[DEDUPE_PROPERTY].

View solution in original post

5 Replies 5
BreannahGladden
Participant

Custom code and Company deduplication

SOLVE

hey - I was SO HAPPY when I saw this; I've attempted to use this on my own for a client and get an error. Any advice? Am I missing something? 😥

WARNING: The logs for this function have exceeded the 4KB limit.
...
2024-01-25T21:08:06.071Z	undefined	ERROR	Uncaught Exception 	{"errorType":"Runtime.UserCodeSyntaxError","errorMessage":"SyntaxError: Unexpected token '['","stack":["Runtime.UserCodeSyntaxError: SyntaxError: Unexpected token '['","    at _loadUserApp (file:///var/runtime/index.mjs:1084:17)","    at async Object.UserFunction.js.module.exports.load (file:///var/runtime/index.mjs:1119:21)","    at async start (file:///var/runtime/index.mjs:1282:23)","    at async file:///var/runtime/index.mjs:1288:1"]}
INIT_REPORT Init Duration: 172.64 ms	Phase: init	Status: error	Error Type: Runtime.ExitError
2024-01-25T21:08:07.463Z	undefined	ERROR	Uncaught Exception 	{"errorType":"Runtime.UserCodeSyntaxError","errorMessage":"SyntaxError: Unexpected token '['","stack":["Runtime.UserCodeSyntaxError: SyntaxError: Unexpected token '['","    at _loadUserApp (file:///var/runtime/index.mjs:1084:17)","    at async Object.UserFunction.js.module.exports.load (file:///var/runtime/index.mjs:1119:21)","    at async start (file:///var/runtime/index.mjs:1282:23)","    at async file:///var/runtime/index.mjs:1288:1"]}
INIT_REPORT Init Duration: 1622.43 ms	Phase: invoke	Status: error	Error Type: Runtime.ExitError
START RequestId: ee8cb700-9ee8-411a-a750-0d62c8409311 Version: $LATEST
Unknown application error occurred
Runtime.UserCodeSyntaxErroran 

 

0 Upvotes
Clare_HS
Participant

Custom code and Company deduplication

SOLVE

Hi, @GJakobTriad... thanks so much for posting your solution - it was enormously helpful!

I also used the contact dedupe snippet from GitHub and combined that with your revisions. The code executed successfully but wasn't doing anything (the companies weren't merging). 

I found that I had a discrepancy further down in my combined code, so I'm reposting the full, working code block here for other folks who may be runing into the same issue.

 

/**
 * Searches for another company with the same value of DEDUPE_PROPERTY.
 * - If no matches are found, nothing happens
 * - If one match is found, the enrolled company is merged into the matching company
 * - If more than one match is found, the action fails
 */

const DEDUPE_PROPERTY = 'domain';

const hubspot = require('@hubspot/api-client');

exports.main = (event, callback) => {
  // Make sure to add your API key under "Secrets" above.
  const hubspotClient = new hubspot.Client({
    accessToken: process.env.[INSERT ACCESS TOKEN]
  });

  hubspotClient.crm.companies.basicApi
    .getById(event.object.objectId, [DEDUPE_PROPERTY])
    .then(companyResult => {
      let dedupePropValue = companyResult.properties[DEDUPE_PROPERTY];

      console.log(`Looking for duplicates based on ${DEDUPE_PROPERTY} = ${dedupePropValue}`);
      hubspotClient.crm.companies.searchApi
        .doSearch({
          filterGroups: [{
            filters: [{
              propertyName: DEDUPE_PROPERTY,
              operator: 'EQ',
              value: dedupePropValue
            }]
          }]
        })
        .then(searchResults => {
          let idsToMerge = searchResults.results
            .map(object => object.id)
            .filter(vid => Number(vid) !== Number(event.object.objectId));

          if (idsToMerge.length == 0) {
            console.log('No matching company, nothing to merge');
            return;
          } else if (idsToMerge.length > 1) {
            console.log(`Found multiple potential company IDs ${idsToMerge.join(', ')} to merge`);
            throw new Error("Ambiguous merge; more than one matching company");
          }

          let idToMerge = idsToMerge[0];
          console.log(`Merging enrolled company id=${event.object.objectId} into company id=${idToMerge}`);
          hubspotClient
            .apiRequest({
              method: 'POST',
              path: `/crm/v3/objects/companies/merge`,
              body: {
                objectIdToMerge: idToMerge,
                primaryObjectId: event.object.objectId
              }
            })
            .then(mergeResult => {
              console.log('Companies merged!');
            });
        });
    });

    callback({
      outputFields: {
        company_id: event.object.objectId
      }
    });
};

 

0 Upvotes
GJakobTriad
Solution
Participant

Custom code and Company deduplication

SOLVE

After a bunch of troubleshooting, I found the two issues which were breaking the code:

 

  1. I was calling the wrong APIs, which should be basicApi and searchApi instead of DefaultApi. The Company Endpoints documentation was misleading in this regard.

  2. The sample code refers to "body.properties" when trying to look into the properties clause of a response, and "body" throws it off, so that's inaccurate too. The reference should only be "properties", as in companyResult.properties[DEDUPE_PROPERTY].
MiaSrebrnjak
Community Manager
Community Manager

Custom code and Company deduplication

SOLVE

@GJakobTriad you're a , kudos to you!

Thank you for sharing the solution with the Community 💛 

 




Wusstest du, dass es auch eine DACH-Community gibt?
Nimm an regionalen Unterhaltungen teil, indem du deine Spracheinstellungen änderst


Did you know that the Community is available in other languages?
Join regional conversations by
changing your language settings


0 Upvotes
MiaSrebrnjak
Community Manager
Community Manager

Custom code and Company deduplication

SOLVE

Hi @GJakobTriad,

 

Thank you for reaching out to the Community! 

I wanted to tag in a couple of subject matter experts to see if they have any input on this matter:

Hi @Teun@ChristinaKay@DanielJeal, do you have any tips for @GJakobTriad? Thank you!      

 

Cheers
Mia, Community Team




Wusstest du, dass es auch eine DACH-Community gibt?
Nimm an regionalen Unterhaltungen teil, indem du deine Spracheinstellungen änderst


Did you know that the Community is available in other languages?
Join regional conversations by
changing your language settings


0 Upvotes