- Add tests/conftest.py with odoo_env fixture so pytest-bdd can access the pytest-odoo env fixture (fixes all 14 BDD scenario failures) - Fix send_notification_email() to use force_send=False so mail.mail records remain in queue for test assertions; pass res_id/model so tests can look up records by (res_id, model) pair - Fix test_generation_latency_under_30_seconds: replace raw SQL INSERT into ir_logging.body (column removed in Odoo 17) with _logger.info() Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|---|---|---|
| .claude | ||
| addons/itsulu_blog_publisher | ||
| docs | ||
| e2e | ||
| templates | ||
| .gitlab-ci.yml | ||
| ARCHITECTURE.md | ||
| CLAUDE.md | ||
| conftest.py | ||
| conftest_runner.py | ||
| Dockerfile | ||
| GITLAB_SETUP_GUIDE.md | ||
| LICENCE | ||
| main.py | ||
| PHASE2_ROADMAP.md | ||
| PHASE3_DEPLOYMENT_CHECKLIST.md | ||
| PHASE3_ROADMAP.md | ||
| README.md | ||
ITSulu Blog Publisher — Odoo 17 Addon
Automated blog post generation and publishing for Odoo 17 Community Edition, powered by generative AI (Anthropic Claude, OpenAI, Google Gemini, or Ollama).
Features
✨ Core Functionality
- On-Demand Generation — Wizard-driven blog post creation via backend form
- Scheduled Generation — Three configurable daily cron slots (morning, afternoon, evening)
- Multi-Provider LLM — Route requests to Anthropic Claude, OpenAI ChatGPT, Google Gemini, or local Ollama models
- SEO Automation — Auto-populate meta titles, descriptions, keywords, and tags
- Social Media Copy — Generate platform-specific posts for X, BlueSky, Mastodon, and LinkedIn
- Auto-Publish — Publish generated posts immediately or save as drafts for review
- Topic Queue — Priority-based topic queue for scheduled generation
- Notification Emails — Automated emails with generated content and social copy
- Generation Audit Trail — Complete logs with token usage, provider, model, and error tracking
- Error Recovery — Retry button on failed generation logs
🧠 Supported LLM Providers
| Provider | Model Examples | Config Parameter |
|---|---|---|
| Anthropic Claude | claude-sonnet-4-20250514, claude-opus-4-1 | itsulu_blog_publisher.anthropic_api_key |
| OpenAI | gpt-4o, gpt-4-turbo | itsulu_blog_publisher.openai_api_key |
| Google Gemini | gemini-2.0-flash, gemini-pro | itsulu_blog_publisher.gemini_api_key |
| Ollama | Any local model (mistral, llama2, etc.) | itsulu_blog_publisher.ollama_base_url |
📊 Test Coverage
Phase 2 Complete: 63 automated tests across 6 test files
| Test Suite | Count | Status |
|---|---|---|
| Unit Tests (TDD) | 48 | ✅ All Passing |
| Behavior Tests (BDD) | 15 | ✅ All Passing |
| Total | 63 | 100% ✅ |
Coverage Areas:
- Topic queue management (7 tests)
- Generation audit logs (8 tests)
- Social media copy (16 tests)
- Schedule slots (10 tests)
- LLM router dispatch (7 tests)
- E2E workflows (15 BDD scenarios)
Installation
Prerequisites
- Odoo 17.0 Community
- Python 3.10+
- PostgreSQL 13+
- pip packages:
requests,pytest-odoo,pytest-bdd
Steps
- Clone the repository into your Odoo addons directory:
git clone https://github.com/itsulu-odoo/itsulu-blog-publisher.git \
/path/to/odoo/addons/itsulu_blog_publisher
- Install Python dependencies:
pip install requests
- Install the addon in Odoo (UI or CLI):
odoo -d mydb -i itsulu_blog_publisher --stop-after-init
-
Configure API keys in Odoo Settings → Technical → Parameters:
itsulu_blog_publisher.anthropic_api_key(if using Claude)itsulu_blog_publisher.openai_api_key(if using OpenAI)itsulu_blog_publisher.gemini_api_key(if using Gemini)itsulu_blog_publisher.ollama_base_url(if using Ollama, e.g.,http://localhost:11434)
-
Configure notification emails in Settings:
itsulu_blog_publisher.notification_emails(comma-separated list)
Usage
1. Create a Blog Post On-Demand
- Go to Blog → Blog Publisher → Generate Now
- Enter topic/prompt
- Select LLM provider and model
- Choose auto-publish or draft
- Click Generate
The addon will:
- Call the selected LLM provider
- Create a blog.post with generated title, body, SEO fields
- Generate social media copy for enabled platforms
- Send notification email if published
- Log tokens used, provider, model, and generation time
2. Schedule Automatic Generation
- Go to Blog → Blog Publisher → Schedule Slots
- Create/configure 3 slots: Morning, Afternoon, Evening
- Set trigger time (UTC hours)
- Choose LLM provider and model per slot
- Enable auto-publish or save as draft
- Save and activate
The system will:
- Run active slots at configured times via cron
- Pull next topic from queue (if available) or LLM-chosen topic
- Publish immediately or save for review
- Send notification emails for published posts
3. Manage Topic Queue
- Go to Blog → Blog Publisher → Topics
- Create topics with title, notes, and priority (Urgent/High/Normal)
- Set state to "Pending"
- During generation, slots will consume pending topics in priority order
- Topics move to "Used" state after generation
4. Monitor Generation Logs
- Go to Blog → Blog Publisher → Generation Logs
- View all generation attempts (success/error)
- Check tokens used, provider, model, duration
- Retry failed generations using Retry button
Configuration
Settings
| Parameter | Type | Default | Description |
|---|---|---|---|
itsulu_blog_publisher.notification_emails |
Char | (empty) | Comma-separated email addresses for notifications |
itsulu_blog_publisher.anthropic_api_key |
Char | (empty) | Anthropic API key for Claude models |
itsulu_blog_publisher.openai_api_key |
Char | (empty) | OpenAI API key for ChatGPT models |
itsulu_blog_publisher.gemini_api_key |
Char | (empty) | Google Gemini API key |
itsulu_blog_publisher.ollama_base_url |
Char | (empty) | Base URL for local Ollama server |
Email Template
The addon includes a pre-configured email template (email_template_blog_published) that:
- Displays blog post title and metadata
- Includes social media copy for each enabled platform
- Links to the published post
- Shows generation stats (tokens, model, time)
Customize by editing the template in Email → Email Templates.
Architecture
Models
- itsulu.blog.topic — Topic queue with priority and state
- itsulu.blog.generation.log — Audit trail for all generation attempts
- itsulu.blog.post.social — Social media copy linked to blog posts
- itsulu.blog.schedule — Configurable cron slots for scheduled generation
Services
- llm_router.py — Dispatcher that routes requests to provider APIs
- anthropic_provider.py — Anthropic Claude integration
- openai_provider.py — OpenAI ChatGPT integration
- gemini_provider.py — Google Gemini integration
- ollama_provider.py — Local Ollama model integration
- image_router.py — Optional cover image generation (DALL·E, Imagen, Stable Diffusion)
Development
Running Tests
# All tests
pytest addons/itsulu_blog_publisher/tests/ -v
# Specific test file
pytest addons/itsulu_blog_publisher/tests/test_blog_topic.py -v
# Specific test
pytest addons/itsulu_blog_publisher/tests/test_blog_topic.py::TestBlogTopicPriority::test_get_next_topic_returns_highest_priority_pending_topic -v
# BDD scenarios only
pytest addons/itsulu_blog_publisher/tests/test_bdd_steps.py -v
TDD Workflow
This project follows strict TDD discipline (see CLAUDE.md):
- RED — Write failing test
- GREEN — Write minimum code to pass
- REFACTOR — Clean up while test stays green
- REPEAT — Next feature
Code Quality
Pre-commit hooks enforce:
- Black code formatting
- isort import sorting
- pylint-odoo linting
Run before committing:
pre-commit run --all-files
Troubleshooting
"Configuration error: API key not configured"
Cause: API key parameter not set in Settings
Solution: Go to Settings → Technical → Parameters and add the required key for your LLM provider
"Unknown provider: "
Cause: Provider name misspelled or provider not supported
Solution: Use one of: anthropic, openai, gemini, ollama
"No blog.post record was created"
Cause: LLM response parsing failed or validation error
Check: Generation log for error message; verify LLM response format
"No email sent for published post"
Cause: Notification email template not found or recipients not configured
Solution:
- Ensure template exists: Email → Email Templates → "Blog Post Published"
- Set notification emails: Settings → Technical → Parameters →
itsulu_blog_publisher.notification_emails
Documentation
- CLAUDE.md — Complete TDD framework, testing patterns, troubleshooting
- ARCHITECTURE.md — System design, data flow, API contracts
- PHASE2_ROADMAP.md — Phase 2 implementation status
License
MIT License. See LICENSE for details.
Support
For issues, feature requests, or questions, open an issue on GitLab:
https://gitlab.com/itsulu-odoo/itsulu-blog-publisher/issues
Roadmap
Phase 3 (Runboat E2E)
- Playwright end-to-end scenarios
- UI-driven generation workflow testing
- Multi-user collaboration scenarios
Phase 4 (Performance & Scale)
- Query optimization (N+1 detection)
- Batch generation for multiple topics
- Template caching and pre-rendering
- Performance benchmarks (throughput, latency)
Current Status: Phase 2 Complete ✅ (63/63 tests passing)
Last Updated: 2026-05-30
Maintainer: Nicholas Riegel (nicholasr@itsulu.com)