Synergy Connect

Documentação

Mídia

Imagem, áudio, vídeo, documento e figurinha podem ser enviados por link (uma URL pública) ou por id (um arquivo que você subiu antes). As rotas de mídia são as da Cloud API da Meta, atrás da mesma chave de escopo messages (Autenticação).

Quero…Chamada
Subir um arquivoPOST /{version}/{phone_number_id}/media
Consultar uma mídiaGET /{version}/{media_id}?phone_number_id=…
Baixar o arquivoGET /{version}/{media_id}/download?phone_number_id=…
Apagar uma mídiaDELETE /{version}/{media_id}?phone_number_id=…

Formatos e tamanhos#

Tipo (type)FormatosTamanho
imageJPEG ou PNG, 8 bits, RGB ou RGBAaté 5 MB
audioAAC, AMR, MP3, M4A ou OGG (só codec OPUS, mono). Mensagem de voz (voice: true): OGG/OPUSaté 16 MB
videoMP4 ou 3GPP, vídeo H.264 e áudio AAC (um só canal de áudio, ou nenhum)até 16 MB
documentTXT, PDF, DOC/DOCX, XLS/XLSX, PPT/PPTXaté 100 MB na Meta; 16 MB pelo upload da Synergy
stickerWEBP de 512 × 512 pxestática até 100 KB, animada até 500 KB

Os tipos MIME aceitos: image/jpeg, image/png, audio/aac, audio/amr, audio/mpeg, audio/mp4, audio/ogg, video/mp4, video/3gpp, text/plain, application/pdf, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-powerpoint, application/vnd.openxmlformats-officedocument.presentationml.presentation e image/webp. Quem valida o arquivo é a Meta.

Subir um arquivo (upload)#

multipart/form-data com file, type (o tipo MIME do arquivo) e messaging_product=whatsapp. A Synergy repassa o formulário à Meta como chegou. O header Content-Length é obrigatório (um upload em partes, sem tamanho declarado, é recusado) e a requisição inteira, arquivo mais campos, cabe em 16 MB: acima disso, 400. Um documento maior que 16 MB vai por link.

Resposta 200 (a da Meta):

O id vale para envios deste número, por 30 dias na Meta. Guarde-o se for reusar o arquivo.

Exemplo

curl

curl -X POST 'https://api.synergyconnect.com.br/v25.0/106540352242922/media' \
  -H "Authorization: Bearer $SYNERGY_API_KEY" \
  -F 'messaging_product=whatsapp' \
  -F 'type=image/jpeg' \
  -F 'file=@foto.jpg;type=image/jpeg'

JavaScript

import { openAsBlob } from 'node:fs';

const form = new FormData();
form.append('messaging_product', 'whatsapp');
form.append('type', 'image/jpeg');
form.append('file', await openAsBlob('foto.jpg', { type: 'image/jpeg' }), 'foto.jpg');

const res = await fetch('https://api.synergyconnect.com.br/v25.0/106540352242922/media', {
  method: 'POST',
  headers: { Authorization: `Bearer ${process.env.SYNERGY_API_KEY}` }, // sem Content-Type: o fetch põe o boundary
  body: form,
});
const { id } = await res.json();

Python

import os

import requests

with open("foto.jpg", "rb") as f:
    res = requests.post(
        "https://api.synergyconnect.com.br/v25.0/106540352242922/media",
        headers={"Authorization": f"Bearer {os.environ['SYNERGY_API_KEY']}"},
        data={"messaging_product": "whatsapp", "type": "image/jpeg"},
        files={"file": ("foto.jpg", f, "image/jpeg")},
    )
media_id = res.json()["id"]
JSON
{
  "id": "1166846181421424"
}

Enviar por id#

O mesmo id serve em audio.id, video.id, document.id, sticker.id, no cabeçalho de uma mensagem interativa e no cabeçalho de um modelo (Modelos de mensagem (templates)).

Exemplo

curl

curl -X POST 'https://api.synergyconnect.com.br/v25.0/106540352242922/messages' \
  -H "Authorization: Bearer $SYNERGY_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
  "messaging_product": "whatsapp",
  "recipient_type": "individual",
  "to": "5511999999999",
  "type": "image",
  "image": {
    "id": "1166846181421424",
    "caption": "Seu comprovante"
  }
}'

JavaScript

const res = await fetch('https://api.synergyconnect.com.br/v25.0/106540352242922/messages', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.SYNERGY_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "messaging_product": "whatsapp",
    "recipient_type": "individual",
    "to": "5511999999999",
    "type": "image",
    "image": {
      "id": "1166846181421424",
      "caption": "Seu comprovante"
    }
  }),
});
console.log(res.status, await res.json());

Python

import os

import requests

res = requests.post(
    "https://api.synergyconnect.com.br/v25.0/106540352242922/messages",
    headers={"Authorization": f"Bearer {os.environ['SYNERGY_API_KEY']}"},
    json={
        "messaging_product": "whatsapp",
        "recipient_type": "individual",
        "to": "5511999999999",
        "type": "image",
        "image": {
            "id": "1166846181421424",
            "caption": "Seu comprovante",
        },
    },
)
print(res.status_code, res.json())

Em vez do id, passe link com uma URL HTTP ou HTTPS pública: a Meta baixa o arquivo na hora do envio. Nunca os dois no mesmo objeto. A Meta recomenda o id: com um link fora do ar o envio é aceito (200) e falha depois, no status failed.

Exemplo

curl

curl -X POST 'https://api.synergyconnect.com.br/v25.0/106540352242922/messages' \
  -H "Authorization: Bearer $SYNERGY_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
  "messaging_product": "whatsapp",
  "recipient_type": "individual",
  "to": "5511999999999",
  "type": "document",
  "document": {
    "link": "https://arquivos.example.com/boletos/42.pdf",
    "filename": "boleto-pedido-42.pdf",
    "caption": "Seu boleto vence dia 10"
  }
}'

JavaScript

const res = await fetch('https://api.synergyconnect.com.br/v25.0/106540352242922/messages', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.SYNERGY_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "messaging_product": "whatsapp",
    "recipient_type": "individual",
    "to": "5511999999999",
    "type": "document",
    "document": {
      "link": "https://arquivos.example.com/boletos/42.pdf",
      "filename": "boleto-pedido-42.pdf",
      "caption": "Seu boleto vence dia 10"
    }
  }),
});
console.log(res.status, await res.json());

Python

import os

import requests

res = requests.post(
    "https://api.synergyconnect.com.br/v25.0/106540352242922/messages",
    headers={"Authorization": f"Bearer {os.environ['SYNERGY_API_KEY']}"},
    json={
        "messaging_product": "whatsapp",
        "recipient_type": "individual",
        "to": "5511999999999",
        "type": "document",
        "document": {
            "link": "https://arquivos.example.com/boletos/42.pdf",
            "filename": "boleto-pedido-42.pdf",
            "caption": "Seu boleto vence dia 10",
        },
    },
)
print(res.status_code, res.json())

Consultar uma mídia#

phone_number_id na query é obrigatório (sem ele, 400 código 100). Só mídia deste número é lida: outro id responde 404 (código 100), sem dizer o que ele é. Serve para mídia enviada e recebida.

Resposta 200. A url é desta API (não a da Meta, que expira em minutos e pede o token da conta):

Exemplo

curl

curl 'https://api.synergyconnect.com.br/v25.0/1166846181421424?phone_number_id=106540352242922' \
  -H "Authorization: Bearer $SYNERGY_API_KEY"

JavaScript

const res = await fetch('https://api.synergyconnect.com.br/v25.0/1166846181421424?phone_number_id=106540352242922', {
  headers: { Authorization: `Bearer ${process.env.SYNERGY_API_KEY}` },
});
const media = await res.json(); // media.url, media.mime_type, media.sha256, media.file_size

Python

import os

import requests

res = requests.get(
    "https://api.synergyconnect.com.br/v25.0/1166846181421424",
    params={"phone_number_id": "106540352242922"},
    headers={"Authorization": f"Bearer {os.environ['SYNERGY_API_KEY']}"},
)
media = res.json()
JSON
{
  "id": "1166846181421424",
  "url": "https://api.synergyconnect.com.br/v25.0/1166846181421424/download?phone_number_id=106540352242922",
  "mime_type": "image/jpeg",
  "sha256": "4b68ab3847feda7d6c62c1fbcbeebfa35eab7351ed5e78f4ddadea5df64b8015",
  "file_size": 303833,
  "messaging_product": "whatsapp"
}

Baixar o arquivo#

Baixe a url da consulta, com a mesma chave. A Synergy busca o arquivo na Meta e repassa os bytes, sem guardar; Content-Type é o do arquivo e a resposta nunca vai para cache. Sem phone_number_id na query, a resposta é 404 (código 100).

Para uma mídia que o cliente enviou, o webhook messages traz só o id (com mime_type e sha256): consulte e baixe (Receber mensagens e status).

Exemplo

curl

curl -o arquivo.jpg 'https://api.synergyconnect.com.br/v25.0/1166846181421424/download?phone_number_id=106540352242922' \
  -H "Authorization: Bearer $SYNERGY_API_KEY"

JavaScript

import { writeFile } from 'node:fs/promises';

const headers = { Authorization: `Bearer ${process.env.SYNERGY_API_KEY}` };
const base = 'https://api.synergyconnect.com.br/v25.0';
const media = await (await fetch(`${base}/${mediaId}?phone_number_id=106540352242922`, { headers })).json();
const file = Buffer.from(await (await fetch(media.url, { headers })).arrayBuffer());
await writeFile('arquivo', file);

Python

import os

import requests

headers = {"Authorization": f"Bearer {os.environ['SYNERGY_API_KEY']}"}
media = requests.get(
    f"https://api.synergyconnect.com.br/v25.0/{media_id}",
    params={"phone_number_id": "106540352242922"},
    headers=headers,
).json()
file = requests.get(media["url"], headers=headers).content
open("arquivo", "wb").write(file)

Apagar uma mídia#

Apaga o arquivo na Meta. Antes, o id é conferido como uma mídia deste número: outro id responde 404 e nada é apagado.

Resposta 200: { "success": true }.

Exemplo

curl

curl -X DELETE 'https://api.synergyconnect.com.br/v25.0/1166846181421424?phone_number_id=106540352242922' \
  -H "Authorization: Bearer $SYNERGY_API_KEY"

JavaScript

const res = await fetch('https://api.synergyconnect.com.br/v25.0/1166846181421424?phone_number_id=106540352242922', {
  method: 'DELETE',
  headers: { Authorization: `Bearer ${process.env.SYNERGY_API_KEY}` },
});
console.log(res.status, await res.json());

Python

res = requests.delete(
    "https://api.synergyconnect.com.br/v25.0/1166846181421424",
    params={"phone_number_id": "106540352242922"},
    headers=headers,
)
print(res.status_code, res.json())

Limites#

As rotas de mídia contam só no limite de borda da chave por número (Limites de taxa), não no limite de mensagens do número. Os erros seguem o formato da Graph API (Erros).

Ficou com dúvida? Escreva para suporte@synergyconnect.com.br.