A vendor or report tool emails you a CSV every morning. getLatestCsvAttachment(query) searches Gmail, picks the newest .csv attachment from the matching messages, and hands back its name, the message date, and the parsed rows.
When to use
- Daily or weekly reports that only arrive by email
- Bank, payment, or ad-platform exports sent as attachments
- Any import where you used to download and upload a file by hand
How to use this snippet
/**
* Newest CSV attachment among Gmail messages matching a search.
*
* @param {string} query Gmail search, e.g. 'from:reports@vendor.com newer_than:2d'
* @return {{name: string, date: Date, rows: string[][]}|null} null when nothing matches
*/
function getLatestCsvAttachment(query) {
var threads = GmailApp.search(query + ' has:attachment filename:csv', 0, 10);
var best = null;
threads.forEach(function (t) {
t.getMessages().forEach(function (m) {
m.getAttachments().forEach(function (a) {
if (!/\.csv$/i.test(a.getName())) return;
if (!best || m.getDate() > best.date) best = { date: m.getDate(), att: a };
});
});
});
if (!best) return null;
return {
name: best.att.getName(),
date: best.date,
rows: Utilities.parseCsv(best.att.getDataAsString())
};
}
Example
function importDailyReport() {
var csv = getLatestCsvAttachment('from:reports@vendor.com newer_than:2d');
if (!csv) return; // nothing arrived yet
var sheet = SpreadsheetApp.getActive().getSheetByName('Daily');
sheet.clearContents();
sheet.getRange(1, 1, csv.rows.length, csv.rows[0].length).setValues(csv.rows);
}
Notes
- Keep the query narrow (
from:plusnewer_than:) so the search stays fast. Utilities.parseCsvhandles quoted commas. If the file uses semicolons, pass the delimiter:Utilities.parseCsv(text, ';').- The first run asks for Gmail read access.
Happy Coding!
