Flag HubSpot deals with missing fields and Slack the rep using Make

medium complexityCost: $10-29/mo

Prerequisites

Prerequisites
  • Make account (Free plan works for low volume)
  • HubSpot connection in Make via OAuth or API key
  • Slack connection in Make
  • A mapping of HubSpot owner IDs to Slack user IDs

Step 1: Schedule daily execution

Create a new scenario. Set the schedule:

  • Schedule type: Every day
  • Time: 07:00

Step 2: Search for deals missing close date

Add an HTTP -> Make a Request module:

  • Method: POST
  • URL: https://api.hubapi.com/crm/v3/objects/deals/search
  • Headers: Authorization: Bearer {{your_hubspot_token}}, Content-Type: application/json
  • Body:
{
  "filterGroups": [{
    "filters": [
      {"propertyName": "closedate", "operator": "NOT_HAS_PROPERTY"},
      {"propertyName": "dealstage", "operator": "NOT_IN", "values": ["closedwon", "closedlost"]}
    ]
  }],
  "properties": ["dealname", "amount", "closedate", "dealstage", "hubspot_owner_id"],
  "limit": 100
}
Why not the HubSpot CRM module?

Make's built-in HubSpot module does not expose the NOT_HAS_PROPERTY operator. Use an HTTP module with a raw POST request to access the full Search API.

Step 3: Search for deals missing amount

Add a second HTTP -> Make a Request module with the same structure, swapping the filter:

{
  "filterGroups": [{
    "filters": [
      {"propertyName": "amount", "operator": "NOT_HAS_PROPERTY"},
      {"propertyName": "dealstage", "operator": "NOT_IN", "values": ["closedwon", "closedlost"]}
    ]
  }],
  "properties": ["dealname", "amount", "closedate", "dealstage", "hubspot_owner_id"],
  "limit": 100
}

Step 4: Merge and group by owner

Add a Tools -> Set Multiple Variables module or a Code (JavaScript) module to deduplicate and group:

const closeResults = JSON.parse(bundles[0].data.body).results || [];
const amountResults = JSON.parse(bundles[1].data.body).results || [];
 
const seen = new Set();
const byOwner = {};
 
for (const deal of [...closeResults, ...amountResults]) {
  if (seen.has(deal.id)) continue;
  seen.add(deal.id);
  const props = deal.properties;
  const missing = [];
  if (!props.closedate) missing.push('close date');
  if (!props.amount) missing.push('amount');
  const ownerId = props.hubspot_owner_id || 'unassigned';
 
  if (!byOwner[ownerId]) byOwner[ownerId] = [];
  byOwner[ownerId].push({
    id: deal.id,
    name: props.dealname,
    missing: missing.join(', '),
  });
}
 
return Object.entries(byOwner).map(([ownerId, deals]) => ({
  ownerId,
  dealCount: deals.length,
  deals,
}));

This outputs one bundle per owner, which feeds into the next module.

Step 5: Slack DM each rep

Add a Slack -> Create a Message module:

  • Channel / User: Map the ownerId to the corresponding Slack user ID from your lookup table
  • Text:
*Missing Deal Fields*
You have {{dealCount}} deals with incomplete data:
 
{{deals mapped to bullet list}}
 
Please update these deals today so forecasting stays accurate.

For richer formatting, switch to Block Kit and use a JSON body:

{
  "blocks": [
    {
      "type": "header",
      "text": {"type": "plain_text", "text": "Missing Deal Fields"}
    },
    {
      "type": "section",
      "text": {
        "type": "mrkdwn",
        "text": "You have *{{dealCount}}* deals with incomplete data:\n\n{{formatted deal list with links}}"
      }
    },
    {
      "type": "context",
      "elements": [{"type": "mrkdwn", "text": "Please update these deals today so forecasting stays accurate."}]
    }
  ]
}
Owner to Slack user mapping

Make doesn't natively map HubSpot owner IDs to Slack users. Create a lookup table using Make's Data Store module, a Google Sheet, or a static JSON object in the Code module.

Step 6: Handle empty results

Add a Filter between the Code module and the Slack module:

  • Condition: dealCount greater than 0

This prevents the scenario from sending empty messages when all deals have complete data.

Step 7: Activate

  1. Click Run once to test
  2. Verify the Slack DM content and deal links
  3. Toggle to Active

Cost

  • Free plan: ~4-5 operations per run (2 HTTP requests + code + filter + Slack). At 30 runs/month = ~150 operations. Within the free tier's 1,000 operations.
  • Core plan: $10.59/mo for higher volume.

Need help implementing this?

We build and optimize automation systems for mid-market businesses. Let's discuss the right approach for your team.