Skip to content

Commit 5cc8c83

Browse files
author
Super Dune
committed
Content strategy: 7 humor posts, updated slide generator, 3 posts scheduled, daily humor cronjob
1 parent b4c388e commit 5cc8c83

21 files changed

Lines changed: 174 additions & 55 deletions

social/content_calendar.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Email35 Content Calendar — Week 1
2+
# Voice: dry, sarcastic, adult humor. Think deadpan delivery.
3+
4+
## POST 1 — The Audacity
5+
Hook: "Companies when you buy one thing from them"
6+
Slides:
7+
1. "You buy a $4 spatula from Amazon"
8+
2. "Amazon: noted. Sending you 47 emails about spatulas"
9+
3. "Also spatula accessories. Spatula insurance. Spatula newsletter."
10+
4. "You hit unsubscribe"
11+
5. "Amazon: how about emails about FORKS instead"
12+
6. "With email35 they'd have to pay $0.01 per email. Suddenly they'd learn restraint. email35.com"
13+
14+
## POST 2 — The Recruiter
15+
Hook: "LinkedIn recruiters in your inbox"
16+
Slides:
17+
1. "Hi [FIRST NAME], I came across your profile and—"
18+
2. "I didn't read your profile"
19+
3. "I don't know what you do"
20+
4. "This job pays 40% less than what you make"
21+
5. "But I will email you every 3 days until heat death of the universe"
22+
6. "Unless it costs them $0.01 each time. email35.com"
23+
24+
## POST 3 — The Unsubscribe
25+
Hook: "The 5 stages of unsubscribing"
26+
Slides:
27+
1. "Stage 1: Click unsubscribe"
28+
2. "Stage 2: 'Are you sure?' Yes I'm sure."
29+
3. "Stage 3: 'It may take 10 business days.' TEN?"
30+
4. "Stage 4: Get the same email 3 days later"
31+
5. "Stage 5: Acceptance. This is your life now."
32+
6. "Or just use an email that charges senders. Problem solved. email35.com"
33+
34+
## POST 4 — The Reply All
35+
Hook: "Reply all should require a $0.01 fee"
36+
Slides:
37+
1. "Someone reply-alls 400 people: 'Thanks!'"
38+
2. "Then someone reply-alls: 'Please remove me from this thread'"
39+
3. "Then 12 people reply-all: 'STOP REPLYING ALL'"
40+
4. "Then Karen from accounting shares a cake recipe"
41+
5. "If reply-all cost a penny per recipient that's $4 per message"
42+
6. "Karen would think twice. email35.com"
43+
44+
## POST 5 — The Newsletter Regret
45+
Hook: "Things I subscribed to at 2am that I now regret"
46+
Slides:
47+
1. "A newsletter about productivity. Ironic."
48+
2. "A crypto newsletter. It's all scams."
49+
3. "5 different cooking newsletters. I eat cereal."
50+
4. "A meditation newsletter. The notifications give me anxiety."
51+
5. "A newsletter about having too many newsletters."
52+
6. "My inbox is a graveyard of 2am decisions. email35.com"
53+
54+
## POST 6 — The Math
55+
Hook: "Let's do the math on spam"
56+
Slides:
57+
1. "300 billion emails sent per day"
58+
2. "Half are spam. 150 BILLION."
59+
3. "Cost to send each one: $0.00"
60+
4. "That's the problem."
61+
5. "If spam cost $0.01 per email:"
62+
6. "$1.5 billion PER DAY. Nobody's paying that."
63+
7. "Spam dies instantly. email35.com"
64+
65+
## POST 7 — The Corporate Signature
66+
Hook: "Corporate email signatures be like"
67+
Slides:
68+
1. "Best regards,"
69+
2. "John Smith"
70+
3. "Senior Vice President of Paper Distribution"
71+
4. "Direct: 555-0142 | Mobile: 555-0143 | Fax: 555-0144"
72+
5. "[3 different logos] [legal disclaimer longer than the email] [diversity statement] [carbon footprint notice] [please consider the environment before printing this email]"
73+
6. "The signature has more content than the email. At least with email35 you get paid to read it. email35.com"

social/make_slides.py

Lines changed: 101 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,118 @@
11
from PIL import Image, ImageDraw, ImageFont
2-
import os
2+
import os, sys, json
33

44
W, H = 1080, 1920
55

6-
def make_slide(text, subtitle, filename):
7-
img = Image.new('RGB', (W, H), (10, 10, 15))
8-
draw = ImageDraw.Draw(img)
9-
6+
def get_fonts():
107
try:
11-
title_font = ImageFont.truetype("/System/Library/Fonts/Helvetica.ttc", 72)
12-
sub_font = ImageFont.truetype("/System/Library/Fonts/Helvetica.ttc", 42)
13-
small_font = ImageFont.truetype("/System/Library/Fonts/Helvetica.ttc", 32)
8+
title = ImageFont.truetype("/System/Library/Fonts/Helvetica.ttc", 64)
9+
body = ImageFont.truetype("/System/Library/Fonts/Helvetica.ttc", 52)
10+
small = ImageFont.truetype("/System/Library/Fonts/Helvetica.ttc", 32)
11+
big = ImageFont.truetype("/System/Library/Fonts/Helvetica.ttc", 80)
1412
except:
15-
title_font = ImageFont.load_default()
16-
sub_font = title_font
17-
small_font = title_font
18-
19-
# Logo
20-
draw.ellipse([W//2-60, 120, W//2+60, 240], outline=(85,85,85), width=3)
21-
draw.text((W//2, 180), "35", fill=(0,212,255), font=title_font, anchor="mm")
22-
23-
# Title
24-
y = 400
13+
title = body = small = big = ImageFont.load_default()
14+
return title, body, small, big
15+
16+
def wrap_text(draw, text, font, max_width):
2517
words = text.split()
2618
lines, current = [], ""
2719
for word in words:
2820
test = (current + " " + word).strip()
29-
bbox = draw.textbbox((0,0), test, font=title_font)
30-
if bbox[2] > W - 120:
31-
lines.append(current)
21+
bbox = draw.textbbox((0,0), test, font=font)
22+
if bbox[2] > max_width:
23+
if current: lines.append(current)
3224
current = word
3325
else:
3426
current = test
3527
if current: lines.append(current)
36-
37-
for line in lines:
38-
draw.text((W//2, y), line, fill=(255,255,255), font=title_font, anchor="mt")
39-
y += 90
40-
41-
# Subtitle
42-
y += 50
43-
for sub_line in subtitle.split("\n"):
44-
words = sub_line.split()
45-
sub_lines, current = [], ""
46-
for word in words:
47-
test = (current + " " + word).strip()
48-
bbox = draw.textbbox((0,0), test, font=sub_font)
49-
if bbox[2] > W - 100:
50-
sub_lines.append(current)
51-
current = word
52-
else:
53-
current = test
54-
if current: sub_lines.append(current)
55-
for line in sub_lines:
56-
draw.text((W//2, y), line, fill=(150,150,150), font=sub_font, anchor="mt")
57-
y += 55
58-
59-
draw.text((W//2, H-100), "email35.com", fill=(0,212,255), font=small_font, anchor="mm")
60-
img.save(filename, "JPEG", quality=90)
61-
print(f"Created {filename}")
28+
return lines
6229

63-
base = os.path.expanduser("~/email35/social")
64-
os.makedirs(base, exist_ok=True)
30+
def make_slide(text, subtitle="", slide_num=0, total=0, is_hook=False, is_cta=False):
31+
img = Image.new('RGB', (W, H), (10, 10, 15))
32+
draw = ImageDraw.Draw(img)
33+
title_font, body_font, small_font, big_font = get_fonts()
34+
35+
# Logo at top
36+
draw.ellipse([W//2-40, 60, W//2+40, 140], outline=(85,85,85), width=2)
37+
draw.text((W//2, 100), "35", fill=(0,212,255), font=title_font, anchor="mm")
38+
39+
if is_hook:
40+
# Hook slide — big text, eye-catching
41+
y = 500
42+
lines = wrap_text(draw, text, big_font, W - 120)
43+
for line in lines:
44+
draw.text((W//2, y), line, fill=(255,255,255), font=big_font, anchor="mt")
45+
y += 100
46+
if subtitle:
47+
y += 30
48+
sub_lines = wrap_text(draw, subtitle, body_font, W - 100)
49+
for line in sub_lines:
50+
draw.text((W//2, y), line, fill=(200,200,200), font=body_font, anchor="mt")
51+
y += 65
52+
elif is_cta:
53+
# CTA slide — cyan accent
54+
y = 600
55+
lines = wrap_text(draw, text, title_font, W - 120)
56+
for line in lines:
57+
draw.text((W//2, y), line, fill=(0,212,255), font=title_font, anchor="mt")
58+
y += 80
59+
if subtitle:
60+
y += 20
61+
draw.text((W//2, y), subtitle, fill=(150,150,150), font=small_font, anchor="mt")
62+
else:
63+
# Content slide — body text, centered
64+
y = 600
65+
lines = wrap_text(draw, text, body_font, W - 100)
66+
total_height = len(lines) * 65
67+
y = (H - total_height) // 2
68+
for line in lines:
69+
draw.text((W//2, y), line, fill=(230,230,240), font=body_font, anchor="mt")
70+
y += 65
71+
72+
# Slide counter
73+
if total > 0:
74+
draw.text((W//2, H-80), f"{slide_num}/{total}", fill=(80,80,80), font=small_font, anchor="mm")
6575

66-
make_slide("Your inbox should PAY YOU", "Every email you receive earns you money.\nSpam becomes impossible when sending\ncosts a penny.", f"{base}/slide1.jpg")
67-
make_slide("Spam costs $0 to send. That's the problem.", "Email35 makes senders pay $0.01\nto reach you. Spammers can't\nafford to spam you.", f"{base}/slide2.jpg")
68-
make_slide("How it works", "1. Get yourname@email35.com\n2. Share it everywhere\n3. Senders pay $0.01 to deliver\n4. Paid emails go to your real inbox", f"{base}/slide3.jpg")
69-
make_slide("100 emails = $1/day = $365/year", "For doing nothing.\nYour attention has value.\nStop giving it away for free.", f"{base}/slide4.jpg")
70-
make_slide("Get your free address now", "email35.com\nYour inbox, spam-free.", f"{base}/slide5.jpg")
76+
# CTA on last slide
77+
if is_cta:
78+
draw.text((W//2, H-80), "email35.com", fill=(0,212,255), font=small_font, anchor="mm")
79+
80+
return img
81+
82+
def generate_post(post_data, output_dir):
83+
"""Generate slides from post data dict with 'slides' list."""
84+
os.makedirs(output_dir, exist_ok=True)
85+
slides = post_data.get("slides", [])
86+
total = len(slides)
87+
88+
for i, slide in enumerate(slides):
89+
is_hook = (i == 0)
90+
is_cta = (i == total - 1)
91+
text = slide.get("text", slide) if isinstance(slide, dict) else slide
92+
subtitle = slide.get("subtitle", "") if isinstance(slide, dict) else ""
93+
94+
img = make_slide(text, subtitle, i+1, total, is_hook=is_hook, is_cta=is_cta)
95+
path = os.path.join(output_dir, f"slide{i+1}.jpg")
96+
img.save(path, "JPEG", quality=90)
97+
98+
print(f"Generated {total} slides in {output_dir}")
7199

72-
print("All slides done!")
100+
# Default: generate from command line JSON or use built-in post
101+
if __name__ == "__main__":
102+
if len(sys.argv) > 1 and os.path.exists(sys.argv[1]):
103+
with open(sys.argv[1]) as f:
104+
post = json.load(f)
105+
generate_post(post, os.path.expanduser("~/email35/social"))
106+
else:
107+
# Default post — The Audacity
108+
post = {
109+
"slides": [
110+
"You buy ONE thing from a company",
111+
"Their email team: noted. Deploying 47 emails about spatulas.",
112+
"Also spatula accessories. Spatula insurance. Spatula newsletter.",
113+
"You hit unsubscribe.",
114+
"Them: how about emails about FORKS instead",
115+
{"text": "What if every email cost them $0.01?", "subtitle": "Suddenly they'd learn restraint. email35.com"}
116+
]
117+
}
118+
generate_post(post, os.path.expanduser("~/email35/social"))

social/post2/slide1.jpg

58 KB
Loading

social/post2/slide2.jpg

54.4 KB
Loading

social/post2/slide3.jpg

55.6 KB
Loading

social/post2/slide4.jpg

52 KB
Loading

social/post2/slide5.jpg

62.2 KB
Loading

social/post2/slide6.jpg

70.1 KB
Loading

social/post3/slide1.jpg

58.8 KB
Loading

social/post3/slide2.jpg

46.8 KB
Loading

0 commit comments

Comments
 (0)