npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@oficialapi/sdk

v9.1.0

Published

SDK oficial da OficialAPI - Integração completa com WhatsApp, Telegram, Facebook, Instagram e WebChat

Readme

OficialAPI SDK

SDK oficial da OficialAPI para integração.

📦 Instalação

npm install @oficialapi/sdk
# ou
yarn add @oficialapi/sdk
# ou
pnpm add @oficialapi/sdk

🔧 Configuração

import { OficialAPISDK } from '@oficialapi/sdk';

const sdk = new OficialAPISDK({
  clientId: 'seu-client-id',
  clientSecret: 'seu-client-secret',
  timeout: 30000,  
  maxRetries: 3,  
  retryDelay: 1000, 
});

🔐 Autenticação

Obtenha o token de acesso e passe-o em cada chamada ao SDK:

const tokenResponse = await sdk.auth.getToken('client-id', 'client-secret');
const accessToken = tokenResponse.access_token;

📚 Exemplos de Uso

Enviar Mensagem de Texto

const result = await sdk.whatsapp.sendText({
  channelToken: 'sk_live_9999999999999999999999999999',
  sender: '5511999999999',
  messageText: 'Olá! Como posso ajudar você hoje?'
}, accessToken);

console.log(result.data.messageId);

Enviar Mídia

 
await sdk.whatsapp.sendMedia({
  channelToken: 'sk_live_...',
  sender: '5511999999999',
  fileUrl: 'https://example.com/image.jpg',
  type: 'image',
  caption: 'Veja esta imagem!'
}, accessToken);

 
await sdk.whatsapp.sendMedia({
  channelToken: 'sk_live_...',
  sender: '5511999999999',
  fileUrl: 'https://example.com/documento.pdf',
  type: 'document',
  caption: 'Confira este documento',
  fileName: 'meu_documento.pdf'  
}, accessToken);

Nota: O parâmetro fileName é opcional e usado apenas para documentos. Se não fornecido e o tipo for document, o nome do arquivo será extraído automaticamente da URL.

Enviar Template

Os templates do WhatsApp suportam diferentes tipos de componentes e parâmetros. Veja os exemplos abaixo:

Template simples com apenas BODY:

await sdk.whatsapp.sendTemplate({
  channelToken: 'sk_live_...',
  sender: '5511999999999',
  templateName: 'hello_world',
  languageCode: 'pt_BR',
  components: [
    {
      type: 'BODY',
      parameters: [
        { type: 'text', text: 'João' }
      ]
    }
  ]
}, accessToken);

Template com HEADER com documento PDF:

await sdk.whatsapp.sendTemplate({
  channelToken: 'sk_live_...',
  sender: '555199579150',
  templateName: 'order_confirmation_pdf',
  languageCode: 'en_US',
  components: [
    {
      type: 'HEADER',
      parameters: [
        {
          type: 'document',
          document: {
            link: 'https://seusite.com/recibos/860198-230332.pdf',
            filename: 'order_860198-230332.pdf'
          }
        }
      ]
    },
    {
      type: 'BODY',
      parameters: [
        { type: 'text', text: 'Pablo' },
        { type: 'text', text: '860198-230332' }
      ]
    }
  ]
}, accessToken);

Template com HEADER com imagem:

await sdk.whatsapp.sendTemplate({
  channelToken: 'sk_live_...',
  sender: '5511999999999',
  templateName: 'promotion_notification',
  languageCode: 'pt_BR',
  components: [
    {
      type: 'HEADER',
      parameters: [
        {
          type: 'image',
          image: {
            link: 'https://seusite.com/imagens/promocao.jpg'
          }
        }
      ]
    },
    {
      type: 'BODY',
      parameters: [
        { type: 'text', text: 'Maria' },
        { type: 'text', text: 'R$ 150,00' }
      ]
    }
  ]
}, accessToken);

Template com HEADER com texto dinâmico:

await sdk.whatsapp.sendTemplate({
  channelToken: 'sk_live_...',
  sender: '5511999999999',
  templateName: 'seasonal_promotion',
  languageCode: 'pt_BR',
  components: [
    {
      type: 'HEADER',
      parameters: [
        {
          type: 'text',
          text: 'Promoção de Verão'
        }
      ]
    },
    {
      type: 'BODY',
      parameters: [
        { type: 'text', text: 'Ana' },
        { type: 'text', text: '25%' }
      ]
    }
  ]
}, accessToken);

Nota: Os tipos de componentes devem ser em maiúsculas (HEADER, BODY, BUTTONS). Para documentos no HEADER, o campo filename é opcional mas recomendado para melhor experiência do usuário.

Enviar Botões

await sdk.whatsapp.sendButtons({
  channelToken: 'sk_live_...',
  sender: '5511999999999',
  text: 'Escolha uma opção:',
  buttons: [
    {
      id: 'option1',
      title: 'Opção 1'
    },
    {
      id: 'option2',
      title: 'Opção 2'
    }
  ],
  // Opcional: incluir mídia (imagem) no topo da mensagem
  media: {
    type: 'image',
    url: 'https://example.com/image.jpg'
  }
}, accessToken);

Enviar Lista Interativa

await sdk.whatsapp.sendList({
  channelToken: 'sk_live_...',
  sender: '5511999999999',
  headerText: 'Escolha um produto:',
  bodyText: 'Selecione uma opção abaixo:',
  footerText: 'Equipe de Vendas', // Opcional
  buttonText: 'Ver Produtos',
  sections: [
    {
      title: 'Produtos',
      rows: [
        {
          id: 'product1',
          title: 'Produto 1',
          description: 'Descrição do produto 1'
        },
        {
          id: 'product2',
          title: 'Produto 2',
          description: 'Descrição do produto 2'
        }
      ]
    }
  ]
}, accessToken);

Enviar Contato

await sdk.whatsapp.sendContact({
  channelToken: 'sk_live_...',
  sender: '5511999999999',
  contacts: [
    {
      name: {
        formatted_name: 'João Silva',
        first_name: 'João',
        last_name: 'Silva'
      },
      phones: [
        {
          phone: '+5511999999999',
          type: 'Mobile',
          wa_id: '5511999999999'
        }
      ]
    }
  ]
}, accessToken);

Enviar Localização

await sdk.whatsapp.sendLocation({
  channelToken: 'sk_live_...',
  sender: '5511999999999',
  latitude: -23.5505,
  longitude: -46.6333,
  name: 'São Paulo',
  address: 'São Paulo, SP, Brasil'
}, accessToken);

Enviar Áudio

// Áudio básico (requer upload prévio da mídia)
await sdk.whatsapp.sendAudio({
  channelToken: 'sk_live_...',
  sender: '5511999999999',
  mediaId: '1013859600285441', // ID da mídia após upload
  voice: false // Opcional: false para áudio básico
}, accessToken);

// Mensagem de voz (arquivo .ogg codec OPUS)
await sdk.whatsapp.sendAudio({
  channelToken: 'sk_live_...',
  sender: '5511999999999',
  mediaId: '1013859600285441',
  voice: true // true para mensagem de voz
}, accessToken);

Enviar Vídeo

// Requer upload prévio da mídia para obter o mediaId
await sdk.whatsapp.sendVideo({
  channelToken: 'sk_live_...',
  sender: '5511999999999',
  mediaId: '1166846181421424', // ID da mídia após upload
  caption: 'Veja este vídeo!' // Opcional
}, accessToken);

Enviar Documento

// Requer upload prévio da mídia para obter o mediaId
await sdk.whatsapp.sendDocument({
  channelToken: 'sk_live_...',
  sender: '5511999999999',
  mediaId: '1376223850470843', // ID da mídia após upload
  filename: 'documento.pdf', // Opcional
  caption: 'Aqui está o documento' // Opcional
}, accessToken);

Enviar Pedido com Opções de Pagamento

⚠️ Nota Importante: O status do pedido deve ser pending ao usar sendOrderDetails. Use sendOrderStatus para atualizar o status após o pagamento.

Exemplo 1: Pedido Digital com PIX

await sdk.whatsapp.sendOrderDetails({
  channelToken: 'sk_live_9999999999999999999999999',
  sender: '5511999999999',
  headerText: 'Confirmação de Pedido',
  bodyText: 'Seu pedido #12345 está pronto para pagamento!',
  footerText: 'Obrigado por comprar conosco!',
  reference_id: 'pedido_12345_1704067200',
  type: 'digital-goods',
  currency: 'BRL',
  total_amount: {
    value: 50000,
    offset: 100
  },
  order: {
    status: 'pending', // OBRIGATÓRIO: deve ser 'pending' para review_and_pay
    items: [
      {
        retailer_id: '1234567',
        name: 'Cake',
        amount: {
          value: 50000,
          offset: 100
        },
        quantity: 1
      }
    ],
    subtotal: {
      value: 50000,
      offset: 100
    },
    tax: {
      value: 0,
      offset: 100,
      description: 'Sem impostos'
    }
  },
  payment_settings: [
    {
      type: 'pix_dynamic_code',
      pix_dynamic_code: {
        code: '00020101021226700014br.gov.bcb.pix2548pix.example.com...',
        merchant_name: 'Minha Empresa Ltda',
        key: '39580525000189',
        key_type: 'CNPJ'
      }
    }
  ]
}, accessToken);

Exemplo 2: Pedido Digital com Link de Pagamento

await sdk.whatsapp.sendOrderDetails({
  channelToken: 'sk_live_9999999999999999999999999',
  sender: '5511999999999',
  bodyText: 'Sua fatura está disponível para pagamento!',
  reference_id: 'fatura_67890_1704067200',
  type: 'digital-goods',
  currency: 'BRL',
  total_amount: {
    value: 150000,
    offset: 100
  },
  order: {
    status: 'pending',
    items: [
      {
        retailer_id: 'item_001',
        name: 'Serviço Premium',
        amount: {
          value: 150000,
          offset: 100
        },
        quantity: 1
      }
    ],
    subtotal: {
      value: 150000,
      offset: 100
    },
    tax: {
      value: 0,
      offset: 100
    }
  },
  payment_settings: [
    {
      type: 'payment_link',
      payment_link: {
        uri: 'https://pagamento.exemplo.com/fatura/67890'
      }
    }
  ]
}, accessToken);

Exemplo 3: Pedido Digital com Boleto

await sdk.whatsapp.sendOrderDetails({
  channelToken: 'sk_live_9999999999999999999999999',
  sender: '5511999999999',
  bodyText: 'Sua inscrição está confirmada! Efetue o pagamento via boleto.',
  reference_id: 'inscricao_11111_1704067200',
  type: 'digital-goods',
  currency: 'BRL',
  total_amount: {
    value: 29900,
    offset: 100
  },
  order: {
    status: 'pending',
    items: [
      {
        retailer_id: 'curso_001',
        name: 'Curso de Programação',
        amount: {
          value: 29900,
          offset: 100
        },
        quantity: 1
      }
    ],
    subtotal: {
      value: 29900,
      offset: 100
    },
    tax: {
      value: 0,
      offset: 100
    }
  },
  payment_settings: [
    {
      type: 'boleto',
      boleto: {
        digitable_line: '03399026944140000002628346101018898510000008848'
      }
    }
  ]
}, accessToken);

Exemplo 4: Pedido Físico com Múltiplas Formas de Pagamento (PIX + Link)

await sdk.whatsapp.sendOrderDetails({
  channelToken: 'sk_live_9999999999999999999999999',
  sender: '5511999999999',
  bodyText: 'Seu pedido está pronto! Escolha a forma de pagamento:',
  reference_id: 'pedido_completo_22222_1704067200',
  type: 'physical-goods',
  currency: 'BRL',
  total_amount: {
    value: 262400, // subtotal (259900) + tax (0) + shipping (2500) - discount (0)
    offset: 100
  },
  order: {
    status: 'pending',
    catalog_id: '1234567890',
    items: [
      {
        retailer_id: 'produto_001',
        name: 'Camiseta Básica',
        amount: {
          value: 79000,
          offset: 100
        },
        quantity: 2
      },
      {
        retailer_id: 'produto_002',
        name: 'Calça Jeans',
        amount: {
          value: 101900,
          offset: 100
        },
        quantity: 1
      }
    ],
    subtotal: {
      value: 259900,
      offset: 100
    },
    tax: {
      value: 0,
      offset: 100
    },
    shipping: {
      value: 2500,
      offset: 100,
      description: 'Frete via SEDEX'
    }
  },
  payment_settings: [
    {
      type: 'pix_dynamic_code',
      pix_dynamic_code: {
        code: '00020101021226700014br.gov.bcb.pix2548pix.example.com...',
        merchant_name: 'Minha Loja Virtual',
        key: '[email protected]',
        key_type: 'EMAIL'
      }
    },
    {
      type: 'payment_link',
      payment_link: {
        uri: 'https://minhaloja.com/pagar/22222'
      }
    }
  ]
}, accessToken);

Exemplo 5: Pedido com Desconto (Black Friday)

await sdk.whatsapp.sendOrderDetails({
  channelToken: 'sk_live_9999999999999999999999999',
  sender: '5511999999999',
  bodyText: 'Black Friday! Seu pedido com desconto especial:',
  reference_id: 'black_friday_33333_1704067200',
  type: 'digital-goods',
  currency: 'BRL',
  total_amount: {
    value: 39900, // subtotal (49900) + tax (0) + shipping (0) - discount (10000)
    offset: 100
  },
  order: {
    status: 'pending',
    items: [
      {
        retailer_id: 'bf_001',
        name: 'Pacote Premium',
        amount: {
          value: 49900,
          offset: 100
        },
        quantity: 1
      }
    ],
    subtotal: {
      value: 49900,
      offset: 100
    },
    tax: {
      value: 0,
      offset: 100
    },
    discount: {
      value: 10000,
      offset: 100,
      description: 'Desconto Black Friday 20%',
      discount_program_name: 'Black Friday 2024'
    }
  },
  payment_settings: [
    {
      type: 'pix_dynamic_code',
      pix_dynamic_code: {
        code: '00020101021226700014br.gov.bcb.pix2548pix.example.com...',
        merchant_name: 'Black Friday Loja',
        key: '5511999999999',
        key_type: 'PHONE'
      }
    }
  ]
}, accessToken);

Importante:

  • O total_amount.value deve ser igual a: subtotal + tax + shipping - discount
  • O status do pedido deve ser pending ao usar sendOrderDetails
  • Use sendOrderStatus para atualizar o status após o pagamento

Atualizar Status do Pedido

await sdk.whatsapp.sendOrderStatus({
  channelToken: 'sk_live_...',
  sender: '5511999999999',
  bodyText: 'Seu pedido foi enviado!',
  footerText: 'Obrigado!',  
  reference_id: 'pedido_12345_1704067200', 
  order_status: 'shipped',  
  status_description: 'Sua encomenda foi despachada pelos Correios',  
  payment_status: 'captured', 
  payment_timestamp: 1722445231  
}, accessToken);

Enviar Sticker

 
await sdk.whatsapp.sendSticker({
  channelToken: 'sk_live_...',
  sender: '5511999999999',
  mediaId: '798882015472548'  
}, accessToken);

Solicitar Localização

await sdk.whatsapp.sendLocationRequest({
  channelToken: 'sk_live_...',
  sender: '5511999999999',
  bodyText: 'Por favor, compartilhe sua localização para entregarmos seu pedido.',
  headerText: 'Confirme sua entrega',  
  footerText: 'Sua privacidade é importante'  
}, accessToken);

Enviar Mensagem com Botão CTA URL

await sdk.whatsapp.sendCtaUrl({
  channelToken: 'sk_live_...',
  sender: '5511999999999',
  bodyText: 'Confira nosso site!',
  buttonText: 'Acessar',  
  url: 'https://example.com',
  header: {  
    type: 'image',  
    link: 'https://example.com/banner.jpg' 
    
  },
  footerText: 'Ofertas válidas até 30/11'  
}, accessToken);

Enviar Carrossel de Mídia

await sdk.whatsapp.sendMediaCarousel({
  channelToken: 'sk_live_...',
  sender: '5511999999999',
  bodyText: 'Confira nossas ofertas da semana!', 
  cards: [  
    {
      cardIndex: 0,
      headerType: 'image', 
      headerLink: 'https://example.com/image1.jpg',
      bodyText: 'Oferta especial!',  
      buttonText: 'Comprar agora',  
      url: 'https://example.com/product1'
    },
    {
      cardIndex: 1,
      headerType: 'image',
      headerLink: 'https://example.com/image2.jpg',
      bodyText: 'Novo lançamento!',
      buttonText: 'Ver detalhes',
      url: 'https://example.com/product2'
    }
  ]
}, accessToken);

Baixar Mídia Descriptografada

const media = await sdk.whatsapp.downloadMedia({
  channelToken: 'sk_live_...',
  url: 'https://lookaside.fbsbx.com/whatsapp_business/attachment/?mid=...'
}, accessToken);

 
console.log(media.data.buffer);  
console.log(media.data.mimeType);  
console.log(media.data.filename);  
console.log(media.data.size);  

Responder Mensagem

await sdk.whatsapp.replyMessage({
  channelToken: 'sk_live_...',
  sender: '5511999999999',  
  messageText: 'Esta é uma resposta!',
  replyMessageId: 'wamid.xxx',  
  preview_url: false  
}, accessToken);

Reagir a Mensagem

await sdk.whatsapp.reactMessage({
  channelToken: 'sk_live_...',
  sender: '5511999999999',  
  emoji: '👍',  
  message_id: 'wamid.xxx'  
}, accessToken);

Gerenciar Templates

 
const templates = await sdk.whatsapp.listTemplates('sk_live_...', accessToken);

 
const template = await sdk.whatsapp.getTemplate('sk_live_...', 'template_id', accessToken);

 
await sdk.whatsapp.createTemplate({
  channelToken: 'sk_live_...',
  name: 'welcome_message',
  language: 'pt_BR',
  category: 'UTILITY',
  components: [
    {
      type: 'BODY',
      text: 'Olá {{1}}! Bem-vindo ao nosso serviço.'
    }
  ]
}, accessToken);

#### Upload de Mídia
 

**Exemplo 1: Upload de imagem sem filename (opcional)**

```typescript
// Em ambiente Node.js
import fs from 'fs';

const fileBuffer = fs.readFileSync('./imagem.jpg');
const uploadResult = await sdk.whatsapp.uploadMedia({
  channelToken: 'sk_live_...',
  file: fileBuffer,
  mediaType: 'image'
  
}, accessToken);

const mediaId = uploadResult.data.handle; // "4::aW1hZ2UtMTIzNDU2Nzg5MGCE..."

Exemplo 2: Upload de imagem com filename

 
import fs from 'fs';

const fileBuffer = fs.readFileSync('./imagem.jpg');
const uploadResult = await sdk.whatsapp.uploadMedia({
  channelToken: 'sk_live_...',
  file: fileBuffer,
  mediaType: 'image',
  filename: 'minha_imagem.jpg'  
}, accessToken);

const mediaId = uploadResult.data.handle;

Exemplo 3: Upload de vídeo (Node.js)

import fs from 'fs';

const videoBuffer = fs.readFileSync('./video.mp4');
const uploadResult = await sdk.whatsapp.uploadMedia({
  channelToken: 'sk_live_...',
  file: videoBuffer,
  mediaType: 'video',
  filename: 'meu_video.mp4'
}, accessToken);

 
await sdk.whatsapp.sendVideo({
  channelToken: 'sk_live_...',
  sender: '5511999999999',
  mediaId: uploadResult.data.handle,
  caption: 'Confira este vídeo!'
}, accessToken);
import fs from 'fs';



 
await sdk.whatsapp.sendDocument({
  channelToken: 'sk_live_...',
  sender: '5511999999999',
  mediaId: uploadResult.data.handle,
  filename: 'documento_importante.pdf',
  caption: 'Aqui está o documento solicitado'
}, accessToken);

Exemplo 6: Upload de sticker (Node.js)

import fs from 'fs';

const stickerBuffer = fs.readFileSync('./sticker.webp');
const uploadResult = await sdk.whatsapp.uploadMedia({
  channelToken: 'sk_live_...',
  file: stickerBuffer,
  mediaType: 'image',  
  filename: 'sticker.webp'
}, accessToken);

 
await sdk.whatsapp.sendSticker({
  channelToken: 'sk_live_...',
  sender: '5511999999999',
  mediaId: uploadResult.data.handle
}, accessToken);

Exemplo 7: Upload em ambiente Browser (Frontend)

 
const fileInput = document.querySelector('input[type="file"]');
const file = fileInput.files[0];

 
const getMediaType = (file: File): 'image' | 'video' | 'document' => {
  if (file.type.startsWith('image/')) return 'image';
  if (file.type.startsWith('video/')) return 'video';
  return 'document';
};

const uploadResult = await sdk.whatsapp.uploadMedia({
  channelToken: 'sk_live_...',
  file: file,
  mediaType: getMediaType(file),
  filename: file.name  
}, accessToken);

const mediaId = uploadResult.data.handle;

Exemplo 8: Upload usando Blob (Browser)

 
const blob = new Blob(['conteúdo do arquivo'], { type: 'text/plain' });

const uploadResult = await sdk.whatsapp.uploadMedia({
  channelToken: 'sk_live_...',
  file: blob,
  mediaType: 'document',
  filename: 'arquivo.txt'
}, accessToken);

const mediaId = uploadResult.data.handle;

Exemplo 9: Upload para usar em template

import fs from 'fs';

// Upload da imagem para usar no header do template
const imageBuffer = fs.readFileSync('./logo.jpg');
const uploadResult = await sdk.whatsapp.uploadMedia({
  channelToken: 'sk_live_...',
  file: imageBuffer,
  mediaType: 'image'
 
}, accessToken);

 
await sdk.whatsapp.createTemplate({
  channelToken: 'sk_live_...',
  name: 'product_launch',
  category: 'MARKETING',
  language: 'pt_BR',
  components: [
    {
      type: 'HEADER',
      format: 'IMAGE',
      example: {
        header_handle: [uploadResult.data.handle]  
      }
    },
    {
      type: 'BODY',
      text: 'Confira nosso novo produto!'
    }
  ]
}, accessToken);

Notas importantes:

  • O parâmetro mediaType é obrigatório e deve ser um dos valores: 'image', 'video' ou 'document'.
  • O parâmetro filename é opcional. Se não fornecido, não será enviado ao servidor (a API da OficialAPI rejeita campos vazios).
  • O mediaId retornado está no formato "4::aW1hZ2UtMTIzNDU2Nzg5MGCE..." e deve ser usado diretamente nos métodos sendAudio, sendVideo, sendDocument ou sendSticker.
  • Para templates, use o handle retornado no campo header_handle ou example.header_handle.
  • Formatos suportados:
    • Imagens (mediaType: 'image'): JPG, PNG, GIF, WEBP
    • Vídeos (mediaType: 'video'): MP4, 3GP
    • Áudios: Use mediaType: 'video' para áudios (OGG codec OPUS para voz, MP3, M4A)
    • Documentos (mediaType: 'document'): PDF, DOC, DOCX, XLS, XLSX, PPT, PPTX
    • Stickers: Use mediaType: 'image' para stickers WEBP (até 500KB para animado, 100KB para estático)

**Mais exemplos de templates:**

```typescript
// Template de atualização de envio (UTILITY)
await sdk.whatsapp.createTemplate({
  channelToken: 'sk_live_01JABCDEFGHIJKLMNOPQRSTUVWXYZ',
  name: 'shipping_update',
  category: 'UTILITY',
  language: 'pt_BR',
  components: [
    {
      type: 'BODY',
      text: 'Ótima notícia! Seu pedido com código #{{1}} já está a caminho. Use o código de rastreio {{2}} para acompanhar.',
      example: {
        body_text: [
          ['ORD12345', 'BR123456789']
        ]
      }
    },
    {
      type: 'BUTTONS',
      buttons: [
        {
          type: 'URL',
          text: 'Rastrear',
          url: 'https://rastreio.com/track/{{1}}',
          example: ['ORD12345']
        },
        {
          type: 'QUICK_REPLY',
          text: 'Entendido'
        }
      ]
    }
  ],
  allow_category_change: false
}, accessToken);

// Template de promoção sazonal (MARKETING)
await sdk.whatsapp.createTemplate({
  channelToken: 'sk_live_01JABCDEFGHIJKLMNOPQRSTUVWXYZ',
  name: 'seasonal_promotion',
  category: 'MARKETING',
  language: 'en_US',
  components: [
    {
      type: 'HEADER',
      format: 'TEXT',
      text: 'Our {{1}} is on!',
      example: {
        header_text: ['Summer Sale']
      }
    },
    {
      type: 'BODY',
      text: 'Shop now through {{1}} and use code {{2}} to get {{3}} off all merchandise.',
      example: {
        body_text: [
          ['the end of August', '25OFF', '25%']
        ]
      }
    },
    {
      type: 'FOOTER',
      text: 'Use the buttons below to manage your marketing subscriptions'
    },
    {
      type: 'BUTTONS',
      buttons: [
        {
          type: 'QUICK_REPLY',
          text: 'Unsubscribe from Promos'
        },
        {
          type: 'QUICK_REPLY',
          text: 'Unsubscribe from All'
        }
      ]
    }
  ],
  allow_category_change: true
}, accessToken);

// Template com documento PDF (UTILITY)
await sdk.whatsapp.createTemplate({
  channelToken: 'sk_live_01JABCDEFGHIJKLMNOPQRSTUVWXYZ',
  name: 'order_confirmation_pdf',
  category: 'UTILITY',
  language: 'en_US',
  components: [
    {
      type: 'HEADER',
      format: 'DOCUMENT',
      example: {
        header_handle: ['4::aW1hZ2UtMTIzNDU2Nzg5MGCE...'],
        header_text: ['order_receipt.pdf']
      }
    },
    {
      type: 'BODY',
      text: 'Thank you for your order, {{1}}! Your order number is {{2}}. Tap the PDF linked above to view your receipt.',
      example: {
        body_text: [
          ['Pablo', '860198-230332']
        ]
      }
    },
    {
      type: 'BUTTONS',
      buttons: [
        {
          type: 'PHONE_NUMBER',
          text: 'Call Support',
          phone_number: '15550051310'
        },
        {
          type: 'URL',
          text: 'Contact Support',
          url: 'https://www.luckyshrub.com/support'
        }
      ]
    }
  ],
  allow_category_change: false
}, accessToken);

// Template de lançamento de produto com imagem (MARKETING)
await sdk.whatsapp.createTemplate({
  channelToken: 'sk_live_01JABCDEFGHIJKLMNOPQRSTUVWXYZ',
  name: 'product_launch',
  category: 'MARKETING',
  language: 'pt_BR',
  components: [
    {
      type: 'HEADER',
      format: 'IMAGE',
      example: {
        header_handle: ['4::aW1hZ2UtMTIzNDU2Nzg5MGCE...']
      }
    },
    {
      type: 'BODY',
      text: 'Olá {{1}}! Nossa nova coleção {{2}} já está disponível!',
      example: {
        body_text: [
          ['Maria', 'Verão 2025']
        ]
      }
    },
    {
      type: 'BUTTONS',
      buttons: [
        {
          type: 'URL',
          text: 'Ver coleção',
          url: 'https://loja.com/colecao'
        },
        {
          type: 'QUICK_REPLY',
          text: 'Compartilhar'
        }
      ]
    }
  ],
  allow_category_change: true
}, accessToken);

// Template de cupom promocional (MARKETING)
await sdk.whatsapp.createTemplate({
  channelToken: 'sk_live_01JABCDEFGHIJKLMNOPQRSTUVWXYZ',
  name: 'coupon_promo',
  category: 'MARKETING',
  language: 'pt_BR',
  components: [
    {
      type: 'HEADER',
      format: 'TEXT',
      text: '🎉 Oferta Especial!'
    },
    {
      type: 'BODY',
      text: 'Olá {{1}}! Use o código abaixo para get {{2}} de desconto em toda a loja.',
      example: {
        body_text: [
          ['Maria', '25%']
        ]
      }
    },
    {
      type: 'BUTTONS',
      buttons: [
        {
          type: 'COPY_CODE',
          text: 'Copiar código',
          example: 'SUMMER25'
        },
        {
          type: 'URL',
          text: 'Ver loja',
          url: 'https://loja.com'
        }
      ]
    }
  ],
  allow_category_change: true
}, accessToken);

// Template com parâmetros nomeados (UTILITY)
await sdk.whatsapp.createTemplate({
  channelToken: 'sk_live_01JABCDEFGHIJKLMNOPQRSTUVWXYZ',
  name: 'order_confirmation',
  category: 'UTILITY',
  language: 'en_US',
  components: [
    {
      type: 'BODY',
      text: 'Thank you, {{first_name}}! Your order number is {{order_number}}.',
      example: {
        body_text_named_params: [
          {
            param_name: 'first_name',
            example: 'Pablo'
          },
          {
            param_name: 'order_number',
            example: '860198-230332'
          }
        ]
      }
    }
  ],
  allow_category_change: false
}, accessToken);

// Template de atualização de entrega com localização (UTILITY)
await sdk.whatsapp.createTemplate({
  channelToken: 'sk_live_01JABCDEFGHIJKLMNOPQRSTUVWXYZ',
  name: 'order_delivery_update',
  category: 'UTILITY',
  language: 'en_US',
  components: [
    {
      type: 'HEADER',
      format: 'LOCATION'
    },
    {
      type: 'BODY',
      text: 'Good news {{1}}! Your order #{{2}} is on its way to the location above.',
      example: {
        body_text: [
          ['Mark', '566701']
        ]
      }
    },
    {
      type: 'FOOTER',
      text: 'To stop receiving delivery updates, tap the button below.'
    },
    {
      type: 'BUTTONS',
      buttons: [
        {
          type: 'QUICK_REPLY',
          text: 'Stop Delivery Updates'
        }
      ]
    }
  ],
  allow_category_change: false
}, accessToken);

// Template de mensagem de boas-vindas simples (MARKETING)
await sdk.whatsapp.createTemplate({
  channelToken: 'sk_live_01JABCDEFGHIJKLMNOPQRSTUVWXYZ',
  name: 'welcome_message',
  category: 'MARKETING',
  language: 'pt_BR',
  components: [
    {
      type: 'BODY',
      text: 'Bem-vindo à nossa loja! Estamos felizes em ter você conosco.'
    },
    {
      type: 'FOOTER',
      text: 'Equipe da Loja'
    },
    {
      type: 'BUTTONS',
      buttons: [
        {
          type: 'QUICK_REPLY',
          text: 'Ver ofertas'
        },
        {
          type: 'QUICK_REPLY',
          text: 'Falar no chat'
        }
      ]
    }
  ],
  allow_category_change: true
}, accessToken);

Telegram

Enviar Mensagem de Texto

await sdk.telegram.sendMessage({
  channelToken: 'sk_live_...',
  chatId: '123456789',
  text: 'Olá! Como posso ajudar?',
  parseMode: 'HTML'
}, accessToken);

Enviar Mídia

await sdk.telegram.sendMedia({
  channelToken: 'sk_live_...',
  chatId: '123456789',
  fileUrl: 'https://example.com/image.jpg',
  type: 'photo',
  caption: 'Veja esta imagem!'
}, accessToken);

Enviar Botões

await sdk.telegram.sendButtons({
  channelToken: 'sk_live_...',
  chatId: '123456789',
  text: 'Escolha uma opção:',
  buttons: [
    { type: 'url', title: 'Visitar Site', url: 'https://example.com' },
    { type: 'callback_data', title: 'Opção 1', callback_data: 'option1' },
    { type: 'callback_data', title: 'Opção 2', callback_data: 'option2' },
    { type: 'web_app', title: 'Abrir App', url: 'https://myapp.com' }
  ]
}, accessToken);

Enviar Localização

await sdk.telegram.sendLocation({
  channelToken: 'sk_live_...',
  chatId: '123456789',
  latitude: -23.5505,
  longitude: -46.6333
}, accessToken);

Enviar Contato

await sdk.telegram.sendContact({
  channelToken: 'sk_live_...',
  chatId: '123456789',
  phoneNumber: '+5511999999999',
  firstName: 'João',
  lastName: 'Silva'
}, accessToken);

Enviar Enquete

await sdk.telegram.sendPoll({
  channelToken: 'sk_live_...',
  chatId: '123456789',
  question: 'Qual sua cor favorita?',
  options: ['Vermelho', 'Azul', 'Verde'],
  isAnonymous: false,
  type: 'quiz',
  correctOptionId: 1
}, accessToken);

Enviar Venue (Local)

await sdk.telegram.sendVenue({
  channelToken: 'sk_live_...',
  chatId: '123456789',
  latitude: -23.5505,
  longitude: -46.6333,
  title: 'Restaurante XYZ',
  address: 'Rua ABC, 123, São Paulo'
}, accessToken);

Enviar Dado/Emoji Animado

await sdk.telegram.sendDice({
  channelToken: 'sk_live_...',
  chatId: '123456789',
  emoji: '🎲'
}, accessToken);

Enviar Sticker

await sdk.telegram.sendSticker({
  channelToken: 'sk_live_...',
  chatId: '123456789',
  stickerUrl: 'https://example.com/sticker.webp'
}, accessToken);

Enviar Voz

await sdk.telegram.sendVoice({
  channelToken: 'sk_live_...',
  chatId: '123456789',
  voiceUrl: 'https://example.com/voice.ogg',
  caption: 'Mensagem de voz',
  duration: 30
}, accessToken);

Enviar Video Note

await sdk.telegram.sendVideoNote({
  channelToken: 'sk_live_...',
  chatId: '123456789',
  videoNoteUrl: 'https://example.com/video_note.mp4',
  duration: 10,
  length: 360
}, accessToken);

Enviar Grupo de Mídia

await sdk.telegram.sendMediaGroup({
  channelToken: 'sk_live_...',
  chatId: '123456789',
  media: [
    { type: 'photo', media: 'https://example.com/image1.jpg', caption: 'Imagem 1' },
    { type: 'photo', media: 'https://example.com/image2.jpg', caption: 'Imagem 2' }
  ]
}, accessToken);

Enviar Teclado de Resposta

await sdk.telegram.sendReplyKeyboard({
  channelToken: 'sk_live_...',
  chatId: '123456789',
  text: 'Escolha uma opção:',
  keyboard: [
    [{ text: 'Opção 1' }, { text: 'Opção 2' }],
    [{ text: 'Opção 3' }]
  ],
  resizeKeyboard: true,
  oneTimeKeyboard: true
}, accessToken);

Editar Mensagem

await sdk.telegram.editMessage({
  channelToken: 'sk_live_...',
  chatId: '123456789',
  messageId: 123,
  text: 'Mensagem editada!',
  parseMode: 'HTML'
}, accessToken);

Deletar Mensagem

await sdk.telegram.deleteMessage({
  channelToken: 'sk_live_...',
  chatId: '123456789',
  messageId: 123
}, accessToken);

Baixar Mídia Descriptografada

 

const media = await sdk.telegram.downloadMedia({
  channelToken: 'sk_live_...',
  fileId: 'AgACAgEAAxkBAAItNmlmklyYNCEtvaFphVfSSO7CrEOjAALUC2sbh9owR9hT7MhQnTGfAQADAgADcwADOAQ'
}, accessToken);

 
console.log(media.data.buffer);  
console.log(media.data.mimeType);  
console.log(media.data.filename);  
console.log(media.data.size); 

WebChat

Enviar Mensagem de Texto

await sdk.webchat.sendText({
  channelToken: 'sk_live_...',
  chatId: 'chat_123456789',
  messageText: 'Olá!',
  typing: true,        // Opcional: mostrar indicador de digitação
  typingTime: 2000     // Opcional: tempo de digitação em ms
}, accessToken);

Enviar Card

await sdk.webchat.sendCard({
  channelToken: 'sk_live_...',
  chatId: 'chat_123456789',
  title: 'Produto',
  description: 'Descrição do produto',
  imageUrl: 'https://example.com/image.jpg',
  buttons: [
    {
      id: 'btn_1',                    // Opcional: ID único do botão
      text: 'Ver Mais',
      type: 'url',                    // 'text' | 'url' | 'phone' | 'postback'
      url: 'https://example.com/product',
      value: 'https://example.com/product'
    }
  ],
  typing: true,
  typingTime: 3000
}, accessToken);

Enviar Mídia

await sdk.webchat.sendMedia({
  channelToken: 'sk_live_...',
  chatId: 'chat_123456789',
  fileUrl: 'https://example.com/image.jpg',
  type: 'image',                      // 'image' | 'video' | 'audio' | 'file'
  caption: 'Veja esta imagem!',
  typing: true,
  typingTime: 2500
}, accessToken);

Enviar Carousel

await sdk.webchat.sendCarousel({
  channelToken: 'sk_live_...',
  chatId: 'chat_123456789',
  cards: [
    {
      title: 'Produto 1',
      subtitle: 'Descrição do produto 1',
      imageUrl: 'https://example.com/product1.jpg',
      buttons: [
        {
          id: 'btn_1',
          text: 'Ver Mais',
          type: 'url',
          url: 'https://example.com/product1',
          value: 'https://example.com/product1'
        }
      ]
    },
    {
      title: 'Produto 2',
      subtitle: 'Descrição do produto 2',
      imageUrl: 'https://example.com/product2.jpg',
      buttons: [
        {
          id: 'btn_2',
          text: 'Comprar',
          type: 'postback',
          value: 'BUY_PRODUCT_2'
        }
      ]
    }
  ],
  typing: true,
  typingTime: 4000
}, accessToken);

Enviar Formulário

await sdk.webchat.sendForm({
  channelToken: 'sk_live_...',
  chatId: 'chat_123456789',
  id: 'form_contact',                // Opcional: ID único do formulário
  title: 'Formulário de Contato',    // Opcional
  fields: [
    {
      id: 'name',                     // Opcional: se não fornecido, usa 'name'
      name: 'name',                   // Opcional: mantido para compatibilidade
      type: 'text',                   // 'text' | 'email' | 'number' | 'tel' | 'date' | 'select'
      label: 'Nome',
      placeholder: 'Digite seu nome',
      required: true
    },
    {
      id: 'email',
      type: 'email',
      label: 'E-mail',
      placeholder: 'Digite seu e-mail',
      required: true
    },
    {
      id: 'subject',
      type: 'select',
      label: 'Assunto',
      required: true,
      options: [
        { value: 'support', label: 'Suporte' },
        { value: 'sales', label: 'Vendas' }
      ]
    }
  ],
  submitButtonText: 'Enviar',        // Opcional
  typing: true,
  typingTime: 3000
}, accessToken);

Enviar Quick Replies

await sdk.webchat.sendQuickReplies({
  channelToken: 'sk_live_...',
  chatId: 'chat_123456789',
  messageText: 'Como podemos ajudar?',
  quickReplies: [
    {
      id: 'qr_1',                     // Opcional: ID único
      text: 'Suporte',
      value: 'SUPPORT'                // Opcional: valor para identificar a resposta
    },
    {
      id: 'qr_2',
      text: 'Vendas',
      value: 'SALES'
    }
  ],
  typing: true,
  typingTime: 2000
}, accessToken);

Enviar Botões

await sdk.webchat.sendButtons({
  channelToken: 'sk_live_...',
  chatId: 'chat_123456789',
  messageText: 'Escolha uma opção:',
  buttons: [
    {
      id: 'btn_1',
      text: 'Visitar Site',
      type: 'url',
      url: 'https://example.com',
      value: 'https://example.com'
    },
    {
      id: 'btn_2',
      text: 'Falar com Atendente',
      type: 'postback',
      value: 'HUMAN_AGENT'
    }
  ],
  typing: true,
  typingTime: 2500
}, accessToken);

Facebook

Listar Posts

// Listar posts do Facebook
const posts = await sdk.facebook.listPosts({
  channelToken: 'sk_live_...',
  channelType: 'facebook',
  limit: 10,
  type: 'feed', // 'feed' | 'photos' | 'videos' | 'events'
  includeComments: false,
  includeReactions: false
}, accessToken);

// Listar mídias do Instagram
const instagramMedia = await sdk.facebook.listPosts({
  channelToken: 'sk_live_...',
  channelType: 'instagram',
  limit: 10,
  type: 'media',
  includeComments: false,
  includeReactions: false
}, accessToken);

Criar Post

await sdk.facebook.createPost({
  channelToken: 'sk_live_...',
  channelType: 'facebook',
  message: 'Novo post!',
  link: 'https://example.com'
}, accessToken);

Listar Comentários

// Listar comentários do Facebook
const comments = await sdk.facebook.listComments({
  channelToken: 'sk_live_...',
  channelType: 'facebook',
  postId: 'post_id',
  limit: 20,
  order: 'created_time', // 'created_time' | 'like_count'
  filterUnanswered: false,
  includeReplies: false
}, accessToken);

// Listar comentários do Instagram
const instagramComments = await sdk.facebook.listComments({
  channelToken: 'sk_live_...',
  channelType: 'instagram',
  postId: 'media_id',
  limit: 20
}, accessToken);

Responder Comentário

await sdk.facebook.replyComment({
  channelToken: 'sk_live_...',
  channelType: 'facebook', // ou 'instagram'
  commentId: 'comment_id',
  message: 'Obrigado pelo comentário!'
}, accessToken);

Deletar Comentário

await sdk.facebook.deleteComment({
  channelToken: 'sk_live_...',
  channelType: 'facebook', // ou 'instagram'
  commentId: 'comment_id'
}, accessToken);

Enviar Mensagem de Texto

await sdk.facebook.sendText({
  channelToken: 'sk_live_...',
  channelType: 'facebook', // ou 'instagram'
  recipientId: 'user_id',
  message: 'Olá!',
  tags: ['HUMAN_AGENT'] // opcional, apenas para Instagram
}, accessToken);

Enviar Mídia

await sdk.facebook.sendMedia({
  channelToken: 'sk_live_...',
  channelType: 'facebook', // ou 'instagram'
  recipientId: 'user_id',
  fileUrl: 'https://example.com/image.jpg',
  type: 'image',
  caption: 'Veja esta imagem!',
  tags: ['HUMAN_AGENT'] // opcional, apenas para Instagram
}, accessToken);

Enviar Botões

await sdk.facebook.sendButtons({
  channelToken: 'sk_live_...',
  channelType: 'facebook', // ou 'instagram'
  recipientId: 'user_id',
  message: 'Escolha uma opção:',
  buttons: [
    { type: 'web_url', title: 'Visitar Site', url: 'https://example.com' },
    { type: 'postback', title: 'Opção', payload: 'OPTION_1' }
  ],
  tags: ['HUMAN_AGENT'] // opcional, apenas para Instagram
}, accessToken);

Enviar Sticker

await sdk.facebook.sendSticker({
  channelToken: 'sk_live_...',
  recipientId: 'user_id',
  stickerId: 369239263222822
}, accessToken);

Responder Mensagem

await sdk.facebook.replyMessage({
  channelToken: 'sk_live_...',
  channelType: 'facebook', // ou 'instagram'
  recipientId: 'user_id',
  messageId: 'message_id',
  message: 'Esta é uma resposta!',
  tags: ['HUMAN_AGENT'] // opcional, apenas para Instagram
}, accessToken);

Responder com Mídia

await sdk.facebook.replyMedia({
  channelToken: 'sk_live_...',
  channelType: 'facebook', // ou 'instagram'
  recipientId: 'user_id',
  messageId: 'message_id',
  fileUrl: 'https://example.com/image.jpg',
  type: 'image',
  caption: 'Aqui está!',
  tags: ['HUMAN_AGENT'] // opcional, apenas para Instagram
}, accessToken);

Compartilhar Post do Instagram

await sdk.facebook.sharePost({
  channelToken: 'sk_live_...',
  mediaId: 'media_id',
  recipientId: 'user_id'
}, accessToken);

Obter Perfil de Usuário

const userProfile = await sdk.facebook.getUserProfile({
  channelToken: 'sk_live_...',
  userId: 'user_id'
}, accessToken);

Obter Perfil de Página

const pageProfile = await sdk.facebook.getPageProfile({
  channelToken: 'sk_live_...',
  pageId: 'page_id'
}, accessToken);

Baixar Mídia Descriptografada

const media = await sdk.facebook.downloadMedia({
  channelToken: 'sk_live_...',
  url: 'https://lookaside.fbsbx.com/ig_messaging_cdn/...'
}, accessToken);

 
console.log(media.data.buffer);  
console.log(media.data.mimeType);  
console.log(media.data.filename); 
console.log(media.data.size); 

Instagram

Enviar Mensagem de Texto

// Mensagem simples
await sdk.instagram.sendText({
  channelToken: 'sk_live_...',
  recipientId: 'user_id',
  text: 'Olá!'
}, accessToken);

// Mensagem com tag HUMAN_AGENT (estende janela de 24h para 7 dias)
await sdk.instagram.sendText({
  channelToken: 'sk_live_...',
  recipientId: 'user_id',
  text: 'Vou transferir você para nosso time de suporte humano.',
  tags: ['HUMAN_AGENT']
}, accessToken);

Enviar Mídia

// Enviar imagem
await sdk.instagram.sendMedia({
  channelToken: 'sk_live_...',
  recipientId: 'user_id',
  attachment: {
    type: 'image',
    url: 'https://example.com/image.jpg'
  }
}, accessToken);

// Enviar vídeo
await sdk.instagram.sendMedia({
  channelToken: 'sk_live_...',
  recipientId: 'user_id',
  attachment: {
    type: 'video',
    url: 'https://example.com/video.mp4'
  }
}, accessToken);

// Enviar áudio
await sdk.instagram.sendMedia({
  channelToken: 'sk_live_...',
  recipientId: 'user_id',
  attachment: {
    type: 'audio',
    url: 'https://example.com/audio.m4a'
  }
}, accessToken);

// Enviar arquivo PDF
await sdk.instagram.sendMedia({
  channelToken: 'sk_live_...',
  recipientId: 'user_id',
  attachment: {
    type: 'file',
    url: 'https://example.com/documento.pdf'
  }
}, accessToken);

// Enviar imagem com tag HUMAN_AGENT
await sdk.instagram.sendMedia({
  channelToken: 'sk_live_...',
  recipientId: 'user_id',
  attachment: {
    type: 'image',
    url: 'https://example.com/image.jpg'
  },
  tags: ['HUMAN_AGENT']
}, accessToken);

Enviar Resposta Privada a Comentário

await sdk.instagram.sendPrivateReply({
  channelToken: 'sk_live_...',
  commentId: 'comment_id',
  message: 'Obrigado pelo comentário!'
}, accessToken);

Enviar Múltiplas Imagens (Carrossel)

await sdk.instagram.sendImages({
  channelToken: 'sk_live_...',
  recipientId: 'user_id',
  images: [
    { url: 'https://example.com/image1.jpg', caption: 'Imagem 1' },
    { url: 'https://example.com/image2.jpg', caption: 'Imagem 2' },
    { url: 'https://example.com/image3.jpg', caption: 'Imagem 3' }
  ]
}, accessToken);

Enviar Sticker (Like Heart)

await sdk.instagram.sendSticker({
  channelToken: 'sk_live_...',
  recipientId: 'user_id',
  stickerType: 'heart'
}, accessToken);

Reagir a Mensagem

await sdk.instagram.reactMessage({
  channelToken: 'sk_live_...',
  messageId: 'message_id',
  reactionType: 'love'
}, accessToken);

Remover Reação

await sdk.instagram.removeReaction({
  channelToken: 'sk_live_...',
  recipientId: 'user_id',
  messageId: 'message_id'
}, accessToken);

Enviar Quick Replies

await sdk.instagram.sendQuickReplies({
  channelToken: 'sk_live_...',
  recipientId: 'user_id',
  message: 'Como podemos ajudar?',
  quickReplies: [
    { content_type: 'text', title: 'Suporte', payload: 'SUPPORT' },
    { content_type: 'text', title: 'Vendas', payload: 'SALES' }
  ]
}, accessToken);

Enviar Template Genérico (Carrossel)

await sdk.instagram.sendGenericTemplate({
  channelToken: 'sk_live_...',
  recipientId: 'user_id',
  elements: [
    {
      title: 'Produto 1',
      subtitle: 'R$ 99,90',
      image_url: 'https://example.com/product1.jpg',
      buttons: [
        { type: 'web_url', title: 'Ver Mais', url: 'https://example.com/product1' },
        { type: 'postback', title: 'Comprar', payload: 'BUY_1' }
      ]
    },
    {
      title: 'Produto 2',
      subtitle: 'R$ 149,90',
      image_url: 'https://example.com/product2.jpg',
      buttons: [
        { type: 'web_url', title: 'Ver Mais', url: 'https://example.com/product2' },
        { type: 'postback', title: 'Comprar', payload: 'BUY_2' }
      ]
    }
  ]
}, accessToken);

Enviar Template de Botões

await sdk.instagram.sendButtonTemplate({
  channelToken: 'sk_live_...',
  recipientId: 'user_id',
  text: 'O que você gostaria de fazer?',
  buttons: [
    { type: 'web_url', title: 'Visitar Site', url: 'https://example.com' },
    { type: 'postback', title: 'Falar com Atendente', payload: 'HUMAN_AGENT' }
  ]
}, accessToken);

Enviar Ação do Remetente (Typing, Seen)

 
await sdk.instagram.sendSenderAction({
  channelToken: 'sk_live_...',
  recipientId: 'user_id',
  action: 'typing_on'
}, accessToken);

 
await sdk.instagram.sendSenderAction({
  channelToken: 'sk_live_...',
  recipientId: 'user_id',
  action: 'typing_off'
}, accessToken);

 
await sdk.instagram.sendSenderAction({
  channelToken: 'sk_live_...',
  recipientId: 'user_id',
  action: 'mark_seen'
}, accessToken);

Obter Perfil de Usuário

const userProfile = await sdk.instagram.getUserProfile({
  channelToken: 'sk_live_...',
  userId: '99999999999999999'
}, accessToken);

console.log(userProfile.data.name);
console.log(userProfile.data.username);
console.log(userProfile.data.follower_count);

Listar Publicações

const posts = await sdk.instagram.listPosts({
  channelToken: 'sk_live_...',
  limit: 10
}, accessToken);

Obter Perfil da Conta Comercial

const businessProfile = await sdk.instagram.getBusinessProfile({
  channelToken: 'sk_live_...'
}, accessToken);

Baixar Mídia Descriptografada

const media = await sdk.instagram.downloadMedia({
  channelToken: 'sk_live_...',
  url: 'https://lookaside.fbsbx.com/ig_messaging_cdn/...'
}, accessToken);

 
console.log(media.data.buffer);  
console.log(media.data.mimeType);  
console.log(media.data.filename);  
console.log(media.data.size);  

Publicar Conteúdo no Instagram

1. Criar Contêiner de Mídia

// Publicar imagem
const container = await sdk.instagram.createMediaContainer({
  channelToken: 'sk_live_...',
  image_url: 'https://example.com/image.jpg',
  media_type: 'IMAGE',
  caption: 'Nossa nova coleção chegou! #moda #verao',
  alt_text: 'Foto de um produto de moda'  // Opcional: texto alternativo
}, accessToken);

const creationId = container.data.data.id; // ID do contêiner criado
// Publicar vídeo
const container = await sdk.instagram.createMediaContainer({
  channelToken: 'sk_live_...',
  video_url: 'https://example.com/video.mp4',
  media_type: 'VIDEO',
  caption: 'Vídeo especial para nossos seguidores'
}, accessToken);
// Publicar Reel
const container = await sdk.instagram.createMediaContainer({
  channelToken: 'sk_live_...',
  video_url: 'https://example.com/reel.mp4',
  media_type: 'REELS',
  caption: 'Confira nosso novo Reel!',
  trial_params: {                    // Opcional: para reels de teste
    graduation_strategy: 'MANUAL'
  }
}, accessToken);
// Publicar Story
const container = await sdk.instagram.createMediaContainer({
  channelToken: 'sk_live_...',
  video_url: 'https://example.com/story.mp4',
  media_type: 'STORIES'
}, accessToken);
// Criar carrossel (até 10 itens)
// Primeiro, criar os contêineres filhos
const child1 = await sdk.instagram.createMediaContainer({
  channelToken: 'sk_live_...',
  image_url: 'https://example.com/image1.jpg',
  media_type: 'IMAGE',
  is_carousel_item: true
}, accessToken);

const child2 = await sdk.instagram.createMediaContainer({
  channelToken: 'sk_live_...',
  image_url: 'https://example.com/image2.jpg',
  media_type: 'IMAGE',
  is_carousel_item: true
}, accessToken);

// Depois, criar o contêiner pai do carrossel
const carousel = await sdk.instagram.createMediaContainer({
  channelToken: 'sk_live_...',
  media_type: 'CAROUSEL',
  caption: 'Balas de frutas',
  children: [
    child1.data.data.id,
    child2.data.data.id
  ]
}, accessToken);

2. Verificar Status do Contêiner (para vídeos grandes)

const status = await sdk.instagram.getContainerStatus({
  channelToken: 'sk_live_...',
  container_id: '99999999999999999'
}, accessToken);

// Status possíveis: EXPIRED, ERROR, FINISHED, IN_PROGRESS, PUBLISHED
console.log(status.data.data.status_code);

// Para vídeos grandes, aguarde até o status ser 'FINISHED' antes de publicar
if (status.data.data.status_code === 'FINISHED') {
  // Pronto para publicar
}

3. Publicar Mídia

const published = await sdk.instagram.publishMedia({
  channelToken: 'sk_live_...',
  creation_id: '99999999999999999'  // ID retornado ao criar o contêiner
}, accessToken);

console.log(published.data.data.id); // ID da publicação criada

4. Verificar Limite de Publicação

const limit = await sdk.instagram.getPublishingLimit({
  channelToken: 'sk_live_...'
}, accessToken);

console.log(`Usado: ${limit.data.data.quota_used} de ${limit.data.data.quota_total}`);
console.log(`Período: ${limit.data.data.quota_duration} segundos (24 horas)`);

5. Upload de Vídeo Grande (Sessão Retomável)

Para vídeos grandes que podem ter interrupções de rede:

// 1. Criar contêiner com upload_type=resumable
const container = await sdk.instagram.createMediaContainer({
  channelToken: 'sk_live_...',
  video_url: 'https://example.com/large-video.mp4',
  media_type: 'VIDEO',
  upload_type: 'resumable',
  caption: 'Vídeo grande com upload retomável'
}, accessToken);

// 2. Fazer upload do vídeo
const upload = await sdk.instagram.uploadVideo({
  channelToken: 'sk_live_...',
  container_id: container.data.data.id,
  file_url: 'https://example.com/large-video.mp4',
  file_size: 10485760,  // Tamanho em bytes (opcional se file_url fornecido)
  offset: 0              // Opcional: para retomar upload (padrão: 0)
}, accessToken);

// 3. Verificar status periodicamente até ser 'FINISHED'
// 4. Publicar quando status for 'FINISHED'

Exemplo Completo: Publicar Imagem

// 1. Criar contêiner
const container = await sdk.instagram.createMediaContainer({
  channelToken: 'sk_live_...',
  image_url: 'https://example.com/image.jpg',
  media_type: 'IMAGE',
  caption: 'Nossa nova coleção chegou! #moda #verao',
  alt_text: 'Foto de um produto de moda',
  location_id: '123456789',  // Opcional: ID da localização
  user_tags: [               // Opcional: marcar usuários
    { username: 'usuario1', x: 0.5, y: 0.5 }
  ]
}, accessToken);

const creationId = container.data.data.id;

// 2. Publicar imediatamente (imagens são processadas rapidamente)
const published = await sdk.instagram.publishMedia({
  channelToken: 'sk_live_...',
  creation_id: creationId
}, accessToken);

console.log(`Publicação criada com ID: ${published.data.data.id}`);

Exemplo Completo: Publicar Vídeo com Verificação de Status

// 1. Criar contêiner de vídeo
const container = await sdk.instagram.createMediaContainer({
  channelToken: 'sk_live_...',
  video_url: 'https://example.com/video.mp4',
  media_type: 'VIDEO',
  caption: 'Vídeo especial para nossos seguidores'
}, accessToken);

const containerId = container.data.data.id;

// 2. Verificar status periodicamente (vídeos podem demorar)
let status = 'IN_PROGRESS';
let attempts = 0;
const maxAttempts = 10;

while (status === 'IN_PROGRESS' && attempts < maxAttempts) {
  await new Promise(resolve => setTimeout(resolve, 5000)); // Aguardar 5 segundos
  
  const statusCheck = await sdk.instagram.getContainerStatus({
    channelToken: 'sk_live_...',
    container_id: containerId
  }, accessToken);
  
  status = statusCheck.data.data.status_code;
  attempts++;
  
  console.log(`Status: ${status} (tentativa ${attempts})`);
}

// 3. Publicar quando status for 'FINISHED'
if (status === 'FINISHED') {
  const published = await sdk.instagram.publishMedia({
    channelToken: 'sk_live_...',
    creation_id: containerId
  }, accessToken);
  
  console.log(`Vídeo publicado com ID: ${published.data.data.id}`);
} else {
  console.error(`Erro: Status final é ${status}`);
}

Canais

Listar Canais

const channels = await sdk.channels.list(accessToken);
console.log(channels);

Integrações

Criar Webhook

const webhook = await sdk.integrations.createWebhook({
  url: 'https://example.com/webhook',
  expiresInDays: 365
}, accessToken);

🛠️ Tratamento de Erros

try {
  await sdk.whatsapp.sendText({
    channelToken: 'sk_live_...',
    sender: '5511999999999',
    messageText: 'Olá!'
  }, accessToken);
} catch (error) {
  console.error('Erro:', error.message);
  console.error('Status:', error.status);
  console.error('Detalhes:', error.details);
}

📝 Tipos TypeScript

import type {
  SDKConfig,
  Channel,
  SendWhatsAppTextParams,
  ApiResponse
} from '@oficialapi/sdk';

🔄 Retry Automático

O SDK possui retry automático configurável:

  • maxRetries: Número máximo de tentativas (padrão: 3)
  • retryDelay: Delay entre tentativas em ms (padrão: 1000)

O retry é aplicado automaticamente em erros de rede, erros 5xx e timeouts.

📖 Documentação Completa

Para mais informações, consulte a documentação completa da API.

📄 Licença

MIT