Smart collection record to collection record via smart action

I have a smart collection(hubspot-company) that retrieves companies that meet a specific criteria from hubspot. I would like add a smart action that follows this flow:

  1. Create a record in a customer collection.
  2. Makes changes in hubspot via API.

Is there an easy way I can reuse the create route for the collection “customer” by passing data from the smart collection “hubspot-company” record?

Even better if it opens a form and prefills some fields so I can complete additional fields that are needed.

If there is a similar example in the docs or in this forum a link will probably just be enough.

1 Like

To put it another way I was hoping to pass form fields via query parameter from the smart action in the smart collection to

data/customer/index/record/customer/create/details?field1=value&field2=value&hubspot=true

And then overwrite the route to do its thing but also an additional api call to hubspot if query parameter hubspot is true.

But unfortunately you can’t add query parameters to the route as you will get an error:

So looking for easy alternatives.

Hi @jonl :wave:t3:

Happy to see you’re working on this custom integration, let’s get it right for you.

There are 2 ways to go about this and I want to make sure you’re aware of both -

  1. Extending the existing default CREATE route in your routes/companies.js file
  2. Building a specific route for your Smart Collection routes/hubspot-companies.js file (what you describe in the post)

1. Extending the existing default CREATE route

Given the flow you describe, I would go this way. First create the record in the database, second call the Hubspot API re-using the code you already wrote for the Smart Action.

Here’s the documentation on extending the default routes (link).

And below is the snippet showing what the next() statement does in the default CREATE route.

routes/companies.js

const { PermissionMiddlewareCreator, RecordCreator } = require('forest-express-sequelize');
const { companies } = require('../models');

const permissionMiddlewareCreator = new PermissionMiddlewareCreator('companies');

...

// Create a Company - Check out our documentation for more details: https://docs.forestadmin.com/documentation/v/v6/reference-guide/routes/default-routes#create-a-record
router.post('/companies', permissionMiddlewareCreator.create(), (request, response, next) => {
  const recordCreator = new RecordCreator(companies);
  recordCreator.deserialize(request.body)
    // Create the company in the database
    .then(recordToCreate => recordCreator.create(recordToCreate))
    // Fire POST request to Hubspot API here
    .then(record => recordCreator.serialize(record))
    .then(recordSerialized => response.send(recordSerialized))
    .catch(next);
});

Let me know if this helps, otherwise I can enrich the provided Hubspot integration woodshop example to fit your use case.

1 Like

Thanks @anon20071947 for the quick reply!

I would follow this approach if there was a way to prefill data in the standard form as data coming from hubspot only tells part of the story of a customer. I discarded this as I couldn’t use query parameters as I mentioned in my second post.

Is this possible?

Ideally the smartest way seems to be:

  1. Fire smart action
  2. Redirect to create form for companies and prefill fields with smart collection hubspot data.
  3. Complete rest of fields
  4. Call extended create route which fires the API request.

Unfortunately I am stuck at 2)

1 Like

If not possible this could make it as a feature request. I think allowing query parameters on default forms to prefill fields would be useful and easy to achieve.

1 Like

Hi again @jonl :wave:t3:

Thanks for providing me with all the details here.

Unfortunately, I don’t see how you can redirect to the create form for the native collection companies when the Smart Action has been triggered from the hubspot-companies Smart Collection.

You can implement a new create form in the Smart Action itself regrouping both -

  • The fields needed to persist the new company in your database
  • The fields needed to fire the call to the Hubspot API

Did you see what the Smart Action documentation had to offer about -

:bulb: Don’t forget to import const { companies } = require('../models'); in your Smart Collection’s route file to use the ORM methods.

1 Like

That is what I was actually trying to avoid. Having to duplicate a form that already exists.
But I guess it’s the only option left :slight_smile:

Should I open a FR in the forum to be able to add query parameters to a form url so that the fields are prefilled?

1 Like

I have another idea in mind but I need to dabble with it first. I’ll come back to you and log the feature request if there are no alternatives to the one above :wink:

Thanks for bearing with me :pray:t3:

1 Like

That’s great. Thanks for considering it!

1 Like

Hi @jonl :wave:t3:

Apologies for the egregious delay here, I haven’t had the chance to get to the bottom of it but here’s the bigger picture for a start.

So the idea is to use as much as Forest Admin provides out-of-the-box to avoid duplication in terms of code/functionality. You want to create records in your customer collection and hit that Hubspot API at the same time.

For this I’d recommend you -

  1. Leverage the existing create form and native route to add a customer to your database
  2. Enrich this collection using Smart Fields -
  • Some fields will pull data from the Hubspot API (getters but no setters defined)
  • Some other fields will only appear in the create form (e.g your hubspot=true flag), make sure those fields are not set as read-only and are hidden from the list and details view.

  1. At the backend level, you’ll get the field inputs to let Forest build the customer object before persisting in the database (native behavior) but you’ll also get the Smart Fields input :point_down:t3:
router.post('/customers', permissionMiddlewareCreator.create(), (request, response, next) => {
  const attributes = request.body.data.attributes;
	// do what you want with the user input i.e call the Hubspot API
  next();
});

Maybe you can try it out and let me know how it works for you :slightly_smiling_face:

3 Likes

Thanks Ziad! I will fiddle around this idea and let you know about the outcome.

2 Likes

I get the general idea, but still fail to understand how I can get the needed info from Hubspot for the right HS company.

Let’s say I have the following companies A and B in hubspot with the following info(nameA, emailA and nameB, emailB).

I also have a collection in FA named customer that has the following fields: name, email and address.

I want to create FA customer records A and B while reusing the create form.

When creating A I want the name and email to get data from hubspot and want to fill the address. So name = nameA
email = emailA
address= 'to be filled in FA'

Same for B
name = nameB
email = emailB
address = 'to be filled in FA'

But how can it discriminate between HS company A and company B

Your solution proposes this:

Some fields will pull data from the Hubspot API (getters but no setters defined)

How does the FA create form know what HS company_id to pull data for? Without me providing it manually of course.

However I look at the problem for me it always comes down to how can I pass data to the create form so it knows what data to retrieve from the API?

1 Like

Hi @jonl :wave:t3:

I believe the flows we are describing are not similar. The solution I suggested above helps you create simultaneously a record in your customers collection (in the database) and then calls the Hubspot API to create a company there (or update if you have also added the hubspot_crm_id key in your create form and database).

The Smart Field type I described here with the getters are only to be used in the list and details view, once the record has been created in the customers collection and you have a ready hubspot_crm_id key in your database which you can use to fire a GET a company by ID call to the 3rd party API to pull its properties. So to answer this question :point_down:t3:

It’s simply not possible for now. What you would ideally need is a multi-step create form -

  • Step 1 - Input form where you can search your CRM company by name (possible in the new Hubspot API - docs) & select it
  • Step 2 - Create customer input form where the fields are prefilled with the results from Step 1

I’ll log this in our Productboard.

Now to finish, for your desired flow as presented here :point_down:t3:

The best I can offer is going back to this post in the thread and implementing a Create form using a Smart Action on your Hubspot collection -

Later, you can enhance the ‘linking’ of both collections for navigation UX, the Customers native one and the Hubspot Companies Smart implementation. A Smart Relationship could come in handy here.

Hope this is much clearer now and apologies for misconstruing your use case :slight_smile:

1 Like

Thanks @anon20071947

I’ll have to go the long route then :slight_smile:
Nonetheless, I’ve learned a lot from this post about the ins and outs of FA and I am pretty sure it will be handy for the future.

Besides the multi-step form which I believe it is already logged in product board I really think an option to append query strings to form URLs would be really handy not only for this scenario but for others too.

So

.../create/details?param1=value1&param2=value2

Just with that, the ability to read URL query strings via req.query and to extend the collection create route anyone can enhance the integration between FA and any API.

1 Like