Introduction: Why I Built This System
For 9 years since joining the company, I've worked as an engineer in the AD/ADAS field. While I accumulated expertise, I felt it was a career risk that my work wasn't visible outside the company and had zero recognition in the global market.
Expertise might as well not exist if it isn't visible.
Then I realized: Nothing will change unless I put myself out there.
However, I faced the following challenges:
- Lack of time: With a full-time job, I couldn't dedicate 10 hours per week to blogging
- Difficulty maintaining: Manual posting is cumbersome and leads to quick abandonment
- Global reach: Japanese-only content has limitations; English content is also necessary
In this article, I'll introduce the bilingual automated blog posting system I built that costs only $10.18 per year to operate.
What This System Can Achieve
Key Features
Write article (Obsidian) → One button → Distribute worldwide
Specifically:
- Write in Japanese → Auto-generate English version via AI translation
- Automatic SEO optimization
- Auto-publish to custom domain blog
- Auto-generate LinkedIn posts
- Prepare for distribution to Medium, Dev.to, etc.
- Automatic Google Analytics tracking
Time required: Within 5 minutes (excluding article writing)
Annual cost: $10.18 (domain fee only)
Challenges Solved
Before (Pre-System Build)
3 hours to publish one article:
- Writing in Obsidian: 2 hours
- Manual HTML conversion: 20 minutes
- Image optimization: 15 minutes
- SEO configuration: 15 minutes
- GitHub push: 10 minutes
- Deploy verification: 10 minutes
- LinkedIn post creation: 30 minutes
- English translation: 1 hour (outsourced or self-translated)
Total: 4-5 hours
→ Impossible to publish 2 articles per week
→ Gave up
After (Post-System Build)
1 hour to publish one article:
- Writing in Obsidian: 50 minutes
- Run automation script: 5 minutes → AI translation → SEO optimization → Image optimization → Automatic GitHub push → Automatic Cloudflare deployment → Auto-generate LinkedIn post
- Final check: 5 minutes
Total: 1 hour
→ Possible to publish 2 articles per week
→ Sustainable
System Architecture
Overall System Diagram
graph TD subgraph Writing["Writing Environment (Obsidian)"] A[Write Articles in Markdown] --> B[Core Vault] B --> C[Blog Vault] end subgraph Automation["Automation Layer (Python + AI)"] C --> D[AI Translation<br/>Claude API] D --> E[SEO Optimization<br/>Auto Description Generation] E --> F[Quality Check<br/>AI Analysis] F --> G[Hugo Static Site Generation] end subgraph Deploy["Deployment & Delivery"] G --> H[GitHub Repository] H --> I[Cloudflare Pages<br/>Auto Build] I --> J[Custom Domain Blog<br/>CDN Delivery] end subgraph SNS["Social Media Distribution"] G --> K[LinkedIn Post Generation] K --> L[LinkedIn API Posting] G --> M[Medium/Dev.to<br/>Distribution Prep] end subgraph Analytics["Analytics"] J --> N[Google Analytics GA4] end J --> O((Readers)) L --> O M --> O style A fill:#DCE7FF,stroke:#333 style D fill:#FFE6CC,stroke:#333 style E fill:#FFE6CC,stroke:#333 style F fill:#FFE6CC,stroke:#333 style I fill:#ADD8E6,stroke:#333 style J fill:#90EE90,stroke:#333 style O fill:#FFB6C1,stroke:#333 Technology Stack
| Category | Technology | Role | Cost |
|---|---|---|---|
| Writing | Obsidian | Markdown article creation, knowledge production core | Free |
| SSG | Hugo | Static site generation (Markdown→HTML) | Free |
| AI | Claude API | Translation, quality check, SEO optimization | $5-10/month |
| Hosting | Cloudflare Pages | Auto deployment & CDN delivery | Free |
| Version Control | GitHub | Source control & CI/CD | Free |
| Domain | NameCheap | Custom domain | $10.18/year ✅ |
| DNS | Cloudflare | DNS management & email forwarding | Free |
| SNS API | LinkedIn API | Auto posting | Free |
| Analytics | Google Analytics | Access tracking | Free |
Total Annual Cost: $10.18 + API usage $60-120 = $70.18-130.18 (approximately ¥10,000)
Core Implementation: 5 Stages
Stage 1: Draft
Purpose: Review and modify articles locally
draft.bat # Or include English translation simultaneously draft_translate.bat Process:
- Retrieve articles from Obsidian (Core Vault)
- Automatically convert to Hugo format
- Save with
draft: true(private) - Auto-launch Hugo server
- Open
http://localhost:1313in browser
At this stage:
- No GitHub push
- Multiple revisions and previews possible
- Completely local process
AI Translation Feature:
# translate_article.py (excerpt) def translate_with_claude(japanese_text): """Translate Japanese to English using Claude API""" prompt = f""" Please translate the following technical article to English: - Use appropriate technical terms - Natural, readable English - Preserve Markdown formatting {japanese_text} """ # Call Claude API response = call_claude_api(prompt) return response Stage 2: Quality Check
Purpose: Perform AI-based article quality analysis
check.bat Check Items:
- Detection of omitted subjects (Japanese-specific issue)
- Detection of logical gaps
- Abstract-to-concrete correspondence
- Detection of ambiguous expressions
- Accuracy of technical terms
- SEO improvement suggestions
Output Example:
# Quality Report ## Subject Omission (3 places) - Line 45: "Built the system" → Who did? Suggestion: "I built the system" ## Logic Gaps (2 locations) - Line 78-82: Gap between Step 2 and Step 3 Suggestion: Add intermediate steps ## Ambiguous Expressions (5 locations) - Line 92: "quite fast" → what are the specific numbers? Suggestion: "3 times faster (7h → 2h)" ## Overall Rating: 85/100 Can improve to: 90/100 Stage 3: Pre-Publish Optimization
Purpose: Perform SEO optimization and Description auto-generation
# Automatically executed when publish.bat runs Execution Details:
1. Description Auto-generation (Claude API)
def generate_description(article_text): """Generate SEO-optimized summary automatically""" prompt = f""" Please generate an SEO-optimized summary from the following article. Requirements: - 120-160 characters - Naturally include keywords - Capture reader interest - Convey article core message {article_text} """ description = call_claude_api(prompt) return description 2. Automated SEO Check
seo_checks = { 'title_length': Within 60 characters?, 'h1_exists': Has H1 tag?, 'description': Between 120-160 characters?, 'images': Has alt attributes?, 'word_count': Minimum 1,500 words?, 'tags': Has 3-5 tags?, 'internal_links': Has internal links? } 3. H1 Handling (Important)
Issue: Hugo theme outputs title as H1 → Duplicates with H1 in Markdown → Bad for SEO Solution: 1. Comment out H1 in Markdown 2. Hide with CSS 3. Keep in HTML (for SEO) Stage 4: Publish
Purpose: Actually publish the article
publish.bat Execution Flow:
def publish_workflow(): # 1. Generate description description = generate_description(article) # 2. SEO automatic check seo_result = check_seo(article) if not seo_result.passed: print("SEO issues found:", seo_result.issues) if not confirm("Publish anyway?"): return # 3. Convert to Hugo format (draft: false) convert_to_hugo(article, draft=False) # 4. Save Japanese and English versions save_bilingual_articles(article_ja, article_en) # 5. Automatic Git push git_push_with_message(f"Publish: {article.title}") # 6. Generate LinkedIn posts generate_linkedin_posts(article) print("✅ Publishing complete!") print(f"Japanese: https://takuyaniioka.com/ja/posts/{slug}/") print(f"English: https://takuyaniioka.com/posts/{slug}/") Post-publish Auto-deployment:
GitHub Push ↓ (Webhook) Cloudflare Pages Detection ↓ Hugo Auto-build (about 30 seconds) ↓ CDN Distribution ↓ Blog Published Stage 5: Social Media (LinkedIn)
Purpose: Automatically generate LinkedIn posts from articles
linkedin_post.bat This system can automatically generate LinkedIn posts from articles. We plan to modify the design in the future to allow manual editing and posting as needed.
Stage 6: Analytics
Google Analytics GA4 Integration:
# BlogVault/config.toml [params] googleAnalytics = "G-XXXXXXXXXX" Tracking Data:
- Real-time access
- Traffic sources (LinkedIn, Medium, Google etc.)
- Popular article rankings
- Device and region statistics
- Time on site and bounce rate
Design Philosophy: Why This Architecture?
1. Obsidian-Centric Approach
Reasons:
- Second Brain: Core of my intellectual productivity
- Unified Management: Articles and notes, all managed in Obsidian
- Prevent Thought Fragmentation: Information is not scattered
Structure:
Obsidian/ ├── Core Vault/ # Private & intellectual production │ ├── Daily Notes/ │ ├── Projects/ │ └── Articles/ # Article drafts │ └── Blog Vault/ # Public & blog-specific ├── content/ ├── static/ └── config.toml Reasons for Separation:
- Core Vault is private (personal notes & confidential information)
- Blog Vault is public (pushed to GitHub)
- Maintains clear boundaries
2. AI Utilization Philosophy
AI is "Augmentation" not "Replacement"
[Wrong Usage] Let AI write everything → Zero originality → Zero value [Correct Usage] Human: Write core insights & experiences AI: Automate translation, SEO, quality checks → Humans focus on intellectual production → AI handles repetitive tasks Concrete Examples:
- ✅ AI Translation: Think deeply in Japanese, AI translates to English
- ✅ SEO Optimization: AI auto-generates descriptions
- ✅ Quality Check: AI provides objective review
- ❌ Article Writing: Written by humans (AI assists only)
3. Staged Workflow
Why Split into 5 Stages:
Reason 1: Safety
- Gradual verification instead of immediate publication
- Detect and fix issues at each stage
Reason 2: Flexibility
- Can pause at any point
- Can resume from any stage
Reason 3: Debuggability
- Clear identification of where problems occur
- Logs provide immediate clarity
Implementation Details: Core Features
Feature 1: Article Format Conversion
Challenge:
- Obsidian format (EvolutionVault)
- Hugo format (BlogVault)
- Different formats
Solution:
def convert_evolution_to_hugo_format(source_file, draft_mode=True): """EvolutionVault format → Hugo format""" # 1. Parse YAML frontmatter with open(source_file, 'r', encoding='utf-8') as f: content = f.read() # Separate frontmatter and body if content.startswith('---'): parts = content.split('---', 2) frontmatter = parts[1] body = parts[2] if len(parts) > 2 else "" # 2. Convert for Hugo hugo_frontmatter = convert_frontmatter(frontmatter) hugo_frontmatter['draft'] = draft_mode # 3. Save output_path = get_hugo_path(source_file) save_hugo_file(output_path, hugo_frontmatter, body) Feature 2: Automated SEO Optimization
Challenge:
- Manual description writing is time-consuming
- Easy to miss SEO checks
Solution:
def optimize_seo(article): """Automated SEO optimization""" # 1. Auto-generate description (Claude API) description = generate_description_with_ai(article.content) article.description = description # 2. SEO checklist checks = [ check_title_length(article.title), check_description_length(article.description), check_h1_tag(article.content), check_image_alt_tags(article.content), check_word_count(article.content), check_tags(article.tags), check_internal_links(article.content) ] # 3. Warning if issues found issues = [c for c in checks if not c.passed] if issues: print("⚠️ SEO issues:") for issue in issues: print(f" - {issue.message}") return article Feature 3: Bilingual Support
Challenge:
- Managing Japanese and English separately is complex
- Separate URLs needed
Solution:
Utilizing Hugo's multilingual features: Japanese: https://takuyaniioka.com/ja/posts/article-slug/ English: https://takuyaniioka.com/posts/article-slug/ Automatic switching: - Detects browser language settings - Japanese browser → /ja/ - English browser → / Implementation:
# config.toml [languages] [languages.en] languageName = "English" weight = 1 contentDir = "content" [languages.ja] languageName = "日本語" weight = 2 contentDir = "content" [params] defaultContentLanguage = "en" defaultContentLanguageInSubdir = false Results: What This System Delivered
Quantitative Results
| Metric | Before | After | Improvement |
|---|---|---|---|
| Writing Efficiency | 5 hours/article | 1 hour/article | 5x faster |
| Weekly Posts | 0-1 posts | 2 posts | 2x+ |
| Annual Articles | 10-20 (including dropouts) | 60+ (achievable target) | 3-6x |
| Cost | Outsourced translation $50-100/article | $10.18/year + API $10/month | 95% reduction |
How to Build This System
Construction Steps (Overview)
Step 1: Environment Setup (1 hour)
- Install Obsidian
- Install Hugo
- Install Git
- Install Python
- Create GitHub account
- Create Cloudflare account
Step 2: Domain Acquisition (15 minutes)
- Get custom domain from NameCheap ($10.18/year)
- Configure DNS in Cloudflare
- Set up email forwarding (optional)
Step 3: Hugo Setup (30 minutes)
- Create Hugo site
- Select theme (Hugo Clarity recommended)
- Configure config.toml
- Set up bilingual settings
Step 4: Cloudflare Pages Setup (15 minutes)
- Create GitHub repository
- Link to Cloudflare Pages
- Configure build settings (Hugo)
- Set up custom domain
Step 5: Automation Script Setup (1 hour)
- Install Python dependencies
- Deploy automation scripts
- Create .bat files
- Configure Claude API
- Run tests
Step 6: First Post Publication (30 minutes)
- Write article in Obsidian
- Run draft.bat
- Check preview
- Run publish.bat
- Complete publication
Total time required: About 4 hours
Summary: The Essence of This System
- Time reduction: 5 hours → 1 hour
- Cost reduction: 95% reduction
- Multilingual support: Japanese-English automatic
- Social media deployment: Automated
Resources
Reference Links
GitHub Repository
While it's not currently public, I'm open to considering making it public upon request. The content is expected to include the following structure:
- Automation scripts
- Setup guide
- Troubleshooting
- FAQ
Top comments (0)