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
Why Make?
Make works for missing field alerts if your team already uses it. The HTTP modules call the HubSpot API directly (Make's built-in HubSpot module doesn't support NOT_HAS_PROPERTY), and a Code module handles deduplication and grouping. At typical volumes (5-10 deals with missing fields), the free plan covers it.
How it works
- Scheduler fires daily at 7 AM
- HTTP modules search for deals missing close date and amount via two separate API calls
- Code module deduplicates results, groups deals by owner, and outputs one bundle per owner
- Filter skips owners with zero missing deals
- Slack module DMs each owner with their incomplete deals and HubSpot links
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
Troubleshooting
Common questions
How many Make credits does this use per month?
About 120-150 credits/month. Each daily run uses 4-5 operations (2 HTTP + code + filter + Slack per owner). With 5 owners getting DMs, that's ~8-10 operations per run. Fits the free plan's 1,000 credits.
Why can't I use Make's HubSpot CRM module for this?
Make's built-in HubSpot module doesn't expose the NOT_HAS_PROPERTY filter operator. You need the HTTP module to call the Search API directly with the raw filter JSON.
Can I audit more than two fields?
Yes. Add another HTTP module for each additional field and include it in the Code module's merge logic. The deduplication handles any number of overlapping searches.
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.
Looking to scale your AI operations?
We build and optimize automation systems for mid-market businesses. Let's discuss the right approach for your team.