Create a Free CSV Automation Tool in Minutes
2026-10-02 · 5 min read
Build a Free CSV Automation Tool in Minutes
Your inbox is full of CSV attachments every morning, and you still click Download manually. Imagine a free CSV automation tool that pulls those files, merges them, and emails a summary before you finish your coffee.
Why a free CSV automation tool matters
I timed myself pulling three daily sales reports, cleaning a column, and copying the result into a master sheet. It took about 12 minutes each time. Multiply that by 20 workdays and you’ve spent four hours on repetitive clicks. Automation can cut that time down to seconds and removes the typo that often appears when you re‑type a header.
Beyond saving time, an automated process always keeps the rows in the same order. This consistency is important because many reporting tools (also called dashboards) expect the data to have the same layout every day. When you do the work manually, you risk missing a file or moving a column to the wrong place.
Choose a free online CSV merge service
Several web‑based services let you send two or more CSV files and receive a combined file. The most popular free options are:
- MergeCSV.io – a simple REST endpoint with a 100 MB daily limit.
- CSV‑Merge.com – supports custom delimiters and requires no authentication.
- DataFusion (free tier) – offers a 5 request‑per‑minute quota and returns JSON metadata.
For the example below I’ll use MergeCSV.io because its API (https://api.mergecsv.io/merge) is the most straightforward.
Schedule the merge with Google Apps Script
If you use Google Workspace, Google Apps Script gives you a free time‑trigger (up to 20 runs per day). If you prefer a platform‑agnostic solution, services like cron‑job.org can call any URL on a schedule you define.
Below is a complete Google Apps Script that:
- Create a Drive folder called
DailyReports. Drop every inbound CSV there, either manually or via a Gmail filter that auto‑saves attachments. - Open Apps Script (
Extensions → Apps Script) and paste the code block that follows. - Replace placeholders (
FOLDER_ID,RECIPIENTS) with your actual values. - Save and click the clock icon → “Add trigger”. Choose “Time‑driven”, “Day timer”, and set the hour you want the script to run (e.g., 07:30).
- Run once manually to grant permissions and verify the output.
function mergeDailyCSVs() {
const folderId = 'FOLDER_ID'; // <-- your Drive folder ID
const recipients = ['you@example.com', 'team@example.com'];
const files = DriveApp.getFolderById(folderId).getFilesByType('text/csv');
const fileIds = [];
while (files.hasNext()) {
const f = files.next();
fileIds.push(f.getId());
}
if (fileIds.length === 0) {
Logger.log('No CSV files found.');
return;
}
// Build multipart/form-data payload (a way to send several files in one request)
const boundary = '----boundary' + new Date().getTime();
let payload = '';
fileIds.forEach(id => {
const blob = DriveApp.getFileById(id).getBlob();
payload += '--' + boundary + '\r\n';
payload += 'Content-Disposition: form-data; name="files"; filename="' + blob.getName() + '"\r\n';
payload += 'Content-Type: text/csv\r\n\r\n';
payload += blob.getDataAsString() + '\r\n';
});
payload += '--' + boundary + '--';
const options = {
method: 'post',
contentType: 'multipart/form-data; boundary=' + boundary,
payload: payload,
muteHttpExceptions: true
};
const response = UrlFetchApp.fetch('https://api.mergecsv.io/merge', options);
if (response.getResponseCode() !== 200) {
Logger.log('Merge failed: ' + response.getContentText());
return;
}
const mergedBlob = response.getBlob().setName('merged_' + Utilities.formatDate(new Date(), Session.getScriptTimeZone(), 'yyyyMMdd') + '.csv');
const mergedFile = DriveApp.getFolderById(folderId).createFile(mergedBlob);
MailApp.sendEmail({
to: recipients.join(','),
subject: 'Daily Merged CSV – ' + mergedFile.getName(),
body: 'The merged report is attached.',
attachments: [mergedBlob]
});
Logger.log('Merged CSV sent to recipients.');
}
The script does the heavy lifting in under a minute, even when you feed it ten files each about 2 MB. The merge service does the actual concatenation and keeps the header row only once.
Test with realistic data
Create three sample CSVs:
date,region,sales
2024-09-30,North,120
2024-09-30,South,95date,region,sales
2024-09-30,East,77
2024-09-30,West,110
date,region,sales
2024-09-30,Central,50
Drop them into DailyReports. After the script runs, you’ll receive a single file with five rows plus the header. Check that the header appears only once. If you need extra logic (for example, to drop duplicate rows), adjust the merge endpoint or add a quick filter in the script.
Staying within free limits
Free tiers usually have three constraints:
- A daily request quota (often around 100 requests).
- A per‑request file‑size ceiling (commonly 100 MB).
- A short retention period for generated files.
Because the script runs once per day and stores the merged result in Drive, you stay comfortably within those limits and keep a permanent copy of every report.
Optional: Slack notification instead of email
If your team uses Slack, replace the MailApp.sendEmail block with a simple webhook call:
const slackWebhook = 'https://hooks.slack.com/services/XXXXX/XXXXX/XXXXX';
UrlFetchApp.fetch(slackWebhook, {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify({
text: 'Daily merged CSV is ready.',
attachments: [{title: mergedFile.getName(), url: mergedFile.getUrl()}]
})
});
This tiny change sends a real‑time alert directly to the #reports channel.
Bonus: Error handling and logging
For production use you’ll want more robust diagnostics. Wrap the fetch call in a try…catch block, write any exception to a dedicated Google Sheet, and optionally send a failure notification to Slack. Adding timestamps to each log entry makes it easy to spot intermittent network glitches or API‑side throttling.
try {
const response = UrlFetchApp.fetch('https://api.mergecsv.io/merge', options);
if (response.getResponseCode() !== 200) throw new Error('Merge failed: ' + response.getContentText());
// …rest of the success flow…
} catch (e) {
Logger.log('Error at ' + new Date() + ': ' + e.message);
// optional Slack alert for failures
}
Scaling beyond the free tier
If your organization eventually outgrows the free limits—say you need to process dozens of large files each hour—you can still keep the same architecture. Simply upgrade the merge service to a paid plan, increase the Apps Script trigger frequency, or move the payload to a cloud function (AWS Lambda, Google Cloud Functions) that can handle higher throughput. The core idea—pull, merge, store, notify—remains unchanged.
Wrap‑up
Building a free CSV automation tool doesn’t require a paid subscription or a dedicated server. By chaining a lightweight merge service with a built‑in scheduler, you get a reliable pipeline that runs while you sleep. Start with the steps above, experiment with your own data volume, and you’ll see the daily grind shrink dramatically.