n8n-nodes-evolution-message-search 1.0.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 ADDED
@@ -0,0 +1,108 @@
1
+ # n8n-nodes-evolution-message-search
2
+
3
+ Evolution API - Search Messages node for n8n. Search WhatsApp message history by keywords, dates, and conversation.
4
+
5
+ ## Features
6
+
7
+ - Search WhatsApp message history via Evolution API
8
+ - Filter by keywords in message content
9
+ - Filter by date range (from/to)
10
+ - Filter by conversation ID (WhatsApp JID)
11
+ - Paginated results with configurable page size
12
+ - AI agent tool support (usable as tool in AI workflows)
13
+
14
+ ## Requirements
15
+
16
+ - n8n instance (v1.0+)
17
+ - Evolution API instance with API access
18
+ - Existing `evolutionApi` credentials configured in n8n
19
+
20
+ ## Installation
21
+
22
+ ### Option 1: Install from npm (coming soon)
23
+
24
+ ```bash
25
+ npm install n8n-nodes-evolution-message-search
26
+ ```
27
+
28
+ ### Option 2: Install as community node
29
+
30
+ 1. In n8n, go to **Settings > Community Nodes**
31
+ 2. Click **Install**
32
+ 3. Enter: `n8n-nodes-evolution-message-search`
33
+ 4. Accept terms and install
34
+
35
+ ### Option 3: Install from source
36
+
37
+ ```bash
38
+ cd n8n-nodes-evolution-message-search
39
+ npm install
40
+ npm run build
41
+ npm link
42
+ ```
43
+
44
+ Then in your n8n installation directory:
45
+ ```bash
46
+ cd ~/.n8n/custom
47
+ npm link n8n-nodes-evolution-message-search
48
+ ```
49
+
50
+ ## Configuration
51
+
52
+ ### Credentials
53
+
54
+ This node uses the existing `evolutionApi` credential type. Before using the node:
55
+
56
+ 1. Go to **Credentials** in n8n
57
+ 2. Create a new `Evolution API` credential
58
+ 3. Enter your Evolution API URL and API key
59
+
60
+ ### Node Parameters
61
+
62
+ | Parameter | Who Sets | Model Can Change | Description |
63
+ |-----------|----------|------------------|-------------|
64
+ | Instance Name | User | No | Evolution API instance name |
65
+ | Conversation ID | User | Only if allowed | WhatsApp conversation JID |
66
+ | Allow Model to Set Conversation | User | No | Permission for AI model to set conversation |
67
+ | Keywords | Model | Yes | Search text in messages |
68
+ | Date From | Model | Yes | Start date for search |
69
+ | Date To | Model | Yes | End date for search |
70
+ | Items per Page | User | No | Results per page (1-100) |
71
+ | Page Number | Model | Yes | Page to retrieve |
72
+
73
+ ## Output Format
74
+
75
+ ```json
76
+ {
77
+ "total": 100,
78
+ "pages": 10,
79
+ "currentPage": 1,
80
+ "pageSize": 10,
81
+ "records": [
82
+ {
83
+ "id": "msg_abc123",
84
+ "key": {
85
+ "remote": "5511999999999@s.whatsapp.net",
86
+ "id": "some_id"
87
+ },
88
+ "message": {
89
+ "conversationMessage": {
90
+ "text": "Hello world"
91
+ }
92
+ },
93
+ "messageType": "conversation",
94
+ "fromMe": true,
95
+ "timestamp": 1703001234
96
+ }
97
+ ]
98
+ }
99
+ ```
100
+
101
+ ## Evolution API Reference
102
+
103
+ - [Evolution API Documentation](https://docs.evolutionfoundation.com.br/evolution-api)
104
+ - [Find Messages Endpoint](https://docs.evolutionfoundation.com.br/evolution-api/find-messages.md)
105
+
106
+ ## License
107
+
108
+ MIT
@@ -0,0 +1,33 @@
1
+ 'use strict';
2
+ Object.defineProperty(exports, '__esModule', { value: true });
3
+ const n8n_workflow_1 = require('n8n-workflow');
4
+ class EvolutionApi {
5
+ constructor() {
6
+ this.name = 'evolutionApi';
7
+ this.displayName = 'Evolution API';
8
+ this.documentationUrl = 'https://docs.evolutionfoundation.com.br/evolution-api';
9
+ this.properties = [
10
+ {
11
+ displayName: 'API Key',
12
+ name: 'apiKey',
13
+ type: 'string',
14
+ default: '',
15
+ },
16
+ ];
17
+ this.authenticate = {
18
+ type: 'generic',
19
+ properties: {
20
+ headers: {
21
+ apikey: '={{$credentials.apiKey}}',
22
+ },
23
+ },
24
+ };
25
+ this.test = {
26
+ request: {
27
+ url: '/instance/connectionStatus',
28
+ method: 'GET',
29
+ },
30
+ };
31
+ }
32
+ }
33
+ exports.EvolutionApi = EvolutionApi;
@@ -0,0 +1,234 @@
1
+ 'use strict';
2
+ Object.defineProperty(exports, '__esModule', { value: true });
3
+ exports.SearchMessages = void 0;
4
+ const n8n_workflow_1 = require('n8n-workflow');
5
+ class SearchMessages {
6
+ constructor() {
7
+ this.description = {
8
+ displayName: 'Evolution API - Search Messages',
9
+ name: 'searchMessages',
10
+ icon: 'file:icon.svg',
11
+ group: ['transform'],
12
+ version: 1,
13
+ subtitle: 'Search WhatsApp message history',
14
+ description: 'Search WhatsApp message history by keywords, dates, and conversation',
15
+ defaults: {
16
+ name: 'Evolution API - Search Messages',
17
+ },
18
+ usableAsTool: true,
19
+ inputs: [n8n_workflow_1.NodeConnectionTypes.Main],
20
+ outputs: [n8n_workflow_1.NodeConnectionTypes.Main],
21
+ credentials: [
22
+ {
23
+ name: 'evolutionApi',
24
+ required: true,
25
+ },
26
+ ],
27
+ requestDefaults: {
28
+ baseURL: '={{$credentials.baseUrl || "http://localhost:8080"}}',
29
+ headers: {
30
+ 'Accept': 'application/json',
31
+ 'Content-Type': 'application/json',
32
+ },
33
+ },
34
+ properties: [
35
+ {
36
+ displayName: 'Resource',
37
+ name: 'resource',
38
+ type: 'hidden',
39
+ default: 'messages',
40
+ },
41
+ {
42
+ displayName: 'Instance Name',
43
+ name: 'instanceName',
44
+ type: 'string',
45
+ required: true,
46
+ displayOptions: {
47
+ show: {
48
+ resource: ['messages'],
49
+ },
50
+ },
51
+ description: 'Name of the Evolution API instance (set by user, model cannot change)',
52
+ hint: 'The instance name is defined by the user and cannot be modified by the AI model',
53
+ },
54
+ {
55
+ displayName: 'Conversation ID',
56
+ name: 'conversationId',
57
+ type: 'string',
58
+ required: false,
59
+ displayOptions: {
60
+ show: {
61
+ resource: ['messages'],
62
+ },
63
+ },
64
+ description: 'WhatsApp conversation ID (JID). If empty, searches all conversations. Model can use if provided by user.',
65
+ placeholder: '5511999999999@s.whatsapp.net',
66
+ },
67
+ {
68
+ displayName: 'Allow Model to Set Conversation',
69
+ name: 'allowModelSetConversation',
70
+ type: 'boolean',
71
+ default: false,
72
+ displayOptions: {
73
+ show: {
74
+ resource: ['messages'],
75
+ },
76
+ },
77
+ description: 'If enabled, the AI model can set the conversation ID. If disabled, model must use the value provided above.',
78
+ },
79
+ {
80
+ displayName: 'Search Parameters',
81
+ name: 'searchParams',
82
+ type: 'fixedCollection',
83
+ displayOptions: {
84
+ show: {
85
+ resource: ['messages'],
86
+ },
87
+ },
88
+ default: {},
89
+ options: [
90
+ {
91
+ displayName: 'Search Fields',
92
+ name: 'fields',
93
+ values: [
94
+ {
95
+ displayName: 'Keywords',
96
+ name: 'keywords',
97
+ type: 'string',
98
+ default: '',
99
+ description: 'Search text in message content (model can set)',
100
+ },
101
+ {
102
+ displayName: 'Date From',
103
+ name: 'dateFrom',
104
+ type: 'dateTime',
105
+ default: '',
106
+ description: 'Start date for message search (model can set)',
107
+ },
108
+ {
109
+ displayName: 'Date To',
110
+ name: 'dateTo',
111
+ type: 'dateTime',
112
+ default: '',
113
+ description: 'End date for message search (model can set)',
114
+ },
115
+ ],
116
+ },
117
+ ],
118
+ },
119
+ {
120
+ displayName: 'Pagination',
121
+ name: 'pagination',
122
+ type: 'fixedCollection',
123
+ displayOptions: {
124
+ show: {
125
+ resource: ['messages'],
126
+ },
127
+ },
128
+ default: {
129
+ fields: {
130
+ pageSize: 10,
131
+ page: 1,
132
+ },
133
+ },
134
+ options: [
135
+ {
136
+ displayName: 'Pagination Fields',
137
+ name: 'fields',
138
+ values: [
139
+ {
140
+ displayName: 'Items per Page',
141
+ name: 'pageSize',
142
+ type: 'number',
143
+ default: 10,
144
+ typeOptions: {
145
+ minValue: 1,
146
+ maxValue: 100,
147
+ },
148
+ description: 'Number of results per page (set by user, model cannot change)',
149
+ },
150
+ {
151
+ displayName: 'Page Number',
152
+ name: 'page',
153
+ type: 'number',
154
+ default: 1,
155
+ typeOptions: {
156
+ minValue: 1,
157
+ },
158
+ description: 'Page number to retrieve (model can navigate)',
159
+ },
160
+ ],
161
+ },
162
+ ],
163
+ },
164
+ ],
165
+ };
166
+ }
167
+ async execute(executeFunctions) {
168
+ const items = executeFunctions.getInputData();
169
+ const returnData = [];
170
+ for (let i = 0; i < items.length; i++) {
171
+ const instanceName = executeFunctions.getNodeParameter('instanceName', i);
172
+ const userConversationId = executeFunctions.getNodeParameter('conversationId', i);
173
+ const allowModelSetConversation = executeFunctions.getNodeParameter('allowModelSetConversation', i);
174
+ const searchParams = executeFunctions.getNodeParameter('searchParams.fields', i);
175
+ const pagination = executeFunctions.getNodeParameter('pagination.fields', i);
176
+ let conversationId = userConversationId;
177
+ if (!conversationId && allowModelSetConversation) {
178
+ conversationId = executeFunctions.getNodeParameter('modelConversationId', i, '');
179
+ }
180
+ const pageSize = pagination.pageSize;
181
+ const page = pagination.page;
182
+ const skip = (page - 1) * pageSize;
183
+ const whereClause = {};
184
+ if (conversationId) {
185
+ whereClause['key.remote'] = conversationId;
186
+ }
187
+ if (searchParams.keywords) {
188
+ whereClause['message.conversationMessage.text'] = {
189
+ contains: searchParams.keywords,
190
+ };
191
+ }
192
+ if (searchParams.dateFrom || searchParams.dateTo) {
193
+ whereClause['timestamp'] = {};
194
+ if (searchParams.dateFrom) {
195
+ const fromTimestamp = new Date(searchParams.dateFrom).getTime() / 1000;
196
+ whereClause['timestamp']['gte'] = fromTimestamp;
197
+ }
198
+ if (searchParams.dateTo) {
199
+ const toTimestamp = new Date(searchParams.dateTo).getTime() / 1000;
200
+ whereClause['timestamp']['lte'] = toTimestamp;
201
+ }
202
+ }
203
+ const body = {
204
+ where: whereClause,
205
+ take: pageSize,
206
+ skip: skip,
207
+ orderBy: {
208
+ timestamp: 'desc',
209
+ },
210
+ };
211
+ const responseData = await executeFunctions.helpers.httpRequest({
212
+ method: 'POST',
213
+ url: `/chat/findMessages/${instanceName}`,
214
+ body,
215
+ });
216
+ const messages = responseData.messages || responseData;
217
+ const total = messages.total || messages.length || 0;
218
+ const totalPages = Math.ceil(total / pageSize);
219
+ const result = {
220
+ total,
221
+ pages: totalPages,
222
+ currentPage: page,
223
+ pageSize,
224
+ records: Array.isArray(messages.records) ? messages.records : messages,
225
+ };
226
+ returnData.push({
227
+ json: result,
228
+ pairedItem: { item: i },
229
+ });
230
+ }
231
+ return [returnData];
232
+ }
233
+ }
234
+ exports.SearchMessages = SearchMessages;
@@ -0,0 +1,20 @@
1
+ {
2
+ "node": "n8n-nodes-evolution-message-search",
3
+ "nodeVersion": "1.0",
4
+ "codexVersion": "1.0",
5
+ "categories": [
6
+ "Communication"
7
+ ],
8
+ "resources": {
9
+ "credentialDocumentation": [
10
+ {
11
+ "url": "https://docs.evolutionfoundation.com.br/evolution-api"
12
+ }
13
+ ],
14
+ "primaryDocumentation": [
15
+ {
16
+ "url": "https://docs.evolutionfoundation.com.br/evolution-api"
17
+ }
18
+ ]
19
+ }
20
+ }
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" fill="none">
2
+ <rect width="64" height="64" rx="8" fill="#25D366"/>
3
+ <path d="M32 16c-8.837 0-16 7.163-16 16 0 6.626 4.134 12.318 10 14.706V44l6.19-3.416c2.206.611 4.54.92 6.81.92 8.837 0 16-7.163 16-16S40.837 16 32 16zm0 30c-2.21 0-4.383-.44-6.4-1.23l-.46-.17-4.89 2.7 2.75-4.77-.27-.46C20.52 40.36 18 36.29 18 32c0-7.732 6.268-14 14-14s14 6.268 14 14-6.268 14-14 14z" fill="white"/>
4
+ <path d="M26 28h4v4h-4v-4zm6 0h4v4h-4v-4zm6 0h4v4h-4v-4z" fill="white"/>
5
+ </svg>
package/index.js ADDED
@@ -0,0 +1,8 @@
1
+ module.exports = {
2
+ nodes: [
3
+ require('./dist/nodes/SearchMessages/SearchMessages.node.js'),
4
+ ],
5
+ credentials: [
6
+ require('./dist/credentials/EvolutionApi.credentials.js'),
7
+ ],
8
+ };
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "n8n-nodes-evolution-message-search",
3
+ "version": "1.0.0",
4
+ "description": "Evolution API - Search Messages node for n8n. Search WhatsApp message history by keywords, dates, and conversation.",
5
+ "keywords": [
6
+ "n8n-community-node-package",
7
+ "evolution-api",
8
+ "whatsapp",
9
+ "message-search"
10
+ ],
11
+ "license": "MIT",
12
+ "homepage": "https://github.com/joaoramos/n8n-nodes-evolution-message-search",
13
+ "author": {
14
+ "name": "Joao Ramos"
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/joaoramos/n8n-nodes-evolution-message-search.git"
19
+ },
20
+ "main": "index.js",
21
+ "scripts": {
22
+ "build": "tsc",
23
+ "lint": "tsc --noEmit"
24
+ },
25
+ "files": [
26
+ "dist"
27
+ ],
28
+ "n8n": {
29
+ "n8nNodesApiVersion": 1,
30
+ "credentials": [
31
+ "dist/credentials/EvolutionApi.credentials.js"
32
+ ],
33
+ "nodes": [
34
+ "dist/nodes/SearchMessages/SearchMessages.node.js"
35
+ ]
36
+ },
37
+ "devDependencies": {
38
+ "@types/node": "^18.17.0",
39
+ "typescript": "^5.3.0"
40
+ },
41
+ "peerDependencies": {
42
+ "n8n": ">=1.0.0"
43
+ }
44
+ }