Bom dia, Tulio.
Aqui está o panorama operacional de hoje.
Resumo Executivo — CEO
Assuntos estratégicos que os times endereçaram diretamente ao CEO, organizados por time.
Mission Control Méliuz
O fluxo de valor de todas as linhas de negócio, com cada alerta do Jira / Opsgenie amarrado à etapa que ele vigia — ao vivo
Mlz-Analysis
Análises do data warehouse, materializadas por área
Operações Integradas
Gestão de redes, parceiros diretos e processos operacionais
Parceiros
O apanhado de cada parceiro para a reunião com ele — e o e-mail de situação e pendências pronto para copiar
Redes de Afiliados
O apanhado de cada rede para a reunião com ela — e o e-mail de situação e pendências pronto para copiar
report=metricas_rede, pelo proxy): a cadeia do e-commerce agrupa
por parceiro e não conhece a rede. A Alavancagem não entra — limite de crédito é do parceiro,
não da rede.Central de Alertas
Os alertas de desempenho disparados, o que ainda está sem tratamento, o que era falso positivo e o que virou caso
Casos Redes e Parceiros
Problemas com dono, prazo e histórico — no lugar da thread de e-mail
Customer Success
Satisfação do cliente, NPS, churn e health score
Prevenção à Fraudes
Monitoramento, análise de risco e prevenção
Mission Control
Monitoramento de sistemas, incidentes e estabilidade
Financeiro
Budget, cash position, forecast e controle orçamentário
Alavancagem de Parceiros
Top 20 por comissão — endividamento (NFs em aberto, separadas em no prazo × já vencidas) × limite por parceiro × saúde financeira pelo balanço oficial
Projeto VAR — Vendas ao Recebimento
Portal de riscos financeiros e status das automações por parceiro
| Rede | Parceiro | Safra | Maturação | Comissão pendente | Cashback pendente | Idade média | Taxa validação safra | Ação recomendada |
|---|
| Rede | Parceiro | Estado do fluxo | Transações | Comissão esperada | Comissão rede | Dias da conf. | Dias da NF | Cobertura rede | Ação recomendada |
|---|
| Rede | Parceiro | Tipo de exposição | Transações | Cashback exposto | Comissão esperada | Idade média | Cobertura rede |
|---|
| Rede | Parceiro | Transações | Comissão esperada | Cashback liberado | Prejuízo (cashback − esperada) | Cashback ÷ Esperada |
|---|
| Rede | Safra | Maturação | Transações faturáveis | Comissão esperada | Comissão casada | Comissão paga na rede | Cobertura da safra | Gate da rede |
|---|
Operação BF
A Black Friday 2026 em uma tela: quanto falta, em que fase estamos, o que pode ir para produção hoje e quem responde quando algo quebrar
GMV, compras, saídas, parceiros, fechamento do dia anterior, contas e atendimento, contra a semana passada e contra a BF 2025
A Fábrica
A planta da fábrica: cada linha de negócio elo a elo, o que quebra em cada elo e o processo que existe por causa disso
Todo negócio do Méliuz obedece à mesma gramática de quatro tempos: o usuário faz algo → um terceiro confirma que aquilo aconteceu → o Méliuz paga o usuário → o Méliuz cobra o terceiro. Operações existe porque o segundo tempo é o único que o Méliuz não controla, e os outros três dependem dele.
| Linha | De onde vem o dinheiro | Quem confirma | Meta 2026 | Peso operacional |
|---|---|---|---|---|
| E-commerce | Comissão da loja sobre a compra, menos o cashback do usuário | Loja ou rede de afiliados | R$ 499M comissão R$ 172M margem | O maior de longe — dez elos, todos com processo |
| Placements | Mídia vendida ao parceiro dentro do app e do site | Contrato comercial (KAMs) | dentro do e-commerce | Só faturamento e controle de prazo |
| MNF | Comissão da indústria por SKU promocionado; cashback base sai do bolso | Indústria / campanha | R$ 18M faturamento 2,75M usuários/mês | Cadastro e matching de produto é o gargalo |
| Jogue e Ganhe | Comissão da Adjoe por instalação, menos cashback por missão | Adjoe | US$ 11,5M | 175 h/mês de CS e nenhum processo de Operações |
| Anúncios internos | eCPM de AdMob e Google Ad Manager, majoritariamente no fluxo da NF | US$ 1,2M | Nenhum processo mapeado em nenhuma área | |
| Serviços Financeiros | R$ 30 por conta BV ativada e R$ 45 pela 1ª compra no cartão | Banco BV / Bankly | 1.395k contas | ~114 h/mês de CS; a receita só existe na ativação |
| Prime | Assinatura mensal ou anual, líquida da taxa das lojas de app | Qonversion / App Store | 176k novos | Herda a quebra de todas as outras linhas |
| Resgate Combinado | Margem na troca de cashback por sorteio, Joy, milhas ou Prime | Interno | R$ 5,1M trocados | Sem processo dedicado |
| Miúdos | Milhas, Gift Card, Recarga, Premiado, Responda&Ganhe, Dados | Vários | ~R$ 5M somados | Fila de CS por produto, sem Operações |
Cada processo da operação está plugado no elo da linha de negócio onde ele existe. A cor diz o estado, e o estado é derivado — nunca digitado: verde é o que já tem tela no cockpit e leva você até ela; azul tem instrução de trabalho no Confluence e abre a IT; cinza só foi declarado no mapeamento, sem IT e sem tela; rosa é buraco, ninguém cuida daquele elo hoje. Um chip cinza não é erro de cadastro: é trabalho real que ainda não tem casa — e é dele que sai a fila de construção.
O usuário abre o app, busca a loja, sai do Méliuz, compra, a loja avisa a rede, a rede avisa o Méliuz, a compra entra pendente no extrato, a loja confirma, o usuário recebe o cashback e o Méliuz fatura a comissão. Dez elos, e a operação mora em todos — o que muda de um para outro é a natureza da vigilância, não a existência dela.
* Mission Control não aponta hora por elo: os oito processos do time são transversais a todas as linhas de negócio. As 22 h/mês são a Investigação de alertas de negócio inteira, não a fatia do e-commerce — não somar com as horas de Operações. A dor declarada pelo próprio time é exatamente esta lacuna: "falta de monitoramento em alguns fluxos críticos" e "falta de acompanhamento em tempo real dos números do negócio".
Conta digital e cartão são dois produtos com a mesma economia: o Méliuz não ganha por abrir, ganha por ativar. R$ 30 quando o usuário faz a primeira transação na conta BV, R$ 45 quando faz a primeira compra no cartão. Toda conta aberta que nunca transaciona é custo de aquisição sem receita.
O usuário manda a nota do mercado ou da farmácia e ganha cashback. Toda nota gera um cashback base que sai do bolso do Méliuz; a receita só aparece quando a nota contém um SKU de campanha e a indústria paga a comissão. Duas economias diferentes no mesmo fluxo — e o time de Operações é quem faz a segunda existir.
O usuário instala um jogo pelo SDK da Adjoe, cumpre missões dentro dele e recebe dinheiro. A Adjoe paga a comissão na instalação e o Méliuz paga o cashback nas missões — duas tabelas separadas, dois momentos diferentes. É a segunda maior linha de receita da empresa e a única sem nenhum processo de Operações.
A única linha cuja receita é previsível e recorrente: o usuário assina, a cobrança renova sozinha e o benefício fica ativo. Mas os cinco benefícios do Prime moram dentro das outras linhas — cashback exclusivo no e-commerce, +R$ 1 por nota no MNF, +50% nas missões do Playtime, resgate sem a trava de R$ 20. Quando qualquer uma delas quebra, a reclamação chega rotulada como Prime.
Seis produtos que somados valem alguns milhões por ano e que compartilham o mesmo padrão: têm fila de atendimento e não têm processo de Operações. Nenhum deles justifica uma aba própria hoje — mas todos precisam aparecer no lugar onde o CS mede transbordo.
O parceiro compra espaço de mídia dentro do app e do site — home, topbar, header exclusivo, carrossel, push, CRM. É a única receita do e-commerce que não nasce de uma compra: nasce de um contrato comercial e de uma peça no ar.
Por isso ela se comporta de forma diferente no banco. A receita de placement entra como
tipo de transação PLACEMENT e cai no cliente interno "Direto pra Loja"
(customer_id 40768), que não é uma pessoa — é o balde de tudo que é comissão sem
compra e sem usuário associado. Consequência prática: placement conta como receita, nunca
como comprador, e precisa sair de qualquer análise de base, cohort ou LTV.
A cadeia é curta: KAM fecha o contrato → a peça sobe → a peça fica no ar pelo período contratado → Operações confere e pede o faturamento → Financeiro emite. Só existe um processo mapeado nela, e ele cobre os dois últimos elos.
O Méliuz monetiza a própria base exibindo anúncio no app — principalmente o
interstitial no fluxo do MNF, mais banner e nativo em outras telas. É a única receita
sem customer_id: chega agregada por rede, unidade e dia.
A cadeia tem quatro elos e nenhum deles é operado por pessoa: requisição de anúncio → a rede preenche (ou não) → impressão entregue → receita por eCPM, convertida de dólar para real pelo câmbio da data. Onde ela pode quebrar em silêncio é no meio: uma queda de fill rate ou de eCPM derruba a receita sem gerar um único ticket, porque o usuário não percebe e não reclama de anúncio que não apareceu.
Há ainda uma regra de negócio que amarra esta linha às outras: não se exibe anúncio para assinante Prime nem para cliente sensível. Quer dizer que o crescimento do Prime reduz o inventário de anúncio — as duas linhas se canibalizam por desenho, e ninguém acompanha esse balanço hoje.
Dentro do MNF
O formato principal é o interstitial exibido no fluxo de envio de nota. A saúde do MNF é o teto da receita de anúncio.
Ninguém
Nenhum processo mapeado em Operações, CS, Fraudes ou Financeiro. Nenhum alerta de fill rate ou de eCPM.
Média simples mente
eCPM e fill rate só podem ser recompostos somando os componentes. Média de médias por dia ou por unidade dá número errado com cara de métrica.
O resgate não é uma linha de negócio — é o funil comum por onde sai o dinheiro de todas elas. Cashback de e-commerce, de MNF, de missão de jogo e de pesquisa chegam ao mesmo saldo, e o usuário só percebe que algo deu errado quando tenta tirar.
A trava histórica é R$ 20, com três exceções que também são portas de venda de outros produtos: o primeiro resgate para a conta digital Méliuz não tem trava, assinante Prime não tem trava, e o Resgate Combinado permite usar parte de um saldo abaixo de R$ 20 para comprar um benefício — sorteio, Joy, milhas Azul ou desconto no Prime — e sacar o resto.
Por isso o resgate é o ponto de maior concentração de trabalho humano de toda a operação: 146 h/mês só em CS entre resgate, conta duplicada e linha digitável, mais o monitoramento de fraude e a dependência do Bankly. Quase nada disso é problema de resgate — é o acúmulo do que quebrou antes chegando na tela em que o usuário conta o dinheiro.
146 h/mês
Resgate de cashback, conta duplicada e linha digitável. Muitas telas para conferir um único caso; o Admin desloga com frequência.
Trava de R$ 100 mil
Se o total de resgates do dia passa de R$ 100 mil, o Financeiro precisa ser avisado. Hoje alguém olha e escreve no canal.
Resgate travado
Alerta no Slack, abertura de caso com o Bankly, espera. O prazo depende de um terceiro.
Mission Control não fica em nenhum elo — fica acima de todos. Cria os monitores que detectam anomalia em qualquer ponto de qualquer cadeia, investiga quando o número desvia, conduz a crise e cobra o que ficou pendente do post mortem.
| Etapa | O que é | A dor declarada |
|---|---|---|
| Criação de alerta | Query e monitor novos para detectar anomalia em produto, serviço ou número de negócio. | Fluxos críticos ainda sem monitoramento |
| Refinamento | Ajuste de parâmetro de alerta que já existe. | Alerta com falso positivo |
| Investigação | Quando o monitor acusa desvio, confirmar se há problema real de negócio. | Falta acompanhamento dos números em tempo real |
| Gestão de crise | Acionar responsáveis, comunicar cliente e fornecedor, testar hipótese, registrar decisões. | Crises que duram dias |
| Post mortem | Documentar, reunir os times envolvidos e cobrar as ações a cada quinze dias. | Recorrência da mesma crise |
| Treinamento | Ensinar os outros times a operar Datadog, Opsgenie, Jira e Grafana. | Times que não sabem atuar no alerta que receberam |
Duas abas já existem e cobrem os elos 05 e 09 do e-commerce — Taxa de Validação e Alavancagem de Parceiros. A fila abaixo está ordenada por horas humanas presas no elo × se o dado já existe no BigQuery, que é o que separa uma aba de duas semanas de um projeto de dois meses.
| # | Aba candidata | Elo | Horas presas | Dado pronto? | Por que esta e por que agora |
|---|---|---|---|---|---|
| 1 | Cancelamento | e-commerce · 06 | 129 h Ops | Sim — ftransaction tem status e data de confirmação |
É o maior processo isolado da empresa: 120 h/mês numa pessoa só. Mesma anatomia da Taxa de Validação (fila por custo do atraso, tratativa guardada, caso aberto), então boa parte da tela já está escrita. |
| 2 | Rastreio e recuperação | e-commerce · 03 | 84 h Ops +30 h CS +8 h Fraudes |
Parcial — logs de jornada e Enviados_RA100 existem; a zona cega não |
Junta o cluster do Carlos Henrique, os alertas do Mantilha e da Samara e as quatro recuperações da Laís numa tela só. É também a origem do maior volume de reclamação do e-commerce. |
| 3 | Comissão divergente | e-commerce · 04 | 40 h Ops +26 h CS |
Sim — comissão esperada × informada estão na mesma tabela | É dinheiro faturado errado nos dois sentidos, e o erro nasce em dois lugares diferentes (cadastro do comercial e configuração do parceiro). A tela precisa separar essas duas causas para saber quem cobrar. |
| 4 | Jogue e Ganhe | playtime · 03 | 175 h CS | Sim — instalações e eventos têm tabela própria | US$ 11,5M de meta sem nenhum instrumento. Primeira pergunta a responder: qual a taxa de missão contabilizada, e ela caiu? Hoje isso só é visível pelo volume de gente reclamando. |
| 5 | Faturamento e recebimento | e-commerce · 08–09 | 17 h Ops +105 h Fin |
Sim — transacoes_pagas fecha o ciclo |
Completa a Alavancagem pelo outro lado: ela mostra quem deve, esta mostraria o que ainda não foi faturado e o que venceu sem cobrança. Também é onde o Financeiro tem mais horas manuais. |
| 6 | Campanhas e SKU do MNF | MNF · 03 | 20 h Ops | Sim — oferta, produto e comissão têm tabelas próprias | Decide a bifurcação entre nota que dá receita e nota que é só custo. Menos horas que as outras, mas mexe direto na margem do produto. |
| 7 | Ativação de conta e cartão | serv. financeiros · 03→04 | 114 h CS | Sim — histórico de status e primeira transação | A meta é contada em contas ativadas e o funil entre abrir e ativar não tem dono. Fica depois das outras porque a alavanca principal é de produto, não de operação. |
Métricas
O ritmo do período de cada linha de negócio contra a meta, aberto em cadeia até a alavanca que explica o desvio — sem filtro, o mês atual
report=metricas
(e-commerce) e report=linhas (demais linhas) do proxy — espelhos legíveis em
scripts/sql/metricas_negocio.sql e scripts/sql/metricas_linhas.sql —
com as métricas, fontes e filtros oficiais da Estratégia (mlz-analysis-ai). O realizado nunca
vem de planilha; a meta é mensal, lida da Controle KPIs — o Méliuz não define meta
diária (Motta, set/2026); a régua do mês é a projeção pelo dia-da-semana.Atendimento
O que a Mel não resolveu, virou ticket e por quê — e o estado da fila que recebeu esse transbordo
report=atendimento do proxy (espelho legível em
scripts/sql/atendimento.sql) — o dado do banco é de D-1.
O lado Mel vem ao vivo da API do mlz-ia-conversa, pelo mesmo proxy. O
Reclame Aqui continua manual: nota e ranking são digitados na sub-aba dele.Taxa de Validação
Quanto de cada parceiro sai do limbo — confirmada ou cancelada, tanto faz: o mal é a transação que nunca recebe resposta
report=validacao do proxy
(espelho legível em scripts/sql/taxa_validacao.sql) — e se atualiza sozinha uma vez
por dia. A planilha "Taxa de validação do e-commerce" saiu de cena: era alimentada à mão,
tinha 13% das células preenchidas e não aplicava os filtros oficiais de e-commerce.| Parceiro | Rede | Em aberto | Transações | Em aberto no total | Mais antiga | Prazo do parceiro | Tratativa |
|---|
Comissão Divergente
Onde a comissão que a rede informou é diferente da que o cadastro comercial prometia — e de que lado está o erro
report=comissao do proxy
(espelho legível em scripts/sql/comissao_divergente.sql) — e se atualizam sozinhos ao abrir a aba.
A comparação é esperada × informada, as duas na mesma linha da ftransaction: sem join e
sem lacuna de cobertura. A terceira comissão — a que entrou no caixa — é o VAR e mora na aba
Alavancagem Parceiros.
A oferta de CPA é a mesma que o Admin >> Comissão >> Gerenciar mostra.
As demandas vêm do Supabase e substituíram a aba DEMANDAS da planilha do alerta.Recuperação de Compras
A compra que o usuário fez e o Méliuz não recebeu — o que se recupera, o que se perde e onde a recuperação trava
report=rcp_r100, rcp_regular,
rcp_insercao, rcp_rcr, rcp_rvc e rcp_usuarios; espelhos legíveis em
scripts/sql/recuperacao_*.sql), e se atualizam sozinhos ao abrir a aba. As duas de histórico só se repetem depois de 24 h.
O quadro de entregas fica no Supabase (rcp_entregas e rcp_entregas_eventos, migração 76): só o dono da aba edita, e tarefa sai do quadro arquivada, nunca apagada.O time de recuperação de compras nasceu para tratar as diferentes causas de perda de cashback do usuário quando uma compra elegível ao Méliuz não é confirmada como deveria. A nossa atuação se organiza em três frentes complementares: o Rastreio 100%, que trata falhas técnicas no rastreio da jornada de compra via InApp e extensão; a Revisão de Cancelamentos, que contesta junto aos parceiros cancelamentos considerados indevidos; e a Recuperação de Reclamadas, que trata os casos reportados pelos próprios usuários. Cada frente endereça uma causa distinta de perda, mas as três compartilham o mesmo compromisso com o usuário final.
Taxa de Confirmação
Quanto do que o usuário comprou o parceiro confirma, safra a safra, e quando a taxa sai do padrão do próprio histórico
report=txconf_base e txconf_motivos;
espelhos legíveis em scripts/sql/confirmacao_*.sql), e se atualizam sozinhos ao abrir a aba quando a leitura tem mais de 12 h.
Toda a conta — taxa, Z, tendência, parceiros em alerta e a decomposição — é feita aqui, para o recorte escolhido.Ver como tabela
- Taxa de confirmação = confirmados ÷ total da safra. O status 34 (a confirmar) conta como confirmado e o 35 (a cancelar) como cancelado: a decisão já foi tomada, só falta efetivar.
- Z = (taxa do mês − média) ÷ desvio-padrão, com média e desvio dos 12 meses de calendário anteriores do mesmo recorte. Anômala quando |Z| ≥ 2.
- Só recebe veredito, e só entra na média, o mês com validação acima de 90% (validação = o que saiu do pendente) e pelo menos 100 pedidos, com 6 meses válidos no histórico. Não há piso de pontos: recorte estável que varia pouco também acende o alerta.
- No gráfico, a linha tracejada no fim da série é a safra em maturação (validação até 90%), ainda sem veredito. A média dos 12 meses e a faixa esperada aparecem ao passar o mouse.
- Tendência = reta de mínimos quadrados da confirmação contra o mês, só com os meses válidos (validação acima de 90% e 100 pedidos) desde janeiro do ano anterior. A inclinação sai em pontos percentuais por mês, e ela só é dita significativa quando o teste t da inclinação dá p < 0,05. Com p maior, a variação cabe no ruído e o card diz "sem tendência estatística". Com menos de 6 meses válidos não há tendência. Meses vizinhos costumam se parecer, e isso deixa o teste um pouco otimista: p perto de 0,05 pede cautela.
- Por que a taxa mudou compara o último mês com veredito com os 12 meses anteriores válidos, somados (por isso a base pode diferir um pouco da média do card, que é a média simples das taxas mensais). A diferença é repartida entre os parceiros (ou entre as redes, quando um parceiro está escolhido): taxa é o parceiro confirmando mais ou menos que antes; mix é o parceiro ganhando ou perdendo peso no volume, o que puxa a média para a taxa dele. Parceiro com validação até 90% no mês comparado fica numa parcela à parte, "ainda em validação": a taxa dele ainda vai subir, e tratá-lo como queda seria confundir maturação com piora. As partes somam exatamente a variação.
- Por que cancela usa as safras do ano corrente do recorte, a mesma janela do cartão de cobertura de justificativa. A pizza reparte os cancelados (status 3 ou 35) pela justificativa da
canceled_orders; cancelado sem registro lá, ou com o motivo vazio, é "Sem justificativa". Os motivos menores entram em "Outros motivos". Pedidos e Comissão trocam a medida. As barras dão a taxa de cancelamento de cada canal de compra (cancelados ÷ pedidos do canal), com a média do recorte tracejada; canal com menos de 100 pedidos fica apagado. - Parceiros em alerta = parceiros com queda de tendência significativa ou com um mês fora do padrão para baixo entre os 3 últimos com veredito e dentro dos 6 últimos meses do calendário, ordenados pela comissão perdida (cancelada + expirada) nos 6 últimos meses válidos.
- O recorte muda o cálculo: o Méliuz inteiro, uma rede ou um parceiro têm cada um o seu histórico. A rede é a origem gravada no pedido.
- Rastreio 100%, WhiteLabel, a conta interna 40768 e a origem MANUAL (lançamento manual, que não é rede) ficam fora. Também sai, da análise inteira, toda rede sem nenhum pedido no ano corrente: é rede desativada.
Operação Cupom
O cupom que derruba o pedido na Affiliate Window — quanto se perde, em qual parceiro, e qual código está por trás
report=cpm_panorama,
cpm_parceiros e cpm_cupons; espelhos legíveis em scripts/sql/cupom_*.sql),
e se atualizam sozinhos ao abrir a aba. A base é a canceled_orders — o que as redes devolvem sobre
pedido cancelado —, cruzada com o catálogo de ofertas para saber se o cupom era nosso.CPM_REDE no proxy e
abas/cupom.md.CPM_PARCEIROS_FORA no proxy.Top 20 Parceiros
Conversão e rastreio das 20 lojas que mais geraram comissão nos últimos 30 dias — quem saiu do próprio padrão, e o caso para resolver
report=topconv;
espelhos legíveis em scripts/sql/topconv_*.sql), e se atualizam sozinhos ao abrir a aba quando a leitura tem mais de 30 min.
O que acende cada parceiro é calculado aqui, com as réguas de abas/topconv.md.Jogue e Ganhe
A saúde do rastreio com a Adjoe — a falha que não quebra tela nenhuma, só deixa de faturar
report=playtime do proxy (espelho em
scripts/sql/playtime_rastreio.sql). Custa ~18 GB por execução, então fica guardada
por 12 horas.Jogos
Quanto cada jogo rende, quanto custa de cashback e qual deles mudou de patamar a ponto de virar conversa com a Adjoe
fct_playtime__installations e cashback de
fct_playtime__events, cruzadas por app_id — nunca pelo nome, que as duas tabelas
grafam diferente. Consulta report=jogos do proxy, ~0,95 GB, guardada por
6 horas. Quem vê o Jogue e Ganhe vê esta aba.Mapa de Alertas
A cobertura de alertas dos processos de Operações — onde a operação enxerga sozinha e onde ela só quebra quando alguém repara
Processos x Alertas (a cobertura) e
Alertas (o registro). Por isso a conta que publicou o proxy precisa ter leitura nessa
planilha. Processo novo ou alerta novo se cadastra na planilha, não aqui.Agentes de Prevenção à Fraudes
O que cada agente de Prevenção à Fraudes decidiu, quanto decidiu sem humano e o que sobrou para o time
AFR_AGENTES, com um leitor de linha próprio.Picodi Turnaround
O diagnóstico do Picodi e o que ainda falta para fechá-lo — status, dono e próximo passo de cada bloco, os gaps consolidados e o plano de ação
Configurações
Gerencie integrações e credenciais do cockpit.
Cole abaixo a URL do Google Apps Script que serve como proxy de leitura das planilhas. Todas as importações usam esta URL automaticamente — sem popup de login, sem expiração de sessão.
Sem o token, o proxy segue liberado para qualquer chamada com a URL — é o estado de sempre.
Defina a propriedade PROXY_TOKEN no Apps Script e cole o mesmo valor aqui para
exigir o token em toda chamada.
- Acesse
script.google.comcom a conta tulio@meliuz.com.br - Clique em Novo projeto. Apague o código existente e cole o código do proxy (ver abaixo)
- Salve o projeto (Ctrl+S). No menu superior, clique em Implantar → Nova implantação
- Em "Tipo de implantação", escolha App da Web
- Configure: Executar como: Eu (tulio@meliuz.com.br) · Quem tem acesso: Qualquer pessoa
- Clique em Implantar, autorize as permissões e copie a URL gerada
- Cole a URL no campo acima e clique em Salvar
script.google.com/.../edit). É a URL gerada ao Implantar → App da Web, que termina em /exec (script.google.com/macros/s/.../exec). Se editar o código depois, use Implantar → Gerenciar implantações → Editar (ícone do lápis) → Nova versão para não trocar a URL.
scripts/apps_script_proxy.gs, no repositório do cockpit. Use aquele arquivo; este bloco fica aqui só como referência do contrato antigo.
function doGet(e) {
try {
var p = (e && e.parameter) || {};
if (!p.spreadsheetId) return json({ error: 'Parametro spreadsheetId e obrigatorio' });
var ss = SpreadsheetApp.openById(p.spreadsheetId);
var sheet = null;
if (p.sheet) {
sheet = ss.getSheetByName(p.sheet);
if (!sheet) return json({ error: 'Aba nao encontrada: ' + p.sheet });
} else if (p.gid) {
var all = ss.getSheets();
for (var i = 0; i < all.length; i++) {
if (String(all[i].getSheetId()) === String(p.gid)) { sheet = all[i]; break; }
}
if (!sheet) return json({ error: 'gid nao encontrado: ' + p.gid });
} else {
sheet = ss.getSheets()[0];
}
var rows = sheet.getDataRange().getDisplayValues();
var csv = rows.map(function (row) {
return row.map(function (cell) {
var s = (cell == null) ? '' : String(cell);
return /[",\n\r]/.test(s) ? '"' + s.replace(/"/g, '""') + '"' : s;
}).join(',');
}).join('\n');
return ContentService.createTextOutput(csv).setMimeType(ContentService.MimeType.CSV);
} catch (err) {
return json({ error: String(err) });
}
}
// Envio de e-mail (cobranca de follow-up). O corpo chega como texto puro de
// proposito: com Content-Type JSON o navegador dispara um preflight OPTIONS,
// que o Apps Script nao responde.
function doPost(e) {
try {
var req = JSON.parse((e && e.postData && e.postData.contents) || '{}');
if (req.action !== 'mail') return json({ error: 'Acao desconhecida: ' + req.action });
// O cockpit esta publico na internet: o proxy so entrega para o dominio da
// empresa, entao nem um login vazado o transforma em relay de spam.
var DOMINIO = 'meliuz.com.br';
var to = (req.to || []).filter(function (a) {
return /@/.test(String(a)) && String(a).split('@')[1].toLowerCase() === DOMINIO;
});
if (!to.length) return json({ error: 'Nenhum destinatario @' + DOMINIO });
var msg = {
to: to.join(','),
subject: String(req.subject || 'Cockpit Meliuz'),
body: String(req.body || ''),
name: 'Cockpit Meliuz'
};
if (req.replyTo && /@/.test(String(req.replyTo))) msg.replyTo = String(req.replyTo);
MailApp.sendEmail(msg);
return json({ ok: true, sent: to, quota: MailApp.getRemainingDailyQuota() });
} catch (err) {
return json({ error: String(err) });
}
}
function json(obj) {
return ContentService.createTextOutput(JSON.stringify(obj))
.setMimeType(ContentService.MimeType.JSON);
}
doPost acima no fim do script existente e publicar Nova versão (Implantar → Gerenciar implantações → ícone do lápis). A URL não muda. Na primeira execução o Google pede uma permissão nova — a de enviar e-mail em seu nome, usada pela cobrança de follow-up. Depois, teste no botão Testar e-mail aqui em cima.
O proxy do Túlio, acima, só entrega e-mail para o domínio da Méliuz e o que ele liberar à parte. O botão Enviar primeiro e-mail (Central de Casos) precisa falar com redes e parceiros, que são domínio de fora — por isso usa este Apps Script separado, sem esse filtro. Fica gravado na nuvem (igual ao proxy acima): quem grava é só o gestor, mas TODO MUNDO que clicar em "Enviar primeiro e-mail" usa esta mesma URL — o e-mail sai da conta Google de quem implantou o script, não da conta de quem clicou no cockpit.
O cockpit inteiro (tela, estilos e código) mora dentro de um arquivo só. Quando alguém publica uma mudança, uma aba já aberta continua rodando a versão antiga — sem nenhum sinal disso. O carimbo abaixo é o do arquivo que este navegador está rodando agora; ao lado, o que está publicado. Se forem diferentes, recarregue com Cmd+Shift+R.
O que mostra: toda migração de banco e toda mudança publicada, com quem fez. Como melhora o negócio: código novo que depende de migração que ninguém rodou derruba a tela de todo mundo — e o sintoma não diz a causa. Aqui a migração é conferida no banco, agora, não pelo número do arquivo.