# Send Messenger campaigns to any slice of your Google Sheet

> Filter your audience sheet into a segment, see who is actually reachable, then send a Messenger campaign and log every result back to the sheet.

- Workflow type: app
- Services: Manychat, Google Sheets
- Categories: Marketing
- Published: 2026-08-31

## What it does

- Reads your audience spreadsheet and lets you filter rows into a segment right in the app, with no exporting and no hand picking contacts
- Matches every row to its Messenger contact and shows you who is reachable, what tags they already carry, and when they last interacted
- Sends either an existing saved sequence or a one off message you write, going out in steady batches with visible progress instead of all at once
- Stamps everyone you contact with a tag so you can exclude them next time, and appends the outcome for each recipient back to your sheet

## What you'll need

- A Manychat account with Messenger connected, plus its API key from Settings > API
- A Google account with an audience spreadsheet, one row per person, including an email or phone column
- Whatever columns you want to slice on, such as segment, last purchase, or source
- At least one saved Manychat flow if you want to send existing sequences rather than writing messages yourself

## Prompt

Build me a Messenger send desk. My audience lives in Google Sheets, one row per person with an email or a phone plus columns like segment, last purchase, and source. I want to turn any slice of that sheet into a Manychat campaign without exporting anything or hand picking contacts inside Manychat. The spreadsheet is the source of truth for who exists and who has been contacted; Manychat is only the send channel.

Setup view. Let me save the spreadsheet ID, the tab name, and which row is the header. Read the audience with the Google Sheets Get Values operation, using Batch Get Values when I have the audience split across more than one tab or range. Infer the columns from the header row rather than hardcoding them, and let me map which column holds email and which holds phone, since every audience sheet names those differently. Cache the parsed rows for the session so filtering does not re-read the sheet on every keystroke.

Segment builder. Show the sheet as a table and let me filter rows into a segment in the UI: pick values from a column, combine a few conditions, and see the matching row count update live. Filters should work on whatever columns exist, so drive them off the inferred headers. Let me save a segment definition and rebuild it later against fresh sheet data, because the sheet keeps changing underneath me.

Resolution. Once I have a segment, resolve each row to a Manychat subscriber with Find Subscriber by System Field. That operation accepts email or phone but only one per request, so try the email first and fall back to the phone when there is no email or the email finds nothing. There is no list-all-subscribers endpoint in Manychat, which is exactly why the audience has to come from the sheet and get resolved row by row. Rows that resolve to nothing stay visible in the table as unresolved. Never silently drop them, because a missing match is information I need.

Enrichment and the review table. For every row that did resolve, call Get Subscriber Info to pull the full subscriber object, then show a review table with one line per person: the identifying columns from their sheet row, whether they are reachable, the tags they already carry, and when they last interacted. Split the table into reachable and unreachable groups before I commit to anything, with counts on each. Also load the page's existing tags with Get Tags and custom fields with Get Custom Fields so I can see and reuse what already exists rather than inventing new tag names.

The reachable split is the important part. Send Content fails with error 3021 when you message someone outside the 24 hour window without a message tag, so compute reachability from the last interaction timestamp on the subscriber object returned by Get Subscriber Info. Verify the exact field name against a live response before relying on it rather than assuming, and if the field is absent treat that person as unreachable rather than guessing they are fine. Anyone last active more than 24 hours ago goes in the unreachable group with the reason shown.

Composing and sending. From the review table let me choose one of two paths. Either pick an existing sequence, loaded with Get Flows and sent with Send Flow, or write a one off message in a composer and send it with Send Content using the Dynamic Block v2 format. Default the recipient list to the reachable group only, show me exactly how many people will receive the send, and require an explicit confirmation before anything goes out. A dry run that shows the resolved recipient list without sending is worth having.

Every send also stamps the person with Add Tag to Subscriber by Name, using a campaign tag I choose or one derived from the campaign name. That tag is how I suppress people from the next campaign, so let me use an existing tag as an exclusion filter back in the segment builder. The stamp should follow a successful send, and a failed send should not leave a tag claiming the person was contacted.

Add a Write this campaign button that runs a background agent. The agent reads the selected segment's sheet columns, works out what those people actually have in common, such as a shared source, a similar last purchase, or a common segment value, and proposes two or three message variants tuned to that. It drops the drafts into the composer for me to edit and pick from. The agent must not send anything itself; drafting is the whole job. Show its progress while it runs and land the variants in the app where I can see them side by side.

Write back after every send. Use the Google Sheets Append Values operation to log one row per recipient with a timestamp, who they were, what was sent (the flow name or the message text), and the outcome: sent, rejected, or unresolved, with the error reason when the send failed. Batch these into a single append call per campaign rather than one call per recipient, because the Sheets write quota is 60 requests per minute per user and a per-recipient append would blow through it. Let the results log go to its own tab so the audience list stays clean.

Throttle everything and show progress. Manychat's limits are per account and shared across everything using the same API key: Find Subscriber by System Field allows 50 requests per second, subscriber reads including Get Subscriber Info allow 10 per second, Get Flows allows 10 per second, subscriber writes including Add Tag allow 10 per second, Send Content allows 25 per second, and Send Flow allows 20 per second with a hard cap of 100 per subscriber per hour. Build resolution and sending as throttled batches with a visible progress bar and a running count, never a single fan out. Note that because every send is paired with a tag write, the real send pace is governed by the 10 per second subscriber write limit rather than the higher send limits, so pace to the slower of the two.

Handle failure without losing the run. Retry 429 responses with backoff, keep going when an individual recipient fails, and show me a per-recipient status list as the campaign progresses. If a send is interrupted, I should still be able to see who was already contacted and the sheet should still have their rows, so a resumed or repeated campaign does not double message anyone who already got it.

## How to customize

- Change which spreadsheet columns become filters in the segment builder, and add saved segments you rebuild often
- Adjust the send pace and batch size, and set how many people a single campaign is allowed to reach
- Change the tag stamped after each send, and use that tag to suppress those people from the next campaign
- Point the results log at a different tab or spreadsheet if you want the record kept separately from the audience list

## FAQ

### Do I have to export my spreadsheet or upload a contact list?

No. The app reads your sheet directly and matches each row to a Messenger contact when you build the segment, so the spreadsheet stays the single source of truth and nothing gets copied into another tool.

### Why do some people show up as unreachable?

Two reasons. Either the person in that row has no matching Messenger contact, or they have not interacted with you in the last 24 hours, which is the window Messenger allows standard messages in. The app shows both groups separately before you send rather than quietly dropping them.

### Does the writing assistant send anything on its own?

No. The Write this campaign button drafts two or three message options based on what the people in your segment have in common and drops them into the composer. You edit and choose, and nothing goes out until you press send.

### Will this work if my sheet has phone numbers instead of emails?

Yes. The app looks up each person by email first, and if there is no email or no match it falls back to the phone number in that row.

### What happens to people the send does not reach?

They are logged as rejected in your sheet with the reason, alongside everyone who was contacted successfully. You keep a full record of who was reached, who was not, and when.

### Can I send to my whole list at once?

The app deliberately sends in throttled batches with a progress view, because Messenger limits how fast messages can go out. Large segments still finish, they just go out in a controlled stream instead of one burst.

Use this prompt in General Input: https://www.generalinput.com/prompts/send-messenger-campaigns-to-any-slice-of-your-google-sheet