reason-machines/trending-skills1 file

Geoflow Content Automation

GEOFlow open-source GEO/SEO content production system with AI generation, review workflow, and publishing pipeline built on PHP and PostgreSQL.

Specification
Skill ID
reason-machines/trending-skills/geoflow-content-automation
Publisher
reason-machines
Repository
trending-skills
Installs
0
Files
1
Synced
Sep 23, 2026
How to use it

Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.

reason-machines/trending-skills/geoflow-content-automationInstalls these files
  • SKILL.md

What this skill tells the agent

GEOFlow Content Automation

Skill by ara.so — Daily 2026 Skills collection.

GEOFlow is an open-source PHP/PostgreSQL system for automated GEO/SEO content production. It chains model configuration, material management, task scheduling, draft review, and front-end publishing into a single pipeline. It supports any OpenAI-compatible API, runs on Docker Compose, and exposes both a REST API and a CLI.


Installation

Docker (Recommended)

git clone https://github.com/yaojingang/GEOFlow.git
cd GEOFlow
cp .env.example .env
# Edit .env — set APP_SECRET_KEY, SITE_URL, and DB credentials
vi .env

# Start web + postgres + scheduler + worker
docker compose --profile scheduler up -d --build

# Front-end
open http://localhost:18080
# Admin panel
open http://localhost:18080/geo_admin/

Local PHP Server

git clone https://github.com/yaojingang/GEOFlow.git
cd GEOFlow

export DB_DRIVER=pgsql
export DB_HOST=127.0.0.1
export DB_PORT=5432
export DB_NAME=geo_system
export DB_USER=geo_user
export DB_PASSWORD=geo_password
export APP_SECRET_KEY=$(openssl rand -hex 32)
export SITE_URL=http://localhost:8080

php -S localhost:8080 router.php
open http://localhost:8080/geo_admin/

Requirements: PHP 7.4+, extensions pdo_pgsql and curl, PostgreSQL instance.


Environment Variables

# .env (copy from .env.example)

HOST_PORT=18080
SITE_URL=http://localhost:18080
APP_SECRET_KEY=$APP_SECRET_KEY          # 32+ char random string — never hardcode
CRON_INTERVAL=60                         # Scheduler poll interval in seconds
TZ=Asia/Shanghai

# Database
DB_DRIVER=pgsql
DB_HOST=postgres
DB_PORT=5432
DB_NAME=geo_system
DB_USER=geo_user
DB_PASSWORD=$DB_PASSWORD                 # Set via environment, not hardcoded

Generate a secure key:

openssl rand -hex 32
# or
php -r "echo bin2hex(random_bytes(32));"

Default Credentials

After first boot, log in at /geo_admin/ with:

  • Username: admin
  • Password: admin888

Change both immediately and rotate APP_SECRET_KEY before any public deployment.


Docker Services

ServicePurposeProfile
webFront-end + admin HTTPalways
postgresPostgreSQL databasealways
schedulerScans tasks, writes job queuescheduler
workerCalls AI API, generates contentscheduler
# Web only (no generation)
docker compose up -d

# Full stack
docker compose --profile scheduler up -d

# Logs
docker compose logs -f worker
docker compose logs -f scheduler

# Restart a single service
docker compose restart worker

# Stop everything
docker compose --profile scheduler down

Content Generation Pipeline

Admin: configure model + prompts + materials
  ↓
Create Task (title library, model, prompt, image library, publish rules)
  ↓
Scheduler (bin/cron.php) → writes to job_queue table
  ↓
Worker (bin/worker.php) → calls AI API → generates article body
  ↓
Optional: insert images, build SEO meta
  ↓
Article enters draft → review → publish states
  ↓
Front-end renders article + SEO/OG tags

Admin Workflow

1. Add an AI Model

Navigate to AI配置中心 → AI模型管理 and fill in:

  • API Base URL (e.g. https://api.openai.com/v1)
  • Model ID (e.g. gpt-4o)
  • API Key (stored encrypted; reference $AI_API_KEY in your env)

2. Create Materials

  • 标题库 — Title pool the task draws from
  • 图片库 — Image pool for article illustrations
  • 知识库 — Reference knowledge injected into prompts
  • 提示词模板 — Prompt templates with placeholders

3. Create a Task

Navigate to 任务管理 → 新建任务:

Title Library  → selects article titles
Model          → which AI model to call
Prompt         → which prompt template
Image Library  → optional illustration set
Publish Mode   → draft | auto-publish
Schedule       → immediate | cron-based

4. Monitor Execution

  • 任务管理 — Task status, retry controls
  • 文章管理 — Draft/review/published states
  • 审核中心 — Review queue for human approval

CLI (bin/geoflow)

The CLI is the programmatic interface used by automation scripts and the companion skill `yaojingang/yao-geo-skills`.

# List available commands
php bin/geoflow help

# Check task status
php bin/geoflow task:status --task-id=<id>

# Create a task
php bin/geoflow task:create \
  --title-library=<id> \
  --model=<id> \
  --prompt=<id> \
  --publish-mode=draft

# Upload an article draft
php bin/geoflow article:create \
  --title="Article Title" \
  --body="<markdown content>" \
  --status=draft

# Review and publish an article
php bin/geoflow article:review --article-id=<id> --action=approve
php bin/geoflow article:publish --article-id=<id>

# Run scheduler manually (one cycle)
php bin/cron.php

# Run worker manually (processes one job then exits)
php bin/worker.php --once

REST API (/api/v1)

All endpoints require Bearer token authentication.

Generate an API Token

php bin/api/create_token.php --name="my-integration"
# Outputs token — store in $GEOFLOW_API_TOKEN

Common Endpoints

BASE=http://localhost:18080/api/v1
TOKEN=$GEOFLOW_API_TOKEN

# List tasks
curl -H "Authorization: Bearer $TOKEN" "$BASE/tasks"

# Get task detail
curl -H "Authorization: Bearer $TOKEN" "$BASE/tasks/<id>"

# Create task
curl -X POST \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title_library_id": 1,
    "model_id": 2,
    "prompt_id": 3,
    "publish_mode": "draft"
  }' \
  "$BASE/tasks"

# List articles
curl -H "Authorization: Bearer $TOKEN" "$BASE/articles"

# Publish article
curl -X POST \
  -H "Authorization: Bearer $TOKEN" \
  "$BASE/articles/<id>/publish"

# Check job queue
curl -H "Authorization: Bearer $TOKEN" "$BASE/jobs?status=pending"

PHP Code Examples

Connect to the Database (using GEOFlow's own layer)

<?php
// includes/db_support.php provides the connection helper
require_once __DIR__ . '/includes/db_support.php';

$pdo = get_db_connection(); // Returns a PDO instance

// Always use prepared statements
$stmt = $pdo->prepare("SELECT * FROM articles WHERE status = :status ORDER BY created_at DESC LIMIT 10");
$stmt->execute([':status' => 'published']);
$articles = $stmt->fetchAll(PDO::FETCH_ASSOC);

Call the Article Service

<?php
require_once __DIR__ . '/includes/article_service.php';

// Create a draft
$articleId = create_article([
    'title'       => 'My Article Title',
    'body'        => '## Introduction\n\nContent here...',
    'status'      => 'draft',
    'task_id'     => 42,
    'seo_title'   => 'My Article Title | Site Name',
    'seo_desc'    => 'Short description for search engines.',
]);

// Approve and publish
approve_article($articleId);
publish_article($articleId);

Trigger the AI Engine Directly

<?php
require_once __DIR__ . '/includes/ai_engine.php';

// Execute a single task job (task_id, job_id)
$result = run_task_job(taskId: 5, jobId: 101);

if ($result['success']) {
    echo "Article created: " . $result['article_id'];
} else {
    echo "Error: " . $result['error'];
}

Queue a Job Manually

<?php
require_once __DIR__ . '/includes/job_queue_service.php';

// Claim next available job (used by worker)
$job = claim_next_job();

if ($job) {
    try {
        // ... process the job ...
        complete_job($job['id']);
    } catch (Exception $e) {
        fail_job($job['id'], $e->getMessage());
        // Eligible jobs will be retried by scheduler
    }
}

// Manually enqueue a task
enqueue_task_jobs(taskId: 5);

Custom Prompt Template in PHP

<?php
// Prompt templates support placeholder substitution
$template = "You are an SEO writer. Write a 600-word article about: {{title}}\n\nBackground knowledge:\n{{knowledge}}";

$prompt = str_replace(
    ['{{title}}', '{{knowledge}}'],

Use this skill in a project

Open any RiverX project, search the Skills panel for reason-machines/trending-skills/geoflow-content-automation, and install it in one click.

Use this skill