समझिए
शीट
Tab Customers:
| A Name | B Email | C Due Amount | D Due Date | E Status |
|---|---|---|---|---|
| Rahul | rahul@example.com | 12500 | 15-Oct-2026 | |
| Priya | priya@example.com | 8300 | 20-Oct-2026 |
Column E शुरू में ख़ाली है; script उसमें timestamp के साथ Sent लिखता है।
GmailApp बनाम MailApp
MailApp.sendEmail(...)— सिर्फ़ email भेजना।GmailApp.sendEmail(...)— भेजना और drafts, labels, inbox search, aliases।
दोनों की रोज़ की recipient quota एक ही है। हम GmailApp लेंगे ताकि testing के लिए drafts बना सकें।
Script
const TEST_MODE = true; // true = create drafts only; false = actually send
function sendReminders() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Customers');
const lastRow = sheet.getLastRow();
if (lastRow < 2) return;
const rows = sheet.getRange(2, 1, lastRow - 1, 5).getValues();
const statusOut = [];
let count = 0;
rows.forEach(([name, email, amount, dueDate, status]) => {
if (!email || String(status).startsWith('Sent')) {
statusOut.push([status]); // keep as is
return;
}
const dateText = Utilities.formatDate(new Date(dueDate), Session.getScriptTimeZone(), 'dd MMM yyyy');
const amountText = Number(amount).toLocaleString('en-IN');
const subject = `Payment reminder: ₹${amountText} due on ${dateText}`;
const plain = `Dear ${name},\n\nThis is a reminder that ₹${amountText} is due on ${dateText}.\n\nThank you.`;
const html =
`<p>Dear ${name},</p>` +
`<p>This is a reminder that <b>₹${amountText}</b> is due on <b>${dateText}</b>.</p>` +
`<p>Thank you.</p>`;
const options = { htmlBody: html, name: 'Accounts Team' };
if (TEST_MODE) {
GmailApp.createDraft(email, subject, plain, options);
statusOut.push(['Draft ' + new Date().toLocaleString('en-IN')]);
} else {
GmailApp.sendEmail(email, subject, plain, options);
statusOut.push(['Sent ' + new Date().toLocaleString('en-IN')]);
}
count++;
});
sheet.getRange(2, 5, statusOut.length, 1).setValues(statusOut); // one batch write
SpreadsheetApp.getActiveSpreadsheet().toast(`${count} emails processed`);
}
यह कैसे काम करता है:
- सारी rows एक साथ पढ़ता है।
- बिना email वाली या पहले से
Sentrows छोड़ देता है। - हर व्यक्ति के लिए subject, plain text और HTML बनाता है।
- Test mode में drafts बनाता है — जाँचने के लिए Gmail → Drafts खोलें।
- Status column एक साथ वापस लिखता है।
Drafts सही लगें तो उन्हें delete करें, Status column साफ़ करें, TEST_MODE = false करें और फिर चलाएँ।
काम के options
{
htmlBody: html, // HTML version
name: 'Accounts Team', // sender display name
cc: 'manager@example.com',
bcc: 'archive@example.com',
replyTo: 'accounts@example.com',
attachments: [pdfBlob] // a file blob (see the PDF invoices lesson)
}
अच्छी आदतें
htmlBodyके साथ plain-text body भी हमेशा रखें।- Customers को भेजने से पहले अपने address या drafts से test करें।
- बड़ी lists के लिए
MailApp.getRemainingDailyQuota()जाँचें (पिछला lesson)। - सिर्फ़ उन्हीं लोगों को email करें जो आपसे सुनने की उम्मीद रखते हैं, और संपर्क का तरीका ज़रूर दें।
मुख्य बातें
- Rows एक साथ पढ़ें, हर message template literals से बनाएँ, status एक साथ वापस लिखें।
- सहेजा गया Status पूरा काम दोहराने से रोकता है। बैच लिखने से पहले रन विफल हो जाए तो भेजे गए ईमेल दोबारा जा सकते हैं; फिर चलाने से पहले Gmail और शीट का मिलान करें।
- Test करने का सबसे सुरक्षित तरीका
createDraftहै।