n8n-nodes-msteams-botframework 1.2.12 → 1.2.13
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.
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MsTeamsBotFrameworkTrigger = void 0;
|
|
4
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
+
const botbuilder_1 = require("botbuilder");
|
|
4
6
|
// Track processed activity IDs to prevent duplicates
|
|
5
7
|
const processedActivities = new Map();
|
|
6
8
|
// Clean up old entries every 5 minutes
|
|
@@ -37,7 +39,8 @@ class MsTeamsBotFrameworkTrigger {
|
|
|
37
39
|
{
|
|
38
40
|
name: 'default',
|
|
39
41
|
httpMethod: 'POST',
|
|
40
|
-
responseMode: '
|
|
42
|
+
responseMode: '={{$parameter["respondWhen"]}}',
|
|
43
|
+
responseData: '={{$parameter["responseData"]}}',
|
|
41
44
|
path: 'webhook',
|
|
42
45
|
},
|
|
43
46
|
],
|
|
@@ -77,6 +80,64 @@ class MsTeamsBotFrameworkTrigger {
|
|
|
77
80
|
required: true,
|
|
78
81
|
description: 'The events to listen to',
|
|
79
82
|
},
|
|
83
|
+
{
|
|
84
|
+
displayName: 'Respond',
|
|
85
|
+
name: 'respondWhen',
|
|
86
|
+
type: 'options',
|
|
87
|
+
options: [
|
|
88
|
+
{
|
|
89
|
+
name: 'Immediately',
|
|
90
|
+
value: 'immediately',
|
|
91
|
+
description: 'Respond immediately (useful for keeping connection alive)',
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
name: 'When Last Node Finishes',
|
|
95
|
+
value: 'lastNode',
|
|
96
|
+
description: 'Wait for workflow to complete before responding',
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
name: 'Using Respond to Webhook Node',
|
|
100
|
+
value: 'responseNode',
|
|
101
|
+
description: 'Use a Respond to Webhook node to control the response',
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
default: 'immediately',
|
|
105
|
+
description: 'When to respond to the webhook call',
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
displayName: 'Response Data',
|
|
109
|
+
name: 'responseData',
|
|
110
|
+
type: 'options',
|
|
111
|
+
displayOptions: {
|
|
112
|
+
show: {
|
|
113
|
+
respondWhen: ['lastNode'],
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
options: [
|
|
117
|
+
{
|
|
118
|
+
name: 'All Entries',
|
|
119
|
+
value: 'allEntries',
|
|
120
|
+
description: 'Return all entries from the workflow',
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
name: 'First Entry JSON',
|
|
124
|
+
value: 'firstEntryJson',
|
|
125
|
+
description: 'Return only the JSON of the first entry',
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
name: 'First Entry Binary',
|
|
129
|
+
value: 'firstEntryBinary',
|
|
130
|
+
description: 'Return only the binary data of the first entry',
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
name: 'No Response Body',
|
|
134
|
+
value: 'noData',
|
|
135
|
+
description: 'Return success status without response body',
|
|
136
|
+
},
|
|
137
|
+
],
|
|
138
|
+
default: 'allEntries',
|
|
139
|
+
description: 'What data should be returned',
|
|
140
|
+
},
|
|
80
141
|
{
|
|
81
142
|
displayName: 'Options',
|
|
82
143
|
name: 'options',
|
|
@@ -98,6 +159,13 @@ class MsTeamsBotFrameworkTrigger {
|
|
|
98
159
|
default: false,
|
|
99
160
|
description: 'Whether to include the raw Bot Framework activity in output',
|
|
100
161
|
},
|
|
162
|
+
{
|
|
163
|
+
displayName: 'Auto Reply',
|
|
164
|
+
name: 'autoReply',
|
|
165
|
+
type: 'boolean',
|
|
166
|
+
default: false,
|
|
167
|
+
description: 'Whether to automatically send a typing indicator',
|
|
168
|
+
},
|
|
101
169
|
],
|
|
102
170
|
},
|
|
103
171
|
],
|
|
@@ -117,114 +185,136 @@ class MsTeamsBotFrameworkTrigger {
|
|
|
117
185
|
};
|
|
118
186
|
}
|
|
119
187
|
async webhook() {
|
|
120
|
-
|
|
121
|
-
const
|
|
188
|
+
const credentials = await this.getCredentials('msTeamsBotFrameworkApi');
|
|
189
|
+
const req = this.getRequestObject();
|
|
122
190
|
const events = this.getNodeParameter('events', []);
|
|
123
191
|
const options = this.getNodeParameter('options', {});
|
|
124
|
-
|
|
125
|
-
const
|
|
126
|
-
//
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
};
|
|
188
|
-
break;
|
|
189
|
-
case 'conversationUpdate':
|
|
190
|
-
activityData.conversationUpdate = {
|
|
191
|
-
membersAdded: activity.membersAdded || [],
|
|
192
|
-
membersRemoved: activity.membersRemoved || [],
|
|
193
|
-
};
|
|
194
|
-
break;
|
|
195
|
-
case 'messageReaction':
|
|
196
|
-
activityData.messageReaction = {
|
|
197
|
-
reactionsAdded: activity.reactionsAdded || [],
|
|
198
|
-
reactionsRemoved: activity.reactionsRemoved || [],
|
|
199
|
-
replyToId: activity.replyToId,
|
|
200
|
-
};
|
|
201
|
-
break;
|
|
202
|
-
case 'messageUpdate':
|
|
203
|
-
activityData.messageUpdate = {
|
|
204
|
-
text: activity.text || '',
|
|
205
|
-
updatedText: activity.text || '',
|
|
192
|
+
const appId = credentials.appId;
|
|
193
|
+
const appPassword = credentials.appPassword;
|
|
194
|
+
// Create Bot Framework Adapter
|
|
195
|
+
const adapter = new botbuilder_1.BotFrameworkAdapter({
|
|
196
|
+
appId,
|
|
197
|
+
appPassword,
|
|
198
|
+
});
|
|
199
|
+
// Process the incoming activity
|
|
200
|
+
let activityData = null;
|
|
201
|
+
let shouldTrigger = false;
|
|
202
|
+
try {
|
|
203
|
+
await adapter.processActivity(req, req.res, async (context) => {
|
|
204
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
205
|
+
const activity = context.activity;
|
|
206
|
+
// Check for duplicate activity
|
|
207
|
+
const activityKey = `${activity.id}_${activity.timestamp}`;
|
|
208
|
+
if (processedActivities.has(activityKey)) {
|
|
209
|
+
// Already processed this activity, skip
|
|
210
|
+
shouldTrigger = false;
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
// Check if we should process this activity type
|
|
214
|
+
if (!events.includes(activity.type)) {
|
|
215
|
+
shouldTrigger = false;
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
// Ignore bot messages if configured
|
|
219
|
+
if (options.ignoreBotMessages && ((_a = activity.from) === null || _a === void 0 ? void 0 : _a.role) === 'bot') {
|
|
220
|
+
shouldTrigger = false;
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
// Mark this activity as processed
|
|
224
|
+
processedActivities.set(activityKey, Date.now());
|
|
225
|
+
shouldTrigger = true;
|
|
226
|
+
// Send typing indicator if auto reply is enabled
|
|
227
|
+
if (options.autoReply && activity.type === 'message') {
|
|
228
|
+
await context.sendActivity({ type: 'typing' });
|
|
229
|
+
}
|
|
230
|
+
// Extract useful data from activity
|
|
231
|
+
activityData = {
|
|
232
|
+
type: activity.type,
|
|
233
|
+
text: activity.text,
|
|
234
|
+
timestamp: activity.timestamp,
|
|
235
|
+
id: activity.id,
|
|
236
|
+
conversation: {
|
|
237
|
+
id: (_b = activity.conversation) === null || _b === void 0 ? void 0 : _b.id,
|
|
238
|
+
name: (_c = activity.conversation) === null || _c === void 0 ? void 0 : _c.name,
|
|
239
|
+
conversationType: (_d = activity.conversation) === null || _d === void 0 ? void 0 : _d.conversationType,
|
|
240
|
+
tenantId: (_e = activity.conversation) === null || _e === void 0 ? void 0 : _e.tenantId,
|
|
241
|
+
},
|
|
242
|
+
from: {
|
|
243
|
+
id: (_f = activity.from) === null || _f === void 0 ? void 0 : _f.id,
|
|
244
|
+
name: (_g = activity.from) === null || _g === void 0 ? void 0 : _g.name,
|
|
245
|
+
aadObjectId: (_h = activity.from) === null || _h === void 0 ? void 0 : _h.aadObjectId,
|
|
246
|
+
role: (_j = activity.from) === null || _j === void 0 ? void 0 : _j.role,
|
|
247
|
+
},
|
|
248
|
+
recipient: {
|
|
249
|
+
id: (_k = activity.recipient) === null || _k === void 0 ? void 0 : _k.id,
|
|
250
|
+
name: (_l = activity.recipient) === null || _l === void 0 ? void 0 : _l.name,
|
|
251
|
+
},
|
|
252
|
+
channelId: activity.channelId,
|
|
253
|
+
serviceUrl: activity.serviceUrl,
|
|
254
|
+
locale: activity.locale,
|
|
206
255
|
};
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
256
|
+
// Add type-specific data
|
|
257
|
+
switch (activity.type) {
|
|
258
|
+
case 'message':
|
|
259
|
+
activityData.message = {
|
|
260
|
+
text: activity.text,
|
|
261
|
+
textFormat: activity.textFormat,
|
|
262
|
+
attachments: activity.attachments,
|
|
263
|
+
mentions: (_m = activity.entities) === null || _m === void 0 ? void 0 : _m.filter((e) => e.type === 'mention'),
|
|
264
|
+
};
|
|
265
|
+
break;
|
|
266
|
+
case 'conversationUpdate':
|
|
267
|
+
activityData.conversationUpdate = {
|
|
268
|
+
membersAdded: activity.membersAdded,
|
|
269
|
+
membersRemoved: activity.membersRemoved,
|
|
270
|
+
};
|
|
271
|
+
break;
|
|
272
|
+
case 'messageReaction':
|
|
273
|
+
activityData.messageReaction = {
|
|
274
|
+
reactionsAdded: activity.reactionsAdded,
|
|
275
|
+
reactionsRemoved: activity.reactionsRemoved,
|
|
276
|
+
replyToId: activity.replyToId,
|
|
277
|
+
};
|
|
278
|
+
break;
|
|
279
|
+
case 'messageUpdate':
|
|
280
|
+
activityData.messageUpdate = {
|
|
281
|
+
text: activity.text,
|
|
282
|
+
updatedText: activity.text,
|
|
283
|
+
};
|
|
284
|
+
break;
|
|
285
|
+
case 'messageDelete':
|
|
286
|
+
activityData.messageDelete = {
|
|
287
|
+
deletedMessageId: activity.id,
|
|
288
|
+
};
|
|
289
|
+
break;
|
|
290
|
+
}
|
|
291
|
+
// Include raw activity if requested
|
|
292
|
+
if (options.includeRawActivity) {
|
|
293
|
+
activityData.rawActivity = activity;
|
|
294
|
+
}
|
|
295
|
+
});
|
|
296
|
+
if (!shouldTrigger || !activityData) {
|
|
297
|
+
// Don't trigger workflow - Bot Framework Adapter already sent 200 OK
|
|
298
|
+
return {
|
|
299
|
+
noWebhookResponse: true,
|
|
211
300
|
};
|
|
212
|
-
|
|
301
|
+
}
|
|
302
|
+
// Return the activity data to the workflow
|
|
303
|
+
return {
|
|
304
|
+
workflowData: [
|
|
305
|
+
[
|
|
306
|
+
{
|
|
307
|
+
json: activityData,
|
|
308
|
+
},
|
|
309
|
+
],
|
|
310
|
+
],
|
|
311
|
+
};
|
|
213
312
|
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
313
|
+
catch (error) {
|
|
314
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to process Teams webhook: ${error.message}`, {
|
|
315
|
+
description: error.message,
|
|
316
|
+
});
|
|
217
317
|
}
|
|
218
|
-
// Return the activity data to the workflow
|
|
219
|
-
return {
|
|
220
|
-
workflowData: [
|
|
221
|
-
[
|
|
222
|
-
{
|
|
223
|
-
json: activityData,
|
|
224
|
-
},
|
|
225
|
-
],
|
|
226
|
-
],
|
|
227
|
-
};
|
|
228
318
|
}
|
|
229
319
|
}
|
|
230
320
|
exports.MsTeamsBotFrameworkTrigger = MsTeamsBotFrameworkTrigger;
|
package/package.json
CHANGED
|
@@ -1,64 +1,64 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "n8n-nodes-msteams-botframework",
|
|
3
|
-
"version": "1.2.
|
|
4
|
-
"description": "n8n node for MS Teams Azure Bot Framework",
|
|
5
|
-
"keywords": [
|
|
6
|
-
"n8n-community-node-package",
|
|
7
|
-
"n8n",
|
|
8
|
-
"msteams",
|
|
9
|
-
"microsoft teams",
|
|
10
|
-
"bot framework",
|
|
11
|
-
"azure"
|
|
12
|
-
],
|
|
13
|
-
"license": "MIT",
|
|
14
|
-
"homepage": "https://weon.vn",
|
|
15
|
-
"author": {
|
|
16
|
-
"name": "Weon Software",
|
|
17
|
-
"email": "doannv@weon.vn"
|
|
18
|
-
},
|
|
19
|
-
"repository": {
|
|
20
|
-
"type": "git",
|
|
21
|
-
"url": "
|
|
22
|
-
},
|
|
23
|
-
"main": "index.js",
|
|
24
|
-
"scripts": {
|
|
25
|
-
"build": "tsc && gulp build:icons",
|
|
26
|
-
"dev": "tsc --watch",
|
|
27
|
-
"format": "prettier nodes credentials --write",
|
|
28
|
-
"lint": "eslint nodes credentials package.json",
|
|
29
|
-
"lintfix": "eslint nodes credentials package.json --fix",
|
|
30
|
-
"prepublishOnly": "npm run build"
|
|
31
|
-
},
|
|
32
|
-
"files": [
|
|
33
|
-
"dist"
|
|
34
|
-
],
|
|
35
|
-
"n8n": {
|
|
36
|
-
"n8nNodesApiVersion": 1,
|
|
37
|
-
"credentials": [
|
|
38
|
-
"dist/credentials/MsTeamsBotFrameworkApi.credentials.js"
|
|
39
|
-
],
|
|
40
|
-
"nodes": [
|
|
41
|
-
"dist/nodes/MsTeamsBotFramework/MsTeamsBotFramework.node.js",
|
|
42
|
-
"dist/nodes/MsTeamsBotFramework/MsTeamsBotFrameworkTrigger.node.js",
|
|
43
|
-
"dist/nodes/MsTeamsBotFramework/MsTeamsAIBot.node.js"
|
|
44
|
-
]
|
|
45
|
-
},
|
|
46
|
-
"devDependencies": {
|
|
47
|
-
"@types/express": "^4.17.6",
|
|
48
|
-
"@types/node": "^
|
|
49
|
-
"@typescript-eslint/parser": "^
|
|
50
|
-
"eslint": "^8.
|
|
51
|
-
"eslint-plugin-n8n-nodes-base": "^1.
|
|
52
|
-
"gulp": "^
|
|
53
|
-
"n8n-workflow": "
|
|
54
|
-
"prettier": "^
|
|
55
|
-
"typescript": "
|
|
56
|
-
},
|
|
57
|
-
"peerDependencies": {
|
|
58
|
-
"n8n-workflow": "
|
|
59
|
-
},
|
|
60
|
-
"dependencies": {
|
|
61
|
-
"botbuilder": "^4.20.0",
|
|
62
|
-
"axios": "^1.6.0"
|
|
63
|
-
}
|
|
64
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "n8n-nodes-msteams-botframework",
|
|
3
|
+
"version": "1.2.13",
|
|
4
|
+
"description": "n8n node for MS Teams Azure Bot Framework",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"n8n-community-node-package",
|
|
7
|
+
"n8n",
|
|
8
|
+
"msteams",
|
|
9
|
+
"microsoft teams",
|
|
10
|
+
"bot framework",
|
|
11
|
+
"azure"
|
|
12
|
+
],
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"homepage": "https://weon.vn",
|
|
15
|
+
"author": {
|
|
16
|
+
"name": "Weon Software",
|
|
17
|
+
"email": "doannv@weon.vn"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "https://github.com/weon-software/n8n-nodes-msteams-botframework.git"
|
|
22
|
+
},
|
|
23
|
+
"main": "index.js",
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "tsc && gulp build:icons",
|
|
26
|
+
"dev": "tsc --watch",
|
|
27
|
+
"format": "prettier nodes credentials --write",
|
|
28
|
+
"lint": "eslint nodes credentials package.json",
|
|
29
|
+
"lintfix": "eslint nodes credentials package.json --fix",
|
|
30
|
+
"prepublishOnly": "npm run build"
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"dist"
|
|
34
|
+
],
|
|
35
|
+
"n8n": {
|
|
36
|
+
"n8nNodesApiVersion": 1,
|
|
37
|
+
"credentials": [
|
|
38
|
+
"dist/credentials/MsTeamsBotFrameworkApi.credentials.js"
|
|
39
|
+
],
|
|
40
|
+
"nodes": [
|
|
41
|
+
"dist/nodes/MsTeamsBotFramework/MsTeamsBotFramework.node.js",
|
|
42
|
+
"dist/nodes/MsTeamsBotFramework/MsTeamsBotFrameworkTrigger.node.js",
|
|
43
|
+
"dist/nodes/MsTeamsBotFramework/MsTeamsAIBot.node.js"
|
|
44
|
+
]
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@types/express": "^4.17.6",
|
|
48
|
+
"@types/node": "^22.10.0",
|
|
49
|
+
"@typescript-eslint/parser": "^8.18.0",
|
|
50
|
+
"eslint": "^8.57.0",
|
|
51
|
+
"eslint-plugin-n8n-nodes-base": "^1.16.0",
|
|
52
|
+
"gulp": "^5.0.0",
|
|
53
|
+
"n8n-workflow": "~2.2.2",
|
|
54
|
+
"prettier": "^3.4.0",
|
|
55
|
+
"typescript": "~5.7.0"
|
|
56
|
+
},
|
|
57
|
+
"peerDependencies": {
|
|
58
|
+
"n8n-workflow": ">=2.0.0"
|
|
59
|
+
},
|
|
60
|
+
"dependencies": {
|
|
61
|
+
"botbuilder": "^4.20.0",
|
|
62
|
+
"axios": "^1.6.0"
|
|
63
|
+
}
|
|
64
|
+
}
|