n8n-nodes-zarkchat 0.1.3 → 0.2.0
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 +22 -2
- package/dist/nodes/ZarkChat/ZarkChat.node.js +13 -0
- package/dist/nodes/ZarkChat/ZarkChat.node.js.map +1 -1
- package/dist/nodes/ZarkChat/shared/rateLimit.d.ts +52 -0
- package/dist/nodes/ZarkChat/shared/rateLimit.js +143 -0
- package/dist/nodes/ZarkChat/shared/rateLimit.js.map +1 -0
- package/dist/nodes/ZarkChatTrigger/ZarkChatTrigger.node.js +32 -1
- package/dist/nodes/ZarkChatTrigger/ZarkChatTrigger.node.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -77,6 +77,18 @@ Passo a passo:
|
|
|
77
77
|
|
|
78
78
|
**Deixe `Validate Signature` ligado.** Sem isso, qualquer pessoa que descubra a URL do seu webhook injeta evento falso no seu agente. O node valida sobre o corpo cru, exatamente como a API assina.
|
|
79
79
|
|
|
80
|
+
### Respondendo no corpo (desde 0.2.0)
|
|
81
|
+
|
|
82
|
+
O campo **Respond** controla quando e como o gatilho responde:
|
|
83
|
+
|
|
84
|
+
| Opção | Quando usar |
|
|
85
|
+
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
86
|
+
| **Immediately** (padrão) | Responde assim que o evento chega, antes do workflow rodar. Comportamento de sempre; quem já tem workflow publicado não muda sozinho. |
|
|
87
|
+
| **When Last Node Finishes** | Espera o workflow terminar e devolve o JSON do último node no corpo. É o que o **Chat de Teste** do painel precisa: monte a resposta como `{"reply": "..."}` no último node do fluxo. |
|
|
88
|
+
| **Using 'Respond to Webhook' Node** | Controle total (status, corpo, headers) via um node `Respond to Webhook` em qualquer ponto do fluxo. |
|
|
89
|
+
|
|
90
|
+
O padrão nunca muda sozinho: instalações existentes continuam em Immediately sem precisar reconfigurar nada.
|
|
91
|
+
|
|
80
92
|
Evento que chega e não está na lista selecionada é descartado com `200`, e não com erro: responder erro faria o ZarkChat repetir a entrega (30s, 2min, 10min, 30min, 2h) de algo que este fluxo ignora de propósito.
|
|
81
93
|
|
|
82
94
|
## Referência: as 31 operações
|
|
@@ -124,6 +136,8 @@ Campo: `Agent ID`.
|
|
|
124
136
|
| **Get Messages** | `messages:read` | Conversation ID + Cursor, Limit |
|
|
125
137
|
| **Send Message** | `messages:send` | Conversation ID + corpo (Text, Media, Template, Interactive) |
|
|
126
138
|
|
|
139
|
+
> **Mudou em 2026-08-14:** cada item de **Get Messages** já traz `media` (URL assinada 15 min, `mime`, `sizeBytes`, `filename`, `expiresAt`) quando a mensagem tem anexo, sem precisar de um `Media: Get` por mensagem. `mediaAssetId` continua no item por retrocompat. **`Message: Get` (mensagem avulsa) não ganhou esse campo**: ainda devolve só `mediaAssetId`, use `Media: Get` nesse caso, ou quando a URL de uma mensagem já listada tiver expirado.
|
|
140
|
+
|
|
127
141
|
### Message
|
|
128
142
|
|
|
129
143
|
| Operação | Escopo | Campos |
|
|
@@ -151,7 +165,7 @@ Devolve os trechos com a origem, para o agente citar a fonte.
|
|
|
151
165
|
| -------- | --------------- | -------------- |
|
|
152
166
|
| **Get** | `messages:read` | Media Asset ID |
|
|
153
167
|
|
|
154
|
-
Metadados e URL assinada (15 minutos) de um anexo recebido. O mime autoritativo vem daqui, não da mensagem: é o caminho para baixar áudio, imagem e documento a partir do `mediaAssetId` que a mensagem entrega. Upload continua fechado para api-key, de propósito: `POST /v1/media` é rota do painel.
|
|
168
|
+
Metadados e URL assinada (15 minutos) de um anexo recebido. O mime autoritativo vem daqui, não da mensagem: é o caminho para baixar áudio, imagem e documento a partir do `mediaAssetId` que a mensagem entrega. **Desde 2026-08-14, `Conversation: Get Messages` já traz esse mesmo `media` embutido em cada item**; use esta operação separada só para `Message: Get` (não resolve `media`) ou quando a URL assinada de uma mensagem já listada expirou. Upload continua fechado para api-key, de propósito: `POST /v1/media` é rota do painel.
|
|
155
169
|
|
|
156
170
|
### Pipeline
|
|
157
171
|
|
|
@@ -184,6 +198,8 @@ Use **Get Stages** para descobrir o `stageId` que `Contact: Move To Stage` exige
|
|
|
184
198
|
| **Template** | Template ID **ou** Name + Language, Parameters |
|
|
185
199
|
| **Interactive** | Payload cru do WhatsApp (botões, listas) |
|
|
186
200
|
|
|
201
|
+
> A API aceita `media.voice: true` (Media Kind = Audio) para marcar o áudio como **nota de voz** (`ptt`) em vez de arquivo comum, mas **este campo ainda não tem UI no node** (só Caption/Filename em Media Options). Para enviar nota de voz hoje, monte o corpo com um nó HTTP genérico até sair uma versão do pacote com o campo.
|
|
202
|
+
|
|
187
203
|
## Esqueleto de um agente de atendimento
|
|
188
204
|
|
|
189
205
|
Fluxo mínimo que respeita as regras da casa:
|
|
@@ -197,7 +213,7 @@ ZarkChat Trigger (message.received, Validate Signature ligado)
|
|
|
197
213
|
├─ ZarkChat Agent: Get Config ← como este cliente quer ser atendido
|
|
198
214
|
├─ ZarkChat Conversation: Get Insight ← temperatura e estágio, já calculados
|
|
199
215
|
├─ ZarkChat Conversation: Get Messages ← só as últimas, não a conversa toda
|
|
200
|
-
│ └─
|
|
216
|
+
│ └─ item já traz `media` (URL assinada) quando tem anexo; `Media: Get` só se precisar reobter depois de expirado
|
|
201
217
|
├─ ZarkChat Knowledge Base: Search ← trechos relevantes, com a fonte
|
|
202
218
|
│
|
|
203
219
|
├─ (seu modelo de IA monta a resposta)
|
|
@@ -217,6 +233,10 @@ Economia que vale: `Agent: Get Config` muda raramente, então cachear corta ~1 c
|
|
|
217
233
|
|
|
218
234
|
Um agente que gasta ~7 chamadas por mensagem sustenta cerca de 17 mensagens por minuto. Se precisar de mais, cachear `Agent: Get Config` corta boa parte das chamadas, porque essa configuração muda raramente.
|
|
219
235
|
|
|
236
|
+
### O node trata 429 sozinho (desde 0.2.0)
|
|
237
|
+
|
|
238
|
+
Ao bater no limite, a API responde `429` com o cabeçalho `Retry-After`. O node **ZarkChat** lê esse cabeçalho e espera o tempo exato antes de tentar de novo, em vez de aplicar um intervalo fixo (a retentativa nativa do n8n, em Settings do node, não lê cabeçalho de resposta). Teto de 4 tentativas (a chamada original + até 3 reenvios): se ainda assim continuar limitado, o erro final deixa claro que foi **ritmo, não defeito**, para não confundir com um bug do workflow. Qualquer outro erro (`400`, `500`, etc.) propaga direto, sem essa retentativa.
|
|
239
|
+
|
|
220
240
|
## Por que só 31 operações, se a API tem 141 rotas
|
|
221
241
|
|
|
222
242
|
As outras 110 são do painel e exigem login de usuário com papel. Uma api-key receberia `403` em todas elas, sempre. Expor essas rotas aqui só produziria nodes que falham, então a fronteira do pacote é exatamente o que uma chave alcança. Há um teste que quebra o build se alguma operação sair dessa fronteira.
|
|
@@ -5,6 +5,7 @@ const contact_1 = require("./resources/contact");
|
|
|
5
5
|
const conversation_1 = require("./resources/conversation");
|
|
6
6
|
const message_1 = require("./resources/message");
|
|
7
7
|
const misc_1 = require("./resources/misc");
|
|
8
|
+
const rateLimit_1 = require("./shared/rateLimit");
|
|
8
9
|
/**
|
|
9
10
|
* Node do ZarkChat (estilo declarativo: as chamadas vivem em `routing`, sem
|
|
10
11
|
* `execute`).
|
|
@@ -39,6 +40,14 @@ class ZarkChat {
|
|
|
39
40
|
'Content-Type': 'application/json',
|
|
40
41
|
},
|
|
41
42
|
},
|
|
43
|
+
// Nenhuma operação pagina de verdade (Get Many usa Cursor manual, não
|
|
44
|
+
// isto). O hook existe só pra ligar `zarkChatRateLimitedRequest`, que
|
|
45
|
+
// trata 429 respeitando Retry-After: ver nodes/ZarkChat/shared/rateLimit.ts
|
|
46
|
+
// pro porquê deste ser o único ponto de extensão possível sem reescrever
|
|
47
|
+
// as 31 operações.
|
|
48
|
+
requestOperations: {
|
|
49
|
+
pagination: rateLimit_1.zarkChatRateLimitedRequest,
|
|
50
|
+
},
|
|
42
51
|
properties: [
|
|
43
52
|
{
|
|
44
53
|
displayName: 'Resource',
|
|
@@ -58,6 +67,10 @@ class ZarkChat {
|
|
|
58
67
|
{ name: 'Pipeline', value: 'pipeline' },
|
|
59
68
|
],
|
|
60
69
|
default: 'conversation',
|
|
70
|
+
// Único campo sempre presente, em toda operação: é o que liga o
|
|
71
|
+
// hook de `requestOperations.pagination` acima pra TODAS as 31
|
|
72
|
+
// operações de uma vez, sem tocar em nenhuma delas.
|
|
73
|
+
routing: { send: { paginate: true } },
|
|
61
74
|
},
|
|
62
75
|
...misc_1.agentOperations,
|
|
63
76
|
...misc_1.agentFields,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ZarkChat.node.js","sourceRoot":"","sources":["../../../nodes/ZarkChat/ZarkChat.node.ts"],"names":[],"mappings":";;;AACA,iDAAuE;AACvE,2DAAsF;AACtF,iDAAuE;AACvE,2CAa0B;
|
|
1
|
+
{"version":3,"file":"ZarkChat.node.js","sourceRoot":"","sources":["../../../nodes/ZarkChat/ZarkChat.node.ts"],"names":[],"mappings":";;;AACA,iDAAuE;AACvE,2DAAsF;AACtF,iDAAuE;AACvE,2CAa0B;AAC1B,kDAAgE;AAEhE;;;;;;;;;;;GAWG;AACH,MAAa,QAAQ;IAArB;QACC,gBAAW,GAAyB;YACnC,WAAW,EAAE,UAAU;YACvB,IAAI,EAAE,UAAU;YAChB,IAAI,EAAE,+BAA+B;YACrC,KAAK,EAAE,CAAC,WAAW,CAAC;YACpB,OAAO,EAAE,CAAC;YACV,QAAQ,EAAE,8DAA8D;YACxE,WAAW,EAAE,sEAAsE;YACnF,QAAQ,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE;YAC9B,YAAY,EAAE,IAAI;YAClB,MAAM,EAAE,CAAC,MAAM,CAAC;YAChB,OAAO,EAAE,CAAC,MAAM,CAAC;YACjB,WAAW,EAAE,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;YACtD,eAAe,EAAE;gBAChB,OAAO,EAAE,2BAA2B;gBACpC,OAAO,EAAE;oBACR,MAAM,EAAE,kBAAkB;oBAC1B,cAAc,EAAE,kBAAkB;iBAClC;aACD;YACD,sEAAsE;YACtE,sEAAsE;YACtE,4EAA4E;YAC5E,yEAAyE;YACzE,mBAAmB;YACnB,iBAAiB,EAAE;gBAClB,UAAU,EAAE,sCAA0B;aACtC;YACD,UAAU,EAAE;gBACX;oBACC,WAAW,EAAE,UAAU;oBACvB,IAAI,EAAE,UAAU;oBAChB,IAAI,EAAE,SAAS;oBACf,gBAAgB,EAAE,IAAI;oBACtB,OAAO,EAAE;wBACR,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE;wBACjC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE;wBACrC,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAE;wBAC/C,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;wBAC/B,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,eAAe,EAAE;wBAClD,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE;wBACjC,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,YAAY,EAAE;wBAC5C,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE;wBACjC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE;wBACrC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE;qBACvC;oBACD,OAAO,EAAE,cAAc;oBACvB,gEAAgE;oBAChE,+DAA+D;oBAC/D,oDAAoD;oBACpD,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE;iBACrC;gBAED,GAAG,sBAAe;gBAClB,GAAG,kBAAW;gBACd,GAAG,2BAAiB;gBACpB,GAAG,uBAAa;gBAChB,GAAG,qCAAsB;gBACzB,GAAG,iCAAkB;gBACrB,GAAG,qBAAc;gBACjB,GAAG,iBAAU;gBACb,GAAG,8BAAuB;gBAC1B,GAAG,0BAAmB;gBACtB,GAAG,sBAAe;gBAClB,GAAG,2BAAoB;gBACvB,GAAG,sBAAe;gBAClB,GAAG,kBAAW;gBACd,GAAG,2BAAiB;gBACpB,GAAG,uBAAa;gBAChB,GAAG,yBAAkB;gBACrB,GAAG,qBAAc;aACjB;SACD,CAAC;IACH,CAAC;CAAA;AA1ED,4BA0EC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { DeclarativeRestApiSettings, IDataObject, IExecutePaginationFunctions, INodeExecutionData } from 'n8n-workflow';
|
|
2
|
+
/**
|
|
3
|
+
* Trata 429 dentro de um node declarativo (`routing`, sem `execute()`), sem
|
|
4
|
+
* reescrever as 31 operações.
|
|
5
|
+
*
|
|
6
|
+
* ONDE ISTO PODE VIVER: o formato declarativo só dá UM ponto de extensão com
|
|
7
|
+
* acesso à requisição HTTP inteira (método, URL, corpo, headers) ANTES dela
|
|
8
|
+
* sair: o hook de paginação
|
|
9
|
+
* (`INodeTypeDescription.requestOperations.pagination`, quando é uma
|
|
10
|
+
* função). Ele roda mesmo sem paginação de verdade acontecer; só precisa que
|
|
11
|
+
* `routing.send.paginate` esteja ligado em algum campo visível na chamada.
|
|
12
|
+
* Ligamos isso UMA vez no campo `resource` (o único sempre presente, em
|
|
13
|
+
* toda operação), então nenhuma das 31 operações muda.
|
|
14
|
+
*
|
|
15
|
+
* Os outros pontos do routing NÃO servem pra isto:
|
|
16
|
+
* - `postReceive` (função ou declarativo) só roda em cima de uma resposta
|
|
17
|
+
* já processada e não recebe de volta a requisição que a gerou, só a
|
|
18
|
+
* resposta. Não dá pra reemitir a chamada a partir dele.
|
|
19
|
+
* - Sem `ignoreHttpStatusErrors`, um 429 já sai como `NodeApiError` antes de
|
|
20
|
+
* qualquer hook rodar, e nessa conversão os headers da resposta (onde mora
|
|
21
|
+
* o `Retry-After`) não sobrevivem no objeto de erro.
|
|
22
|
+
*
|
|
23
|
+
* Por isso a chamada HTTP em si é feita AQUI, com
|
|
24
|
+
* `helpers.httpRequestWithAuthentication` (o mesmo helper que o RoutingNode
|
|
25
|
+
* usa por baixo) e `ignoreHttpStatusErrors: true`, pra poder ler o
|
|
26
|
+
* `Retry-After` num 429 sem que ele vire exceção primeiro. A consequência é
|
|
27
|
+
* que este arquivo também reimplementa, à mão, os dois pedaços que o n8n
|
|
28
|
+
* faria sozinho num node declarativo comum:
|
|
29
|
+
*
|
|
30
|
+
* 1. O pós-processamento declarativo (`postReceive`) — hoje só o tipo
|
|
31
|
+
* `rootProperty`, usado por Contact/Conversation: Get Many e
|
|
32
|
+
* Conversation: Get Messages pra desembrulhar `{data:[...], nextCursor}`.
|
|
33
|
+
* 2. O `NodeApiError` pros status que não são 429, pra manter a mesma
|
|
34
|
+
* mensagem de erro que as operações já davam antes desta mudança.
|
|
35
|
+
*
|
|
36
|
+
* Se uma operação nova um dia precisar de um tipo de `postReceive` diferente
|
|
37
|
+
* de `rootProperty` (`filter`, `limit`, `set`, `sort`, `setKeyValue`,
|
|
38
|
+
* `binaryData` ou uma função customizada), `aplicarPostReceive` abaixo
|
|
39
|
+
* lança um erro claro em vez de ignorar silenciosamente: é o sinal de que
|
|
40
|
+
* este arquivo precisa ganhar suporte a esse tipo.
|
|
41
|
+
*/
|
|
42
|
+
/** Teto de tentativas pro 429: 1 chamada original + até 3 reenvios. Não fica preso pra sempre. */
|
|
43
|
+
export declare const RATE_LIMIT_MAX_ATTEMPTS = 4;
|
|
44
|
+
/** Lê o `Retry-After` (sempre em segundos inteiros, ver `rate-limit.service.ts`) em ms, com teto e fallback. */
|
|
45
|
+
export declare function parseRetryAfterMs(headers: IDataObject): number;
|
|
46
|
+
/**
|
|
47
|
+
* Hook de paginação usado como ponto de extensão único (ver comentário do
|
|
48
|
+
* arquivo). Ligado via `requestOperations.pagination` na descrição do node
|
|
49
|
+
* e ativado em toda chamada porque o campo `resource` (sempre presente)
|
|
50
|
+
* liga `routing.send.paginate`.
|
|
51
|
+
*/
|
|
52
|
+
export declare function zarkChatRateLimitedRequest(this: IExecutePaginationFunctions, requestOptions: DeclarativeRestApiSettings.ResultOptions): Promise<INodeExecutionData[]>;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RATE_LIMIT_MAX_ATTEMPTS = void 0;
|
|
4
|
+
exports.parseRetryAfterMs = parseRetryAfterMs;
|
|
5
|
+
exports.zarkChatRateLimitedRequest = zarkChatRateLimitedRequest;
|
|
6
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
7
|
+
/**
|
|
8
|
+
* Trata 429 dentro de um node declarativo (`routing`, sem `execute()`), sem
|
|
9
|
+
* reescrever as 31 operações.
|
|
10
|
+
*
|
|
11
|
+
* ONDE ISTO PODE VIVER: o formato declarativo só dá UM ponto de extensão com
|
|
12
|
+
* acesso à requisição HTTP inteira (método, URL, corpo, headers) ANTES dela
|
|
13
|
+
* sair: o hook de paginação
|
|
14
|
+
* (`INodeTypeDescription.requestOperations.pagination`, quando é uma
|
|
15
|
+
* função). Ele roda mesmo sem paginação de verdade acontecer; só precisa que
|
|
16
|
+
* `routing.send.paginate` esteja ligado em algum campo visível na chamada.
|
|
17
|
+
* Ligamos isso UMA vez no campo `resource` (o único sempre presente, em
|
|
18
|
+
* toda operação), então nenhuma das 31 operações muda.
|
|
19
|
+
*
|
|
20
|
+
* Os outros pontos do routing NÃO servem pra isto:
|
|
21
|
+
* - `postReceive` (função ou declarativo) só roda em cima de uma resposta
|
|
22
|
+
* já processada e não recebe de volta a requisição que a gerou, só a
|
|
23
|
+
* resposta. Não dá pra reemitir a chamada a partir dele.
|
|
24
|
+
* - Sem `ignoreHttpStatusErrors`, um 429 já sai como `NodeApiError` antes de
|
|
25
|
+
* qualquer hook rodar, e nessa conversão os headers da resposta (onde mora
|
|
26
|
+
* o `Retry-After`) não sobrevivem no objeto de erro.
|
|
27
|
+
*
|
|
28
|
+
* Por isso a chamada HTTP em si é feita AQUI, com
|
|
29
|
+
* `helpers.httpRequestWithAuthentication` (o mesmo helper que o RoutingNode
|
|
30
|
+
* usa por baixo) e `ignoreHttpStatusErrors: true`, pra poder ler o
|
|
31
|
+
* `Retry-After` num 429 sem que ele vire exceção primeiro. A consequência é
|
|
32
|
+
* que este arquivo também reimplementa, à mão, os dois pedaços que o n8n
|
|
33
|
+
* faria sozinho num node declarativo comum:
|
|
34
|
+
*
|
|
35
|
+
* 1. O pós-processamento declarativo (`postReceive`) — hoje só o tipo
|
|
36
|
+
* `rootProperty`, usado por Contact/Conversation: Get Many e
|
|
37
|
+
* Conversation: Get Messages pra desembrulhar `{data:[...], nextCursor}`.
|
|
38
|
+
* 2. O `NodeApiError` pros status que não são 429, pra manter a mesma
|
|
39
|
+
* mensagem de erro que as operações já davam antes desta mudança.
|
|
40
|
+
*
|
|
41
|
+
* Se uma operação nova um dia precisar de um tipo de `postReceive` diferente
|
|
42
|
+
* de `rootProperty` (`filter`, `limit`, `set`, `sort`, `setKeyValue`,
|
|
43
|
+
* `binaryData` ou uma função customizada), `aplicarPostReceive` abaixo
|
|
44
|
+
* lança um erro claro em vez de ignorar silenciosamente: é o sinal de que
|
|
45
|
+
* este arquivo precisa ganhar suporte a esse tipo.
|
|
46
|
+
*/
|
|
47
|
+
/** Teto de tentativas pro 429: 1 chamada original + até 3 reenvios. Não fica preso pra sempre. */
|
|
48
|
+
exports.RATE_LIMIT_MAX_ATTEMPTS = 4;
|
|
49
|
+
/** Nome da credencial usada por todas as 31 operações (ver ZarkChatApi.credentials.ts). */
|
|
50
|
+
const CREDENTIAL_TYPE = 'zarkChatApi';
|
|
51
|
+
/** Espera default quando o Retry-After vem ausente ou ilegível (defensivo; a API sempre manda). */
|
|
52
|
+
const DEFAULT_RETRY_AFTER_MS = 2000;
|
|
53
|
+
/** Teto de espera por tentativa, pra um Retry-After absurdo não travar o workflow indefinidamente. */
|
|
54
|
+
const MAX_RETRY_AFTER_MS = 120000;
|
|
55
|
+
/** Lê o `Retry-After` (sempre em segundos inteiros, ver `rate-limit.service.ts`) em ms, com teto e fallback. */
|
|
56
|
+
function parseRetryAfterMs(headers) {
|
|
57
|
+
var _a;
|
|
58
|
+
const bruto = (_a = headers['retry-after']) !== null && _a !== void 0 ? _a : headers['Retry-After'];
|
|
59
|
+
const valor = Array.isArray(bruto) ? bruto[0] : bruto;
|
|
60
|
+
const segundos = Number(valor);
|
|
61
|
+
if (!Number.isFinite(segundos) || segundos <= 0)
|
|
62
|
+
return DEFAULT_RETRY_AFTER_MS;
|
|
63
|
+
return Math.min(segundos * 1000, MAX_RETRY_AFTER_MS);
|
|
64
|
+
}
|
|
65
|
+
/** Acessa `a.b.c` num objeto qualquer, sem lodash (não é dependência deste pacote). */
|
|
66
|
+
function getByPath(valor, caminho) {
|
|
67
|
+
return caminho.split('.').reduce((atual, chave) => {
|
|
68
|
+
if (atual && typeof atual === 'object' && chave in atual) {
|
|
69
|
+
return atual[chave];
|
|
70
|
+
}
|
|
71
|
+
return undefined;
|
|
72
|
+
}, valor);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Reimplementação mínima do pós-processamento declarativo do RoutingNode.
|
|
76
|
+
* Cobre só o que as 31 operações realmente usam hoje (ver o comentário do
|
|
77
|
+
* arquivo): passagem direta do corpo e `rootProperty`.
|
|
78
|
+
*/
|
|
79
|
+
async function aplicarPostReceive(ctx, grupos, response) {
|
|
80
|
+
var _a;
|
|
81
|
+
let itens = Array.isArray(response.body)
|
|
82
|
+
? response.body.map((json) => ({ json }))
|
|
83
|
+
: [{ json: ((_a = response.body) !== null && _a !== void 0 ? _a : {}) }];
|
|
84
|
+
for (const grupo of grupos) {
|
|
85
|
+
for (const acao of grupo.actions) {
|
|
86
|
+
if (typeof acao === 'function') {
|
|
87
|
+
itens = await acao.call(ctx, itens, response);
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (acao.type === 'rootProperty') {
|
|
91
|
+
itens = itens.flatMap((item) => {
|
|
92
|
+
let conteudo = getByPath(item.json, acao.properties.property);
|
|
93
|
+
if (!Array.isArray(conteudo))
|
|
94
|
+
conteudo = [conteudo];
|
|
95
|
+
return conteudo.map((json) => ({ json }));
|
|
96
|
+
});
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
throw new n8n_workflow_1.NodeOperationError(ctx.getNode(), `Tratamento de limite de taxa do ZarkChat não sabe reproduzir a ação postReceive "${acao.type}". Estenda nodes/ZarkChat/shared/rateLimit.ts antes de usar este tipo numa operação.`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return itens;
|
|
103
|
+
}
|
|
104
|
+
/** Monta o objeto que o NodeApiError espera pra extrair status e mensagem do corpo de erro da API. */
|
|
105
|
+
function respostaComoErro(response) {
|
|
106
|
+
return {
|
|
107
|
+
response: { status: response.statusCode, data: response.body },
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Hook de paginação usado como ponto de extensão único (ver comentário do
|
|
112
|
+
* arquivo). Ligado via `requestOperations.pagination` na descrição do node
|
|
113
|
+
* e ativado em toda chamada porque o campo `resource` (sempre presente)
|
|
114
|
+
* liga `routing.send.paginate`.
|
|
115
|
+
*/
|
|
116
|
+
async function zarkChatRateLimitedRequest(requestOptions) {
|
|
117
|
+
let tentativa = 1;
|
|
118
|
+
while (true) {
|
|
119
|
+
const response = (await this.helpers.httpRequestWithAuthentication.call(this, CREDENTIAL_TYPE, {
|
|
120
|
+
...requestOptions.options,
|
|
121
|
+
returnFullResponse: true,
|
|
122
|
+
ignoreHttpStatusErrors: true,
|
|
123
|
+
}));
|
|
124
|
+
if (response.statusCode === 429 && tentativa < exports.RATE_LIMIT_MAX_ATTEMPTS) {
|
|
125
|
+
tentativa += 1;
|
|
126
|
+
await (0, n8n_workflow_1.sleep)(parseRetryAfterMs(response.headers));
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
if (response.statusCode === 429) {
|
|
130
|
+
throw new n8n_workflow_1.NodeApiError(this.getNode(), respostaComoErro(response), {
|
|
131
|
+
httpCode: '429',
|
|
132
|
+
message: `Limite de taxa da API ZarkChat (429): ${exports.RATE_LIMIT_MAX_ATTEMPTS} tentativas esgotadas respeitando o Retry-After. Isto é ritmo, não defeito: espere e tente de novo, ou reduza a frequência de chamadas deste workflow.`,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
if (response.statusCode >= 400) {
|
|
136
|
+
throw new n8n_workflow_1.NodeApiError(this.getNode(), respostaComoErro(response), {
|
|
137
|
+
httpCode: String(response.statusCode),
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
return aplicarPostReceive(this, requestOptions.postReceive, response);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=rateLimit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rateLimit.js","sourceRoot":"","sources":["../../../../nodes/ZarkChat/shared/rateLimit.ts"],"names":[],"mappings":"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"}
|
|
@@ -59,7 +59,7 @@ class ZarkChatTrigger {
|
|
|
59
59
|
{
|
|
60
60
|
name: 'default',
|
|
61
61
|
httpMethod: 'POST',
|
|
62
|
-
responseMode: '
|
|
62
|
+
responseMode: '={{$parameter["responseMode"]}}',
|
|
63
63
|
path: 'webhook',
|
|
64
64
|
rawBody: true,
|
|
65
65
|
},
|
|
@@ -71,6 +71,37 @@ class ZarkChatTrigger {
|
|
|
71
71
|
type: 'notice',
|
|
72
72
|
default: '',
|
|
73
73
|
},
|
|
74
|
+
{
|
|
75
|
+
displayName: 'Respond',
|
|
76
|
+
name: 'responseMode',
|
|
77
|
+
type: 'options',
|
|
78
|
+
options: [
|
|
79
|
+
{
|
|
80
|
+
name: 'Immediately',
|
|
81
|
+
value: 'onReceived',
|
|
82
|
+
description: 'Assim que o evento chega, antes do workflow terminar de rodar',
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
name: 'When Last Node Finishes',
|
|
86
|
+
value: 'lastNode',
|
|
87
|
+
description: 'Devolve o JSON do último node no corpo da resposta, depois que o workflow terminar (ex: {"reply": "..."} para o Chat de Teste do painel)',
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
name: "Using 'Respond to Webhook' Node",
|
|
91
|
+
value: 'responseNode',
|
|
92
|
+
description: 'A resposta é definida por um node Respond to Webhook no fluxo',
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
default: 'onReceived',
|
|
96
|
+
description: 'Quando e como responder ao webhook. O padrão é Immediately e não muda: quem já tem workflow publicado continua recebendo a resposta antes do workflow rodar, sem precisar reconfigurar nada.',
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
displayName: 'Insira um node "Respond to Webhook" no fluxo para montar a resposta (status, corpo, headers).',
|
|
100
|
+
name: 'avisoRespondToWebhook',
|
|
101
|
+
type: 'notice',
|
|
102
|
+
displayOptions: { show: { responseMode: ['responseNode'] } },
|
|
103
|
+
default: '',
|
|
104
|
+
},
|
|
74
105
|
{
|
|
75
106
|
displayName: 'Events',
|
|
76
107
|
name: 'events',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ZarkChatTrigger.node.js","sourceRoot":"","sources":["../../../nodes/ZarkChatTrigger/ZarkChatTrigger.node.ts"],"names":[],"mappings":";;;AAAA,mCAAqD;AACrD,+CAOsB;AAEtB,iEAAiE;AACjE,MAAM,OAAO,GAAG;IACf,EAAE,IAAI,EAAE,oBAAoB,EAAE,KAAK,EAAE,oBAAoB,EAAE;IAC3D,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,iBAAiB,EAAE;IACrD,EAAE,IAAI,EAAE,sBAAsB,EAAE,KAAK,EAAE,sBAAsB,EAAE;IAC/D,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,iBAAiB,EAAE;IACrD,EAAE,IAAI,EAAE,uBAAuB,EAAE,KAAK,EAAE,uBAAuB,EAAE;IACjE,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,gBAAgB,EAAE;IACnD,EAAE,IAAI,EAAE,oBAAoB,EAAE,KAAK,EAAE,oBAAoB,EAAE;IAC3D,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,kBAAkB,EAAE;IACvD,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,gBAAgB,EAAE;CACnD,CAAC;AAEF,uFAAuF;AACvF,SAAS,iBAAiB,CAAC,QAAgB,EAAE,QAAgB;IAC5D,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAChC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAChC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACxC,OAAO,IAAA,wBAAe,EAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC9B,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAa,eAAe;IAA5B;QACC,gBAAW,GAAyB;YACnC,WAAW,EAAE,kBAAkB;YAC/B,IAAI,EAAE,iBAAiB;YACvB,IAAI,EAAE,+BAA+B;YACrC,KAAK,EAAE,CAAC,SAAS,CAAC;YAClB,OAAO,EAAE,CAAC;YACV,QAAQ,EAAE,sCAAsC;YAChD,WAAW,EAAE,iDAAiD;YAC9D,QAAQ,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE;YACtC,MAAM,EAAE,EAAE;YACV,OAAO,EAAE,CAAC,MAAM,CAAC;YACjB,WAAW,EAAE;gBACZ;oBACC,IAAI,EAAE,oBAAoB;oBAC1B,QAAQ,EAAE,KAAK;oBACf,cAAc,EAAE,EAAE,IAAI,EAAE,EAAE,iBAAiB,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE;iBACvD;aACD;YACD,QAAQ,EAAE;gBACT;oBACC,IAAI,EAAE,SAAS;oBACf,UAAU,EAAE,MAAM;oBAClB,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"ZarkChatTrigger.node.js","sourceRoot":"","sources":["../../../nodes/ZarkChatTrigger/ZarkChatTrigger.node.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "n8n-nodes-zarkchat",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Nodes do ZarkChat para o n8n: CRM, contatos, conversas, envio de mensagem no WhatsApp, base de conhecimento e gatilho por webhook assinado.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/mayconjordanr/zark-chat/tree/main/packages/n8n-nodes-zarkchat#readme",
|