What you'll buildA simple, private tracker
A Gmail filter that catches AO3 subscription update emails and forwards them to a Google Apps Script, which parses the story title and chapter number and logs them into a Google Sheet. Your Sheet becomes your WIP tracker — sortable, searchable, and entirely inside your own Google account.
Cost: $0. Accounts needed: just Google. Time: roughly 45–60 minutes if you follow the steps carefully.
Step 01Set up your Google Sheet
Create a new Google Sheet. Name it whatever you like — "WIP Tracker" works fine. Set up the following columns in row 1, in this exact order:
| Column | Header text | What goes here |
|---|---|---|
| A | Story Title | Parsed from the email subject line |
| B | Latest Chapter | Most recent chapter number received |
| C | Last Updated | Date the update email arrived |
| D | Last Chapter Read | Fill this in manually as you read |
| E | AO3 Link | Optional — paste the story URL here manually |
| F | Notes | Whatever you want — status, thoughts, reminders |
Copy the Sheet's ID from the URL — it's the long string between /d/ and /edit. You'll need it in the next step.
Step 02Add the Apps Script
In your Sheet, go to Extensions → Apps Script. Delete any placeholder code in the editor and paste in the following:
// ── CONFIG ──────────────────────────────────────────────
// Paste your Google Sheet ID here (from the URL)
const SHEET_ID = 'YOUR_SHEET_ID_HERE';
// The tab name inside your Sheet
const SHEET_TAB = 'Sheet1';
// How far back to look for emails on first run (adjust if needed)
const DAYS_BACK = 1;
// ────────────────────────────────────────────────────────
function processAO3Updates() {
const sheet = SpreadsheetApp
.openById(SHEET_ID)
.getSheetByName(SHEET_TAB);
// Search Gmail for AO3 update emails from the last DAYS_BACK days
const cutoff = new Date();
cutoff.setDate(cutoff.getDate() - DAYS_BACK);
const dateStr = Utilities.formatDate(cutoff, 'UTC', 'yyyy/MM/dd');
const query = `from:do-not-reply@archiveofourown.org after:${dateStr} subject:"posted Chapter"`;
const threads = GmailApp.search(query);
if (threads.length === 0) return;
// Load existing story titles to avoid duplicate rows
const data = sheet.getDataRange().getValues();
const existing = {};
for (let i = 1; i < data.length; i++) {
if (data[i][0]) existing[data[i][0].toLowerCase()] = i + 1;
}
threads.forEach(thread => {
thread.getMessages().forEach(msg => {
const subject = msg.getSubject();
// Parse chapter number and story title from subject line
// Expected format: [AO3] AuthorName posted Chapter X of Story Title
const match = subject.match(/posted Chapter (\d+) of (.+)$/i);
if (!match) return;
const chapterNum = parseInt(match[1], 10);
const title = match[2].trim();
const date = msg.getDate();
const titleKey = title.toLowerCase();
if (existing[titleKey]) {
// Story already exists — update chapter and date
const row = existing[titleKey];
const currentChapter = sheet.getRange(row, 2).getValue();
if (chapterNum > currentChapter) {
sheet.getRange(row, 2).setValue(chapterNum);
sheet.getRange(row, 3).setValue(date);
}
} else {
// New story — add a row
sheet.appendRow([title, chapterNum, date, 0, '', '']);
existing[titleKey] = sheet.getLastRow();
}
});
});
}
Replace YOUR_SHEET_ID_HERE with the ID you copied in Step 1. If your Sheet tab isn't named "Sheet1", update SHEET_TAB to match.
Click Save (the floppy disk icon), then click Run to test it. The first time you run it, Google will ask you to authorize the script to access Gmail and Sheets — this is normal. Approve it.
DAYS_BACK setting. Set it to 1 for the first run, check your Sheet looks right, then adjust upward if you want to backfill older updates.Step 03Set up the trigger
The script needs to run automatically so your Sheet stays updated without you touching it.
- In the Apps Script editor, click the clock icon in the left sidebar (Triggers)
- Click + Add Trigger in the bottom right
- Set: Function →
processAO3Updates, Event source → Time-driven, Type → Hour timer, Interval → Every hour - Click Save
The script will now check for new AO3 emails once an hour and update your Sheet automatically.
Step 04(Optional) Add a dashboard with AppSheet
If you want something more readable than a raw spreadsheet, Google's AppSheet can turn your Sheet into a simple mobile-friendly app for free. Connect your Sheet, set "Last Updated" as the sort field, and you'll have a sortable reading list you can use from your phone.
This step is genuinely optional — plenty of people find the Sheet itself is enough.
Known issuesThings to watch for
Gmail occasionally routes AO3 update emails to spam. The script only searches your inbox by default. If updates are being missed, create a Gmail filter: From: do-not-reply@archiveofourown.org → Never send to spam. This also stops them cluttering your inbox.
If a story title starts with the word "Chapter" (e.g. "Chapterhouse"), the regex may misparse it. It's an edge case but worth knowing. You'd need to manually correct the Sheet row if it happens.
Many AO3 authors leave their chapter count as "?" while writing. The script handles this fine — it only tracks the chapter number from the update email, not the total planned. You won't know how far a story is from completion unless the author sets a total.
Column D ("Last Chapter Read") is manual — you fill it in yourself. The script only updates "Latest Chapter" and "Last Updated." Sorting by the gap between B and D tells you what needs catching up, but you're the one keeping track of where you left off.
Google occasionally revokes script authorization, especially if you haven't used the Sheet in a while. If updates stop appearing, go back to Apps Script and re-run manually — it'll prompt you to re-authorize if needed.
Why this guide exists
I built WIP Inbox because I was losing track of fics I loved and couldn't find anything that solved it the way I wanted. But I know not everyone wants to sign up for a new product — some people just want to solve the problem themselves, with tools they already control.
This guide is for those people. The Apps Script version above is a genuinely good personal solution: free, private, runs entirely inside your own Google account, and you own all your data outright.
WIP Inbox goes further — automatic progress tracking, a proper reading dashboard, a completed library, and no spreadsheet wrangling. If that sounds useful, it's at wipinbox.com. If this guide is enough for you — great. That's a win too.
This guide is free to share, adapt, and improve. No rights reserved. — Katie
