with one click
instagram-boost
// Analisa a conta @app.ladoalado, seleciona os melhores posts, e executa o impulsionamento via Marketing API (se token tiver ads_management) ou via automação Chrome no Instagram web como fallback.
// Analisa a conta @app.ladoalado, seleciona os melhores posts, e executa o impulsionamento via Marketing API (se token tiver ads_management) ou via automação Chrome no Instagram web como fallback.
[HINT] Download the complete skill directory including SKILL.md and all related files
| name | instagram-boost |
| version | 2.0.0 |
| description | Analisa a conta @app.ladoalado, seleciona os melhores posts, e executa o impulsionamento via Marketing API (se token tiver ads_management) ou via automação Chrome no Instagram web como fallback. |
Plano + execução de tráfego pago para o Instagram do Lado a Lado. Tenta via Marketing API primeiro; se o token não tiver permissão, executa via Chrome (Instagram web). Nunca manda dinheiro sem confirmação explícita do usuário.
/instagram-boost [mês] [--budget <R$>] [--post <número>] [--dry-run]
Exemplos:
/instagram-boost maio 2026 — análise completa + executa os 3 boosts/instagram-boost junho --budget 200/instagram-boost maio --post 1 — executa só o boost do post 1/instagram-boost maio --dry-run — gera plano mas não executa nadaCONFIG=$(cat ~/.claude/instagram-planner-config.json 2>/dev/null || echo '{}')
IG_ID=$(echo "$CONFIG" | python3 -c "import sys,json; print(json.load(sys.stdin).get('ig_user_id','17841434375697785'))")
TOKEN=$(echo "$CONFIG" | python3 -c "import sys,json; print(json.load(sys.stdin).get('meta_access_token_cached',''))")
PAGE_ID=$(echo "$CONFIG" | python3 -c "import sys,json; print(json.load(sys.stdin).get('page_id',''))")
curl -s "https://graph.facebook.com/v21.0/debug_token?input_token=$TOKEN&access_token=$TOKEN" | python3 -c "
import sys, json
d = json.load(sys.stdin)
scopes = d.get('data', {}).get('scopes', [])
has_ads = 'ads_management' in scopes
has_ads_read = 'ads_read' in scopes
print(f'ads_management={has_ads}')
print(f'ads_read={has_ads_read}')
print(f'scopes={scopes}')
"
Decisão com base nas permissões:
ads_management=True e ads_read=True → usar Marketing API (passo 4)Aviso quando token sem permissão de ads:
⚠️ Token atual não tem permissão `ads_management`.
Para usar a Marketing API (mais confiável, sem interação manual):
1. Acesse: https://developers.facebook.com/tools/explorer/
2. No topo, selecione o App "Lado a Lado" (ID 1283164293145569)
3. Em "Permissions", adicione: ads_management, ads_read, pages_manage_ads
4. Clique "Generate Access Token" e autorize
5. Copie o token e rode:
python3 -c "
import json, os
cfg = json.load(open(os.path.expanduser('~/.claude/instagram-planner-config.json')))
cfg['meta_access_token_cached'] = 'COLE_O_TOKEN_AQUI'
json.dump(cfg, open(os.path.expanduser('~/.claude/instagram-planner-config.json'), 'w'), indent=2)
print('Token salvo.')
"
6. Rode /instagram-boost novamente
Continuando com automação via Chrome (requer Chrome aberto e logado em @app.ladoalado)...
Continuar para o passo 3 (não bloquear — Chrome é o fallback).
Métricas da conta (últimos 28 dias):
SINCE=$(date -v-28d +%s 2>/dev/null || date -d '28 days ago' +%s)
UNTIL=$(date +%s)
curl -s "https://graph.facebook.com/v21.0/$IG_ID?fields=id,username,followers_count,follows_count,media_count&access_token=$TOKEN"
curl -s "https://graph.facebook.com/v21.0/$IG_ID/insights?metric=reach,follower_count&period=day&since=$SINCE&until=$UNTIL&access_token=$TOKEN"
curl -s "https://graph.facebook.com/v21.0/$IG_ID/insights?metric=profile_views,website_clicks&metric_type=total_value&period=day&since=$SINCE&until=$UNTIL&access_token=$TOKEN"
Buscar posts e rankear por engajamento:
curl -s "https://graph.facebook.com/v21.0/$IG_ID/media?fields=id,caption,media_type,timestamp,like_count,comments_count,permalink&limit=20&access_token=$TOKEN" | python3 -c "
import sys, json, datetime
d = json.load(sys.stdin)
agora = datetime.datetime.utcnow()
posts = []
for p in d.get('data', []):
ts = datetime.datetime.strptime(p['timestamp'][:19], '%Y-%m-%dT%H:%M:%S')
dias = (agora - ts).days
score = p.get('like_count',0) + p.get('comments_count',0)*3
elegivel = p.get('media_type') in ('CAROUSEL_ALBUM','IMAGE','VIDEO') and score >= 3 and dias <= 60
posts.append({**p, 'dias': dias, 'score': score, 'elegivel': elegivel})
posts.sort(key=lambda x: x['score'], reverse=True)
for i, p in enumerate(posts[:10], 1):
flag = '✓' if p['elegivel'] else '✗'
cap = (p.get('caption','') or '')[:80].replace(chr(10),' ')
print(f'{flag} {i}. score={p[\"score\"]} [{p[\"media_type\"]}] {p[\"dias\"]}d | {p[\"permalink\"]}')
print(f' \"{cap}\"')
"
Selecionar os 3 melhores posts elegíveis. Se --post N especificado, usar só aquele.
Budget default: R$ 150 (se não especificado)
budget_total = <valor do --budget ou 150>
posts_selecionados = [post1, post2, post3] # ordenados por score
# Distribuição: 50% / 30% / 20%
pesos = [0.50, 0.30, 0.20]
for post, peso in zip(posts_selecionados, pesos):
post['budget'] = round(budget_total * peso, 2)
post['dias'] = round((budget_total * peso) / (budget_total / 30))
post['diario'] = round(post['budget'] / post['dias'], 2)
Projeção de resultados:
| Seguidores atuais | CPM estimado | Reach por R$ 150 | Novos seguidores |
|---|---|---|---|
| < 100 | R$ 8–12 | 12.500–18.750 | 15–45 |
| 100–500 | R$ 6–9 | 16.700–25.000 | 25–70 |
| > 500 | R$ 5–7 | 21.400–30.000 | 40–100 |
Salvar plano em ~/.claude/instagram-boost-<mês>.md com:
Antes de qualquer ação que gaste dinheiro, exibir:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
PLANO DE BOOST — @app.ladoalado — [mês]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Conta: 26 seguidores | Reach 28d: 1.957 | Cliques App Store: 25
Budget total: R$ 150,00
Método: [Marketing API / Chrome via Instagram web]
Post 1 — R$ 75,00 (dias 1–10, R$ 7,50/dia)
[CAROUSEL] score=17 — "Mãe de primeira viagem, salva esse post..."
https://www.instagram.com/p/DXMzrEGD9BZ/
Post 2 — R$ 45,00 (dias 11–19, R$ 5,00/dia)
[CAROUSEL] score=11 — "Você está amamentando às 3h da manhã..."
https://www.instagram.com/p/...
Post 3 — R$ 30,00 (dias 20–28, R$ 3,33/dia)
[CAROUSEL] score=8 — "Simples assim..."
https://www.instagram.com/p/...
Segmentação: Mulheres + Homens 22–38 anos, Brasil
Interesses: bebê, maternidade, puerpério, amamentação, recém-nascido
Projeção: ~12.500–18.750 impressões | 15–45 novos seguidores
Confirmar e executar? (s/n — ou "só post 1" para executar parcialmente)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Aguardar confirmação. Não executar sem aprovação explícita.
Se --dry-run especificado: parar aqui, não perguntar.
Só executar se token tiver ads_management + ads_read E usuário confirmou.
curl -s "https://graph.facebook.com/v21.0/me/adaccounts?fields=id,name,account_status&access_token=$TOKEN" | python3 -c "
import sys, json
d = json.load(sys.stdin)
accounts = d.get('data', [])
for a in accounts:
print(f'ID: {a[\"id\"]} | Nome: {a[\"name\"]} | Status: {a[\"account_status\"]}')
"
Status 1 = ativo. Salvar ad_account_id (formato act_XXXXXXXXX) no config:
import json, os
cfg = json.load(open(os.path.expanduser("~/.claude/instagram-planner-config.json")))
cfg["ad_account_id"] = "act_XXXXXXXXX"
json.dump(cfg, open(os.path.expanduser("~/.claude/instagram-planner-config.json"), "w"), indent=2)
Se nenhuma conta retornar: avisar usuário e redirecionar para Chrome (passo 7).
Para cada post selecionado, criar uma campanha separada:
AD_ACCOUNT_ID="act_XXXXXXXXX"
curl -s -X POST "https://graph.facebook.com/v21.0/$AD_ACCOUNT_ID/campaigns" \
-d "name=Boost+@app.ladoalado+[Post N]+[mês]" \
-d "objective=POST_ENGAGEMENT" \
-d "status=PAUSED" \
-d "special_ad_categories=[]" \
-d "access_token=$TOKEN"
Salvar campaign_id retornado.
A conta de anúncios está configurada em America/Los_Angeles (GMT-7), mas as campanhas são para o Brasil (GMT-3). A API aceita timestamps em qualquer offset — sempre converter as datas brasileiras explicitamente para evitar que o Meta interprete os horários no fuso errado:
from datetime import datetime, timezone, timedelta
# Fuso do Brasil (GMT-3) — usado para definir início/fim em horário local BR
TZ_BR = timezone(timedelta(hours=-3))
def br_date_to_api(date_str, hour=0):
"""Converte 'YYYY-MM-DD' + hora BR para timestamp ISO com offset -03:00."""
dt = datetime(int(date_str[:4]), int(date_str[5:7]), int(date_str[8:10]),
hour, 0, 0, tzinfo=TZ_BR)
return dt.strftime("%Y-%m-%dT%H:%M:%S-03:00")
# Exemplos:
# Início hoje às 08h BR → "2026-05-06T08:00:00-03:00"
# Fim em 10 dias às 23h59 BR → "2026-05-16T23:59:00-03:00"
start_time = br_date_to_api(data_inicio_br, hour=8)
end_time = br_date_to_api(data_fim_br, hour=23)
⚠️ Regra crítica de status: O ad set deve ser criado com status=ACTIVE. Se criado como PAUSED, não entregará mesmo quando o start_time agendado chegar — o Meta não ativa automaticamente adsets pausados. Campanhas com start_time futuro aguardam a data automaticamente quando o adset está ACTIVE.
Targeting — duas estratégias (escolher por post):
Opção A — Manual (maior controle, recomendado para posts de produto):
TARGETING=$(python3 -c "
import json
t = {
'geo_locations': {'countries': ['BR'], 'location_types': ['home', 'recent']},
'age_min': 22,
'age_max': 45,
'user_age_unknown': True,
'flexible_spec': [{
'interests': [
{'id': '6002991239659', 'name': 'Maternidade (crianças e paternidade)'},
{'id': '6003323844497', 'name': 'Bebê (crianças e paternidade)'},
{'id': '6003345696474', 'name': 'Criança (crianças e paternidade)'},
{'id': '6003413469735', 'name': 'Gestação'}
]
}],
'targeting_automation': {'advantage_audience': 0}
}
print(json.dumps(t))
")
Opção B — Advantage+ ML (maior alcance, recomendado para posts emocionais/de identificação):
TARGETING=$(python3 -c "
import json
t = {
'geo_locations': {'countries': ['BR'], 'location_types': ['home', 'recent']},
'age_min': 22,
'flexible_spec': [{
'interests': [
{'id': '6002991239659', 'name': 'Maternidade (crianças e paternidade)'},
{'id': '6003323844497', 'name': 'Bebê (crianças e paternidade)'},
{'id': '6003345696474', 'name': 'Criança (crianças e paternidade)'},
{'id': '6003413469735', 'name': 'Gestação'}
]
}],
'targeting_automation': {'advantage_audience': 1}
}
print(json.dumps(t))
# Nota: com Advantage+, age_max não pode ser inferior a 65 — omitir para deixar o ML decidir
")
curl -s -X POST "https://graph.facebook.com/v21.0/$AD_ACCOUNT_ID/adsets" \
-d "name=AdSet+Post+N+[mês]" \
-d "campaign_id=$CAMPAIGN_ID" \
-d "daily_budget=$(python3 -c "print(int(<orçamento_diário> * 100))")" \
-d "billing_event=IMPRESSIONS" \
-d "optimization_goal=REACH" \
-d "bid_strategy=LOWEST_COST_WITHOUT_CAP" \
-d "start_time=<start_time gerado por br_date_to_api>" \
-d "end_time=<end_time gerado por br_date_to_api>" \
-d "targeting=$TARGETING" \
-d "instagram_actor_id=$IG_ID" \
-d "status=ACTIVE" \
-d "access_token=$TOKEN"
Salvar adset_id.
# Extrair shortcode da permalink
SHORTCODE=$(echo "$PERMALINK" | python3 -c "import sys,re; print(re.search(r'instagram\.com/(?:p|reel)/([^/]+)/', sys.stdin.read()).group(1))")
curl -s -X POST "https://graph.facebook.com/v21.0/$AD_ACCOUNT_ID/adcreatives" \
-d "name=Creative+Post+N+[mês]" \
-d "instagram_actor_id=$IG_ID" \
-d "source_instagram_media_id=$POST_ID" \
-d "access_token=$TOKEN"
Salvar creative_id.
curl -s -X POST "https://graph.facebook.com/v21.0/$AD_ACCOUNT_ID/ads" \
-d "name=Ad+Post+N+[mês]" \
-d "adset_id=$ADSET_ID" \
-d "creative={\"creative_id\": \"$CREATIVE_ID\"}" \
-d "status=ACTIVE" \
-d "access_token=$TOKEN"
Verificar resposta: se id retornar → boost ativo. Se erro → registrar e tentar Chrome.
curl -s -X POST "https://graph.facebook.com/v21.0/$CAMPAIGN_ID" \
-d "status=ACTIVE" \
-d "access_token=$TOKEN"
Usar quando: token sem ads_management, sem ad account, ou API falhou.
Pré-requisitos:
@app.ladoaladoPara cada post selecionado, executar o AppleScript abaixo:
import subprocess, os
def boost_post_via_chrome(permalink, budget_diario, dias, objetivo="PROFILE_VISITS"):
"""
Navega até o post no Instagram web, clica em Impulsionar e preenche o formulário.
Retorna: 'ok' | 'sem_boost_button' | 'erro'
"""
# Extrair shortcode e garantir URL /p/
import re
match = re.search(r'instagram\.com/(?:p|reel)/([^/]+)/', permalink)
shortcode = match.group(1)
post_url = f"https://www.instagram.com/p/{shortcode}/"
script = f"""
tell application "Google Chrome"
set URL of active tab of front window to "{post_url}"
end tell
delay 4
-- Verificar se o botão Impulsionar existe (só aparece para o dono da conta)
tell application "Google Chrome"
set boost_btn to execute active tab of front window javascript "
var btns = Array.from(document.querySelectorAll('button, [role=button]'));
var boost = btns.find(function(b) {{
return b.innerText && (b.innerText.includes('Turbinar') || b.innerText.includes('Impulsionar') || b.innerText.includes('Boost'));
}});
boost ? 'found' : 'not_found';
"
if boost_btn is not "found" then return "sem_boost_button"
-- Clicar no botão (PT-BR: "Turbinar post")
execute active tab of front window javascript "
var btns = Array.from(document.querySelectorAll('button, [role=button]'));
var boost = btns.find(function(b) {{
return b.innerText && (b.innerText.includes('Turbinar') || b.innerText.includes('Impulsionar') || b.innerText.includes('Boost'));
}});
if (boost) boost.click();
"
end tell
delay 3
-- Verificar se abriu o fluxo de impulsionamento
tell application "Google Chrome"
set page_state to execute active tab of front window javascript "
document.body.innerText.includes('Objetivo') ||
document.body.innerText.includes('Orçamento') ||
document.body.innerText.includes('Público') ? 'boost_open' : 'not_open'
"
return page_state
end tell
"""
with open("/tmp/ig_boost_check.applescript", "w") as f:
f.write(script)
result = subprocess.run(
["osascript", "/tmp/ig_boost_check.applescript"],
capture_output=True, text=True, timeout=30
).stdout.strip()
return result
Se boost_open: o fluxo de impulsionamento está aberto no Chrome. Informar ao usuário:
✓ Fluxo de impulsionamento aberto para o post [N].
O Chrome abriu o assistente de boost. Configure:
• Objetivo: "Mais visitas ao perfil"
• Público: Criar público → Interesses → [lista acima]
• Orçamento diário: R$ {budget_diario}
• Duração: {dias} dias (total: R$ {budget_total_post})
Quando terminar de configurar no Chrome, confirme aqui para prosseguir com o próximo post.
Se sem_boost_button: o botão não apareceu (Chrome pode não estar logado, ou post não é da conta). Exibir:
⚠️ Botão "Impulsionar" não encontrado no post {N}.
Verifique se:
1. Chrome está logado como @app.ladoalado (não como conta pessoal)
2. O post URL está correto: {post_url}
3. A conta está conectada a uma Página do Facebook
Alternativa — acessar diretamente no celular:
Instagram → Post → "Impulsionar publicação"
Se not_open: botão clicado mas não abriu o fluxo. Tentar reload e repetir 1x. Se persistir, reportar e oferecer instruções manuais.
Registrar os boosts ativos no tracking:
import json, datetime, os
tracking_path = os.path.expanduser("~/.claude/instagram-boost-tracking.json")
tracking = json.load(open(tracking_path)) if os.path.exists(tracking_path) else {"boosts": []}
tracking["boosts"].append({
"mes": "<mês>",
"budget_total": budget_total,
"metodo": "marketing_api" if usou_api else "chrome",
"posts": [
{
"numero": 1,
"post_id": post1_id,
"permalink": post1_permalink,
"budget": post1_budget,
"inicio": str(datetime.date.today()),
"fim": str(datetime.date.today() + datetime.timedelta(days=post1_dias)),
"campaign_id": campaign_id_se_api,
"status": "ativo"
}
],
"criado_em": datetime.datetime.now().isoformat()
})
json.dump(tracking, open(tracking_path, "w"), indent=2, ensure_ascii=False)
print("Tracking salvo.")
Verificação semanal (rodar a cada 7 dias):
# Seguidores atuais
CONFIG=$(cat ~/.claude/instagram-planner-config.json)
IG_ID=$(echo "$CONFIG" | python3 -c "import sys,json; print(json.load(sys.stdin).get('ig_user_id',''))")
TOKEN=$(echo "$CONFIG" | python3 -c "import sys,json; print(json.load(sys.stdin).get('meta_access_token_cached',''))")
curl -s "https://graph.facebook.com/v21.0/$IG_ID?fields=followers_count&access_token=$TOKEN" | python3 -c "import sys,json; d=json.load(sys.stdin); print(f'Seguidores: {d[\"followers_count\"]}')"
# Se Marketing API: verificar gasto da campanha
# curl -s "https://graph.facebook.com/v21.0/$CAMPAIGN_ID/insights?fields=spend,reach,impressions&access_token=$TOKEN"
Após execução, exibir:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
BOOST ATIVADO — @app.ladoalado — [mês]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Método: [Marketing API / Chrome]
Budget total: R$ 150,00
✓ Post 1 — R$ 75,00 — dias 1–10
https://www.instagram.com/p/DXMzrEGD9BZ/
✓ Post 2 — R$ 45,00 — dias 11–19
https://www.instagram.com/p/...
✓ Post 3 — R$ 30,00 — dias 20–28
https://www.instagram.com/p/...
Projeção: +15 a +45 seguidores | +12.500 impressões
Próxima verificação: [data + 7 dias]
Tracking salvo em: ~/.claude/instagram-boost-tracking.json
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
| Métrica | Conta nova (<100 seg) | Conta em crescimento (100–1k) |
|---|---|---|
| CPM médio | R$ 7–12 | R$ 5–9 |
| CPC médio | R$ 0,80–2,50 | R$ 0,50–1,80 |
| CTR médio | 1,2–2,8% | 1,5–3,5% |
| Custo/seguidor | R$ 3–8 | R$ 2–5 |
| Reach por R$ 100 | 8.000–14.000 | 11.000–20.000 |
1283164293145569)ads_management, ads_read, pages_manage_adspython3 -c "
import json, os
cfg = json.load(open(os.path.expanduser('~/.claude/instagram-planner-config.json')))
cfg['meta_access_token_cached'] = 'COLE_O_TOKEN_AQUI'
json.dump(cfg, open(os.path.expanduser('~/.claude/instagram-planner-config.json'), 'w'), indent=2)
print('Token salvo.')
"
/instagram-boost novamente — desta vez usará a Marketing API./instagram-planner — gerar conteúdo para boostar no próximo mês/instagram-publisher — publicar posts antes de boostar/cfo-dashboard — inclui gasto Meta Ads no relatório mensal/instagram-growth — crescimento orgânico complementar ao pago