Email snooze functionality has become essential for managing inbox overwhelm. Chrome extensions that implement email snooze scheduling allow users to temporarily remove emails from their inbox and have them reappear at a specified future time. This guide covers the implementation patterns, APIs, and practical considerations for developers building this type of extension.
How Email Snooze Extensions Work
Chrome extensions for email snooze scheduling typically operate by interacting with email provider APIs. The extension intercepts email messages, stores the snooze metadata on a backend or locally, and then uses scheduled triggers to move or relabel those emails back to the inbox at the designated time.
The core architecture involves three main components:
- Content Script - Runs in the context of the email provider’s web interface, identifying emails and adding snooze UI elements
- Background Service Worker - Handles scheduling logic and API calls
- Storage Layer - Maintains snooze state using chrome.storage or a backend database
Manifest V3 Implementation
Modern Chrome extensions must use Manifest V3, which introduces several changes from V2. Here’s a basic manifest structure for an email snooze extension:
{
"manifest_version": 3,
"name": "Email Snooze Scheduler",
"version": "1.0",
"permissions": [
"storage",
"alarms",
"activeTab",
"scripting"
],
"host_permissions": [
"https://mail.google.com/*",
"https://outlook.office.com/*"
],
"background": {
"service_worker": "background.js"
},
"content_scripts": [{
"matches": [
"https://mail.google.com/*",
"https://outlook.office.com/*"
],
"js": ["content.js"]
}]
}
Core Implementation Patterns
Storing Snooze Data
The chrome.storage API provides persistent storage that works across browser sessions. For email snooze extensions, you’ll need to store the email ID, original label, and scheduled return time.
// content.js - Snooze an email
function snoozeEmail(emailId, snoozeUntil) {
const snoozeEntry = {
emailId: emailId,
originalLabels: ['INBOX'], // Capture current labels
snoozeUntil: snoozeUntil,
provider: 'gmail' // or 'outlook', etc.
};
chrome.storage.local.get(['snoozedEmails'], (result) => {
const snoozedEmails = result.snoozedEmails || [];
snoozedEmails.push(snoozeEntry);
chrome.storage.local.set({ snoozedEmails });
});
// Notify background script to schedule the alarm
chrome.runtime.sendMessage({
action: 'scheduleSnooze',
emailId: emailId,
snoozeUntil: snoozeUntil
});
}
Scheduling with Chrome Alarms
Chrome’s alarms API allows you to schedule future events reliably, even when the extension isn’t actively running:
// background.js
chrome.alarms.onAlarm.addListener((alarm) => {
if (alarm.name.startsWith('snooze-')) {
const emailId = alarm.name.replace('snooze-', '');
processSnoozeReturn(emailId);
}
});
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.action === 'scheduleSnooze') {
const delay = message.snoozeUntil - Date.now();
if (delay > 0) {
chrome.alarms.create(`snooze-${message.emailId}`, {
delayInMinutes: Math.ceil(delay / 60000),
periodInMinutes: null
});
}
}
});
async function processSnoozeReturn(emailId) {
// Retrieve stored email metadata
const result = await chrome.storage.local.get(['snoozedEmails']);
const snoozedEmails = result.snoozedEmails || [];
const entry = snoozedEmails.find(e => e.emailId === emailId);
if (entry) {
// Use provider API to move email back to inbox
await moveEmailToInbox(entry);
// Clean up storage
const updated = snoozedEmails.filter(e => e.emailId !== emailId);
await chrome.storage.local.set({ snoozedEmails: updated });
}
}
Provider API Integration
Gmail API Integration
For Gmail integration, you’ll need to use the Gmail API to modify email labels:
async function moveEmailToInbox(snoozeEntry) {
const { accessToken } = await getAccessToken();
// First, remove the snooze label if you added one
await fetch(
`https://gmail.googleapis.com/gmail/v1/users/me/messages/${snoozeEntry.emailId}/modify`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
removeLabelIds: ['SNOOZE_LABEL_ID'],
addLabelIds: ['INBOX']
})
}
);
}
Outlook API Integration
Microsoft Graph API handles Outlook.com and Office 365:
async function moveOutlookEmailToInbox(snoozeEntry) {
const { accessToken } = await getAccessToken();
// Move message to inbox folder
await fetch(
`https://graph.microsoft.com/v1.0/me/messages/${snoozeEntry.emailId}/move`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
destinationId: 'inbox'
})
}
);
}
User Interface Considerations
The snooze UI typically appears as a dropdown or popup when users hover over or select an email. Common preset options include:
- Later Today - 6 PM or custom time
- Tomorrow Morning - 9 AM next day
- Tomorrow Evening - 6 PM next day
- This Weekend - Saturday 9 AM
- Next Week - Monday 9 AM
- Custom - User-specified date and time
Implement custom time selection using a date-time picker:
function showCustomSnoozeDialog() {
const dialog = document.createElement('div');
dialog.innerHTML = `
<div class="snooze-dialog">
<h3>Schedule Snooze</h3>
<input type="datetime-local" id="snooze-datetime">
<button id="confirm-snooze">Snooze</button>
<button id="cancel-snooze">Cancel</button>
</div>
`;
document.body.appendChild(dialog);
document.getElementById('confirm-snooze').addEventListener('click', () => {
const datetime = document.getElementById('snooze-datetime').value;
const snoozeUntil = new Date(datetime).getTime();
snoozeEmail(currentEmailId, snoozeUntil);
dialog.remove();
});
}
Security and Privacy
Email snooze extensions handle sensitive data, so implement these security practices:
- Minimal Permissions - Request only the scopes needed for email access
- Secure Token Storage - Use chrome.storage.session for access tokens when possible
- Content Security Policy - Restrict script sources in your manifest
- OAuth 2.0 Flow - Never store user passwords directly
{
"oauth2": {
"client_id": "YOUR_CLIENT_ID",
"scopes": [
"https://www.googleapis.com/auth/gmail.modify",
"https://www.googleapis.com/auth/gmail.readonly"
]
}
}
Building a Custom Solution
For developers building their own snooze functionality, start with the fundamental patterns shown here and expand based on your specific requirements. Consider supporting multiple email providers, implementing snooze categories (work, personal, follow-up), and adding notification reminders before emails reappear.
The key is maintaining reliable scheduling even when the browser is closed, which requires combining chrome.alarms with a lightweight backend or leveraging the browser’s built-in scheduling capabilities effectively.
Built by theluckystrike — More at zovo.one