Site

Consumindo a API em Node.js v3

Backend, scripts, bots (Discord, Telegram) ou workers. Qualquer processo Node que fale HTTP.


Cliente mínimo

Node 18+ · fetch nativo

const base = process.env.MUCRM_URL; // https://seu-site.com
let token;

async function login(username, password) {
  const res = await fetch(`${base}/api/login`, {
    method: 'POST',
    headers: {
      Accept: 'application/json',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({username, password}),
  });
  const data = await res.json();
  if (!data.success) throw new Error(data.error || 'login failed');
  token = data.token;
  return token;
}

async function api(path, body) {
  const res = await fetch(`${base}${path}`, {
    method: 'POST',
    headers: {
      Accept: 'application/json',
      'Content-Type': 'application/json',
      Authorization: `Bearer ${token}`,
    },
    body: body ? JSON.stringify(body) : undefined,
  });
  if (res.status === 422) {
    const {errors} = await res.json();
    throw Object.assign(new Error('validation'), {errors});
  }
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  return res.json();
}

await login(process.env.MU_USER, process.env.MU_PASS);
const me = await api('/api/me');

discord.js snippet

import {Client, GatewayIntentBits} from 'discord.js';

const client = new Client({intents: [GatewayIntentBits.Guilds]});

client.on('interactionCreate', async (interaction) => {
  if (!interaction.isChatInputCommand()) return;
  if (interaction.commandName !== 'me') return;

  // token de um user de serviço / vínculo já autenticado
  const me = await api('/api/me');
  await interaction.reply({content: `Conta: ${me.username ?? 'ok'}`, ephemeral: true});
});
⚠️Segredos
Guarde MUCRM_URL, usuário de serviço e token em variáveis de ambiente / secrets do host do bot — nunca no repositório.

Allowlist

Se auth.allowed não for ['*'], adicione o IP de saída do bot (VPS/Railway/etc.) na lista. Veja Rate Limiting & Headers.

Próximo: JavaScript / Fetch · Social OAuth.