@oficialapi/sdk 9.0.1 → 9.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -20,9 +20,9 @@ import { OficialAPISDK } from '@oficialapi/sdk';
20
20
  const sdk = new OficialAPISDK({
21
21
  clientId: 'seu-client-id',
22
22
  clientSecret: 'seu-client-secret',
23
- timeout: 30000, // opcional, padrão: 30000ms
24
- maxRetries: 3, // opcional, padrão: 3
25
- retryDelay: 1000, // opcional, padrão: 1000ms
23
+ timeout: 30000,
24
+ maxRetries: 3,
25
+ retryDelay: 1000,
26
26
  });
27
27
  ```
28
28
 
@@ -37,15 +37,6 @@ const accessToken = tokenResponse.access_token;
37
37
 
38
38
  ## 📚 Exemplos de Uso
39
39
 
40
- ### WhatsApp
41
-
42
- > **⚠️ Nota Importante:** Alguns métodos requerem upload prévio da mídia para obter o `mediaId` antes de enviar. Isso se aplica a:
43
- > - `sendAudio` - Use `uploadMedia` primeiro para obter o `mediaId`
44
- > - `sendVideo` - Use `uploadMedia` primeiro para obter o `mediaId`
45
- > - `sendDocument` - Use `uploadMedia` primeiro para obter o `mediaId`
46
- > - `sendSticker` - Use `uploadMedia` primeiro para obter o `mediaId`
47
- >
48
- > O método `sendMedia` ainda aceita `fileUrl` diretamente para imagens e outros tipos de mídia.
49
40
 
50
41
  #### Enviar Mensagem de Texto
51
42
 
@@ -62,7 +53,7 @@ console.log(result.data.messageId);
62
53
  #### Enviar Mídia
63
54
 
64
55
  ```typescript
65
- // Enviar imagem
56
+
66
57
  await sdk.whatsapp.sendMedia({
67
58
  token: 'sk_live_...',
68
59
  sender: '5511999999999',
@@ -71,14 +62,14 @@ await sdk.whatsapp.sendMedia({
71
62
  caption: 'Veja esta imagem!'
72
63
  }, accessToken);
73
64
 
74
- // Enviar documento com nome de arquivo
65
+
75
66
  await sdk.whatsapp.sendMedia({
76
67
  token: 'sk_live_...',
77
68
  sender: '5511999999999',
78
69
  fileUrl: 'https://example.com/documento.pdf',
79
70
  type: 'document',
80
71
  caption: 'Confira este documento',
81
- fileName: 'meu_documento.pdf' // Opcional: se não fornecido, será extraído da URL
72
+ fileName: 'meu_documento.pdf'
82
73
  }, accessToken);
83
74
  ```
84
75
 
@@ -629,23 +620,23 @@ await sdk.whatsapp.sendOrderStatus({
629
620
  token: 'sk_live_...',
630
621
  sender: '5511999999999',
631
622
  bodyText: 'Seu pedido foi enviado!',
632
- footerText: 'Obrigado!', // Opcional
633
- reference_id: 'pedido_12345_1704067200', // Mesmo ID usado em sendOrderDetails
634
- order_status: 'shipped', // pending, processing, partially-shipped, shipped, completed, canceled
635
- status_description: 'Sua encomenda foi despachada pelos Correios', // Opcional
636
- payment_status: 'captured', // Opcional: pending, captured, failed
637
- payment_timestamp: 1722445231 // Opcional: timestamp do pagamento em segundos
623
+ footerText: 'Obrigado!',
624
+ reference_id: 'pedido_12345_1704067200',
625
+ order_status: 'shipped',
626
+ status_description: 'Sua encomenda foi despachada pelos Correios',
627
+ payment_status: 'captured',
628
+ payment_timestamp: 1722445231
638
629
  }, accessToken);
639
630
  ```
640
631
 
641
632
  #### Enviar Sticker
642
633
 
643
634
  ```typescript
644
- // Requer upload prévio da mídia para obter o mediaId
635
+
645
636
  await sdk.whatsapp.sendSticker({
646
637
  token: 'sk_live_...',
647
638
  sender: '5511999999999',
648
- mediaId: '798882015472548' // ID da mídia após upload (.webp até 500KB para animado, 100KB para estático)
639
+ mediaId: '798882015472548'
649
640
  }, accessToken);
650
641
  ```
651
642
 
@@ -656,8 +647,8 @@ await sdk.whatsapp.sendLocationRequest({
656
647
  token: 'sk_live_...',
657
648
  sender: '5511999999999',
658
649
  bodyText: 'Por favor, compartilhe sua localização para entregarmos seu pedido.',
659
- headerText: 'Confirme sua entrega', // Opcional (máximo 60 caracteres)
660
- footerText: 'Sua privacidade é importante' // Opcional (máximo 60 caracteres)
650
+ headerText: 'Confirme sua entrega',
651
+ footerText: 'Sua privacidade é importante'
661
652
  }, accessToken);
662
653
  ```
663
654
 
@@ -668,14 +659,14 @@ await sdk.whatsapp.sendCtaUrl({
668
659
  token: 'sk_live_...',
669
660
  sender: '5511999999999',
670
661
  bodyText: 'Confira nosso site!',
671
- buttonText: 'Acessar', // Máximo 20 caracteres
662
+ buttonText: 'Acessar',
672
663
  url: 'https://example.com',
673
- header: { // Opcional: cabeçalho com mídia
674
- type: 'image', // ou 'video', 'document', 'text'
675
- link: 'https://example.com/banner.jpg' // Para image/video/document
676
- // ou text: 'Título' para tipo text
664
+ header: {
665
+ type: 'image',
666
+ link: 'https://example.com/banner.jpg'
667
+
677
668
  },
678
- footerText: 'Ofertas válidas até 30/11' // Opcional (máximo 60 caracteres)
669
+ footerText: 'Ofertas válidas até 30/11'
679
670
  }, accessToken);
680
671
  ```
681
672
 
@@ -685,14 +676,14 @@ await sdk.whatsapp.sendCtaUrl({
685
676
  await sdk.whatsapp.sendMediaCarousel({
686
677
  token: 'sk_live_...',
687
678
  sender: '5511999999999',
688
- bodyText: 'Confira nossas ofertas da semana!', // Obrigatório
689
- cards: [ // 2 a 10 cartões
679
+ bodyText: 'Confira nossas ofertas da semana!',
680
+ cards: [
690
681
  {
691
682
  cardIndex: 0,
692
- headerType: 'image', // ou 'video'
683
+ headerType: 'image',
693
684
  headerLink: 'https://example.com/image1.jpg',
694
- bodyText: 'Oferta especial!', // Máximo 160 caracteres
695
- buttonText: 'Comprar agora', // Máximo 20 caracteres
685
+ bodyText: 'Oferta especial!',
686
+ buttonText: 'Comprar agora',
696
687
  url: 'https://example.com/product1'
697
688
  },
698
689
  {
@@ -715,11 +706,11 @@ const media = await sdk.whatsapp.downloadMedia({
715
706
  url: 'https://lookaside.fbsbx.com/whatsapp_business/attachment/?mid=...'
716
707
  }, accessToken);
717
708
 
718
- // A mídia retorna em base64
719
- console.log(media.data.buffer); // Base64 string
720
- console.log(media.data.mimeType); // image/jpeg, video/mp4, etc.
721
- console.log(media.data.filename); // Nome do arquivo
722
- console.log(media.data.size); // Tamanho em bytes
709
+
710
+ console.log(media.data.buffer);
711
+ console.log(media.data.mimeType);
712
+ console.log(media.data.filename);
713
+ console.log(media.data.size);
723
714
  ```
724
715
 
725
716
  #### Responder Mensagem
@@ -727,10 +718,10 @@ console.log(media.data.size); // Tamanho em bytes
727
718
  ```typescript
728
719
  await sdk.whatsapp.replyMessage({
729
720
  token: 'sk_live_...',
730
- sender: '5511999999999', // Obrigatório
721
+ sender: '5511999999999',
731
722
  messageText: 'Esta é uma resposta!',
732
- replyMessageId: 'wamid.xxx', // Opcional: ID da mensagem a responder
733
- preview_url: false // Opcional: se true, mostra preview de URLs no texto
723
+ replyMessageId: 'wamid.xxx',
724
+ preview_url: false
734
725
  }, accessToken);
735
726
  ```
736
727
 
@@ -739,22 +730,22 @@ await sdk.whatsapp.replyMessage({
739
730
  ```typescript
740
731
  await sdk.whatsapp.reactMessage({
741
732
  token: 'sk_live_...',
742
- sender: '5511999999999', // Obrigatório
743
- emoji: '👍', // Emoji da reação
744
- message_id: 'wamid.xxx' // Opcional: ID da mensagem específica a reagir
733
+ sender: '5511999999999',
734
+ emoji: '👍',
735
+ message_id: 'wamid.xxx'
745
736
  }, accessToken);
746
737
  ```
747
738
 
748
739
  #### Gerenciar Templates
749
740
 
750
741
  ```typescript
751
- // Listar templates
742
+
752
743
  const templates = await sdk.whatsapp.listTemplates('sk_live_...', accessToken);
753
744
 
754
- // Obter detalhes de um template
745
+
755
746
  const template = await sdk.whatsapp.getTemplate('sk_live_...', 'template_id', accessToken);
756
747
 
757
- // Criar template
748
+
758
749
  await sdk.whatsapp.createTemplate({
759
750
  token: 'sk_live_...',
760
751
  name: 'welcome_message',
@@ -769,8 +760,7 @@ await sdk.whatsapp.createTemplate({
769
760
  }, accessToken);
770
761
 
771
762
  #### Upload de Mídia
772
-
773
- O método `uploadMedia` é usado para fazer upload de arquivos (imagens, vídeos, áudios, documentos) que serão usados em templates ou enviados via `sendAudio`, `sendVideo`, `sendDocument` ou `sendSticker`.
763
+
774
764
 
775
765
  **Exemplo 1: Upload de imagem sem filename (opcional)**
776
766
 
@@ -781,8 +771,9 @@ import fs from 'fs';
781
771
  const fileBuffer = fs.readFileSync('./imagem.jpg');
782
772
  const uploadResult = await sdk.whatsapp.uploadMedia({
783
773
  token: 'sk_live_...',
784
- file: fileBuffer
785
- // filename é opcional
774
+ file: fileBuffer,
775
+ mediaType: 'image'
776
+
786
777
  }, accessToken);
787
778
 
788
779
  const mediaId = uploadResult.data.handle; // "4::aW1hZ2UtMTIzNDU2Nzg5MGCE..."
@@ -798,6 +789,7 @@ const fileBuffer = fs.readFileSync('./imagem.jpg');
798
789
  const uploadResult = await sdk.whatsapp.uploadMedia({
799
790
  token: 'sk_live_...',
800
791
  file: fileBuffer,
792
+ mediaType: 'image',
801
793
  filename: 'minha_imagem.jpg'
802
794
  }, accessToken);
803
795
 
@@ -813,10 +805,11 @@ const videoBuffer = fs.readFileSync('./video.mp4');
813
805
  const uploadResult = await sdk.whatsapp.uploadMedia({
814
806
  token: 'sk_live_...',
815
807
  file: videoBuffer,
808
+ mediaType: 'video',
816
809
  filename: 'meu_video.mp4'
817
810
  }, accessToken);
818
811
 
819
- // Use o mediaId para enviar o vídeo
812
+
820
813
  await sdk.whatsapp.sendVideo({
821
814
  token: 'sk_live_...',
822
815
  sender: '5511999999999',
@@ -829,12 +822,7 @@ await sdk.whatsapp.sendVideo({
829
822
  ```typescript
830
823
  import fs from 'fs';
831
824
 
832
- const pdfBuffer = fs.readFileSync('./documento.pdf');
833
- const uploadResult = await sdk.whatsapp.uploadMedia({
834
- token: 'sk_live_...',
835
- file: pdfBuffer,
836
- filename: 'documento_importante.pdf'
837
- }, accessToken);
825
+
838
826
 
839
827
 
840
828
  await sdk.whatsapp.sendDocument({
@@ -847,24 +835,6 @@ await sdk.whatsapp.sendDocument({
847
835
  ```
848
836
 
849
837
 
850
- ```typescript
851
- import fs from 'fs';
852
-
853
- const audioBuffer = fs.readFileSync('./audio.ogg');
854
- const uploadResult = await sdk.whatsapp.uploadMedia({
855
- token: 'sk_live_...',
856
- file: audioBuffer,
857
- filename: 'mensagem_audio.ogg'
858
- }, accessToken);
859
-
860
-
861
- await sdk.whatsapp.sendAudio({
862
- token: 'sk_live_...',
863
- sender: '5511999999999',
864
- mediaId: uploadResult.data.handle,
865
- voice: true // true para mensagem de voz
866
- }, accessToken);
867
- ```
868
838
 
869
839
  **Exemplo 6: Upload de sticker (Node.js)**
870
840
 
@@ -875,10 +845,11 @@ const stickerBuffer = fs.readFileSync('./sticker.webp');
875
845
  const uploadResult = await sdk.whatsapp.uploadMedia({
876
846
  token: 'sk_live_...',
877
847
  file: stickerBuffer,
848
+ mediaType: 'image',
878
849
  filename: 'sticker.webp'
879
850
  }, accessToken);
880
851
 
881
- // Use o mediaId para enviar o sticker
852
+
882
853
  await sdk.whatsapp.sendSticker({
883
854
  token: 'sk_live_...',
884
855
  sender: '5511999999999',
@@ -889,14 +860,22 @@ await sdk.whatsapp.sendSticker({
889
860
  **Exemplo 7: Upload em ambiente Browser (Frontend)**
890
861
 
891
862
  ```typescript
892
- // Em ambiente Browser
863
+
893
864
  const fileInput = document.querySelector('input[type="file"]');
894
865
  const file = fileInput.files[0];
895
866
 
867
+
868
+ const getMediaType = (file: File): 'image' | 'video' | 'document' => {
869
+ if (file.type.startsWith('image/')) return 'image';
870
+ if (file.type.startsWith('video/')) return 'video';
871
+ return 'document';
872
+ };
873
+
896
874
  const uploadResult = await sdk.whatsapp.uploadMedia({
897
875
  token: 'sk_live_...',
898
876
  file: file,
899
- filename: file.name // Opcional
877
+ mediaType: getMediaType(file),
878
+ filename: file.name
900
879
  }, accessToken);
901
880
 
902
881
  const mediaId = uploadResult.data.handle;
@@ -905,12 +884,13 @@ const mediaId = uploadResult.data.handle;
905
884
  **Exemplo 8: Upload usando Blob (Browser)**
906
885
 
907
886
  ```typescript
908
- // Criar um Blob a partir de dados
887
+
909
888
  const blob = new Blob(['conteúdo do arquivo'], { type: 'text/plain' });
910
889
 
911
890
  const uploadResult = await sdk.whatsapp.uploadMedia({
912
891
  token: 'sk_live_...',
913
892
  file: blob,
893
+ mediaType: 'document',
914
894
  filename: 'arquivo.txt'
915
895
  }, accessToken);
916
896
 
@@ -926,11 +906,12 @@ import fs from 'fs';
926
906
  const imageBuffer = fs.readFileSync('./logo.jpg');
927
907
  const uploadResult = await sdk.whatsapp.uploadMedia({
928
908
  token: 'sk_live_...',
929
- file: imageBuffer
930
- // filename não é necessário para templates
909
+ file: imageBuffer,
910
+ mediaType: 'image'
911
+
931
912
  }, accessToken);
932
913
 
933
- // Use o handle no template
914
+
934
915
  await sdk.whatsapp.createTemplate({
935
916
  token: 'sk_live_...',
936
917
  name: 'product_launch',
@@ -941,7 +922,7 @@ await sdk.whatsapp.createTemplate({
941
922
  type: 'HEADER',
942
923
  format: 'IMAGE',
943
924
  example: {
944
- header_handle: [uploadResult.data.handle] // Use o handle aqui
925
+ header_handle: [uploadResult.data.handle]
945
926
  }
946
927
  },
947
928
  {
@@ -953,15 +934,16 @@ await sdk.whatsapp.createTemplate({
953
934
  ```
954
935
 
955
936
  **Notas importantes:**
937
+ - O parâmetro `mediaType` é **obrigatório** e deve ser um dos valores: `'image'`, `'video'` ou `'document'`.
956
938
  - O parâmetro `filename` é **opcional**. Se não fornecido, não será enviado ao servidor (a API da OficialAPI rejeita campos vazios).
957
939
  - O `mediaId` retornado está no formato `"4::aW1hZ2UtMTIzNDU2Nzg5MGCE..."` e deve ser usado diretamente nos métodos `sendAudio`, `sendVideo`, `sendDocument` ou `sendSticker`.
958
940
  - Para templates, use o `handle` retornado no campo `header_handle` ou `example.header_handle`.
959
941
  - Formatos suportados:
960
- - **Imagens**: JPG, PNG, GIF, WEBP
961
- - **Vídeos**: MP4, 3GP
962
- - **Áudios**: OGG (codec OPUS para voz), MP3, M4A
963
- - **Documentos**: PDF, DOC, DOCX, XLS, XLSX, PPT, PPTX
964
- - **Stickers**: WEBP (até 500KB para animado, 100KB para estático)
942
+ - **Imagens** (`mediaType: 'image'`): JPG, PNG, GIF, WEBP
943
+ - **Vídeos** (`mediaType: 'video'`): MP4, 3GP
944
+ - **Áudios**: Use `mediaType: 'video'` para áudios (OGG codec OPUS para voz, MP3, M4A)
945
+ - **Documentos** (`mediaType: 'document'`): PDF, DOC, DOCX, XLS, XLSX, PPT, PPTX
946
+ - **Stickers**: Use `mediaType: 'image'` para stickers WEBP (até 500KB para animado, 100KB para estático)
965
947
  ```
966
948
 
967
949
  **Mais exemplos de templates:**
@@ -1464,22 +1446,25 @@ const media = await sdk.telegram.downloadMedia({
1464
1446
  fileId: 'AgACAgEAAxkBAAItNmlmklyYNCEtvaFphVfSSO7CrEOjAALUC2sbh9owR9hT7MhQnTGfAQADAgADcwADOAQ'
1465
1447
  }, accessToken);
1466
1448
 
1467
- // A mídia retorna em base64
1468
- console.log(media.data.buffer); // Base64 string
1469
- console.log(media.data.mimeType); // image/jpeg, video/mp4, etc.
1470
- console.log(media.data.filename); // Nome do arquivo
1471
- console.log(media.data.size); // Tamanho em bytes
1449
+
1450
+ console.log(media.data.buffer);
1451
+ console.log(media.data.mimeType);
1452
+ console.log(media.data.filename);
1453
+ console.log(media.data.size);
1472
1454
  ```
1473
1455
 
1474
1456
  ### WebChat
1457
+
1475
1458
 
1476
1459
  #### Enviar Mensagem de Texto
1477
1460
 
1478
1461
  ```typescript
1479
1462
  await sdk.webchat.sendText({
1480
- token: 'sk_live_...',
1481
- sender: 'user123',
1482
- messageText: 'Olá!'
1463
+ channelToken: 'sk_live_...',
1464
+ chatId: 'chat_123456789',
1465
+ messageText: 'Olá!',
1466
+ typing: true, // Opcional: mostrar indicador de digitação
1467
+ typingTime: 2000 // Opcional: tempo de digitação em ms
1483
1468
  }, accessToken);
1484
1469
  ```
1485
1470
 
@@ -1487,18 +1472,22 @@ await sdk.webchat.sendText({
1487
1472
 
1488
1473
  ```typescript
1489
1474
  await sdk.webchat.sendCard({
1490
- token: 'sk_live_...',
1491
- sender: 'user123',
1475
+ channelToken: 'sk_live_...',
1476
+ chatId: 'chat_123456789',
1492
1477
  title: 'Produto',
1493
1478
  description: 'Descrição do produto',
1494
1479
  imageUrl: 'https://example.com/image.jpg',
1495
1480
  buttons: [
1496
1481
  {
1497
- type: 'url',
1498
- title: 'Ver Mais',
1482
+ id: 'btn_1', // Opcional: ID único do botão
1483
+ text: 'Ver Mais',
1484
+ type: 'url', // 'text' | 'url' | 'phone' | 'postback'
1485
+ url: 'https://example.com/product',
1499
1486
  value: 'https://example.com/product'
1500
1487
  }
1501
- ]
1488
+ ],
1489
+ typing: true,
1490
+ typingTime: 3000
1502
1491
  }, accessToken);
1503
1492
  ```
1504
1493
 
@@ -1506,11 +1495,13 @@ await sdk.webchat.sendCard({
1506
1495
 
1507
1496
  ```typescript
1508
1497
  await sdk.webchat.sendMedia({
1509
- token: 'sk_live_...',
1510
- sender: 'user123',
1498
+ channelToken: 'sk_live_...',
1499
+ chatId: 'chat_123456789',
1511
1500
  fileUrl: 'https://example.com/image.jpg',
1512
- type: 'image',
1513
- caption: 'Veja esta imagem!'
1501
+ type: 'image', // 'image' | 'video' | 'audio' | 'file'
1502
+ caption: 'Veja esta imagem!',
1503
+ typing: true,
1504
+ typingTime: 2500
1514
1505
  }, accessToken);
1515
1506
  ```
1516
1507
 
@@ -1518,26 +1509,39 @@ await sdk.webchat.sendMedia({
1518
1509
 
1519
1510
  ```typescript
1520
1511
  await sdk.webchat.sendCarousel({
1521
- token: 'sk_live_...',
1522
- sender: 'user123',
1512
+ channelToken: 'sk_live_...',
1513
+ chatId: 'chat_123456789',
1523
1514
  cards: [
1524
1515
  {
1525
1516
  title: 'Produto 1',
1526
- description: 'Descrição do produto 1',
1517
+ subtitle: 'Descrição do produto 1',
1527
1518
  imageUrl: 'https://example.com/product1.jpg',
1528
1519
  buttons: [
1529
- { type: 'url', title: 'Ver Mais', value: 'https://example.com/product1' }
1520
+ {
1521
+ id: 'btn_1',
1522
+ text: 'Ver Mais',
1523
+ type: 'url',
1524
+ url: 'https://example.com/product1',
1525
+ value: 'https://example.com/product1'
1526
+ }
1530
1527
  ]
1531
1528
  },
1532
1529
  {
1533
1530
  title: 'Produto 2',
1534
- description: 'Descrição do produto 2',
1531
+ subtitle: 'Descrição do produto 2',
1535
1532
  imageUrl: 'https://example.com/product2.jpg',
1536
1533
  buttons: [
1537
- { type: 'url', title: 'Ver Mais', value: 'https://example.com/product2' }
1534
+ {
1535
+ id: 'btn_2',
1536
+ text: 'Comprar',
1537
+ type: 'postback',
1538
+ value: 'BUY_PRODUCT_2'
1539
+ }
1538
1540
  ]
1539
1541
  }
1540
- ]
1542
+ ],
1543
+ typing: true,
1544
+ typingTime: 4000
1541
1545
  }, accessToken);
1542
1546
  ```
1543
1547
 
@@ -1545,24 +1549,40 @@ await sdk.webchat.sendCarousel({
1545
1549
 
1546
1550
  ```typescript
1547
1551
  await sdk.webchat.sendForm({
1548
- token: 'sk_live_...',
1549
- sender: 'user123',
1550
- title: 'Formulário de Contato',
1552
+ channelToken: 'sk_live_...',
1553
+ chatId: 'chat_123456789',
1554
+ id: 'form_contact', // Opcional: ID único do formulário
1555
+ title: 'Formulário de Contato', // Opcional
1551
1556
  fields: [
1552
1557
  {
1553
- type: 'text',
1554
- name: 'name',
1558
+ id: 'name', // Opcional: se não fornecido, usa 'name'
1559
+ name: 'name', // Opcional: mantido para compatibilidade
1560
+ type: 'text', // 'text' | 'email' | 'number' | 'tel' | 'date' | 'select'
1555
1561
  label: 'Nome',
1562
+ placeholder: 'Digite seu nome',
1556
1563
  required: true
1557
1564
  },
1558
1565
  {
1566
+ id: 'email',
1559
1567
  type: 'email',
1560
- name: 'email',
1561
1568
  label: 'E-mail',
1569
+ placeholder: 'Digite seu e-mail',
1562
1570
  required: true
1571
+ },
1572
+ {
1573
+ id: 'subject',
1574
+ type: 'select',
1575
+ label: 'Assunto',
1576
+ required: true,
1577
+ options: [
1578
+ { value: 'support', label: 'Suporte' },
1579
+ { value: 'sales', label: 'Vendas' }
1580
+ ]
1563
1581
  }
1564
1582
  ],
1565
- submitButtonText: 'Enviar'
1583
+ submitButtonText: 'Enviar', // Opcional
1584
+ typing: true,
1585
+ typingTime: 3000
1566
1586
  }, accessToken);
1567
1587
  ```
1568
1588
 
@@ -1570,14 +1590,23 @@ await sdk.webchat.sendForm({
1570
1590
 
1571
1591
  ```typescript
1572
1592
  await sdk.webchat.sendQuickReplies({
1573
- token: 'sk_live_...',
1574
- sender: 'user123',
1593
+ channelToken: 'sk_live_...',
1594
+ chatId: 'chat_123456789',
1575
1595
  messageText: 'Como podemos ajudar?',
1576
1596
  quickReplies: [
1577
- { type: 'text', title: 'Suporte', payload: 'SUPPORT' },
1578
- { type: 'text', title: 'Vendas', payload: 'SALES' },
1579
- { type: 'location', title: 'Compartilhar Localização' }
1580
- ]
1597
+ {
1598
+ id: 'qr_1', // Opcional: ID único
1599
+ text: 'Suporte',
1600
+ value: 'SUPPORT' // Opcional: valor para identificar a resposta
1601
+ },
1602
+ {
1603
+ id: 'qr_2',
1604
+ text: 'Vendas',
1605
+ value: 'SALES'
1606
+ }
1607
+ ],
1608
+ typing: true,
1609
+ typingTime: 2000
1581
1610
  }, accessToken);
1582
1611
  ```
1583
1612
 
@@ -1585,13 +1614,26 @@ await sdk.webchat.sendQuickReplies({
1585
1614
 
1586
1615
  ```typescript
1587
1616
  await sdk.webchat.sendButtons({
1588
- token: 'sk_live_...',
1589
- sender: 'user123',
1617
+ channelToken: 'sk_live_...',
1618
+ chatId: 'chat_123456789',
1590
1619
  messageText: 'Escolha uma opção:',
1591
1620
  buttons: [
1592
- { type: 'url', title: 'Visitar Site', value: 'https://example.com' },
1593
- { type: 'postback', title: 'Falar com Atendente', value: 'HUMAN_AGENT' }
1594
- ]
1621
+ {
1622
+ id: 'btn_1',
1623
+ text: 'Visitar Site',
1624
+ type: 'url',
1625
+ url: 'https://example.com',
1626
+ value: 'https://example.com'
1627
+ },
1628
+ {
1629
+ id: 'btn_2',
1630
+ text: 'Falar com Atendente',
1631
+ type: 'postback',
1632
+ value: 'HUMAN_AGENT'
1633
+ }
1634
+ ],
1635
+ typing: true,
1636
+ typingTime: 2500
1595
1637
  }, accessToken);
1596
1638
  ```
1597
1639
 
@@ -1751,11 +1793,11 @@ const media = await sdk.facebook.downloadMedia({
1751
1793
  url: 'https://lookaside.fbsbx.com/ig_messaging_cdn/...'
1752
1794
  }, accessToken);
1753
1795
 
1754
- // A mídia retorna em base64
1755
- console.log(media.data.buffer); // Base64 string
1756
- console.log(media.data.mimeType); // image/jpeg, video/mp4, etc.
1757
- console.log(media.data.filename); // Nome do arquivo
1758
- console.log(media.data.size); // Tamanho em bytes
1796
+
1797
+ console.log(media.data.buffer);
1798
+ console.log(media.data.mimeType);
1799
+ console.log(media.data.filename);
1800
+ console.log(media.data.size);
1759
1801
  ```
1760
1802
 
1761
1803
  ### Instagram
@@ -1896,21 +1938,21 @@ await sdk.instagram.sendButtonTemplate({
1896
1938
  #### Enviar Ação do Remetente (Typing, Seen)
1897
1939
 
1898
1940
  ```typescript
1899
- // Mostrar "digitando..."
1941
+
1900
1942
  await sdk.instagram.sendSenderAction({
1901
1943
  token: 'sk_live_...',
1902
1944
  recipientId: 'user_id',
1903
1945
  action: 'typing_on'
1904
1946
  }, accessToken);
1905
1947
 
1906
- // Parar de mostrar "digitando..."
1948
+
1907
1949
  await sdk.instagram.sendSenderAction({
1908
1950
  token: 'sk_live_...',
1909
1951
  recipientId: 'user_id',
1910
1952
  action: 'typing_off'
1911
1953
  }, accessToken);
1912
1954
 
1913
- // Marcar como visualizado
1955
+
1914
1956
  await sdk.instagram.sendSenderAction({
1915
1957
  token: 'sk_live_...',
1916
1958
  recipientId: 'user_id',
@@ -1956,11 +1998,229 @@ const media = await sdk.instagram.downloadMedia({
1956
1998
  url: 'https://lookaside.fbsbx.com/ig_messaging_cdn/...'
1957
1999
  }, accessToken);
1958
2000
 
1959
- // A mídia retorna em base64
1960
- console.log(media.data.buffer); // Base64 string
1961
- console.log(media.data.mimeType); // image/jpeg, video/mp4, etc.
1962
- console.log(media.data.filename); // Nome do arquivo
1963
- console.log(media.data.size); // Tamanho em bytes
2001
+
2002
+ console.log(media.data.buffer);
2003
+ console.log(media.data.mimeType);
2004
+ console.log(media.data.filename);
2005
+ console.log(media.data.size);
2006
+ ```
2007
+
2008
+ #### Publicar Conteúdo no Instagram
2009
+
2010
+
2011
+
2012
+ **1. Criar Contêiner de Mídia**
2013
+
2014
+ ```typescript
2015
+ // Publicar imagem
2016
+ const container = await sdk.instagram.createMediaContainer({
2017
+ token: 'sk_live_...',
2018
+ image_url: 'https://example.com/image.jpg',
2019
+ media_type: 'IMAGE',
2020
+ caption: 'Nossa nova coleção chegou! #moda #verao',
2021
+ alt_text: 'Foto de um produto de moda' // Opcional: texto alternativo
2022
+ }, accessToken);
2023
+
2024
+ const creationId = container.data.data.id; // ID do contêiner criado
2025
+ ```
2026
+
2027
+ ```typescript
2028
+ // Publicar vídeo
2029
+ const container = await sdk.instagram.createMediaContainer({
2030
+ token: 'sk_live_...',
2031
+ video_url: 'https://example.com/video.mp4',
2032
+ media_type: 'VIDEO',
2033
+ caption: 'Vídeo especial para nossos seguidores'
2034
+ }, accessToken);
2035
+ ```
2036
+
2037
+ ```typescript
2038
+ // Publicar Reel
2039
+ const container = await sdk.instagram.createMediaContainer({
2040
+ token: 'sk_live_...',
2041
+ video_url: 'https://example.com/reel.mp4',
2042
+ media_type: 'REELS',
2043
+ caption: 'Confira nosso novo Reel!',
2044
+ trial_params: { // Opcional: para reels de teste
2045
+ graduation_strategy: 'MANUAL'
2046
+ }
2047
+ }, accessToken);
2048
+ ```
2049
+
2050
+ ```typescript
2051
+ // Publicar Story
2052
+ const container = await sdk.instagram.createMediaContainer({
2053
+ token: 'sk_live_...',
2054
+ video_url: 'https://example.com/story.mp4',
2055
+ media_type: 'STORIES'
2056
+ }, accessToken);
2057
+ ```
2058
+
2059
+ ```typescript
2060
+ // Criar carrossel (até 10 itens)
2061
+ // Primeiro, criar os contêineres filhos
2062
+ const child1 = await sdk.instagram.createMediaContainer({
2063
+ token: 'sk_live_...',
2064
+ image_url: 'https://example.com/image1.jpg',
2065
+ media_type: 'IMAGE',
2066
+ is_carousel_item: true
2067
+ }, accessToken);
2068
+
2069
+ const child2 = await sdk.instagram.createMediaContainer({
2070
+ token: 'sk_live_...',
2071
+ image_url: 'https://example.com/image2.jpg',
2072
+ media_type: 'IMAGE',
2073
+ is_carousel_item: true
2074
+ }, accessToken);
2075
+
2076
+ // Depois, criar o contêiner pai do carrossel
2077
+ const carousel = await sdk.instagram.createMediaContainer({
2078
+ token: 'sk_live_...',
2079
+ media_type: 'CAROUSEL',
2080
+ caption: 'Balas de frutas',
2081
+ children: [
2082
+ child1.data.data.id,
2083
+ child2.data.data.id
2084
+ ]
2085
+ }, accessToken);
2086
+ ```
2087
+
2088
+ **2. Verificar Status do Contêiner** (para vídeos grandes)
2089
+
2090
+ ```typescript
2091
+ const status = await sdk.instagram.getContainerStatus({
2092
+ token: 'sk_live_...',
2093
+ container_id: '17841465415913137'
2094
+ }, accessToken);
2095
+
2096
+ // Status possíveis: EXPIRED, ERROR, FINISHED, IN_PROGRESS, PUBLISHED
2097
+ console.log(status.data.data.status_code);
2098
+
2099
+ // Para vídeos grandes, aguarde até o status ser 'FINISHED' antes de publicar
2100
+ if (status.data.data.status_code === 'FINISHED') {
2101
+ // Pronto para publicar
2102
+ }
2103
+ ```
2104
+
2105
+ **3. Publicar Mídia**
2106
+
2107
+ ```typescript
2108
+ const published = await sdk.instagram.publishMedia({
2109
+ token: 'sk_live_...',
2110
+ creation_id: '17841465415913137' // ID retornado ao criar o contêiner
2111
+ }, accessToken);
2112
+
2113
+ console.log(published.data.data.id); // ID da publicação criada
2114
+ ```
2115
+
2116
+ **4. Verificar Limite de Publicação**
2117
+
2118
+ ```typescript
2119
+ const limit = await sdk.instagram.getPublishingLimit({
2120
+ token: 'sk_live_...'
2121
+ }, accessToken);
2122
+
2123
+ console.log(`Usado: ${limit.data.data.quota_used} de ${limit.data.data.quota_total}`);
2124
+ console.log(`Período: ${limit.data.data.quota_duration} segundos (24 horas)`);
2125
+ ```
2126
+
2127
+ **5. Upload de Vídeo Grande (Sessão Retomável)**
2128
+
2129
+ Para vídeos grandes que podem ter interrupções de rede:
2130
+
2131
+ ```typescript
2132
+ // 1. Criar contêiner com upload_type=resumable
2133
+ const container = await sdk.instagram.createMediaContainer({
2134
+ token: 'sk_live_...',
2135
+ video_url: 'https://example.com/large-video.mp4',
2136
+ media_type: 'VIDEO',
2137
+ upload_type: 'resumable',
2138
+ caption: 'Vídeo grande com upload retomável'
2139
+ }, accessToken);
2140
+
2141
+ // 2. Fazer upload do vídeo
2142
+ const upload = await sdk.instagram.uploadVideo({
2143
+ token: 'sk_live_...',
2144
+ container_id: container.data.data.id,
2145
+ file_url: 'https://example.com/large-video.mp4',
2146
+ file_size: 10485760, // Tamanho em bytes (opcional se file_url fornecido)
2147
+ offset: 0 // Opcional: para retomar upload (padrão: 0)
2148
+ }, accessToken);
2149
+
2150
+ // 3. Verificar status periodicamente até ser 'FINISHED'
2151
+ // 4. Publicar quando status for 'FINISHED'
2152
+ ```
2153
+
2154
+ **Exemplo Completo: Publicar Imagem**
2155
+
2156
+ ```typescript
2157
+ // 1. Criar contêiner
2158
+ const container = await sdk.instagram.createMediaContainer({
2159
+ token: 'sk_live_...',
2160
+ image_url: 'https://example.com/image.jpg',
2161
+ media_type: 'IMAGE',
2162
+ caption: 'Nossa nova coleção chegou! #moda #verao',
2163
+ alt_text: 'Foto de um produto de moda',
2164
+ location_id: '123456789', // Opcional: ID da localização
2165
+ user_tags: [ // Opcional: marcar usuários
2166
+ { username: 'usuario1', x: 0.5, y: 0.5 }
2167
+ ]
2168
+ }, accessToken);
2169
+
2170
+ const creationId = container.data.data.id;
2171
+
2172
+ // 2. Publicar imediatamente (imagens são processadas rapidamente)
2173
+ const published = await sdk.instagram.publishMedia({
2174
+ token: 'sk_live_...',
2175
+ creation_id: creationId
2176
+ }, accessToken);
2177
+
2178
+ console.log(`Publicação criada com ID: ${published.data.data.id}`);
2179
+ ```
2180
+
2181
+ **Exemplo Completo: Publicar Vídeo com Verificação de Status**
2182
+
2183
+ ```typescript
2184
+ // 1. Criar contêiner de vídeo
2185
+ const container = await sdk.instagram.createMediaContainer({
2186
+ token: 'sk_live_...',
2187
+ video_url: 'https://example.com/video.mp4',
2188
+ media_type: 'VIDEO',
2189
+ caption: 'Vídeo especial para nossos seguidores'
2190
+ }, accessToken);
2191
+
2192
+ const containerId = container.data.data.id;
2193
+
2194
+ // 2. Verificar status periodicamente (vídeos podem demorar)
2195
+ let status = 'IN_PROGRESS';
2196
+ let attempts = 0;
2197
+ const maxAttempts = 10;
2198
+
2199
+ while (status === 'IN_PROGRESS' && attempts < maxAttempts) {
2200
+ await new Promise(resolve => setTimeout(resolve, 5000)); // Aguardar 5 segundos
2201
+
2202
+ const statusCheck = await sdk.instagram.getContainerStatus({
2203
+ token: 'sk_live_...',
2204
+ container_id: containerId
2205
+ }, accessToken);
2206
+
2207
+ status = statusCheck.data.data.status_code;
2208
+ attempts++;
2209
+
2210
+ console.log(`Status: ${status} (tentativa ${attempts})`);
2211
+ }
2212
+
2213
+ // 3. Publicar quando status for 'FINISHED'
2214
+ if (status === 'FINISHED') {
2215
+ const published = await sdk.instagram.publishMedia({
2216
+ token: 'sk_live_...',
2217
+ creation_id: containerId
2218
+ }, accessToken);
2219
+
2220
+ console.log(`Vídeo publicado com ID: ${published.data.data.id}`);
2221
+ } else {
2222
+ console.error(`Erro: Status final é ${status}`);
2223
+ }
1964
2224
  ```
1965
2225
 
1966
2226
  ### Canais