How to Send a WhatsApp Broadcast from a Google Sheet
Keep your list in a spreadsheet? Send straight from it — pick the sheet, choose the phone column, and merge each person's row into their message.
A Google Sheet broadcast is a WhatsApp campaign whose recipient list is read straight out of a spreadsheet at the moment of sending, instead of from contacts stored in ConvoFly or a CSV you uploaded. You connect Google once, pick the sheet, pick the tab, and tell ConvoFly which column holds the phone numbers.
The reason to bother: the sheet is re-read on every send. Add 40 rows on Thursday and Friday's recurring broadcast includes them, with nothing to re-upload and nothing to remember. It is the closest thing WhatsApp has to a mail-merge — each person's row can fill in their own name, order number or appointment time.
This guide covers connecting Google, laying the sheet out so it is detected correctly, mail-merging from the columns, what happens to bad rows, and the four honest limitations worth knowing before you rely on it.
When a Google Sheet beats the alternatives
ConvoFly gives you five audience tabs. The sheet is the right answer in a specific case — when the list is maintained by people, outside the app:
| Audience source | Updates itself? | Per-person personalization | Best for |
|---|---|---|---|
| Google Sheet | Yes — re-read every send | From any column in the row | Lists your team edits in a spreadsheet: bookings, waitlists, event RSVPs |
| CSV list | No — frozen at upload | Positional: phone first, then {{1}}, {{2}}… | A genuine one-off send from an exported file |
| By segment | Yes — re-checked every send | From stored contact fields | Anyone already in ConvoFly, filtered by tag, field or date |
| By tag | Yes | From stored contact fields | One simple label, e.g. everyone tagged vip |
| Re-target | Yes | From stored contact fields | Following up on a previous broadcast's outcome |
If the people are already in ConvoFly with tags and fields on them, segments are better — they carry the contact's whole history, not just one row. The sheet wins when the data only exists in the spreadsheet: a class register, a delivery run, a list your operations team updates hourly.
Connect Google and pick your sheet
- In the audience picker, click the Google Sheet tab.
- Click Sign in with Google and approve access. This is a one-time step per organisation; afterwards the pane shows Connected as your email, with a Change account button if you need a different one.
- Click 📄 Choose from Google Drive and select your spreadsheet from the picker.
- Choose the Tab — the worksheet inside the file. Column headers are read fresh for each tab, because different tabs legitimately have different headers.
- Choose the Phone number column from the dropdown of detected headers.
All four selections are required and they unlock in order: no tab list until a sheet is picked, no column list until a tab is picked. If you try to continue early, the picker tells you exactly which step is missing — "Choose which tab of the sheet to use", "Pick which column holds the phone number".
What access Google actually grants
Worth being precise here rather than reassuring. ConvoFly requests Google's per-file permission, not access to your Drive. The practical meaning: ConvoFly can only ever touch files you personally hand it through the Drive picker. It cannot list, search or open anything else in your Drive, and it never sees your other spreadsheets, documents or folders.
Within that one file, the permission Google grants is read and write — the same connection powers the automation builder's Google Sheets block, which can add and update rows. The broadcast audience path itself only reads: it fetches the rows to work out who to message and never writes back. So "we only touch the file you picked" is exactly true; "read-only" would be an overstatement, and you should judge the connection on the first claim rather than the second.
You can revoke the connection at any time from your Google Account's security settings, at which point the live re-read stops and campaigns relying on the sheet can no longer resolve their audience.
How to lay out the sheet
There is no rigid template, but detection follows a specific rule and knowing it prevents nearly every problem. ConvoFly scans the first 25 rows of the tab and treats the first row containing two or more non-empty cells as your header row. Everything below it is data.
That rule is generous on purpose: a merged title banner across the top ("Q3 Waitlist — updated Tuesday") occupies a single cell, so it is skipped rather than mistaken for headers. What it cannot survive is a header row where only one column is filled in.
| Sheet layout | Detected? | Why |
|---|---|---|
| Headers in row 1: Phone, Name, Order | Yes | First row with 2+ filled cells |
| Merged title in row 1, headers in row 3 | Yes | Row 1 has one cell; row 3 is the first with 2+ |
| Headers 30 rows down | No | Only the first 25 rows are scanned |
| A single column with no header text | No | Needs at least two non-empty header cells |
| Header names with trailing spaces | Yes | Header names are trimmed automatically |
If detection fails you get a plain-English message rather than silence: "We couldn't find column headers in this tab. Put your column names (like Phone, Name) in a row near the top of the sheet, or pick a different tab."
Two practical notes on size. There is no row limit imposed by ConvoFly — the ceiling in practice is WhatsApp's own daily messaging limit, which starts at 250 unique customers per rolling 24 hours for a new number (Meta, WhatsApp messaging limits). Columns are read up to column ZZ, which is 702 columns — comfortably more than any sane recipient list.
Personalize from the sheet's columns
This is the part that makes a sheet worth using: a proper mail-merge. In the Message template section — or on each step, in a drip campaign — every {{1}}, {{2}} in your approved template gets its own source dropdown with three choices:
- Sheet column — that person's own value from their row, listed as "Sheet column: Name", "Sheet column: Order".
- Contact's saved detail — a field already stored on the contact in ConvoFly, if they exist there.
- Custom text — one fixed value for everyone, such as a shared promo code.
You can mix them in one message: {{1}} from the sheet's Name column, {{2}} as fixed text. For anything not fixed, fill the "If blank, use…" box — ConvoFly blocks the launch until you do, with the message "Variable {{1}} comes from a sheet column — add a fallback for rows where that cell is blank." The reason is not fussiness: WhatsApp rejects a template whose variable resolves to nothing, so one empty cell would otherwise fail that recipient's message. The fallback also fires when a cell contains only spaces, not just when it is truly empty. More on this in personalizing broadcasts with variables.
One limitation to plan around: only body variables can be personalized per recipient. A header image, a header video or a button's URL parameter is a single fixed value for the whole broadcast — see adding media, buttons and offers.
What happens to messy rows
Real spreadsheets are messy, so it is worth knowing exactly how each kind of mess is handled:
- Duplicate numbers — the same person appearing twice is messaged once, and the last row wins for personalization values. Keep your most current data lower in the sheet, or de-duplicate before sending.
- Blank or unreadable phone cells — the row is skipped silently. This is the one to watch: a 500-row sheet with 40 bad numbers previews as 460 recipients with no warning that 40 were dropped. If the preview count is lower than your row count and the skipped-count note doesn't explain the gap, the difference is bad phone cells.
- Numbers in odd formats — leading zeros, spaces, brackets and dashes are normalised, using your organisation's country as the default when a number has no country code. Storing numbers in full international format is still safest.
- Short rows — a row that simply ends before the phone column is treated as blank and skipped.
- Opted-out people — skipped even though they are in the sheet. Honouring opt-outs is required by the WhatsApp Business Messaging Policy, and putting someone back in a spreadsheet does not undo their STOP.
Recurring broadcasts and drip campaigns
The sheet is not a one-shot import, and this is where it earns its place:
- Recurring broadcasts — each scheduled occurrence resolves its audience from scratch, so every run reads the sheet as it stands at that moment. A weekly Monday send always reflects last week's additions.
- Drip campaigns — the sheet can enrol people into a multi-step sequence, and when a later step uses a sheet column for personalization, the sheet is re-read at send time rather than replaying the values captured at enrolment. If someone's order number changed between step 1 and step 3, step 3 uses the new one. If the re-read fails — the file was moved, renamed or unshared — the campaign falls back to the values captured at enrolment rather than failing outright.
Two things break the live re-read, both fixable in Google rather than in ConvoFly: the file being removed from the connected account's access, and the header row or phone column changing name. Rename "Phone" to "Mobile" mid-campaign and the mapping no longer resolves.
Consent still applies to spreadsheet rows
A spreadsheet makes it technically easy to message people who never agreed to hear from you, and that is the fastest route to blocks and a damaged number. Meta's Business Messaging Policy requires opt-in before you message someone, and marketing templates are charged on delivery whether or not the recipient wanted them (Meta, WhatsApp pricing).
A useful habit: keep an opt-in column in the sheet — a date, or a Yes — and only paste in rows that have it. It costs nothing and it makes the list auditable. See broadcast best practices for what counts as consent.
Before you launch: check the count
- Under 5. Review & test, click Preview recipients. Compare the number against your sheet's row count — the difference is opted-out contacts, previously undeliverable numbers, duplicates and unreadable phone cells.
- Send yourself a test message and read it on a phone. Mail-merge errors are obvious in a real chat bubble and invisible in a form.
- Check the estimated sending time shown beside the count. Sending paces at roughly 120 messages a minute, so 3,000 rows is about 25 minutes of sending — slow progress is normal, not a fault.
Troubleshooting
| What you see | Cause | Fix |
|---|---|---|
| "We couldn't find column headers in this tab" | Headers below row 25, or fewer than two filled header cells | Move headers near the top and label at least two columns |
| "Couldn't read this sheet" | File moved out of the connected account's reach, or the connection expired | Reconnect Google, then re-pick the sheet |
| Fewer recipients than rows | Duplicates, opt-outs, or blank/unreadable phone cells | Check the skipped-count note; anything unexplained is bad phone cells |
| Column dropdown is empty | No tab selected yet | Pick the tab first — columns load per tab |
| Launch button blocked | A sheet-column variable has no fallback | Fill the "If blank, use…" box for every non-fixed variable |
| New rows aren't being messaged | Header or phone column renamed, or file unshared | Restore the original header names and re-pick the sheet |
Once it is running, the sheet becomes the interface: your team edits rows, and the campaign quietly follows. That is the whole appeal — no export, no re-upload, no version of the list that is three days out of date.
Frequently asked questions
Can I send a WhatsApp broadcast from a Google Sheet?
Yes. In the audience picker choose the Google Sheet tab, connect your Google account once, then pick the spreadsheet, the tab, and the column holding phone numbers. The sheet is re-read on every send, so rows added later are included automatically — including on recurring broadcasts and drip campaigns.
Can I personalize messages with columns from my sheet?
Yes — it's a full mail-merge on body variables. Each placeholder ({{1}}, {{2}}…) can pull from a sheet column, a saved contact detail, or fixed custom text. A fallback is required for every column-backed variable, because WhatsApp rejects a template whose variable resolves to nothing. Header images and button parameters stay fixed for the whole broadcast.
Can ConvoFly see or change my other Google files?
No. Google's per-file permission means ConvoFly can only ever touch spreadsheets you hand it through the Drive picker — it cannot list, search or open anything else. Within that one file the granted permission does include writing, which the automation builder's Sheets block uses, but the broadcast audience path only reads.
How does ConvoFly find my column headers?
It scans the first 25 rows of the tab and uses the first row containing two or more non-empty cells as the header row. A merged single-cell title banner is skipped correctly. Headers below row 25, or a header row with only one filled cell, will not be detected.
What happens if the same number appears twice in my sheet?
It is messaged once, and the last matching row wins for personalization values. Blank or unreadable phone cells are skipped silently, so a 500-row sheet with 40 bad numbers previews as 460 recipients with no separate warning.
Can I broadcast from a CSV or Excel file instead?
Yes — upload a CSV in the audience picker (export Excel as CSV first), and its extra columns feed variables positionally: phone number first, then {{1}}, {{2}} in order. The difference is that a Google Sheet is re-read live on every send while a CSV is a frozen snapshot for that one campaign.