Connect Google Sheets to SMTP via Webhook: Auto-Send Emails 2026
Table of contents:
- 1. Why Google Sheets Needs an SMTP Bridge to Send Real Email
- 2. Two Architectures: Apps Script-as-SMTP-Client vs External Webhook Relay
- 3. Building the Webhook Relay Step by Step
- 4. Payload Design: What to Send and What to Validate
- 5. Real-World Use Cases Where This Pattern Pays Off
- 6. Security and Reliability Checklist Before Going Live
- 7. Frequently asked questions
Why Google Sheets Needs an SMTP Bridge to Send Real Email
Google Sheets has no native way to talk to an external SMTP server. Apps Script ships with MailApp and GmailApp, both of which route mail through your Google account — fine for internal notifications, but limited to roughly 100 emails/day on a free account (1,500/day on Workspace) and always sent "from" your Gmail address. If you need to send from a branded domain (orders@yourshop.vn), hit higher volume, or track deliverability through a dedicated provider like SendGrid, Mailgun, or Amazon SES, you need a webhook that bridges Sheets to an SMTP relay.
The pattern is simple in concept: a row is added or updated in Sheets → a trigger fires → the row data is packaged as JSON → it's POSTed to a webhook endpoint → that endpoint (usually a small serverless function or Apps Script itself) authenticates with an SMTP server and sends the email. The complexity lives entirely in getting the trigger reliable and the payload correctly formatted — not in the SMTP call itself, which is 10 lines of code in any language.
Two Architectures: Apps Script-as-SMTP-Client vs External Webhook Relay
There are two ways to wire this up, and picking the wrong one wastes hours.
Option A: Apps Script sends via SMTP directly
Apps Script itself cannot open raw SMTP sockets — Google sandboxes network access to UrlFetchApp (HTTP/HTTPS only). So "SMTP from Apps Script" in practice means calling your provider's HTTP API (SendGrid, Mailgun, Brevo, Amazon SES all expose HTTP endpoints that wrap SMTP delivery) rather than literal SMTP protocol. This is the simplest path if your provider has an HTTP API — no separate server needed.
Option B: External webhook relay with real SMTP
If you need actual SMTP (port 587/465, LOGIN/PLAIN auth, self-hosted mail server, or a provider with SMTP-only support), Apps Script sends a webhook to an external service — a Cloudflare Worker, a Node.js endpoint, a Zapier/Make.com scenario, or a small Python Flask app — and that service opens the SMTP connection. This is the setup most people mean by "connect Google Sheets to SMTP via webhook."
| Criteria | Option A: HTTP API (no relay) | Option B: Webhook + SMTP relay |
|---|---|---|
| Setup complexity | Low — one Apps Script function | Medium — need a hosted endpoint |
| Works with any SMTP host | No, only providers with HTTP APIs | Yes |
| Latency | ~200-500ms per send | ~500ms-2s (extra hop) |
| Best for | SendGrid, Mailgun, Brevo, Resend | Self-hosted mail, cPanel SMTP, legacy corporate mail servers |
| Cost | Provider's free tier (often 100-300/day) | Relay hosting (often free on Cloudflare Workers/Vercel) |
If you already run a webhook that ingests form data into Sheets — like the setups described in Webhook Google Sheets: Nhận Dữ Liệu Từ Form, Zalo OA, Facebook — the outbound email webhook is the mirror image: instead of receiving POST data, you send it.
Building the Webhook Relay Step by Step
Step 1: Choose and configure the relay endpoint
For most SME setups, a lightweight serverless function is enough. A minimal Node.js relay using Nodemailer looks like this:
- Accept a POST request with JSON body:
{to, subject, body, from} - Validate a shared secret header (e.g.
X-Webhook-Secret) to prevent abuse - Open an SMTP transport with
nodemailer.createTransport({host, port, auth}) - Call
transporter.sendMail()and return a 200/500 status
Deploy this as a Cloudflare Worker, Vercel serverless function, or even a $5/mo VPS cron endpoint. Keep SMTP credentials in environment variables — never hardcode them in the Apps Script source, since Apps Script code is visible to anyone with edit access to the sheet.
Step 2: Trigger from Apps Script on edit or form submit
Use an installable trigger (onFormSubmit or a time-driven trigger checking for new rows) rather than a simple trigger, because simple triggers can't call UrlFetchApp with authorization scopes reliably. The core call is:
UrlFetchApp.fetch(webhookUrl, {method: "post", contentType: "application/json", payload: JSON.stringify(rowData), headers: {"X-Webhook-Secret": secret}})- Wrap in try/catch and log failures to a "Send Log" sheet with timestamp, row number, and error message
- Mark the row as "sent" only after receiving a 200 response — this prevents duplicate sends on trigger retry
This doPost/fetch pattern mirrors the inbound webhook logic covered in Tạo Webhook Nhận Dữ Liệu Vào Google Sheets Bằng Apps Script doPost — same authentication and payload-validation principles apply in reverse.
Step 3: Handle rate limits and retries
SMTP servers typically cap connections per minute (Gmail SMTP: 100/day for consumer accounts via relay; SES sandbox: 1 email/second by default; most shared-hosting SMTP: 30-50/hour). Batch sends with a delay — Utilities.sleep(1000) between rows — or better, queue rows and process them via a time-driven trigger every 5 minutes instead of firing one webhook per edit event. This avoids the classic failure mode where 200 rows get pasted at once and 150 emails silently fail because the SMTP server started rejecting connections.
Payload Design: What to Send and What to Validate
A well-designed payload keeps the relay endpoint dumb and the Sheet smart. Recommended JSON shape:
to: recipient email — validate with a regex in Apps Script before sending, since malformed addresses cause silent SMTP bouncessubject: pull from a template column so non-technical staff can edit wording without touching script codebody: support both plain text and HTML; if HTML, sanitize any user-entered fields to avoid broken markupfrom/replyTo: lock this server-side in the relay, not client-side in Sheets, so a compromised sheet can't spoof arbitrary sender addressesrowId: always include the sheet row number so the relay's response can be matched back for logging
On the relay side, reject any payload missing to or exceeding a size limit (e.g. 50KB) — this blocks both accidental malformed rows and deliberate abuse if the webhook URL leaks.
Real-World Use Cases Where This Pattern Pays Off
Order confirmation emails for retail
A Sheets-based order tracker (common in the setups described in Giải Pháp Google Sheets Cho Ngành Bán Lẻ 2027) can trigger a branded confirmation email the moment a new order row is added, without needing a full e-commerce backend. The webhook relay lets the "from" address be orders@yourdomain.vn instead of a personal Gmail, which materially improves customer trust and deliverability.
Project status digests
Teams tracking tasks in a Gantt-style sheet — like the templates in Template Google Sheets Quản Lý Dự Án — Gantt Chart & Timeline Tự Động — can run a daily time-driven trigger that scans for overdue tasks and emails the assigned owner via the SMTP relay, turning a static tracker into a lightweight reminder system without third-party project management software.
Weekly report distribution
Combined with dashboard-style reporting sheets like those in Mẫu Báo Cáo Dự Án & Quản Lý Công Việc Google Sheets 2027, a Friday-afternoon trigger can render a summary and email it to stakeholders as HTML, avoiding manual screenshot-and-send routines.
Security and Reliability Checklist Before Going Live
- Never expose SMTP credentials in Apps Script. Store them only in the relay's environment variables; Apps Script only holds the webhook URL and a shared secret.
- Rotate the shared secret if the sheet is ever shared with someone who shouldn't see the script — Apps Script properties are visible to editors with script access.
- Log every send attempt to a dedicated sheet tab (timestamp, row, status code, error) so failures are debuggable without digging through Apps Script execution logs, which expire after 7 days on free accounts.
- Set up SPF/DKIM/DMARC on the sending domain regardless of which architecture you choose — without them, even a technically correct SMTP send lands in spam.
- Cap send volume per trigger run (e.g. max 20 rows per execution) to stay under Apps Script's 6-minute execution limit and your SMTP provider's rate limit simultaneously.
- Test with a sandboxed SMTP (Mailtrap or similar) before pointing at production credentials — a misconfigured loop can otherwise send hundreds of duplicate emails in minutes.
If you're managing this alongside a broader operational sheet (orders, projects, or inventory), platforms like SheetStore package pre-built templates that already separate the data layer from the notification layer, so you're not wiring the webhook logic from a blank sheet each time.
Frequently asked questions
Can Google Sheets send emails directly through SMTP?
Google Sheets itself doesn't send emails, but Apps Script bound to a sheet can connect to an SMTP server (like Gmail SMTP or SendGrid) and trigger emails whenever a webhook event or row change occurs, giving you full SMTP-based automation without third-party platforms.
What's the difference between using Gmail's built-in MailApp and a real SMTP connection?
MailApp/GmailApp in Apps Script uses your Google account's sending quota and simple templates. A dedicated SMTP connection (via a library or external service) gives you custom headers, dedicated IPs, higher volume, and better deliverability for transactional emails triggered by webhooks.
How do I trigger an SMTP email when a webhook adds a new row?
Set up a doPost() webhook in Apps Script that writes incoming data to Sheets, then attach an onEdit or onFormSubmit trigger that calls your SMTP-sending function, passing the new row's data as email variables.
Is this approach secure for handling SMTP credentials?
Yes, if you store SMTP credentials in Apps Script's PropertiesService (not hardcoded in code) and restrict webhook access with a secret token or signature check, keeping credentials out of the spreadsheet and script editor's visible code.
Related articles:
Want to apply this without building from scratch?
Explore ready-made Google Sheets templates and management tools for your business at SheetStore Marketplace.
📚 Bài Viết Liên Quan
Chia sẻ bài viết:
Tuân Hoang
Đội ngũ SheetStore
Google Workspace Certified, 5+ years experience
Bạn thấy bài viết hữu ích?
Đăng ký nhận thông báo khi có bài viết mới.


