ITSulu Blog Publisher Odoo addon
Find a file
Nicholas Riegel a13f37c2bf
Merge branch 'fix/ci-pipeline-corrections' into 'main'
fix: correct CI pipeline stage ordering and DB auth issues

See merge request itsulu-odoo/itsulu-blog-publisher!1
2026-05-30 07:11:35 +00:00
.claude docs: add Kubernetes test infrastructure documentation 2026-05-29 18:13:32 -04:00
addons/itsulu_blog_publisher fix: resolve remaining 9 BDD failures + production empty-body bug 2026-05-30 03:11:28 -04:00
docs Add comprehensive BDD framework documentation 2026-05-29 12:42:54 -04:00
e2e fix: deploy E2E tests on ITSulu K8s cluster instead of external Runboat 2026-05-30 00:58:46 -04:00
templates Initialized from 'GitLab CI/CD components' project template 2025-03-19 11:40:54 +01:00
.gitlab-ci.yml fix: remove duplicate itsulu_social_id field and fix CI addons path 2026-05-30 02:20:54 -04:00
ARCHITECTURE.md docs: add Kubernetes test infrastructure documentation 2026-05-29 18:13:32 -04:00
CLAUDE.md fix: use _render_field() for template rendering; fix wizard import name 2026-05-30 02:53:57 -04:00
conftest.py fix: use request.getfixturevalue for odoo_env and list API for generate_email 2026-05-30 02:43:27 -04:00
conftest_runner.py fix: auto-install addon via conftest for pytest-odoo 2026-05-29 22:45:54 -04:00
Dockerfile fix: place conftest.py at /mnt/extra-addons/ for pytest discovery 2026-05-30 02:41:19 -04:00
GITLAB_SETUP_GUIDE.md docs: Add GitLab setup guide for Phase 3 E2E testing 2026-05-30 01:15:14 -04:00
LICENCE Initialized from 'GitLab CI/CD components' project template 2025-03-19 11:40:54 +01:00
main.py Claude Sonnet 4.6 2026-05-29 01:40:58 -04:00
PHASE2_ROADMAP.md docs: mark Phase 2 as complete with final status 2026-05-30 00:47:09 -04:00
PHASE3_DEPLOYMENT_CHECKLIST.md docs: update deployment checklist for ITSulu K8s cluster 2026-05-30 00:59:31 -04:00
PHASE3_ROADMAP.md feat: integrate Runboat E2E testing and performance tests into CI/CD pipeline 2026-05-30 00:54:59 -04:00
README.md docs: add comprehensive project README with features and usage guide 2026-05-30 00:46:19 -04:00

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

  1. 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
  1. Install Python dependencies:
pip install requests
  1. Install the addon in Odoo (UI or CLI):
odoo -d mydb -i itsulu_blog_publisher --stop-after-init
  1. 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)
  2. Configure notification emails in Settings:

    • itsulu_blog_publisher.notification_emails (comma-separated list)

Usage

1. Create a Blog Post On-Demand

  1. Go to BlogBlog PublisherGenerate Now
  2. Enter topic/prompt
  3. Select LLM provider and model
  4. Choose auto-publish or draft
  5. 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

  1. Go to BlogBlog PublisherSchedule Slots
  2. Create/configure 3 slots: Morning, Afternoon, Evening
  3. Set trigger time (UTC hours)
  4. Choose LLM provider and model per slot
  5. Enable auto-publish or save as draft
  6. 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

  1. Go to BlogBlog PublisherTopics
  2. Create topics with title, notes, and priority (Urgent/High/Normal)
  3. Set state to "Pending"
  4. During generation, slots will consume pending topics in priority order
  5. Topics move to "Used" state after generation

4. Monitor Generation Logs

  1. Go to BlogBlog PublisherGeneration Logs
  2. View all generation attempts (success/error)
  3. Check tokens used, provider, model, duration
  4. 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 EmailEmail 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):

  1. RED — Write failing test
  2. GREEN — Write minimum code to pass
  3. REFACTOR — Clean up while test stays green
  4. 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:

  1. Ensure template exists: EmailEmail Templates → "Blog Post Published"
  2. Set notification emails: Settings → Technical → Parameters → itsulu_blog_publisher.notification_emails

Documentation

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)