---
title: "SDK JavaScript e TypeScript da WAME: WhatsApp tipado, nos três canais"
description: "O SDK oficial da WAME em Node.js e TypeScript: envio tipado com autocompletar, os três canais da Meta na mesma chamada e webhook no envelope padrão."
url: "https://wame.api.br/blog/sdk-javascript-typescript-whatsapp"
language: "pt-BR"
og:type: "article"
published_time: "2026-09-10"
modified_time: "2026-09-10"
author: "Raphael Serafim"
keywords: "sdk whatsapp javascript, api whatsapp node js, whatsapp typescript, npm whatsapp api, enviar whatsapp node, sdk whatsapp nodejs, biblioteca whatsapp node"
reading_time: "9 min de leitura"
---

# SDK JavaScript e TypeScript da WAME: WhatsApp tipado, nos três canais

> O SDK oficial da WAME em Node.js e TypeScript: envio tipado com autocompletar, os três canais da Meta na mesma chamada e webhook no envelope padrão.

**Se o seu sistema é Node, o SDK da WAME tipa a integração inteira** — os três canais da Meta, o envio, a instância e o webhook. Este guia vai do `npm install` até o handler recebendo mensagem.

## Instalação

```bash
npm install @raphaelvserafim/client-api-whatsapp
```

```ts
import { Wame, TypeMessage } from '@raphaelvserafim/client-api-whatsapp';

const wa = new Wame({
  server: 'https://server.wame.api.br',
  key: process.env.WAME_KEY!,
});
```

Os tipos vêm no pacote. Não há `@types` separado para instalar.

## Primeiro envio

```ts
const to = '5566996852025';   // internacional, só dígitos

await wa.message.send({
  type: TypeMessage.TEXT,
  body: { to, text: 'Seu pedido #1042 saiu para entrega 🚚' },
});
```

O `TypeMessage` é um enum, e é ele que faz o trabalho pesado no editor: o autocompletar lista os tipos disponíveis, e o corpo esperado muda conforme o tipo escolhido.

```ts
// o compilador recusa: mensagem de texto não tem `url`
await wa.message.send({
  type: TypeMessage.TEXT,
  body: { to, url: 'https://exemplo.com/foto.jpg' },
});
```

Esse erro, num projeto sem tipos, seria uma resposta 400 em produção às três da manhã.

## Mídia

```ts
await wa.message.send({
  type: TypeMessage.IMAGE,
  body: { to, url: 'https://exemplo.com/nota.jpg', caption: 'Sua NF-e' },
});

await wa.message.send({
  type: TypeMessage.AUDIO,
  body: { to, url: 'https://exemplo.com/audio.mp3' },
});
```

## Os três canais

```ts
await wa.message.send({
  type: TypeMessage.TEXT,
  body: { to, text: 'Oi', provider: 'instagram' },
});
```

Um campo. Sem `provider`, vai no WhatsApp; com `instagram` ou `messenger`, vai no outro canal — [mesma instância, mesma chave, mesmo webhook](/blog/api-instagram-messenger-mesma-api-whatsapp).

## Instância e webhook

```ts
// Conectar (API não oficial)
const qr = await wa.instance.connect();
const code = await wa.instance.pairingCode('5566996852025');

// Estado
const info = await wa.instance.info();

// Operação
await wa.instance.logout();
await wa.instance.restart();
await wa.instance.resync();
```

Configurar para onde os eventos vão:

```ts
await wa.instance.updateWebhook({
  allowWebhook: true,
  allowNumber: 'all',
  webhookMessage: 'https://seusistema.com/webhook/wame',
  webhookFormat: 'meta',   // envelope da Cloud API — o mesmo p/ os 3 canais
});

const stats = await wa.instance.webhookStatistics();
```

O `webhookStatistics()` vale conhecer: quando o webhook "para de funcionar", ele mostra se as entregas estão saindo e falhando ou se nem estão sendo tentadas — o que decide em que lado procurar. É o primeiro passo depois do [teste com webhook.site](/blog/webhook-whatsapp-nao-chega-como-testar).

## O handler que serve os três canais

```ts
import express from 'express';

type EventoWame = {
  provider: 'whatsapp' | 'instagram' | 'messenger';
  entry: Array<{
    changes: Array<{
      value: {
        messages?: Array<{
          from: string;
          id: string;
          type: string;
          text?: { body: string };
        }>;
        statuses?: Array<{ id: string; status: string }>;
      };
    }>;
  }>;
};

const app = express();
app.use(express.json());

app.post('/webhook/wame', (req, res) => {
  res.sendStatus(200);                     // primeiro isto, sempre
  processar(req.body as EventoWame).catch(console.error);
});

async function processar(evento: EventoWame) {
  const value = evento.entry?.[0]?.changes?.[0]?.value;

  // `statuses` é entrega/leitura, não mensagem nova.
  const msg = value?.messages?.[0];
  if (!msg || msg.type !== 'text') return;

  await registrar({
    canal: evento.provider,
    de: msg.from,
    texto: msg.text!.body,
    messageId: msg.id,
  });
}
```

Um handler. Três canais. O único campo que varia é `provider`.

## Em Next.js e serverless

Só no servidor:

```ts
// app/api/webhook/wame/route.ts
export async function POST(req: Request) {
  const evento = await req.json();
  after(() => processar(evento));   // responde já, processa depois
  return Response.json({ ok: true });
}
```

**Nunca chame o SDK a partir do cliente.** A chave da instância iria para o bundle, e qualquer visitante poderia enviar mensagem pelo seu número. Server action, route handler ou função serverless — nunca componente de cliente.

Em serverless há uma segunda armadilha: se você responde e a função encerra, o processamento em segundo plano morre junto. Use o mecanismo da plataforma para trabalho pós-resposta (`after` no Next, `waitUntil` em edge runtimes) ou empurre para uma fila.

## Tratamento de erro

```ts
try {
  await wa.message.send({ type: TypeMessage.TEXT, body: { to, text } });
} catch (e) {
  // Número sem WhatsApp, instância desconectada, limite atingido.
  // O erro traz o código; trate cada caso, não engula tudo num catch mudo.
  console.error('falha ao enviar para', to, e);
  await enfileirarParaNovaTentativa({ to, text });
}
```

Vale conferir antes de mandar, quando a lista veio de cadastro do cliente:

```ts
const existe = await wa.contact.checkNumber(to);
if (!existe) return marcarInvalido(to);
```

Isso é o que separa uma lista que entrega de uma lista que queima reputação — assunto de [higiene de lista e opt-out](/blog/lista-contatos-optin-optout-whatsapp).

## Conclusão

O ganho do SDK tipado não é escrever menos: é o compilador recusando o payload errado antes do deploy. Com três canais no mesmo contrato, isso vale três vezes.

Se você trabalha em PHP, o [SDK PHP](/blog/sdk-php-whatsapp-instagram-messenger) cobre o mesmo terreno. Se vai colocar isso em produção, [webhook em produção](/blog/webhook-producao-assinatura-retry-idempotencia) trata da parte que só aparece com volume.

Referência completa em [docs/sdk/ts](/docs/sdk/ts).

## Perguntas frequentes

### Como instalar o SDK JavaScript da WAME?

npm install @raphaelvserafim/client-api-whatsapp. O pacote já inclui as definições de tipo, então funciona em JavaScript puro e em TypeScript sem instalar @types separado.

### O SDK funciona com TypeScript?

Sim, e é onde ele rende mais. Os tipos de mensagem são um enum (TypeMessage) e o corpo de cada tipo é tipado, então o editor mostra os campos válidos e o compilador acusa erro se você mandar url numa mensagem de texto.

### Dá para usar o SDK em Next.js ou em serverless?

Sim, desde que a chamada aconteça no servidor: route handler, server action ou função serverless. Nunca no cliente — a chave da instância ficaria exposta no bundle e qualquer pessoa poderia enviar mensagens em nome do seu número.

### Como enviar no Instagram e no Messenger pelo SDK?

É o mesmo método send, com o campo provider no corpo da mensagem. WhatsApp é o padrão; informar instagram ou messenger direciona a mesma chamada ao outro canal, porque a instância cobre os três.

### O SDK cobre criação de instância?

Sim. O objeto instance expõe conexão por QR Code e por pairing code, informações, logout, restart, resync e configuração de webhook — o suficiente para provisionar e operar contas sem ninguém abrir um painel.
