--- name: agency-publisher description: "Pubblicare o programmare post social e video YouTube tramite webhook, solo dopo approvazione. Usare quando: (1) content approvato ready per publish, (2) scheduling programmato, (3) aggiornare publish log. Output: Content pubblicato, publish log aggiornato, status file aggiornato." --- # Agency Publisher — Publish Gate-Based Pubblica (o programma) content su social e YouTube solo dopo approvazione esplicita. ## Quando Usare - **Social publish:** Post approvato ready - **YouTube publish:** Video metadata approvati - **Scheduling:** Programmare publish futuro - **Publish log:** Aggiornare storico --- ## Input | Input | Tipo | Validazione | |-------|------|-------------| | `project_path` | string | Percorso progetto (cartella di lavoro) | | `content_files` | array | File content da pubblicare | | `platform` | string | "social" / "youtube" | | `publish_mode` | string | "immediate" / "scheduled" | | `scheduled_for` | string | Data/ora (se scheduled) | --- ## Processo ### Fase 1: Verify Approval Gate **Obiettivo:** Verificare che content sia approvato. **Azioni:** 1. Per ogni content file, verifica: - Frontmatter contiene `status: approved` - Frontmatter contiene `APPROVED: YES` - `PUBLISH_APPROVED.md` del cliente contiene `YES` 2. Se gate NON superato: - **STOP:** Non procedere - Notifica utente che approvazione manca 3. Se gate superato: - Procedi a Fase 2 **Checklist:** - [ ] `status: approved` nel frontmatter - [ ] `APPROVED: YES` presente - [ ] `PUBLISH_APPROVED.md` = YES - [ ] QA compilato e passato --- ### Fase 2: Preparazione Payload **Obiettivo:** Creare payload per webhook. **Azioni:** 1. Estrai dati dal content file: - **Social:** Text, asset_path, platform, hashtags - **YouTube:** Title, description, thumbnail_path, tags, scheduled_for 2. Genera `idempotency_key`: - Formula: `{project}_{platform}_{post_id}_{version}` - Esempio: `demo_co_linkedin_post_001_v1` 3. Compila payload: **Payload Social:** ```json { "client": "{client_name}", "platform": "linkedin", "text": "{post_copy}", "asset_paths": ["{path_to_image}"], "scheduled_for": "2026-03-10T09:00:00Z", "idempotency_key": "demo_co_linkedin_post_001_v1", "hashtags": ["#tag1", "#tag2"], "metadata": { "post_id": "post_001", "pillar": "Education" } } ``` **Payload YouTube:** ```json { "client": "{client_name}", "platform": "youtube", "title": "{video_title}", "description": "{video_description}", "thumbnail_path": "{path_to_thumbnail}", "tags": ["tag1", "tag2"], "scheduled_for": "2026-03-10T14:00:00Z", "idempotency_key": "demo_co_youtube_ep_001_v1", "metadata": { "episode": "001", "duration": "8:45" } } ``` --- ### Fase 3: Webhook Call **Obiettivo:** Inviare payload a webhook di publish. **Azioni:** 1. Identifica webhook endpoint (configurato in `core/skills/publish_webhook.md` o variabile ambiente) 2. Invia POST request con: - Headers: `Content-Type: application/json` - Body: Payload JSON 3. Gestisci risposta: - **Success (2xx):** Estrai `remote_id` e `post_url` - **Error (4xx/5xx):** Logga errore, non aggiornare status 4. Implementa retry logic (opzionale): - Max 3 retry - Backoff: 30s, 60s, 120s --- ### Fase 4: Update Content File **Obiettivo:** Aggiornare file con status publish. **Azioni:** 1. Aggiungi/aggiorna frontmatter: ```yaml status: published # o "scheduled" published_at: 2026-03-09T10:30:00Z post_url: https://linkedin.com/post/xyz123 remote_id: xyz123 ``` 2. Se scheduled: ```yaml status: scheduled scheduled_for: 2026-03-10T09:00:00Z ``` --- ### Fase 5: Update Publish Log **Obiettivo:** Tracciare publish in log centrale. **Azioni:** 1. Apri/crea `{project}/ops/publish_log.md` 2. Aggiungi entry: **Template:** ```markdown # Publish Log — {Client} | Data | Platform | Content ID | Status | URL | Note | |------|----------|------------|--------|-----|------| | 2026-03-09 | LinkedIn | post_001 | Published | https://... | Engagement buono | | 2026-03-09 | YouTube | ep_001 | Scheduled | - | Publish: 2026-03-10 14:00 | ``` 3. Per YouTube, aggiorna anche `{project}/youtube/published_log.md` 4. Per Social, aggiorna `{project}/social/published_log.md` --- ## Output | File | Formato | Descrizione | |------|---------|-------------| | `{project}/ops/publish_log.md` | Markdown | Log centrale publish | | `{project}/social/published_log.md` | Markdown | Log social (opzionale) | | `{project}/youtube/published_log.md` | Markdown | Log YouTube (opzionale) | | Content files aggiornati | Markdown | `status: published/scheduled` | --- ## References - [publishing_gates.md](../agency-shared-references/references/publishing_gates.md) — Gate rules - [quality_bar.md](../agency-shared-references/references/quality_bar.md) — Standard qualità --- ## Note **Edge Cases:** - **Webhook fallisce:** Logga errore, riprova (max 3 volte), notifica utente - **Doppio publish:** Idempotency_key previene duplicati - **Scheduled in futuro:** Imposta status "scheduled", aggiorna log **Limitazioni:** - Richiede webhook integration configurata (n8n/Make/Zapier) - YouTube video upload (file) out-of-scope senza integrazione specifica - Alcuni platform hanno rate limits (rispettare) **Sicurezza:** - Mai pubblicare senza `APPROVED: YES` - Idempotency_key previene publish accidentali multipli - Logga tutto per audit trail --- _Skill generata da framework-translator_