n8n-nodes-digitalsac 0.2.1 → 0.2.5
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 +93 -5
- package/dist/nodes/Digitalsac/Digitalsac.node.js +89 -100
- package/index.ts +5 -0
- package/nodes/Digitalsac/Digitalsac.node.ts +226 -0
- package/nodes/Digitalsac/digitalsac.svg +3 -0
- package/package.json +6 -4
package/README.md
CHANGED
|
@@ -53,19 +53,53 @@ Configure as credenciais Digitalsac com a URL base e seu Bearer Token:
|
|
|
53
53
|
|
|
54
54
|
### Validar Data
|
|
55
55
|
1. Selecione a operação **Validar Data**
|
|
56
|
-
2. No campo **Dados (JSON)**, insira os dados no formato
|
|
56
|
+
2. No campo **Dados (JSON)**, insira os dados no formato:
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"data": "string com a data a ser validada"
|
|
60
|
+
}
|
|
61
|
+
```
|
|
57
62
|
|
|
58
63
|
### Listar Filas/Atendentes
|
|
59
64
|
1. Selecione a operação **Listar Filas** ou **Listar Atendentes**
|
|
60
65
|
2. Não é necessário configurar parâmetros adicionais
|
|
61
66
|
|
|
62
|
-
### Transferir para Fila
|
|
63
|
-
1. Selecione a operação **Transferir para Fila**
|
|
64
|
-
2. No campo **Dados (JSON)**, insira os dados no formato
|
|
67
|
+
### Transferir para Fila
|
|
68
|
+
1. Selecione a operação **Transferir para Fila**
|
|
69
|
+
2. No campo **Dados (JSON)**, insira os dados no formato:
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"ticketId": 0,
|
|
73
|
+
"queueId": 0
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
Onde:
|
|
77
|
+
- `ticketId`: ID do ticket a ser transferido
|
|
78
|
+
- `queueId`: ID da fila de destino
|
|
79
|
+
|
|
80
|
+
### Transferir para Atendente
|
|
81
|
+
1. Selecione a operação **Transferir para Atendente**
|
|
82
|
+
2. No campo **Dados (JSON)**, insira os dados no formato:
|
|
83
|
+
```json
|
|
84
|
+
{
|
|
85
|
+
"ticketId": 0,
|
|
86
|
+
"userId": 0
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
Onde:
|
|
90
|
+
- `ticketId`: ID do ticket a ser transferido
|
|
91
|
+
- `userId`: ID do atendente de destino
|
|
65
92
|
|
|
66
93
|
### Fechar Ticket
|
|
67
94
|
1. Selecione a operação **Fechar Ticket**
|
|
68
|
-
2. No campo **Dados (JSON)**, insira os dados no formato
|
|
95
|
+
2. No campo **Dados (JSON)**, insira os dados no formato:
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"ticketId": 0
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
Onde:
|
|
102
|
+
- `ticketId`: ID do ticket a ser fechado
|
|
69
103
|
|
|
70
104
|
### Enviar Mensagem de Texto
|
|
71
105
|
1. Selecione a operação **Enviar Mensagem**
|
|
@@ -94,6 +128,38 @@ Configure as credenciais Digitalsac com a URL base e seu Bearer Token:
|
|
|
94
128
|
```
|
|
95
129
|
Onde `data` é o nome da propriedade binária que contém o arquivo.
|
|
96
130
|
|
|
131
|
+
## Exemplos de Respostas da API
|
|
132
|
+
|
|
133
|
+
### Transferir para Fila
|
|
134
|
+
**Resposta de sucesso:**
|
|
135
|
+
```json
|
|
136
|
+
{
|
|
137
|
+
"status": 0
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Transferir para Atendente
|
|
142
|
+
**Resposta de sucesso:**
|
|
143
|
+
```json
|
|
144
|
+
{
|
|
145
|
+
"status": 0
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Fechar Ticket
|
|
150
|
+
**Resposta de sucesso:**
|
|
151
|
+
```json
|
|
152
|
+
"string"
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Validar Data
|
|
156
|
+
**Resposta de sucesso:**
|
|
157
|
+
```json
|
|
158
|
+
{
|
|
159
|
+
"status": 0
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
97
163
|
## Exemplo de Fluxo
|
|
98
164
|
|
|
99
165
|
### Enviar PDF para um contato
|
|
@@ -111,6 +177,28 @@ Onde `data` é o nome da propriedade binária que contém o arquivo.
|
|
|
111
177
|
}
|
|
112
178
|
```
|
|
113
179
|
|
|
180
|
+
### Transferir ticket para uma fila específica
|
|
181
|
+
1. Adicione um nó **Digitalsac**
|
|
182
|
+
- Operação: **Transferir para Fila**
|
|
183
|
+
- Dados (JSON):
|
|
184
|
+
```json
|
|
185
|
+
{
|
|
186
|
+
"ticketId": 123,
|
|
187
|
+
"queueId": 5
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Transferir ticket para um atendente específico
|
|
192
|
+
1. Adicione um nó **Digitalsac**
|
|
193
|
+
- Operação: **Transferir para Atendente**
|
|
194
|
+
- Dados (JSON):
|
|
195
|
+
```json
|
|
196
|
+
{
|
|
197
|
+
"ticketId": 123,
|
|
198
|
+
"userId": 10
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
114
202
|
## Suporte
|
|
115
203
|
|
|
116
204
|
Para suporte, entre em contato com [contato@digitalsac.io](mailto:contato@digitalsac.io).
|
|
@@ -49,19 +49,19 @@ class Digitalsac {
|
|
|
49
49
|
operation: ['validateWhatsapp', 'validateCpf', 'sendMessage'],
|
|
50
50
|
},
|
|
51
51
|
},
|
|
52
|
-
description: 'Número, CPF ou UUID da
|
|
52
|
+
description: 'Número, CPF ou UUID da mensagem (conforme operação)',
|
|
53
53
|
},
|
|
54
54
|
{
|
|
55
55
|
displayName: 'Dados (JSON)',
|
|
56
56
|
name: 'bodyData',
|
|
57
57
|
type: 'json',
|
|
58
|
-
default: '{
|
|
58
|
+
default: '{"body": "Mensagem de teste", "number": "5511999999999", "externalKey": "chave123"}',
|
|
59
59
|
displayOptions: {
|
|
60
60
|
show: {
|
|
61
61
|
operation: ['validateDate', 'transferQueue', 'transferAgent', 'closeTicket', 'sendMessage'],
|
|
62
62
|
},
|
|
63
63
|
},
|
|
64
|
-
description: '
|
|
64
|
+
description: 'Dados no formato JSON',
|
|
65
65
|
},
|
|
66
66
|
],
|
|
67
67
|
};
|
|
@@ -77,32 +77,37 @@ class Digitalsac {
|
|
|
77
77
|
let responseData;
|
|
78
78
|
const headers = {
|
|
79
79
|
Authorization: `Bearer ${token}`,
|
|
80
|
-
'Content-Type': 'application/json',
|
|
81
80
|
Accept: 'application/json',
|
|
82
81
|
};
|
|
83
82
|
let url = '';
|
|
84
83
|
let method = 'GET';
|
|
85
84
|
let body;
|
|
86
|
-
let param = '';
|
|
85
|
+
let param = this.getNodeParameter('param', i, '');
|
|
87
86
|
let options = {};
|
|
88
|
-
let isFormData = false;
|
|
89
|
-
let formDataFields = {};
|
|
90
|
-
let binaryData;
|
|
91
|
-
let binaryFileName;
|
|
92
|
-
let binaryContentType;
|
|
93
87
|
switch (operation) {
|
|
94
88
|
case 'validateWhatsapp':
|
|
95
|
-
param = this.getNodeParameter('param', i);
|
|
96
89
|
url = `/typebot/whatsappnumber/${param}`;
|
|
97
90
|
break;
|
|
98
91
|
case 'validateCpf':
|
|
99
|
-
param = this.getNodeParameter('param', i);
|
|
100
92
|
url = `/typebot/validate/cpf/${param}`;
|
|
101
93
|
break;
|
|
102
94
|
case 'validateDate':
|
|
103
95
|
url = '/typebot/validate/data';
|
|
104
96
|
method = 'POST';
|
|
105
|
-
|
|
97
|
+
try {
|
|
98
|
+
body = JSON.parse(this.getNodeParameter('bodyData', i));
|
|
99
|
+
}
|
|
100
|
+
catch (e) {
|
|
101
|
+
throw new Error('Formato de JSON inválido para Dados (JSON)');
|
|
102
|
+
}
|
|
103
|
+
headers['Content-Type'] = 'application/json';
|
|
104
|
+
options = {
|
|
105
|
+
method,
|
|
106
|
+
headers,
|
|
107
|
+
body,
|
|
108
|
+
uri: `${baseUrl}${url}`,
|
|
109
|
+
json: true,
|
|
110
|
+
};
|
|
106
111
|
break;
|
|
107
112
|
case 'listQueues':
|
|
108
113
|
url = '/typebot/listar_filas';
|
|
@@ -113,116 +118,100 @@ class Digitalsac {
|
|
|
113
118
|
case 'transferQueue':
|
|
114
119
|
url = '/typebot/transferir_para_fila';
|
|
115
120
|
method = 'POST';
|
|
116
|
-
|
|
121
|
+
try {
|
|
122
|
+
body = JSON.parse(this.getNodeParameter('bodyData', i));
|
|
123
|
+
}
|
|
124
|
+
catch (e) {
|
|
125
|
+
throw new Error('Formato de JSON inválido para Dados (JSON)');
|
|
126
|
+
}
|
|
127
|
+
headers['Content-Type'] = 'application/json';
|
|
128
|
+
options = {
|
|
129
|
+
method,
|
|
130
|
+
headers,
|
|
131
|
+
body,
|
|
132
|
+
uri: `${baseUrl}${url}`,
|
|
133
|
+
json: true,
|
|
134
|
+
};
|
|
117
135
|
break;
|
|
118
136
|
case 'transferAgent':
|
|
119
137
|
url = '/typebot/transferir_para_atendente';
|
|
120
138
|
method = 'POST';
|
|
121
|
-
|
|
139
|
+
try {
|
|
140
|
+
body = JSON.parse(this.getNodeParameter('bodyData', i));
|
|
141
|
+
}
|
|
142
|
+
catch (e) {
|
|
143
|
+
throw new Error('Formato de JSON inválido para Dados (JSON)');
|
|
144
|
+
}
|
|
145
|
+
headers['Content-Type'] = 'application/json';
|
|
146
|
+
options = {
|
|
147
|
+
method,
|
|
148
|
+
headers,
|
|
149
|
+
body,
|
|
150
|
+
uri: `${baseUrl}${url}`,
|
|
151
|
+
json: true,
|
|
152
|
+
};
|
|
122
153
|
break;
|
|
123
154
|
case 'closeTicket':
|
|
124
155
|
url = '/typebot/fechar_ticket';
|
|
125
156
|
method = 'POST';
|
|
126
|
-
|
|
157
|
+
try {
|
|
158
|
+
body = JSON.parse(this.getNodeParameter('bodyData', i));
|
|
159
|
+
}
|
|
160
|
+
catch (e) {
|
|
161
|
+
throw new Error('Formato de JSON inválido para Dados (JSON)');
|
|
162
|
+
}
|
|
163
|
+
headers['Content-Type'] = 'application/json';
|
|
164
|
+
options = {
|
|
165
|
+
method,
|
|
166
|
+
headers,
|
|
167
|
+
body,
|
|
168
|
+
uri: `${baseUrl}${url}`,
|
|
169
|
+
json: true,
|
|
170
|
+
};
|
|
127
171
|
break;
|
|
128
172
|
case 'sendMessage':
|
|
129
|
-
|
|
130
|
-
const uuid = this.getNodeParameter('param', i);
|
|
131
|
-
url = `/v1/api/external/${uuid}`;
|
|
173
|
+
url = `/v1/api/external/${param}`;
|
|
132
174
|
method = 'POST';
|
|
133
|
-
// Verificar se há dados binários (para envio de arquivo)
|
|
134
|
-
const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i, '');
|
|
135
|
-
let hasBinaryData = false;
|
|
136
|
-
if (binaryPropertyName && items[i].binary) {
|
|
137
|
-
const binary = items[i].binary;
|
|
138
|
-
hasBinaryData = binary[binaryPropertyName] !== undefined;
|
|
139
|
-
}
|
|
140
|
-
// Obter dados do corpo da mensagem
|
|
141
|
-
const messageData = this.getNodeParameter('bodyData', i, '{}');
|
|
142
|
-
let messageBody = {};
|
|
143
175
|
try {
|
|
144
|
-
//
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
messageBody = messageData;
|
|
150
|
-
}
|
|
176
|
+
// Obter o JSON como string e converter para objeto
|
|
177
|
+
const bodyDataStr = this.getNodeParameter('bodyData', i);
|
|
178
|
+
// Remover espaços extras e quebras de linha
|
|
179
|
+
const cleanJson = bodyDataStr.replace(/\s+/g, ' ').trim();
|
|
180
|
+
body = JSON.parse(cleanJson);
|
|
151
181
|
}
|
|
152
|
-
catch (
|
|
153
|
-
|
|
154
|
-
messageBody = { body: messageData };
|
|
155
|
-
}
|
|
156
|
-
// Se não tiver dados binários, enviar como JSON normal
|
|
157
|
-
if (!hasBinaryData) {
|
|
158
|
-
body = messageBody;
|
|
159
|
-
}
|
|
160
|
-
else {
|
|
161
|
-
// Configurar para envio de arquivo
|
|
162
|
-
isFormData = true;
|
|
163
|
-
formDataFields = messageBody;
|
|
164
|
-
// Preparar arquivo binário
|
|
165
|
-
if (items[i].binary) {
|
|
166
|
-
const binaryKeyData = items[i].binary;
|
|
167
|
-
if (binaryKeyData[binaryPropertyName]) {
|
|
168
|
-
const binaryProperty = binaryKeyData[binaryPropertyName];
|
|
169
|
-
binaryData = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
|
|
170
|
-
binaryFileName = binaryProperty.fileName || 'file';
|
|
171
|
-
binaryContentType = binaryProperty.mimeType;
|
|
172
|
-
}
|
|
173
|
-
else {
|
|
174
|
-
throw new Error(`Nenhum dado binário encontrado na propriedade "${binaryPropertyName}"`);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
headers['Content-Type'] = 'multipart/form-data';
|
|
178
|
-
options = {
|
|
179
|
-
formData: true,
|
|
180
|
-
};
|
|
182
|
+
catch (e) {
|
|
183
|
+
throw new Error('Formato de JSON inválido para Dados (JSON)');
|
|
181
184
|
}
|
|
185
|
+
headers['Content-Type'] = 'application/json';
|
|
186
|
+
options = {
|
|
187
|
+
method,
|
|
188
|
+
headers,
|
|
189
|
+
body, // Enviar o objeto diretamente, sem JSON.stringify
|
|
190
|
+
uri: `${baseUrl}${url}`,
|
|
191
|
+
json: true,
|
|
192
|
+
};
|
|
182
193
|
break;
|
|
183
194
|
}
|
|
184
|
-
//
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
if (body && !isFormData) {
|
|
193
|
-
requestOptions.body = body;
|
|
194
|
-
}
|
|
195
|
-
// Configurar FormData quando necessário
|
|
196
|
-
if (isFormData) {
|
|
197
|
-
const formData = {};
|
|
198
|
-
// Adicionar campos de texto
|
|
199
|
-
Object.entries(formDataFields).forEach(([key, value]) => {
|
|
200
|
-
formData[key] = value;
|
|
201
|
-
});
|
|
202
|
-
// Adicionar arquivo se disponível
|
|
203
|
-
if (binaryData && binaryFileName) {
|
|
204
|
-
formData.media = {
|
|
205
|
-
value: binaryData,
|
|
206
|
-
options: {
|
|
207
|
-
filename: binaryFileName,
|
|
208
|
-
contentType: binaryContentType,
|
|
209
|
-
},
|
|
210
|
-
};
|
|
211
|
-
}
|
|
212
|
-
requestOptions.formData = formData;
|
|
195
|
+
// Se as opções não foram definidas no switch, defina-as aqui para operações GET
|
|
196
|
+
if (!options.method) {
|
|
197
|
+
options = {
|
|
198
|
+
method,
|
|
199
|
+
headers,
|
|
200
|
+
uri: `${baseUrl}${url}`,
|
|
201
|
+
json: true,
|
|
202
|
+
};
|
|
213
203
|
}
|
|
214
|
-
// Mesclar opções adicionais
|
|
215
|
-
Object.assign(requestOptions, options);
|
|
216
204
|
try {
|
|
217
|
-
responseData = await this.helpers.request(
|
|
205
|
+
responseData = await this.helpers.request(options);
|
|
218
206
|
returnData.push({ json: responseData });
|
|
219
207
|
}
|
|
220
208
|
catch (error) {
|
|
221
|
-
if (
|
|
209
|
+
if (error.response) {
|
|
210
|
+
returnData.push({ json: { error: error.response.body || error.message } });
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
222
213
|
returnData.push({ json: { error: error.message } });
|
|
223
|
-
continue;
|
|
224
214
|
}
|
|
225
|
-
throw error;
|
|
226
215
|
}
|
|
227
216
|
}
|
|
228
217
|
return [returnData];
|
package/index.ts
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import {
|
|
2
|
+
IExecuteFunctions,
|
|
3
|
+
INodeExecutionData,
|
|
4
|
+
INodeType,
|
|
5
|
+
INodeTypeDescription,
|
|
6
|
+
NodeConnectionType,
|
|
7
|
+
} from 'n8n-workflow';
|
|
8
|
+
|
|
9
|
+
export class Digitalsac implements INodeType {
|
|
10
|
+
description: INodeTypeDescription = {
|
|
11
|
+
displayName: 'Digitalsac Izing Pro',
|
|
12
|
+
name: 'digitalsac',
|
|
13
|
+
icon: 'file:digitalsac.svg',
|
|
14
|
+
group: ['transform'],
|
|
15
|
+
version: 1,
|
|
16
|
+
description: 'Interage com a API do Digitalsac',
|
|
17
|
+
defaults: {
|
|
18
|
+
name: 'Digitalsac',
|
|
19
|
+
},
|
|
20
|
+
inputs: <NodeConnectionType[]>['main'],
|
|
21
|
+
outputs: <NodeConnectionType[]>['main'],
|
|
22
|
+
|
|
23
|
+
credentials: [
|
|
24
|
+
{
|
|
25
|
+
name: 'digitalsacApi',
|
|
26
|
+
required: true,
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
properties: [
|
|
30
|
+
{
|
|
31
|
+
displayName: 'Operação',
|
|
32
|
+
name: 'operation',
|
|
33
|
+
type: 'options',
|
|
34
|
+
options: [
|
|
35
|
+
{ name: 'Validar WhatsApp', value: 'validateWhatsapp' },
|
|
36
|
+
{ name: 'Validar CPF', value: 'validateCpf' },
|
|
37
|
+
{ name: 'Validar Data', value: 'validateDate' },
|
|
38
|
+
{ name: 'Listar Filas', value: 'listQueues' },
|
|
39
|
+
{ name: 'Listar Atendentes', value: 'listAgents' },
|
|
40
|
+
{ name: 'Transferir para Fila', value: 'transferQueue' },
|
|
41
|
+
{ name: 'Transferir para Atendente', value: 'transferAgent' },
|
|
42
|
+
{ name: 'Fechar Ticket', value: 'closeTicket' },
|
|
43
|
+
{ name: 'Enviar Mensagem', value: 'sendMessage' },
|
|
44
|
+
],
|
|
45
|
+
default: 'validateWhatsapp',
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
displayName: 'Parâmetro',
|
|
49
|
+
name: 'param',
|
|
50
|
+
type: 'string',
|
|
51
|
+
default: '',
|
|
52
|
+
displayOptions: {
|
|
53
|
+
show: {
|
|
54
|
+
operation: ['validateWhatsapp', 'validateCpf', 'sendMessage'],
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
description: 'Número, CPF ou UUID da mensagem (conforme operação)',
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
displayName: 'Dados (JSON)',
|
|
61
|
+
name: 'bodyData',
|
|
62
|
+
type: 'json',
|
|
63
|
+
default: '{"body": "Mensagem de teste", "number": "5511999999999", "externalKey": "chave123"}',
|
|
64
|
+
displayOptions: {
|
|
65
|
+
show: {
|
|
66
|
+
operation: ['validateDate', 'transferQueue', 'transferAgent', 'closeTicket', 'sendMessage'],
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
description: 'Dados no formato JSON',
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
|
75
|
+
const items = this.getInputData();
|
|
76
|
+
const returnData: INodeExecutionData[] = [];
|
|
77
|
+
|
|
78
|
+
const credentials = await this.getCredentials('digitalsacApi');
|
|
79
|
+
const baseUrl = credentials.baseUrl;
|
|
80
|
+
const token = credentials.token;
|
|
81
|
+
|
|
82
|
+
for (let i = 0; i < items.length; i++) {
|
|
83
|
+
const operation = this.getNodeParameter('operation', i) as string;
|
|
84
|
+
let responseData;
|
|
85
|
+
|
|
86
|
+
const headers: Record<string, string> = {
|
|
87
|
+
Authorization: `Bearer ${token}`,
|
|
88
|
+
Accept: 'application/json',
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
let url = '';
|
|
92
|
+
let method: 'GET' | 'POST' = 'GET';
|
|
93
|
+
let body;
|
|
94
|
+
let param = this.getNodeParameter('param', i, '') as string;
|
|
95
|
+
let options: Record<string, any> = {};
|
|
96
|
+
|
|
97
|
+
switch (operation) {
|
|
98
|
+
case 'validateWhatsapp':
|
|
99
|
+
url = `/typebot/whatsappnumber/${param}`;
|
|
100
|
+
break;
|
|
101
|
+
case 'validateCpf':
|
|
102
|
+
url = `/typebot/validate/cpf/${param}`;
|
|
103
|
+
break;
|
|
104
|
+
case 'validateDate':
|
|
105
|
+
url = '/typebot/validate/data';
|
|
106
|
+
method = 'POST';
|
|
107
|
+
try {
|
|
108
|
+
body = JSON.parse(this.getNodeParameter('bodyData', i) as string);
|
|
109
|
+
} catch (e) {
|
|
110
|
+
throw new Error('Formato de JSON inválido para Dados (JSON)');
|
|
111
|
+
}
|
|
112
|
+
headers['Content-Type'] = 'application/json';
|
|
113
|
+
options = {
|
|
114
|
+
method,
|
|
115
|
+
headers,
|
|
116
|
+
body,
|
|
117
|
+
uri: `${baseUrl}${url}`,
|
|
118
|
+
json: true,
|
|
119
|
+
};
|
|
120
|
+
break;
|
|
121
|
+
case 'listQueues':
|
|
122
|
+
url = '/typebot/listar_filas';
|
|
123
|
+
break;
|
|
124
|
+
case 'listAgents':
|
|
125
|
+
url = '/typebot/listar_atendentes';
|
|
126
|
+
break;
|
|
127
|
+
case 'transferQueue':
|
|
128
|
+
url = '/typebot/transferir_para_fila';
|
|
129
|
+
method = 'POST';
|
|
130
|
+
try {
|
|
131
|
+
body = JSON.parse(this.getNodeParameter('bodyData', i) as string);
|
|
132
|
+
} catch (e) {
|
|
133
|
+
throw new Error('Formato de JSON inválido para Dados (JSON)');
|
|
134
|
+
}
|
|
135
|
+
headers['Content-Type'] = 'application/json';
|
|
136
|
+
options = {
|
|
137
|
+
method,
|
|
138
|
+
headers,
|
|
139
|
+
body,
|
|
140
|
+
uri: `${baseUrl}${url}`,
|
|
141
|
+
json: true,
|
|
142
|
+
};
|
|
143
|
+
break;
|
|
144
|
+
case 'transferAgent':
|
|
145
|
+
url = '/typebot/transferir_para_atendente';
|
|
146
|
+
method = 'POST';
|
|
147
|
+
try {
|
|
148
|
+
body = JSON.parse(this.getNodeParameter('bodyData', i) as string);
|
|
149
|
+
} catch (e) {
|
|
150
|
+
throw new Error('Formato de JSON inválido para Dados (JSON)');
|
|
151
|
+
}
|
|
152
|
+
headers['Content-Type'] = 'application/json';
|
|
153
|
+
options = {
|
|
154
|
+
method,
|
|
155
|
+
headers,
|
|
156
|
+
body,
|
|
157
|
+
uri: `${baseUrl}${url}`,
|
|
158
|
+
json: true,
|
|
159
|
+
};
|
|
160
|
+
break;
|
|
161
|
+
case 'closeTicket':
|
|
162
|
+
url = '/typebot/fechar_ticket';
|
|
163
|
+
method = 'POST';
|
|
164
|
+
try {
|
|
165
|
+
body = JSON.parse(this.getNodeParameter('bodyData', i) as string);
|
|
166
|
+
} catch (e) {
|
|
167
|
+
throw new Error('Formato de JSON inválido para Dados (JSON)');
|
|
168
|
+
}
|
|
169
|
+
headers['Content-Type'] = 'application/json';
|
|
170
|
+
options = {
|
|
171
|
+
method,
|
|
172
|
+
headers,
|
|
173
|
+
body,
|
|
174
|
+
uri: `${baseUrl}${url}`,
|
|
175
|
+
json: true,
|
|
176
|
+
};
|
|
177
|
+
break;
|
|
178
|
+
case 'sendMessage':
|
|
179
|
+
url = `/v1/api/external/${param}`;
|
|
180
|
+
method = 'POST';
|
|
181
|
+
try {
|
|
182
|
+
// Obter o JSON como string e converter para objeto
|
|
183
|
+
const bodyDataStr = this.getNodeParameter('bodyData', i) as string;
|
|
184
|
+
// Remover espaços extras e quebras de linha
|
|
185
|
+
const cleanJson = bodyDataStr.replace(/\s+/g, ' ').trim();
|
|
186
|
+
body = JSON.parse(cleanJson);
|
|
187
|
+
} catch (e) {
|
|
188
|
+
throw new Error('Formato de JSON inválido para Dados (JSON)');
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
headers['Content-Type'] = 'application/json';
|
|
192
|
+
options = {
|
|
193
|
+
method,
|
|
194
|
+
headers,
|
|
195
|
+
body, // Enviar o objeto diretamente, sem JSON.stringify
|
|
196
|
+
uri: `${baseUrl}${url}`,
|
|
197
|
+
json: true,
|
|
198
|
+
};
|
|
199
|
+
break;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Se as opções não foram definidas no switch, defina-as aqui para operações GET
|
|
203
|
+
if (!options.method) {
|
|
204
|
+
options = {
|
|
205
|
+
method,
|
|
206
|
+
headers,
|
|
207
|
+
uri: `${baseUrl}${url}`,
|
|
208
|
+
json: true,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
try {
|
|
213
|
+
responseData = await this.helpers.request(options);
|
|
214
|
+
returnData.push({ json: responseData });
|
|
215
|
+
} catch (error: any) {
|
|
216
|
+
if (error.response) {
|
|
217
|
+
returnData.push({ json: { error: error.response.body || error.message } });
|
|
218
|
+
} else {
|
|
219
|
+
returnData.push({ json: { error: error.message } });
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return [returnData];
|
|
225
|
+
}
|
|
226
|
+
}
|