Draft, review, and send WhatsApp outreach from one screen
Pick your audience from HubSpot, let a background assistant write each WhatsApp message, then approve every one before it sends through Freshchat.
Build me an app that my growth and support team opens whenever we run a WhatsApp outreach push through Freshchat. It has two tabs: an audience builder where I assemble the list, review drafts and send, and a sent log where I see what went out and who replied. Nothing runs on a schedule, a person opens the app and drives the push.
Audience builder tab. At the top I name the push and define the audience by picking a HubSpot contact search, for example customers in a given lifecycle stage, or contacts with a deal closed in the last 30 days. A handler runs HubSpot Search Contacts with those filters and pulls the fields I care about: first name, last name, email, phone, lifecycle stage, company, deal or close information, and owner. Show the results as a table, one row per contact.
Matching to Freshchat. For every contact in the audience, match to their Freshchat record with List Users, keyed on email and then phone. Important data path nuance: Freshchat has no account wide list-all-conversations operation, so any conversation data has to be assembled by walking users first. For each matched user call List User Conversations, take the most recent conversation, then call List Conversation Messages on that conversation to get the latest message and its timestamp. Each row should show: matched or unmatched, the last chat snippet, how long ago they spoke, and the status of that most recent conversation. Use the list pagination parameters page and items_per_page (message lists default to 20 and cap at 50) and only pull the newest page of messages, do not walk full history. Load the Freshchat enrichment progressively so the HubSpot rows render immediately and each row fills in as its conversation lookup completes.
Creating missing people. Rows with no Freshchat record get an "Add to Freshchat" action that calls Create User with the contact's name, email and phone so they can be messaged, plus a bulk version that does it for every unmatched row in the push. Freshchat create and update calls return 202 Accepted and are processed asynchronously, so the resource does not come back in the response: update the row optimistically, then refetch shortly after to confirm, and show a pending state in between rather than treating a 202 as a failure.
Eligibility rules, enforced in the app and not left to the user. Exclude anyone whose most recent Freshchat conversation is still open or unresolved, so we never talk over a live support thread. Exclude anyone who has already been sent to inside this same push, so nobody is messaged twice. Excluded rows stay visible, greyed out, with the exclusion reason spelled out on the row so I can see exactly who got skipped and why. Re-evaluate both rules at send time as well as at display time, since a conversation can open between building the list and pressing send.
The template. The app holds the configuration for a pre-approved WhatsApp template: its name, its language, and the ordered list of variables it expects, each with a short description of what belongs in it. Drafting fills those variables, it never produces free text, because only approved template content can go out.
"Draft messages" button and the background agent. Pressing it kicks off a background agent over the eligible rows. For each person, the agent reads their recent chat transcript (List User Conversations, then List Conversation Messages on the most recent one) plus that person's HubSpot fields from the audience search, and produces values for the configured template variables in a strict schema, along with a one line reason for the angle it chose. The agent writes each person's result back into the app as it goes, so rows populate live and I can watch progress rather than waiting on one big result at the end.
Review table. The drafts land in a review table showing the person, a rendered preview of the template with their variables substituted, the raw variable values, the agent's reason, and a status of pending, approved or rejected. I can edit any variable value inline (the preview updates as I type), reject a row, or approve it, with bulk approve and bulk reject for a filtered selection. Nothing is sendable until it is approved, and rejected rows are kept for the record rather than deleted.
Sending. A "Send approved" action sends each approved row with Send Outbound WhatsApp Message, passing the template and that person's variable values. Send sequentially with a short delay, watch the X-RateLimit-Remaining header that every Freshchat response carries, slow down as it drops and stop cleanly on a 429 so the remaining rows can be retried afterwards rather than lost. Show live progress with per-row outcome and timestamp, and mark each person as sent for this push the moment the send succeeds so the no-double-message rule holds even if I press send again.
CRM write back. After each successful send, create a note on that person's HubSpot contact with Create Note, associated to the contact id, recording which template went out, the rendered message text, and when it was sent, so the CRM shows the outreach alongside everything else on the record. Show the note status on the row and let me retry a failed note without resending the message.
Sent log tab. Build this from List Outbound Messages: one row per message showing who it went to (resolve the Freshchat user back to a name with Get User or Fetch Users by IDs, and link it to the HubSpot contact where we know it), which push and template it belonged to, when it was sent, its delivery status, and whether the person replied. Work out replies by checking that user's conversations for an inbound message after the send timestamp, again via List User Conversations and List Conversation Messages. Let me filter by push, by date range, and by replied versus no reply, and put a small summary strip at the top with sent, delivered, replied and reply rate.
Persistence. Store pushes, their audience rows, the drafts and their approval state, and the send outcomes in the app, so a push survives a reload, the sent log is accurate without refetching everything, and the never-twice rule is actually enforceable. Record which team member approved and which one sent each row, since growth and support share this app.
What does this prompt do?
- Build the audience: choose a group of HubSpot contacts, such as everyone in a lifecycle stage or anyone with a deal closed recently, and see each person matched to their chat history.
- See when you last spoke: every row shows the person's last chat and how long ago it happened, and anyone who has no chat record yet can be added in one click so they can be messaged.
- Draft with help, approve by hand: a background assistant reads each person's recent chat and CRM details and writes a personalized message, then you edit, reject, or approve every row before anything goes out.
- Keep the record: approved messages send over WhatsApp, a note lands on the HubSpot contact, and a sent log tab shows who was messaged, when, and who replied.
What do I need to use this?
- A Freshchat account with WhatsApp messaging enabled
- At least one WhatsApp message template that has already been approved, with its variables ready to fill
- A HubSpot login with access to your contacts and notes
- Phone numbers on your HubSpot contact records, so people can be reached on WhatsApp
How can I customize it?
- Change the audience: swap the contact filters for any segment you push to, such as a lifecycle stage, a recent purchase, a deal owner, or a signup date range.
- Change the template: point the app at a different approved WhatsApp template and the drafts will fill in that template's variables instead.
- Change the guardrails: set how far back the assistant reads someone's chat history, or add a cooling-off window so anyone messaged in the last few weeks is skipped.
FAQs
Do the messages send as soon as they are drafted?
Will this interrupt someone who is in the middle of a support conversation?
Can the same person get two messages in one push?
Can I use our own approved WhatsApp template?
What happens to people who have never chatted with us before?
Does this work with a free HubSpot account?
Related templates
Stop buying stale lists. Reps run a saved search, work the results like an inbox, and only the accounts they approve ever reach your CRM.
Pick a date, a starting point and a radius, then build a sequenced day of customer visits that lands straight on your calendar.
One screen where reps filter for companies that fit, see who is actually reachable at each account, and save only the addresses that verify.
See every competitor battlecard next to the number of open deals that name that competitor, so the cards carrying real pipeline get refreshed first.
Score every target account against the buying committee you actually need, see the exact holes, and have an assistant fill them in your CRM.
See open and pending conversations from all your Help Scout inboxes in one queue, sorted so the customers who have waited longest on you come first.
Stop running WhatsApp pushes out of a spreadsheet.
Build the audience, review every draft, and send the whole push from one screen, with the record written straight back to your CRM.