# Motor de Conteudo Borrello - Automacao IG

Sistema de agendamento automatico de posts Instagram via Social Planner do CRM Linkia (GoHighLevel white-label).

Fase 1 = 22/09/2026 a 26/10/2026 (5 semanas, 7 posts/semana = 35 posts IG).

---

## Estrutura de pastas

```
motor_conteudo/
├── biblioteca/                                 # midias reusaveis (symlinks + pastas)
│   ├── fotos_borrello/         -> FOTOS BORRELLO (50 fotos aprovadas)
│   ├── cortes_live_fengshui/   (Max popula)
│   ├── featured_images/        -> featured_images do blog v1
│   └── logos_marca/            (vazia)
├── publicados/                                 # espelho das ig_* postadas com sucesso
├── semana_01_2026-09-22/                       # tema: Feng Shui no Quarto (WP 33387)
│   ├── blog_post.md                            # referencia do artigo
│   ├── email_seg_blog.md                       # copy email seg
│   ├── email_qua_video.md                      # copy email qua
│   ├── yt_qua_longform/                        # video YT longform (Borrello grava)
│   ├── ig_seg/  ig_ter/  ig_qua/  ig_qui/
│   ├── ig_sex/  ig_sab/  ig_dom/
├── semana_02_2026-09-29/                       # Espada-de-sao-jorge (WP 33388)
├── semana_03_2026-10-06/                       # Entrada da Casa (WP 33386)
├── semana_04_2026-10-13/                       # 5 Animais Celestiais (WP 33389)
├── semana_05_2026-10-20/                       # Bagua (WP 33390)
└── cronograma_editorial_fase1_2026-09-22.md    # cronograma detalhado v2.0
```

### Cada ig_* contem 4 arquivos:

| Arquivo | Preenche quem | O que | Regra |
|---------|---------------|-------|-------|
| `copy.md` | Jonathan (copy) | Headline + corpo do post | 1a pessoa Borrello, sem auto-elogio, desejo antes de features |
| `hashtags.txt` | Jonathan | 1 hashtag por linha (max 30) | Linhas iniciadas por `# ` sao comentario, ignoradas |
| `midia/` | Juliana (design) | Arquivos `.jpg/.png/.webp/.mp4` OU `.url.txt` com URL publica | Ver secao "Como popular midia" abaixo |
| `status.json` | script (auto) | Estado do agendamento | Nao editar manualmente exceto pra reagendar |

---

## Como Juliana popula midia/

**Fluxo simples (padrao):** Juliana solta o arquivo local (`.jpg`, `.png`, `.webp`, `.mp4`, `.mov`) direto na pasta `midia/`. O script sobe automaticamente pro **Media Library do Linkia** e usa a URL publica retornada no post. Nao precisa mexer em WordPress, SFTP, Drive nem CDN externo.

```
midia/
├── carrossel_01.jpg
├── carrossel_02.jpg
└── carrossel_03.jpg
```

Ordem alfabetica define a ordem do carrossel. Formatos aceitos: JPG, PNG, WEBP, MP4, MOV.

O script salva um cache em `midia/../.linkia_uploaded.json` (dentro da pasta ig_*) com o hash SHA-256 de cada arquivo, entao se rodar 2x nao reupload da mesma coisa. Se voce trocar o arquivo (mesmo nome, conteudo diferente), o hash muda e o script sobe de novo.

### Opcao alternativa - URL publica ja pronta

Se a midia ja esta hospedada em outro lugar (ex: link do WordPress do Borrello, YouTube thumb, etc), cria `.url.txt` dentro de `midia/`:

```
https://franciscoborrello.com.br/wp-content/uploads/2026/09/quarto.jpg
https://franciscoborrello.com.br/wp-content/uploads/2026/09/quarto-2.jpg
```

Opcionalmente informa MIME apos `|`: `URL|image/jpeg`.

Multiplas URLs = carrossel (ordem = ordem das linhas).

### Formatos aceitos

- **Foto:** JPG, PNG, WEBP (proporcao 1:1 ou 4:5 recomendado, min 1080x1080)
- **Video/reel:** MP4 (9:16, 15-90s, max 100MB - Instagram limits)

---

## Como Jonathan popula copy.md e hashtags.txt

### copy.md

```markdown
# Copy Post IG - Feng Shui no Quarto

- Semana: 1
- Dia: segunda
- Tipo: carousel

## Headline
5 erros no quarto que travam sua energia

## Corpo
(texto real, 1a pessoa Borrello, seguindo brief)

## CTA
Comenta "quarto" que te mando o link do artigo completo.
```

Regras de copy Borrello (feedback_borrello_email_primeira_pessoa + feedback_borrello_sem_autoelogio):
- 1a pessoa (Borrello falando, nao "o Francisco disse")
- Zero "40 anos", "meu metodo", "meus 40 mil alunos"
- Desejo antes de features
- Referenciar tema da semana + gancho pro artigo do blog

O script concatena **corpo + hashtags** no campo `summary` do post (removendo linhas iniciadas por `#` markdown e linhas com `TODO:`).

### hashtags.txt

```
# comentario ignorado
#fengshui
#borrello
#francisco_borrello
```

Uma por linha. Sem `#` no inicio o script adiciona. Linhas `# xxx` (comentario markdown) sao ignoradas.

---

## Ciclo de vida do status.json

```
DRAFT               -> Jonathan/Juliana ainda populando midia/ e copy
                    (published=false, error=null)

AGENDADO/NA_JANELA  -> Script vai processar no proximo cron
                    (published=false, scheduled_at dentro dos proximos ~2h)

PUBLICADO           -> Post foi aceito pelo Linkia, scheduleDate no futuro
                    (published=true, post_id_linkia preenchido)

ERRO                -> Falha na API ou dependencia
                    (published=false, error preenchido, attempts>0)
```

### Reagendar um post ja publicado

1. Deletar o post via API Linkia: `DELETE /social-media-posting/{loc}/posts/{postId}` (ou via UI Social Planner)
2. Editar `status.json`: `published: false`, `post_id_linkia: null`, `error: null`, `attempts: 0`
3. Ajustar `scheduled_at` pra nova data
4. Proximo cron reagenda

### Forcar postagem manual

```bash
python3 /opt/mia/scripts/agendar_posts_ig_borrello.py \
  --force-post /opt/mia/workspace/clientes/borrello/motor_conteudo/semana_01_2026-09-22/ig_seg/status.json
```

Ignora a janela de tempo (posta AGORA no Linkia com o scheduleDate que estiver no status.json).

### Dry-run (nao envia, so imprime)

```bash
python3 /opt/mia/scripts/agendar_posts_ig_borrello.py --dry-run
```

### Pausar tudo

Comentar a linha do crontab (`crontab -e -u mia`). O cron para de rodar mas os posts ja agendados no Linkia continuam ativos (deletar via API se precisar cancelar).

---

## Onde ver o log

```
/opt/mia/logs/agendar_posts_ig_borrello.log       # log principal (rotativo 5MB x 3)
/opt/mia/logs/agendar_posts_ig_borrello_cron.log  # stdout do cron (se ativo)
```

---

## Descobertas tecnicas da API (2026-09-19)

**Social Planner:**
- `POST /social-media-posting/{loc}/posts` cria/agenda mas **nao retorna postId**. Pra capturar o ID o script consulta `POST /posts/list` filtrando por summary + scheduleDate.
- `media[].type` = **MIME type** (`image/jpeg`, `image/png`, `video/mp4`). NAO aceita `photo`, `IMAGE`, `jpg`.
- Post `type` enum: `post | story | reel | short`. Nada de `carousel`. Carrossel vira `type=post` com multiplas midias no array.
- `userId` obrigatorio no payload. Usa o userId do Borrello (`XrUs3k8xopy10mgIslBp`).
- Headers: `Authorization: Bearer <PIT>`, `Version: 2021-07-28`, `User-Agent` de browser (Cloudflare bloqueia Python default).
- Conta IG expira em ~90 dias (`account.expire`, `account.isExpired`). Se expirar, script alerta e nao tenta postar. Renato/Amanda reconecta na UI.

**Media Library (upload direto - 2026-09-19 upgrade):**
- `POST /medias/upload-file` (multipart form-data: `altType=location`, `altId=<loc>`, `file=@<binario>`) sobe o arquivo pro Media Library da sub-account. Retorna `{fileId, url}`.
- URL retornada eh `https://assets.cdn.filesafe.space/<locId>/media/<uuid>.<ext>` - servida pelo Google Cloud Storage via CDN do Linkia, publica (200 sem auth), cache 1 ano.
- Pode ser usada direto em `media[].url` do Social Planner. Fim da dependencia de wp-content, Drive publico ou R2.
- Videos sao transcodificados automaticamente (360p/480p/720p/1080p/1440p) alem de gerar `preview` e `thumbnail` proprios.
- Listar: `GET /medias/files?altType=location&altId=<loc>&type=file&limit=100&sortBy=createdAt&sortOrder=desc` (parametro `type` obrigatorio, nao aceita `type=all` da erro vazio, use `type=file`).
- Deletar: `DELETE /medias/{fileId}?altType=location&altId=<loc>` (nao `/medias/files/{id}` que da 404).

Ver tambem `/home/mia/.claude/projects/-opt-mia/memory/ghl_social_planner_api_ativo.md`.

---

## Contatos / Responsaveis

- **Jonathan (copy)**: `copy.md` + `hashtags.txt` (35 posts pra Fase 1)
- **Juliana (design)**: `midia/` (35 sets - carrosseis, estaticos, reels)
- **Max (video)**: `biblioteca/cortes_live_fengshui/` + `yt_qua_longform/`
- **Amanda (CRM)**: monitora Social Planner, resolve reconexao de conta expirada
- **Paulo (dev)**: script `/opt/mia/scripts/agendar_posts_ig_borrello.py`
- **Rafael (projetos)**: cronograma + escalation de bloqueios

## Rota do cron (DISABLED por padrao)

```
# 0 * * * * /usr/bin/flock -n /tmp/agendar_posts_ig_borrello.lock python3 /opt/mia/scripts/agendar_posts_ig_borrello.py >> /opt/mia/logs/agendar_posts_ig_borrello_cron.log 2>&1
```

Renato/Rafael descomenta quando as pastas estiverem populadas com copies e midias reais e Borrello tiver aprovado o volume.
