FeaturesTemplatesShowcaseTownie
AI
BlogDocsPricing
Log inSign up
paulkinlan
paulkinlanpostherous
https://posthero.us - an email powered blogging system
Public
Like
6
postherous
Home
Code
12
backend
3
frontend
1
shared
2
ACTIVITYPUB.md
README.md
SECURITY.md
SETUP.md
H
debug-config.ts
E
email.ts
H
test-activitypub-inbox.ts
H
test-activitypub.ts
H
test-publish.ts
Branches
1
Pull requests
Remixes
4
History
Environment variables
9
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
7/11/2025
Viewing readonly version of main branch: v135
View latest version
README.md

Email Blog Platform

A modern blog platform inspired by Posterous that allows publishing posts via email.

๐Ÿš€ Status: READY TO USE

Your email blog platform is fully functional! Send an email to start publishing.

โœจ Features

  • ๐Ÿ“ง Email-to-Publish: Send an email to publish posts instantly
  • ๐Ÿ”’ Email Security: Allowlist and verification system to prevent unauthorized posts
  • ๐ŸŽจ Multi-format Support: HTML and plain text posts
  • ๐Ÿ“ก RSS Feed: Full RSS 2.0 support for syndication
  • ๐ŸŒ WebSub: Real-time feed updates via WebSub protocol (configured)
  • ๐Ÿ˜ ActivityPub: Full federated social networking with followers, likes, and shares โœ…
  • ๐Ÿฆ‹ AT Protocol: Bluesky integration for cross-platform syndication (configured)
  • ๐Ÿ”— SEO Friendly: Clean URLs with slugified titles
  • ๐Ÿ“ฑ Responsive Design: Mobile-first responsive interface with TailwindCSS
  • โšก Fast: Built on Val Town with SQLite storage and static HTML generation
  • ๐Ÿš€ No JavaScript: Pure HTML/CSS frontend for maximum performance

๐Ÿ—๏ธ Architecture

Backend (/backend/)

  • index.ts - Main Hono server with HTML generation and API routes โœ…
  • database/ - SQLite schema and query functions โœ…
  • services/ - External service integrations โœ…

Email Handler (/email.ts)

  • Email trigger handler with security verification โœ…
  • Allowlist checking and draft post creation โœ…
  • Automated verification email sending โœ…

Static HTML Generation

  • Server-side HTML rendering with TailwindCSS โœ…
  • No client-side JavaScript dependencies โœ…
  • Fast loading and SEO optimized โœ…

๐ŸŽฏ Quick Start

  1. Configure Security: Set ALLOWED_EMAIL_ADDRESSES environment variable (see Security section)
  2. Send Email: Send email from an allowed address to your Val Town email address
  3. Verify Email: Click the verification link sent to your email
  4. View Blog: Visit your backend HTTP val URL after verification
  5. RSS Feed: Access /rss for syndication
  6. Individual Posts: Visit /post/[slug]

๐Ÿ”ง Configuration

See SETUP.md for detailed setup instructions and ACTIVITYPUB.md for ActivityPub federation details.

Environment Variables (Required for Security)

  • ALLOWED_EMAIL_ADDRESSES - Comma-separated list of allowed email addresses (required)
  • BASE_URL - Your blog's base URL for verification links (optional, auto-detected)

Environment Variables (Optional)

  • WEBSUB_HUB_URL - WebSub hub URL
  • ACTIVITYPUB_DOMAIN - Domain for ActivityPub federation
  • ATPROTO_HANDLE - AT Protocol handle
  • ATPROTO_PASSWORD - AT Protocol app password

๐Ÿ“Š API Endpoints

  • GET / - Main blog interface
  • GET /post/:slug - Individual post page
  • GET /rss - RSS 2.0 feed
  • GET /api/posts - JSON API for posts
  • GET /api/posts/:slug - JSON API for single post
  • GET /websub - WebSub subscription endpoint
  • GET /.well-known/webfinger - WebFinger discovery for ActivityPub โœ…
  • GET /actor - ActivityPub actor document โœ…
  • GET /outbox - ActivityPub outbox (published activities) โœ…
  • GET /followers - ActivityPub followers collection โœ…
  • GET /following - ActivityPub following collection โœ…
  • POST /inbox - ActivityPub inbox (processes Follow, Like, Announce, Undo) โœ…
  • GET /api/posts/:slug/activities - Get activity counts (likes, shares, replies) โœ…
  • GET /verify-email - Email verification endpoint โœ…
  • GET /health - Health check

๐Ÿ”’ Security Features

Email Allowlist

Only emails from pre-configured addresses can publish posts. Configure via environment variable:

ALLOWED_EMAIL_ADDRESSES=user1@example.com,user2@example.com,admin@myblog.com

Email Verification

To prevent spoofing, all emails go through a verification process:

  1. Email Received: Email is stored as a draft (not published)
  2. Verification Sent: Automated verification email sent to sender
  3. User Clicks Link: Sender clicks verification link in email
  4. Post Published: After verification, post is published and syndicated

Security Benefits

  • Anti-spoofing: Prevents unauthorized users from publishing posts
  • Email confirmation: Ensures the sender actually sent the email
  • Time-limited: Verification links expire after 24 hours
  • Automatic cleanup: Expired drafts are automatically removed

๐Ÿงช Testing

Use /test-publish.ts to create sample posts for testing.

๐Ÿ“ Usage Example

Send an email like this:

To: your-email-val@val.town
From: allowed-user@example.com  (must be in ALLOWED_EMAIL_ADDRESSES)
Subject: My Amazing Blog Post
Body: <h2>Hello World!</h2><p>This post was published via email!</p>

The process will be:

  1. Email received and stored as draft
  2. Verification email sent to allowed-user@example.com
  3. User clicks verification link
  4. Post published with:
    • Title: "My Amazing Blog Post"
    • Slug: "my-amazing-blog-post"
    • Content: Rendered HTML
    • Author: Extracted from email address

๐ŸŽจ Customization

  • Edit HTML generation functions in /backend/index.ts
  • Modify CSS styles in the getCustomCSS() function
  • Update branding in HTML templates
  • Configure federation services via environment variables

๐Ÿ”„ Syndication

Posts are automatically syndicated to:

  • RSS feed (always enabled)
  • WebSub subscribers (if configured)
  • ActivityPub followers (with full interaction support) โœ…
  • AT Protocol/Bluesky (if configured)

ActivityPub Federation

Your blog is now fully federated with ActivityPub! Users can:

  • Follow your blog from Mastodon, Pleroma, and other ActivityPub platforms
  • Like your blog posts (shows โค๏ธ count on posts)
  • Share/Boost your posts (shows ๐Ÿ”„ count on posts)
  • Reply to your posts (shows ๐Ÿ’ฌ count on posts)

Discovery formats:

  • WebFinger: @blog@your-domain.com
  • Direct actor URL: https://your-domain.com/actor

Real-time interaction tracking:

  • All likes, shares, and replies are stored and displayed on individual post pages
  • Follower count is maintained and accurate
  • Full ActivityPub inbox processing for Follow/Unfollow activities

Example: If your blog is at myblog.web.val.run, users can follow @blog@myblog.web.val.run from their Mastodon client and interact with your posts!


Ready to blog via email? Send your first post now! ๐Ÿ“งโœจ

Go to top
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Product
FeaturesPricing
Developers
DocsStatusAPI ExamplesNPM Package Examples
Explore
ShowcaseTemplatesNewest ValsTrending ValsNewsletter
Company
AboutBlogCareersBrandhi@val.town
Terms of usePrivacy policyAbuse contact
ยฉ 2025 Val Town, Inc.