waiaconnect

Documentação / Essencial

Receber o histórico de Coexistence

GET /v1/connections/:id/history

Markdown

Ao conectar um número por Coexistence, antes de abrir a janela da Meta, o negócio responde se quer que entreguemos o histórico das suas conversas: até 6 meses, as mensagens das duas partes, sem grupos. O histórico continua no celular dele: nada é apagado nem movido dali. A escolha é agora: a Meta compartilha o histórico uma única vez, quando o número é conectado, e se a resposta for não, depois não dá para pedir. Se a resposta for sim, pedimos à Meta (no app WhatsApp Business é preciso aceitar compartilhá-lo), guardamos criptografado por até 7 dias e entregamos a você de duas formas, a que acontecer primeiro:

· Por webhook: eventos history.batch com até 500 mensagens cada um (no formato da Meta, como message.received, com contact e direction), assinados como os demais, e um history.completed quando não sobra nada. Vão por uma fila separada que não atrasa as suas mensagens ao vivo: um histórico grande pode levar horas.
· Pela API, se você ainda não tem webhook: GET /v1/connections/{id}/history entrega os lotes em ordem (limit de 1 a 5, after = o nextCursor anterior). Ler não apaga: quando tiver guardado um lote, confirme-o com POST /v1/connections/{id}/history/{batchId}/ack.

Cada lote é apagado assim que é entregue (o seu 2xx ou a sua confirmação); o que não for entregue é apagado aos 7 dias de qualquer jeito. Se no quinto dia restarem lotes sem entregar, avisamos UMA vez por número (painel e e-mail) com a data em que serão apagados. Não conta como tráfego nem consome cota. Se o negócio respondeu que não, não pedimos nada à Meta. Se um dia ficarmos sem espaço, deixamos de guardar histórico novo e avisamos com history.dropped.

# 1) read a page (reading does NOT delete)
curl "https://api.waiaconnect.com/v1/connections/conn_…/history?limit=1" -H "Authorization: Bearer wc_live_YOUR_API_KEY"
# → { "data": [ { "batchId": "hb_…", "count": 500, "messages": [ … ] } ], "hasMore": true, "nextCursor": 1 }

# 2) once you stored it, confirm it → deleted from WAIA Connect at once
curl -X POST "https://api.waiaconnect.com/v1/connections/conn_…/history/hb_…/ack" -H "Authorization: Bearer wc_live_YOUR_API_KEY"
# 3) next page: ?after=1 (the nextCursor) — until hasMore is false
const H = { "Authorization": "Bearer wc_live_YOUR_API_KEY" };
let after = 0, hasMore = true;
while (hasMore) {
  const page = await (await fetch(`https://api.waiaconnect.com/v1/connections/conn_…/history?limit=1&after=${after}`, { headers: H })).json();
  for (const batch of page.data) {
    await saveMessages(batch.messages);            // your storage; dedupe on batch.batchId
    await fetch(`https://api.waiaconnect.com/v1/connections/conn_…/history/${batch.batchId}/ack`, { method: "POST", headers: H });
  }
  hasMore = page.hasMore;
  after = page.nextCursor;
}
<?php
$h = ["Authorization: Bearer wc_live_YOUR_API_KEY"];
$after = 0;
do {
  $ch = curl_init("https://api.waiaconnect.com/v1/connections/conn_…/history?limit=1&after=" . $after);
  curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => $h]);
  $page = json_decode(curl_exec($ch), true);
  foreach ($page["data"] as $batch) {
    save_messages($batch["messages"]); // your storage; dedupe on batchId
    $ack = curl_init("https://api.waiaconnect.com/v1/connections/conn_…/history/" . $batch["batchId"] . "/ack");
    curl_setopt_array($ack, [CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => $h]);
    curl_exec($ack);
  }
  $after = $page["nextCursor"];
} while ($page["hasMore"]);
import requests
H = {"Authorization": "Bearer wc_live_YOUR_API_KEY"}
after, has_more = 0, True
while has_more:
    page = requests.get("https://api.waiaconnect.com/v1/connections/conn_…/history", headers=H, params={"limit": 1, "after": after}).json()
    for batch in page["data"]:
        save_messages(batch["messages"])  # your storage; dedupe on batchId
        requests.post(f"https://api.waiaconnect.com/v1/connections/conn_…/history/{batch['batchId']}/ack", headers=H)
    has_more, after = page["hasMore"], page["nextCursor"]

Fotos, áudios e documentos chegam sem o arquivo (type: "media_placeholder", sem id). A Meta manda o arquivo só dos últimos 14 dias, numa mensagem separada com o mesmo id de mensagem e o seu image.id (ou .audio.id, …), e nem sempre manda: se chegar, baixe-o com GET /v1/media/{id} dentro dos 7 dias. Cada um traz o nosso connect.media: { status: "available", available_until } se veio com o seu id, ou { status: "unavailable", reason } com older_than_14_days (a Meta nunca o manda), meta_failed (a Meta não conseguiu trazê-lo do celular; esse 131052 já não chega a você como message.status) ou pending (pode chegar em outro lote).

Deduplique por batchId: um lote pode chegar duas vezes (por exemplo, se reiniciarmos no meio de uma entrega).

Se você integra com links de cadastro, mande historyDelivery: true|false ao criar o link se já perguntou ao seu cliente; se não, a página pergunta a ele.

history.synced continua chegando como resumo de cada lote da Meta (progress: 100 = a Meta terminou).