v2.0

Código Inline

Escreva Node.js ou Python direto no editor da etapa de Regra Customizada: a API do Mini SDK (bm) e o que está disponível em cada linguagem.

Nem toda variável precisa de código Montar uma mensagem, fazer uma conta ou gravar um valor numa variável já existente não exige script: a seção Variáveis do Fluxo da mesma etapa faz isso com valor fixo, variável ou fórmula, e roda antes do seu código, que já lê o resultado com bm.get('{nome}'). Veja Manipulação de Variáveis → Locais. Reserve o script para o que realmente pede lógica. O mesmo vale para uma pausa simples: o Timer de Espera da etapa faz o processo aguardar alguns segundos depois do script, sem setTimeout nem time.sleep(). Veja Timers → Timer de Espera.

Configurando a etapa

Editor de código inline da etapa de Regra Customizada.
Editor de código inline da etapa de Regra Customizada.

O editor abre expandido quando a etapa já tem script. Sem script, ele fica recolhido: clique em ▼ Mostrar para abrir.

No bloco Código Customizado da etapa de 🔢 Regra Customizada:

Qual a linguagem do seu script? seleção Obrigatório

Node.js ou Python. Define o interpretador usado no runtime.

Modo de Execução seleção Obrigatório
  • Inline: O código é escrito diretamente no campo Script Customizado abaixo.
  • Projeto: O código é um projeto ZIP enviado via Projetos e SDK. Neste caso, selecione o projeto em Projeto de Script.
Script Customizado código

O código a ser executado (apenas no modo Inline). O editor aceita Node.js ou Python conforme a linguagem selecionada acima.

Projeto de Script seleção

Visível apenas no modo Projeto. Selecione o projeto ZIP previamente enviado no Menu, na opção Codebase. Veja Projetos e SDK.

Limite de Tempo do Script segundos

Por quantos segundos este script pode rodar antes de ser encerrado. Vale igual para Node.js e Python, no modo Inline e no modo Projeto. Padrão de 3600 (1 hora), com atalhos de 2 minutos, 10 minutos, 1 hora e 8 horas, e qualquer valor entre 10 segundos e 8 horas.

Ao estourar, a etapa é encerrada e conta como erro, entrando na Gestão de Erros da etapa. É assim que um travamento vira nova tentativa em vez de uma execução perdida, então prefira o menor tempo que a etapa realmente precisa: 120 para cálculo puro, 600 quando há arquivo, API, banco ou aplicativo envolvido, 3600 quando a etapa processa um lote inteiro de uma vez.

O campo aparece quando a etapa tem código escrito ou um projeto selecionado. Etapa que só itera listas não roda script, e o Script de Sessão não passa por esse limite. Detalhes e a razão de não existir "sem limite" aqui em Timers.

Erros de sintaxe e avisos: o aviso vem antes da execução

Uma chave a mais, uma aspa aberta ou uma indentação fora do lugar derrubam o script inteiro, e sem aviso o erro só apareceria no meio da execução, depois de outras etapas já terem rodado. Por isso o browserMate confere o código do Script Inline e do Script de Sessão, e separa o que encontra em dois níveis:

No editor, a linha fica sublinhada e uma faixa abaixo dele mostra Linha N com a descrição, mais o número de outros achados. Clique na faixa para ir até a linha. A conferência acontece alguns instantes depois de você parar de digitar.

O que é erro (vermelho)

O que é conferidoNode.jsPython
Chave, parêntese ou colchete a mais, faltando ou trocado. O aviso aponta a linha onde o símbolo sobrou ou onde foi abertoSimSim
Aspas não fechadasSimSim
Aspas curvas, traço especial e caractere invisível colados de uma página ou documento (o olho não distingue do certo)Sim. Exceção: o espaço especial (NBSP), que o Node aceita como espaço comumSim, inclusive o espaço especial
Indentação errada, inclusive tab misturado com espaçoNão se aplicaSim
: esquecido no fim de if, for, def e similaresNão se aplicaSim
Erro de digitação em palavra ou operadorSim (retrun, x = = 1)Em parte: palavra-chave escrita errada (retrun x, iff x:) e dois valores colados sem nada entre eles (x 5, print "a"). Erros como x = = 1 só aparecem quando o script roda
const sem valor inicial, nome declarado duas vezes e await solto no nível de cimaSimNão se aplica
Dois erros clássicos do Node.js inline O browserMate já declara bm antes do seu código, então const bm = require('./browsermate') repete a declaração e o script não roda (já foi declarado). E await solto no nível de cima do script também não roda no Script Inline: envolva o código numa função assíncrona (veja Código assíncrono, mais abaixo). Os dois aparecem em vermelho no editor.

O que é aviso (amarelo)

O que o aviso dizNode.jsPython
Nome usado e nunca declarado ou definido, com sugestão quando parece um erro de digitação (totl, você quis dizer total)SimSim: só quando o nome não é definido em lugar nenhum do script
const que recebe outro valor mais adianteSimNão se aplica
Variável usada antes da linha em que é declaradaSimNão
Texto que parece um JSON e não é válido (} a mais, vírgula sobrando, lista sem fechar). O aviso aponta o ponto do texto onde o JSON quebraSimSim
O que nenhuma conferência consegue pegar Trocar o = por ; (let a ; 5) é código válido: declara a e depois avalia um 5. O problema é a ficar sem valor, e isso não se distingue de um script legítimo, então não há aviso. O mesmo vale para um nome montado em tempo de execução, e, no Python, para um nome que só é definido dentro de outra função e usado fora dela. Só o Debug mostra esses casos.

A conferência vale só para o modo Inline. O código de um Projeto ZIP não fica no cadastro da etapa e não é conferido.

Node.js inline

O código roda em Node.js 24, embarcado no runtime. Veja Versões de Node.js e Python.

O código é executado em um contexto Node.js com o Mini SDK bm já disponível (o runtime injeta const bm = require('./browsermate') automaticamente antes do seu código). As variáveis do processo vivem no globalData e são acessadas pela chave no formato {variavel}, com chaves.

Acesso a variáveis

Node.js: leitura e escrita de variáveis
// Ler variável do processo. A chave usa o formato {variavel}
const valor = bm.get('{nome_variavel}');
// com valor padrão caso não exista
const tipo  = bm.get('{tipo_documento}', 'NFe');
// todas as variáveis de uma vez (somente leitura)
const todas = bm.globalData;

// Escrever variáveis: SEMPRE via bm.done() ao final do script
bm.done('ok', {
  '{resultado}': 'texto calculado',
  '{total}':     1500.75,
  '{lista}':     [1, 2, 3]
});
O valor chega e é gravado no tipo que tem bm.get() devolve o valor como ele está no fluxo: texto, número, lista (array) ou objeto. Uma variável com tipo declarado chega no tipo dela (uma Moeda chega como número). No bm.done(), número, array e objeto são gravados como estão. Texto capturado da tela chega como texto: para fazer conta com ele, converta com Number().
bm.done() é obrigatório A única forma de gravar variáveis de volta ao processo é o segundo parâmetro de bm.done(result, updates). Sem essa chamada ao final, nenhuma variável é atualizada e o log indica que o script não produziu output.
As variáveis que você grava aparecem nas listas Depois de salvar a etapa, as chaves escritas como texto no bm.done() passam a aparecer no botão { } das etapas seguintes, no autocomplete dos outros scripts e no Copilot, sem nada a declarar. Vale para Node.js e Python. Os detalhes, e o que não entra na lista, estão em Manipulação de Variáveis: Script.

Módulos disponíveis

O runtime Node.js suporta require() para módulos nativos e para dependências pré-instaladas:

Módulos nativos disponíveis
const fs      = require('fs');
const path    = require('path');
const crypto  = require('crypto');
const https   = require('https');
const Buffer  = require('buffer').Buffer;
const xml2js  = require('xml2js');   // parsing XML
const xlsx    = require('xlsx');     // Excel
const moment  = require('moment');  // datas

Logging

Use bm.bmLog() para registrar mensagens nos logs oficiais de execução, que aparecem no Control Room:

Node.js: registrar log no processo
bm.bmLog('Processando item: ' + bm.get('{item_atual}'));
bm.bmLog('Total de itens: ' + lista.length);
bm.bmLog('Erro ao processar: ' + err.message);

Código assíncrono

O runtime suporta async/await. Envolva o código em uma função assíncrona auto-executável e chame bm.done() ao final:

Node.js: await em código inline
(async () => {
  const axios = require('axios');

  // Buscar dados de uma API externa
  const id   = bm.get('{id}');
  const resp = await axios.get(`https://api.exemplo.com/item/${id}`);

  bm.bmLog('Item carregado: ' + resp.data.nome);

  bm.done('ok', {
    '{nome_item}':  resp.data.nome,
    '{preco_item}': resp.data.preco
  });
})();

Python inline

O código roda em Python 3.14, embarcado no runtime, com pip disponível. Veja Versões de Node.js e Python.

O código é executado em um ambiente Python 3 com o Mini SDK bm já disponível (o runtime injeta import browsermate as bm automaticamente antes do seu código). As variáveis usam o mesmo formato de chave {variavel}.

Acesso a variáveis

Python: leitura e escrita de variáveis
# Ler variável do processo. A chave usa o formato {variavel}
valor = bm.get('{nome_variavel}')
lista = bm.get('{lista}', [])

# Escrever variáveis: SEMPRE via bm.done() ao final do script
bm.done('ok', {
    '{resultado}': 'texto calculado',
    '{total}':     1500.75,
    '{lista}':     [1, 2, 3]
})
Tipos em Python bm.get() devolve o valor como ele está no fluxo: str, int/float, bool, list ou dict. Uma variável com tipo declarado chega no tipo dela (uma Moeda chega como número). No bm.done(), número, list e dict são gravados como estão. Texto capturado da tela chega como texto: para fazer conta com ele, converta com int() ou float().

Bibliotecas disponíveis

Python: imports disponíveis no runtime
import json, re, os, sys, math, datetime
import base64, hashlib, hmac
import csv, io
import xml.etree.ElementTree as ET
import urllib.request, urllib.parse
import pandas as pd       # análise de dados
import openpyxl           # Excel
import PyPDF2             # PDF

Logging em Python

Use bm.bmLog() para registrar mensagens nos logs oficiais de execução, que aparecem no Control Room:

Python: registrar log no processo
bm.bmLog('Processando...')
bm.bmLog('Total de itens: ' + str(len(lista)))

API de contexto do processo

Além das variáveis, o runtime expõe outras utilidades:

Objeto / FunçãoLinguagemDescrição
bm.get('{var}', default)Node.js e PythonLê uma variável do processo (chave no formato {variavel})
bm.globalDataNode.js e PythonObjeto/dict somente leitura com todas as variáveis do processo
bm.bmLog(mensagem)Node.js e PythonRegistra mensagem nos logs oficiais de execução (visível no Control Room)
bm.done(result, updates)Node.js e PythonObrigatório ao final. Finaliza o script e escreve as variáveis de updates de volta ao processo
Credencial vem de bm.secret(), não de {vault.CHAVE} Dentro de um script ninguém substitui {...}, então a referência do Cofre de Senhas que funciona no resto do produto não vale aqui. Use bm.secret('CHAVE'), com a chave crua. A chave pode ser montada em tempo de execução, e chave inexistente levanta erro listando as disponíveis. Veja Mini SDK, credenciais do Cofre.
Variável marcada como Dado sensível bm.get('{var}') devolve o valor real, mesmo de uma variável marcada como Dado sensível. A marca esconde o valor do log e do estado guardado, não do seu código. Não escreva esse valor em bm.bmLog(): o que o script cria por conta própria não é marcado sozinho.

Exemplos práticos

Calcular impostos sobre um valor

Node.js
const valor_bruto  = parseFloat(bm.get('{valor_bruto}')) || 0;
const aliquota_iss = 0.05;  // 5%
const aliquota_pis = 0.0065;

const valor_iss = valor_bruto * aliquota_iss;
const valor_pis = valor_bruto * aliquota_pis;

bm.done('calculado', {
  '{valor_iss}':     valor_iss.toFixed(2),
  '{valor_pis}':     valor_pis.toFixed(2),
  '{valor_liquido}': (valor_bruto - valor_iss - valor_pis).toFixed(2)
});

Parsear XML de NF-e

Node.js: parsear XML
const xml2js  = require('xml2js');
const xml_nfe = bm.get('{xml_nfe}', '');

(async () => {
  const resultado = await xml2js.parseStringPromise(xml_nfe, { explicitArray: false });
  const nfe = resultado.nfeProc?.NFe?.infNFe;

  const numero = nfe?.ide?.nNF || '';
  bm.bmLog('NF-e parseada: ' + numero);

  bm.done('ok', {
    '{numero_nf}':      numero,
    '{valor_total}':    nfe?.total?.ICMSTot?.vNF || '0',
    '{cnpj_emitente}':  nfe?.emit?.CNPJ || ''
  });
})();

Gerar CSV e salvar em variável

Python: criar CSV em memória
import csv, io, base64

itens = bm.get('{lista_itens}', [])

output = io.StringIO()
writer = csv.DictWriter(output, fieldnames=['produto', 'qty', 'preco'])
writer.writeheader()
writer.writerows(itens)

csv_texto = output.getvalue()
# Codifica em base64 para armazenar na variável
bm.done('csv gerado', {
    '{csv_base64}': base64.b64encode(csv_texto.encode()).decode()
})