Flag HubSpot deals with missing fields and Slack the rep using Make
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
}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
ownerIdto 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."}]
}
]
}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:
dealCountgreater than0
This prevents the scenario from sending empty messages when all deals have complete data.
Step 7: Activate
- Click Run once to test
- Verify the Slack DM content and deal links
- 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.