Pular para o conteúdo principal

Exemplos com o SDK

Esta página mostra, passo a passo, como usar o SDK de aplicativos nas operações mais comuns. Cada exemplo funciona sozinho e pode ser copiado para a página do seu aplicativo.

Antes, leia Desenvolver um aplicativo para entender o contexto, os erros e os limites.

Esqueleto de um aplicativo​

Todo aplicativo começa igual: carrega o SDK, conecta e monta o caminho do quadro.

<!doctype html>
<html lang="pt-BR">
<head>
<meta charset="utf-8">
<title>Meu aplicativo</title>
</head>
<body>
<main id="tela">Carregando…</main>

<script src="https://app.makepro.com.br/sdk/apps-v1.js"></script>
<script type="module">
const contexto = await makepro.conectar();

// Caminho base do quadro onde o aplicativo foi aberto
const empresa = contexto.escopo.empresaId;
const quadro = contexto.conteiner.id;
const base = `/api/v1/companies/${empresa}/notes/boards/${quadro}`;

document.getElementById('tela').textContent = `Olá, ${contexto.usuario.nome}!`;
</script>
</body>
</html>

Os exemplos abaixo usam as variáveis contexto e base desse esqueleto.

Ler as colunas do quadro​

Leia as colunas antes de ler ou gravar valores. É nelas que estão o id de cada coluna, o tipo e as opções de status e de lista.

const resposta = await makepro.fetch(`${base}/columns`);
const colunas = resposta.corpo; // lista de colunas

for (const coluna of colunas) {
console.log(coluna.id, coluna.type, coluna.label);
}

// Achar uma coluna pelo nome que aparece no quadro
const situacao = colunas.find((coluna) => coluna.label === 'Situação');

Listar os itens​

const resposta = await makepro.fetch(`${base}/elements`);
const itens = resposta.corpo.elements;

for (const item of itens) {
console.log(item.name);
}

Cada item traz os valores em column_values, uma lista de { column_id, type, value }. Para ler o valor de uma coluna:

function valorDaColuna(item, columnId) {
const celula = item.column_values.find((c) => c.column_id === columnId);
return celula ? celula.value : null;
}

const total = itens.reduce((soma, item) => soma + (valorDaColuna(item, 'valor') || 0), 0);

Quadros grandes vêm em páginas. Quando a resposta trouxer next_cursor, peça a próxima página com ele:

async function todosOsItens() {
const itens = [];
let cursor = null;
do {
const caminho = cursor ? `${base}/elements?cursor=${encodeURIComponent(cursor)}` : `${base}/elements`;
const resposta = await makepro.fetch(caminho);
itens.push(...resposta.corpo.elements);
cursor = resposta.corpo.next_cursor;
} while (cursor);
return itens;
}

Ler os itens em que a pessoa clicou​

No painel do item, no menu do item e na seleção, contexto.alvos.ids traz os itens que a pessoa escolheu. Na guia do quadro, a lista vem vazia.

const ids = contexto.alvos.ids;

if (ids.length === 0) {
mostrar('Abra o aplicativo a partir de um item ou de uma seleção.');
} else {
const itens = await Promise.all(
ids.map((id) => makepro.fetch(`${base}/elements/${id}`)),
);
desenhar(itens.filter((r) => r.ok).map((r) => r.corpo));
}

No painel do item, a pessoa pode trocar de item sem fechar o aplicativo. Redesenhe a tela quando isso acontecer:

makepro.aoMudarContexto(async (novo) => {
const [id] = novo.alvos.ids;
const resposta = await makepro.fetch(`${base}/elements/${id}`);
desenhar([resposta.corpo]);
});

Criar um item​

Exige a permissão Alterar itens do quadro.

const resposta = await makepro.fetch(`${base}/elements`, {
method: 'POST',
body: {
name: 'Medição 06 — Revestimentos',
column_values: [
{ column_id: 'situacao', value: 'pendente' }, // id da opção de status
{ column_id: 'data_medicao', value: '2026-12-15' }, // data no formato AAAA-MM-DD
{ column_id: 'valor', value: 98500 }, // número
],
},
});

if (resposta.ok) {
await makepro.avisar(`Item "${resposta.corpo.name}" criado`);
}

Na gravação, informe só column_id e value. O tipo vem da própria coluna.

Tipo da colunaFormato do value
Texto'Observação livre'
Número98500
Data'2026-12-15'
Statuso id da opção, por exemplo 'aprovada'
Linha do tempo{ inicio: '2026-12-01', fim: '2026-12-20' }

Alterar um item​

Envie só o que muda. Os outros valores ficam como estão.

const [id] = contexto.alvos.ids;

const resposta = await makepro.fetch(`${base}/elements/${id}`, {
method: 'PATCH',
body: {
column_values: [{ column_id: 'situacao', value: 'aprovada' }],
},
});

if (!resposta.ok) {
await makepro.avisar('Não foi possível aprovar a medição');
}

Para renomear o item, envie name no mesmo corpo.

Alterar vários itens de uma vez​

Na barra de seleção, use a rota em lote para gravar o mesmo valor em todos os itens marcados com um único pedido.

const resposta = await makepro.fetch(`${base}/elements/bulk/column-value`, {
method: 'POST',
body: {
element_ids: contexto.alvos.ids,
column_id: 'situacao',
value: 'em_analise',
},
});

const { total_falha } = resposta.corpo;
await makepro.avisar(
total_falha === 0
? `${contexto.alvos.ids.length} itens enviados para análise`
: `${total_falha} itens não puderam ser alterados`,
);
await makepro.fechar();

A resposta traz total_sucesso, total_falha e, em resultados, uma linha por item com sucesso e motivo. Um item que a pessoa não pode alterar não derruba o lote: ele volta com sucesso: false.

Comentar num item​

const [id] = contexto.alvos.ids;

await makepro.fetch(`${base}/elements/${id}/comments`, {
method: 'POST',
body: { body: '<p>Medição conferida em campo.</p>' },
});

O comentário aceita HTML simples e sai em nome da pessoa que está usando o aplicativo. Para listar os comentários, use GET no mesmo caminho: a resposta é uma lista.

Ler as pessoas do quadro​

const resposta = await makepro.fetch(`${base}/people`);
const pessoas = resposta.corpo; // lista de pessoas

Use a lista para montar um seletor de responsável no aplicativo.

Enviar e baixar arquivos​

Exige a permissão Baixar e enviar arquivos. O item precisa estar em contexto.alvos.ids, e column_id é o id de uma coluna do tipo arquivo.

Para gerar um arquivo no aplicativo e anexá-lo ao item:

const [id] = contexto.alvos.ids;
const conteudo = new TextEncoder().encode('Item;Valor\nMedição 01;182400\n');

const anexo = await makepro.enviarArquivo({
element_id: id,
column_id: 'anexos',
filename: 'resumo-das-medicoes.csv',
content_type: 'text/csv',
bytes: conteudo.buffer,
});
// anexo = { asset_id, filename, extension, content_type, size }

await makepro.avisar(`Arquivo ${anexo.filename} anexado`);

Para ler um arquivo que já está no item, pegue o asset_id no valor da coluna de arquivo. Cada anexo vem como { asset_id, filename, extension, content_type, size }:

const [id] = contexto.alvos.ids;
const { corpo: item } = await makepro.fetch(`${base}/elements/${id}`);
const anexos = item.column_values.find((c) => c.column_id === 'anexos')?.value ?? [];

for (const anexo of anexos) {
// Bytes do arquivo, para processar no aplicativo
const arquivo = await makepro.baixarArquivo({
element_id: id,
column_id: 'anexos',
asset_id: anexo.asset_id,
});
console.log(anexo.filename, arquivo.bytes.byteLength);
}

// Ou salvar no computador da pessoa
await makepro.salvarArquivo({ element_id: id, column_id: 'anexos', asset_id: anexos[0].asset_id });

O asset_id devolvido por enviarArquivo serve do mesmo jeito. O MakePro só entrega arquivo que está na coluna do item informado, e só para item que está no contexto.

observação

A lista de anexos da coluna devolve links de arquivo, por isso não passa por makepro.fetch: o pedido termina com ROTA_DE_ARQUIVO_PELA_PONTE.

Tratar erros​

Há dois tipos de falha, e o aplicativo precisa tratar os dois:

  • A API recusou o pedido. A promessa termina normalmente, com ok: false, e o motivo vem em status e corpo.
  • O MakePro recusou o pedido. A promessa é rejeitada com { codigo, mensagem }, por exemplo LIMITE_DE_TAXA ou FORA_DO_CONTEXTO.

Uma função auxiliar resolve os dois casos num lugar só:

async function chamar(caminho, opcoes) {
try {
const resposta = await makepro.fetch(caminho, opcoes);
if (resposta.ok) return resposta.corpo;
const motivo = resposta.corpo?.detail?.message || `erro ${resposta.status}`;
await makepro.avisar(`Não foi possível concluir: ${motivo}`);
} catch (erro) {
await makepro.avisar(`Não foi possível concluir: ${erro.mensagem}`);
}
return null;
}

const itens = await chamar(`${base}/elements`);

Seguir o tema do MakePro​

O contexto informa se a pessoa usa o tema claro ou escuro. Aplique a mesma aparência:

document.documentElement.dataset.tema = contexto.tema; // 'claro' ou 'escuro'
makepro.aoMudarContexto((novo) => {
document.documentElement.dataset.tema = novo.tema;
});
:root { --fundo: #ffffff; --texto: #1f2937; }
:root[data-tema="escuro"] { --fundo: #111827; --texto: #f3f4f6; }
body { background: var(--fundo); color: var(--texto); }

Exemplo completo: aprovar medições selecionadas​

Um aplicativo cadastrado em Ação em vários itens selecionados, com as permissões Ler itens do quadro e Alterar itens do quadro. A pessoa marca as medições no quadro, abre o aplicativo, confere o total e aprova todas de uma vez.

<!doctype html>
<html lang="pt-BR">
<head>
<meta charset="utf-8">
<title>Aprovar medições</title>
<style>
body { font-family: system-ui, sans-serif; margin: 24px; }
li { margin: 4px 0; }
button { margin-top: 16px; padding: 8px 16px; }
</style>
</head>
<body>
<h1>Aprovar medições</h1>
<ul id="lista"></ul>
<p id="total"></p>
<button id="aprovar" disabled>Aprovar todas</button>

<script src="https://app.makepro.com.br/sdk/apps-v1.js"></script>
<script type="module">
const contexto = await makepro.conectar();
const base = `/api/v1/companies/${contexto.escopo.empresaId}/notes/boards/${contexto.conteiner.id}`;
const ids = contexto.alvos.ids;

const respostas = await Promise.all(ids.map((id) => makepro.fetch(`${base}/elements/${id}`)));
const itens = respostas.filter((r) => r.ok).map((r) => r.corpo);
const valor = (item) => item.column_values.find((c) => c.column_id === 'valor')?.value || 0;

document.getElementById('lista').replaceChildren(...itens.map((item) => {
const li = document.createElement('li');
li.textContent = `${item.name}: R$ ${valor(item).toLocaleString('pt-BR')}`;
return li;
}));
const total = itens.reduce((soma, item) => soma + valor(item), 0);
document.getElementById('total').textContent = `Total: R$ ${total.toLocaleString('pt-BR')}`;

const botao = document.getElementById('aprovar');
botao.disabled = itens.length === 0;
botao.addEventListener('click', async () => {
botao.disabled = true;
const resposta = await makepro.fetch(`${base}/elements/bulk/column-value`, {
method: 'POST',
body: { element_ids: ids, column_id: 'situacao', value: 'aprovada' },
});
await makepro.avisar(resposta.ok ? `${itens.length} medições aprovadas` : 'Não foi possível aprovar');
await makepro.fechar();
});
</script>
</body>
</html>

Troque valor e situacao pelos id das colunas do seu quadro. Eles aparecem na resposta de GET ${base}/columns.