// Cadastra um lead, abre um negócio no funil padrão, avança uma etapa e lista os negócios abertos. // Rode com: RUMO_TOKEN=teha_pat_... npx tsx exemplo.ts (Node 20.3+) import { RateLimitError, RumoApiError, RumoCRM } from "@rumocrm/api"; const token = process.env.RUMO_TOKEN; if (!token) throw new Error("Defina RUMO_TOKEN com um token criado em Configurações → API e integrações."); const rumo = new RumoCRM({ token }); // endereço padrão: https://rumocrm.com/api/v1 async function main() { // Upsert: o mesmo telefone devolve o mesmo contato, nunca duplica. const contato = await rumo.contacts.upsert({ name: "Maria Souza", phone: "(15) 99807-3400", tags: ["site"] }); const { data: funis } = await rumo.pipelines.list(); const funil = funis.find((f) => f.isDefault) ?? funis[0]; const { data: etapas } = await rumo.pipelines.listStages(funil.id); // valueCents: dinheiro em centavos (R$ 1.500,00). const negocio = await rumo.deals.create({ title: `Proposta - ${contato.name}`, pipelineId: funil.id, contactId: contato.id, valueCents: 150000, }); const segundaEtapa = etapas.filter((etapa) => etapa.type === "open")[1]; if (segundaEtapa) await rumo.deals.move(negocio.id, { stageId: segundaEtapa.id }); // Percorre todas as páginas sozinho (nextCursor/hasMore). for await (const aberto of rumo.deals.listAll({ pipelineId: funil.id, status: "open" })) { console.log(aberto.title, aberto.valueCents === null ? "sem valor" : aberto.valueCents / 100); } } main().catch((erro: unknown) => { if (erro instanceof RateLimitError) console.error(`Limite atingido; tente em ${erro.retryAfter ?? "?"} s`); else if (erro instanceof RumoApiError) console.error(erro.status, erro.code, erro.message, erro.requestId); else console.error(erro); process.exitCode = 1; });