José Manuel Gómez 8fb0b69896 Add Baserow persistence, Slack interactive reports, Streamlit dashboard, and full analysis pipeline
- Migrate from Airtable to Baserow: BaserowClient with snapshots, actions, creatives, logs
- Claude agents (Haiku for decisions/units, Sonnet for creatives) with cost_cap_eur vs CPL comparison
- Slack bot with colored action emojis, effect text before approval buttons, 500-char justifications
- Streamlit dashboard with date-range navigation, campaign drill-down (adsets/ads), Histórico tab
- Approval server (FastAPI + ngrok) for Slack button callbacks
- backfill.py for historical snapshot regeneration with Claude re-analysis
- Margin fix: 0-lead campaigns contribute -spend (not 0) to margin
- CTR fix: Meta returns CTR as percentage already, removed *100
- Parameter fix: pass decision parameter to Slack action for correct budget effect display

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 09:30:13 +02:00

50 lines
1.6 KiB
YAML

name: Daily Meta Optimizer
on:
# schedule:
# - cron: '0 5 * * *' # 7:00 AM hora española (CEST/UTC+2) — pausado temporalmente
workflow_dispatch:
jobs:
run:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install dependencies
run: pip install -r requirements.txt
- name: Run optimizer
env:
META_APP_ID: ${{ secrets.META_APP_ID }}
META_APP_SECRET: ${{ secrets.META_APP_SECRET }}
META_ACCESS_TOKEN: ${{ secrets.META_ACCESS_TOKEN }}
META_AD_ACCOUNT_ID: ${{ secrets.META_AD_ACCOUNT_ID }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
BASEROW_URL: ${{ secrets.BASEROW_URL }}
BASEROW_TOKEN: ${{ secrets.BASEROW_TOKEN }}
BASEROW_TABLE_CAMPAIGNS: ${{ secrets.BASEROW_TABLE_CAMPAIGNS }}
BASEROW_TABLE_ACTIONS: ${{ secrets.BASEROW_TABLE_ACTIONS }}
BASEROW_TABLE_CREATIVES: ${{ secrets.BASEROW_TABLE_CREATIVES }}
BASEROW_TABLE_LOGS: ${{ secrets.BASEROW_TABLE_LOGS }}
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
SLACK_SIGNING_SECRET: ${{ secrets.SLACK_SIGNING_SECRET }}
SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }}
DRY_RUN: ${{ vars.DRY_RUN }}
run: python run.py
- name: Upload log
if: always()
uses: actions/upload-artifact@v4
with:
name: meta-optimizer-log-${{ github.run_id }}
path: logs/
retention-days: 30