Clientes e SDKs
O cliente mínimo em Node, Python e PHP — e por que não publicamos um pacote.
A Amivu não publica pacote em npm, PyPI ou Packagist. O que existe aqui é o que um pacote faria — em vinte linhas que você cola no seu projeto e passa a manter.
Por que não há SDK
Um SDK oficial é um contrato a mais para manter: ele versiona junto com a API, atrasa quando a API anda, e trava quem usa numa versão do cliente enquanto o servidor já mudou. Para uma superfície REST com autenticação por cabeçalho e JSON dos dois lados, ele resolve pouco e custa caro.
Enquanto isso não muda, dizer que existe um SDK seria pior que não ter: quem procurasse o pacote não acharia, e a documentação teria mentido no primeiro contato. Preferimos entregar o pedaço de código que resolve o mesmo problema.
code preservado, e gerar a chave de idempotência nas escritas. O resto é fetch.O cliente, em vinte linhas
É o mesmo amivu(...) que os guias usam. Cole no seu projeto, e a partir daí toda chamada é uma linha.
const BASE = "https://api.amivu.com.br/v1";
export async function amivu(path, { method = "GET", body, idempotencyKey } = {}) {
const headers = { Authorization: `Bearer ${process.env.AMIVU_API_KEY}` };
if (body) {
headers["Content-Type"] = "application/json";
// Sem chave, um reenvio depois de timeout manda a mensagem duas vezes.
headers["Idempotency-Key"] = idempotencyKey ?? crypto.randomUUID();
}
const response = await fetch(BASE + path, {
method,
headers,
body: body ? JSON.stringify(body) : undefined,
});
const payload = await response.json();
if (!response.ok) throw new AmivuError(payload.error);
return payload;
}
export class AmivuError extends Error {
constructor(error) {
super(error?.message ?? "Falha na chamada à Amivu.");
this.type = error?.type;
this.code = error?.code;
this.requestId = error?.request_id;
}
}Tratar erro uma vez só
Com o cliente acima, o erro chega como exceção e carrega o type, o code e o request_id. Decida pelo type, registre o code — um switch exaustivo sobre code quebra no dia em que a API ganhar um caso novo.
try {
await amivu("/messages", { method: "POST", body: mensagem });
} catch (erro) {
if (erro.type === "rate_limit_error") return repetirDepois(erro);
if (erro.type === "validation_error") return corrigirEDesistir(erro);
// Guarde o request_id: é o que transforma "deu erro ontem" numa linha exata.
registrar({ code: erro.code, requestId: erro.requestId });
throw erro;
}Gerar um cliente da especificação
Se o seu time prefere um cliente tipado, gere-o do openapi.json — ele é a mesma especificação que a API valida, e um cliente gerado dela nunca fica atrás da API por esquecimento.
npx openapi-typescript https://api.amivu.com.br/v1/openapi.json \
-o src/amivu.d.tsVeja também Erros e Idempotência.
Escrevemos sobre operação de atendimento, canais e IA no blog da Amivu.