@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 +407 -147
- package/dist/index.d.mts +130 -32
- package/dist/index.d.ts +130 -32
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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,
|
|
24
|
-
maxRetries: 3,
|
|
25
|
-
retryDelay: 1000,
|
|
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
|
-
|
|
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
|
-
|
|
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'
|
|
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!',
|
|
633
|
-
reference_id: 'pedido_12345_1704067200',
|
|
634
|
-
order_status: 'shipped',
|
|
635
|
-
status_description: 'Sua encomenda foi despachada pelos Correios',
|
|
636
|
-
payment_status: 'captured',
|
|
637
|
-
payment_timestamp: 1722445231
|
|
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
|
-
|
|
635
|
+
|
|
645
636
|
await sdk.whatsapp.sendSticker({
|
|
646
637
|
token: 'sk_live_...',
|
|
647
638
|
sender: '5511999999999',
|
|
648
|
-
mediaId: '798882015472548'
|
|
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',
|
|
660
|
-
footerText: 'Sua privacidade é importante'
|
|
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',
|
|
662
|
+
buttonText: 'Acessar',
|
|
672
663
|
url: 'https://example.com',
|
|
673
|
-
header: {
|
|
674
|
-
type: 'image',
|
|
675
|
-
link: 'https://example.com/banner.jpg'
|
|
676
|
-
|
|
664
|
+
header: {
|
|
665
|
+
type: 'image',
|
|
666
|
+
link: 'https://example.com/banner.jpg'
|
|
667
|
+
|
|
677
668
|
},
|
|
678
|
-
footerText: 'Ofertas válidas até 30/11'
|
|
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!',
|
|
689
|
-
cards: [
|
|
679
|
+
bodyText: 'Confira nossas ofertas da semana!',
|
|
680
|
+
cards: [
|
|
690
681
|
{
|
|
691
682
|
cardIndex: 0,
|
|
692
|
-
headerType: 'image',
|
|
683
|
+
headerType: 'image',
|
|
693
684
|
headerLink: 'https://example.com/image1.jpg',
|
|
694
|
-
bodyText: 'Oferta especial!',
|
|
695
|
-
buttonText: 'Comprar agora',
|
|
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
|
-
|
|
719
|
-
console.log(media.data.buffer);
|
|
720
|
-
console.log(media.data.mimeType);
|
|
721
|
-
console.log(media.data.filename);
|
|
722
|
-
console.log(media.data.size);
|
|
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',
|
|
721
|
+
sender: '5511999999999',
|
|
731
722
|
messageText: 'Esta é uma resposta!',
|
|
732
|
-
replyMessageId: 'wamid.xxx',
|
|
733
|
-
preview_url: false
|
|
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',
|
|
743
|
-
emoji: '👍',
|
|
744
|
-
message_id: 'wamid.xxx'
|
|
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
|
-
|
|
742
|
+
|
|
752
743
|
const templates = await sdk.whatsapp.listTemplates('sk_live_...', accessToken);
|
|
753
744
|
|
|
754
|
-
|
|
745
|
+
|
|
755
746
|
const template = await sdk.whatsapp.getTemplate('sk_live_...', 'template_id', accessToken);
|
|
756
747
|
|
|
757
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
909
|
+
file: imageBuffer,
|
|
910
|
+
mediaType: 'image'
|
|
911
|
+
|
|
931
912
|
}, accessToken);
|
|
932
913
|
|
|
933
|
-
|
|
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]
|
|
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
|
|
961
|
-
- **Vídeos
|
|
962
|
-
- **Áudios**: OGG
|
|
963
|
-
- **Documentos
|
|
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
|
-
|
|
1468
|
-
console.log(media.data.buffer);
|
|
1469
|
-
console.log(media.data.mimeType);
|
|
1470
|
-
console.log(media.data.filename);
|
|
1471
|
-
console.log(media.data.size);
|
|
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
|
-
|
|
1481
|
-
|
|
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
|
-
|
|
1491
|
-
|
|
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
|
-
|
|
1498
|
-
|
|
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
|
-
|
|
1510
|
-
|
|
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
|
-
|
|
1522
|
-
|
|
1512
|
+
channelToken: 'sk_live_...',
|
|
1513
|
+
chatId: 'chat_123456789',
|
|
1523
1514
|
cards: [
|
|
1524
1515
|
{
|
|
1525
1516
|
title: 'Produto 1',
|
|
1526
|
-
|
|
1517
|
+
subtitle: 'Descrição do produto 1',
|
|
1527
1518
|
imageUrl: 'https://example.com/product1.jpg',
|
|
1528
1519
|
buttons: [
|
|
1529
|
-
{
|
|
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
|
-
|
|
1531
|
+
subtitle: 'Descrição do produto 2',
|
|
1535
1532
|
imageUrl: 'https://example.com/product2.jpg',
|
|
1536
1533
|
buttons: [
|
|
1537
|
-
{
|
|
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
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1574
|
-
|
|
1593
|
+
channelToken: 'sk_live_...',
|
|
1594
|
+
chatId: 'chat_123456789',
|
|
1575
1595
|
messageText: 'Como podemos ajudar?',
|
|
1576
1596
|
quickReplies: [
|
|
1577
|
-
{
|
|
1578
|
-
|
|
1579
|
-
|
|
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
|
-
|
|
1589
|
-
|
|
1617
|
+
channelToken: 'sk_live_...',
|
|
1618
|
+
chatId: 'chat_123456789',
|
|
1590
1619
|
messageText: 'Escolha uma opção:',
|
|
1591
1620
|
buttons: [
|
|
1592
|
-
{
|
|
1593
|
-
|
|
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
|
-
|
|
1755
|
-
console.log(media.data.buffer);
|
|
1756
|
-
console.log(media.data.mimeType);
|
|
1757
|
-
console.log(media.data.filename);
|
|
1758
|
-
console.log(media.data.size);
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1960
|
-
console.log(media.data.buffer);
|
|
1961
|
-
console.log(media.data.mimeType);
|
|
1962
|
-
console.log(media.data.filename);
|
|
1963
|
-
console.log(media.data.size);
|
|
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
|