- 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>
36 lines
1.4 KiB
Python
36 lines
1.4 KiB
Python
import os
|
|
from dotenv import load_dotenv
|
|
|
|
load_dotenv()
|
|
|
|
# Meta Ads
|
|
META_APP_ID = os.environ["META_APP_ID"]
|
|
META_APP_SECRET = os.environ["META_APP_SECRET"]
|
|
META_ACCESS_TOKEN = os.environ["META_ACCESS_TOKEN"]
|
|
META_AD_ACCOUNT_ID = os.environ["META_AD_ACCOUNT_ID"] # format: act_XXXXXXXX
|
|
|
|
# Anthropic
|
|
ANTHROPIC_API_KEY = os.environ["ANTHROPIC_API_KEY"]
|
|
|
|
# Baserow
|
|
BASEROW_URL = os.environ["BASEROW_URL"] # e.g. https://baserow.yourdomain.com
|
|
BASEROW_TOKEN = os.environ["BASEROW_TOKEN"]
|
|
BASEROW_TABLE_CAMPAIGNS = int(os.environ["BASEROW_TABLE_CAMPAIGNS"])
|
|
BASEROW_TABLE_ACTIONS = int(os.environ["BASEROW_TABLE_ACTIONS"])
|
|
BASEROW_TABLE_CREATIVES = int(os.environ["BASEROW_TABLE_CREATIVES"])
|
|
BASEROW_TABLE_LOGS = int(os.environ["BASEROW_TABLE_LOGS"])
|
|
BASEROW_TABLE_VERTICALS = int(os.environ["BASEROW_TABLE_VERTICALS"])
|
|
BASEROW_TABLE_SNAPSHOTS = int(os.environ["BASEROW_TABLE_SNAPSHOTS"])
|
|
|
|
# Slack (Bot Token, not webhook)
|
|
SLACK_BOT_TOKEN = os.environ["SLACK_BOT_TOKEN"] # xoxb-...
|
|
SLACK_SIGNING_SECRET = os.environ["SLACK_SIGNING_SECRET"] # for verifying callbacks
|
|
SLACK_CHANNEL_ID = os.environ["SLACK_CHANNEL_ID"] # e.g. C0XXXXXXX
|
|
|
|
# Campaign filter
|
|
META_CAMPAIGN_PREFIX = os.environ.get("META_CAMPAIGN_PREFIX", "VIVIFUL")
|
|
META_TARGET_CPL = float(os.environ.get("META_TARGET_CPL", "0")) # 0 = use per-campaign Baserow value
|
|
|
|
# Operation
|
|
DRY_RUN = os.environ.get("DRY_RUN", "true").lower() != "false"
|