• Blog
  • Docs
  • Pricing
  • We’re hiring!
Log inSign up
toddpiersall

toddpiersall

DesignEngineerNewsletter

Public
Like
DesignEngineerNewsletter
Home
Code
4
README.md
H
main.ts
newsletter.ts
C
scheduler.ts
Branches
1
Pull requests
Remixes
History
Environment variables
7
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Sign up now
Code
/
README.md
Code
/
README.md
Search
…
README.md

Design Engineer Newsletter

A Val Town-powered newsletter system for curating and sending design engineering news twice a week.

Features

  • 📧 Email Subscription Management: Subscribe/unsubscribe endpoints
  • 🔍 Automated News Search: Uses Tavily API to find latest design engineering content
  • 🤖 AI-Powered Summaries: Hugging Face generates newsletter summaries
  • ⏰ Scheduled Sending: Automatically sends twice weekly (Monday & Thursday at 9 AM UTC)
  • 💾 SQLite Database: Tracks subscribers and newsletter history
  • 📬 Resend Integration: Reliable email delivery

Setup

Required Environment Variables

You need to set these environment variables in your Val Town project:

  1. TAVILY_API_KEY - Get from Tavily

    • Used for searching design engineering news
  2. HUGGING_FACE_API_KEY - Get from Hugging Face

    • Used for generating AI summaries
    • Uses the facebook/bart-large-cnn model
  3. RESEND_API_KEY - Get from Resend

    • Used for sending newsletter emails
  4. ADMIN_API_KEY - Set this to a secure random string

    • Used to authenticate manual newsletter triggers
    • Generate with: openssl rand -hex 32
  5. FROM_EMAIL - Your verified sender email (e.g., newsletter@yourdomain.com)

    • Must be verified in Resend

Optional Environment Variables

  1. TAVILY_SEARCH_QUERY (optional)
    • Default: "design engineering news product design"
    • Customize the search query for finding articles

API Endpoints

GET /

Returns API information and available endpoints.

POST /subscribe

Subscribe to the newsletter.

Request:

{ "email": "user@example.com", "name": "John Doe" }

Response:

{ "message": "Successfully subscribed to Design Engineer Newsletter!", "email": "user@example.com" }

POST /unsubscribe

Unsubscribe from the newsletter.

Request:

{ "email": "user@example.com" }

Response:

{ "message": "Successfully unsubscribed", "email": "user@example.com" }

POST /admin/send

Manually trigger newsletter generation and sending (admin only).

Headers:

X-Admin-Key: your-admin-api-key

Response:

{ "message": "Newsletter sent successfully", "recipientCount": 42, "articlesCount": 10, "status": "success" }

Database Schema

subscribers

  • id - Auto-increment primary key
  • email - Unique email address
  • name - Subscriber name (optional)
  • subscribed_at - Timestamp of subscription
  • active - Boolean flag (1 = subscribed, 0 = unsubscribed)

newsletter_sends

  • id - Auto-increment primary key
  • sent_at - Timestamp of newsletter send
  • recipient_count - Number of recipients
  • articles_count - Number of articles included
  • status - Send status (success/failed)

Schedule

The newsletter automatically sends twice a week:

  • Monday at 9:00 AM UTC
  • Thursday at 9:00 AM UTC

Schedule is configured using cron expression: 0 9 * * 1,4

File Structure

  • main.ts - HTTP API handler with subscribe/unsubscribe endpoints
  • newsletter.ts - Core newsletter generation logic (Tavily, Hugging Face, Resend)
  • scheduler.ts - Interval job for automated twice-weekly sending

Testing

Test Subscribe

curl -X POST https://your-val-url.val.run/subscribe \ -H "Content-Type: application/json" \ -d '{"email":"test@example.com","name":"Test User"}'

Test Manual Send

curl -X POST https://your-val-url.val.run/admin/send \ -H "X-Admin-Key: your-admin-api-key"

Customizing Search Query

You can customize the Tavily search query in two ways:

  1. Set the TAVILY_SEARCH_QUERY environment variable
  2. Pass a custom query when calling the admin endpoint (modify code as needed)

Example queries:

  • "design engineering product design UX UI"
  • "design systems engineering frontend"
  • "interaction design developer experience"

Notes

  • Val Town uses Deno runtime - use npm: imports for packages
  • Free tier has 15-minute minimum for interval jobs
  • Pro tier allows 1-minute minimum intervals
  • Resend batch API supports sending to multiple recipients efficiently

Support

For issues or questions, refer to:

  • Val Town Docs
  • Tavily API Docs
  • Hugging Face API Docs
  • Resend API Docs
FeaturesVersion controlCode intelligenceCLIMCP
Use cases
TeamsAI agentsSlackGTM
DocsShowcaseTemplatesNewestTrendingAPI examplesNPM packages
PricingNewsletterBlogAboutCareers
We’re hiring!
Brandhi@val.townStatus
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Open Source Pledge
Terms of usePrivacy policyAbuse contact
© 2025 Val Town, Inc.