#!/usr/bin/env npx tsx /** * Inject a test HTML email into the mailbox via JMAP * Usage: npx tsx scripts/inject-test-email.ts * * Requires: JMAP_URL, JMAP_USER, JMAP_PASS environment variables * Or create a .env.local file with these values */ import * as fs from 'fs'; import * as path from 'path'; // Load environment variables from .env.local if it exists const envPath = path.join(process.cwd(), '.env.local'); if (fs.existsSync(envPath)) { const envContent = fs.readFileSync(envPath, 'utf-8'); for (const line of envContent.split('\n')) { const match = line.match(/^([^=]+)=(.*)$/); if (match) { process.env[match[1].trim()] = match[2].trim(); } } } const JMAP_URL = process.env.JMAP_URL || process.env.NEXT_PUBLIC_JMAP_URL; const JMAP_USER = process.env.JMAP_USER; const JMAP_PASS = process.env.JMAP_PASS; if (!JMAP_URL || !JMAP_USER || !JMAP_PASS) { console.error('Missing required environment variables: JMAP_URL, JMAP_USER, JMAP_PASS'); console.error('Set them in .env.local or as environment variables'); process.exit(1); } // NYTimes Morning newsletter sample HTML const htmlContent = `The Morning: Wind farms
Plus, a weight loss pill, Planned Parenthood and Sydney Sweeney.
The Morning
December 23, 2025

Good morning. This is a test email to verify HTML rendering width.

Four offshore wind turbines.
Off the coast of Rhode Island. Lucy Lu for The New York Times

Without evidence

President Trump doesn't like wind farms. Never has. He thinks they're ugly. He calls them inefficient and expensive. Years ago, he failed to stop the construction of one that's visible from one of his golf courses in Scotland.

On his first day in office this year, Trump stopped new wind projects on public lands and waters. A judge called that order "arbitrary" and said it violated federal law.

THE LATEST NEWS

China

  • The Pentagon and American A.I. companies share a weakness: They both desperately need China's batteries.
  • The Trump administration banned sales of foreign-made drones, including a popular brand from China.

GAMES

Spelling Bee

Here is today's Spelling Bee. Yesterday's pangrams were clunked and knuckled.

Thanks for spending part of your morning with The Times. - Sam

The Morning Newsletter Logo

Host: Sam Sifton

The New York Times Company. 620 Eighth Avenue New York, NY 10018

`; async function main() { console.log('Connecting to JMAP server...'); // Get session const authHeader = 'Basic ' + Buffer.from(`${JMAP_USER}:${JMAP_PASS}`).toString('base64'); const sessionRes = await fetch(JMAP_URL!, { headers: { 'Authorization': authHeader } }); if (!sessionRes.ok) { throw new Error(`Failed to get session: ${sessionRes.status}`); } const session = await sessionRes.json(); const accountId = Object.keys(session.accounts)[0]; const apiUrl = session.apiUrl; console.log(`Connected as account: ${accountId}`); // Get inbox mailbox const mailboxRes = await fetch(apiUrl, { method: 'POST', headers: { 'Authorization': authHeader, 'Content-Type': 'application/json' }, body: JSON.stringify({ using: ['urn:ietf:params:jmap:core', 'urn:ietf:params:jmap:mail'], methodCalls: [ ['Mailbox/get', { accountId }, '0'] ] }) }); const mailboxData = await mailboxRes.json(); const mailboxes = mailboxData.methodResponses[0][1].list; const inbox = mailboxes.find((mb: { role: string }) => mb.role === 'inbox'); if (!inbox) { throw new Error('No inbox found'); } console.log(`Found inbox: ${inbox.id}`); // Create the test email const emailId = `test-${Date.now()}`; const createRes = await fetch(apiUrl, { method: 'POST', headers: { 'Authorization': authHeader, 'Content-Type': 'application/json' }, body: JSON.stringify({ using: ['urn:ietf:params:jmap:core', 'urn:ietf:params:jmap:mail'], methodCalls: [ ['Email/set', { accountId, create: { [emailId]: { from: [{ name: 'The New York Times', email: 'nytdirect@nytimes.com' }], to: [{ email: JMAP_USER }], subject: 'The Morning: Wind farms (TEST - HTML Width)', receivedAt: new Date().toISOString(), keywords: {}, mailboxIds: { [inbox.id]: true }, bodyValues: { 'html': { value: htmlContent } }, htmlBody: [{ partId: 'html', type: 'text/html' }] } } }, '0'] ] }) }); const result = await createRes.json(); if (result.methodResponses[0][1].created?.[emailId]) { console.log('Test email injected successfully!'); console.log('Email ID:', result.methodResponses[0][1].created[emailId].id); } else { console.error('Failed to create email:', JSON.stringify(result, null, 2)); } } main().catch(console.error);