n8n-nodes-msteams-botframework 1.2.10 → 1.2.12
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,8 +1,6 @@
|
|
|
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");
|
|
6
4
|
// Track processed activity IDs to prevent duplicates
|
|
7
5
|
const processedActivities = new Map();
|
|
8
6
|
// Clean up old entries every 5 minutes
|
|
@@ -39,8 +37,7 @@ class MsTeamsBotFrameworkTrigger {
|
|
|
39
37
|
{
|
|
40
38
|
name: 'default',
|
|
41
39
|
httpMethod: 'POST',
|
|
42
|
-
responseMode: '
|
|
43
|
-
responseData: '={{$parameter["responseData"]}}',
|
|
40
|
+
responseMode: 'onReceived',
|
|
44
41
|
path: 'webhook',
|
|
45
42
|
},
|
|
46
43
|
],
|
|
@@ -80,64 +77,6 @@ class MsTeamsBotFrameworkTrigger {
|
|
|
80
77
|
required: true,
|
|
81
78
|
description: 'The events to listen to',
|
|
82
79
|
},
|
|
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
|
-
},
|
|
141
80
|
{
|
|
142
81
|
displayName: 'Options',
|
|
143
82
|
name: 'options',
|
|
@@ -159,13 +98,6 @@ class MsTeamsBotFrameworkTrigger {
|
|
|
159
98
|
default: false,
|
|
160
99
|
description: 'Whether to include the raw Bot Framework activity in output',
|
|
161
100
|
},
|
|
162
|
-
{
|
|
163
|
-
displayName: 'Auto Reply',
|
|
164
|
-
name: 'autoReply',
|
|
165
|
-
type: 'boolean',
|
|
166
|
-
default: false,
|
|
167
|
-
description: 'Whether to automatically send a typing indicator',
|
|
168
|
-
},
|
|
169
101
|
],
|
|
170
102
|
},
|
|
171
103
|
],
|
|
@@ -185,145 +117,114 @@ class MsTeamsBotFrameworkTrigger {
|
|
|
185
117
|
};
|
|
186
118
|
}
|
|
187
119
|
async webhook() {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
try {
|
|
191
|
-
credentials = await this.getCredentials('msTeamsBotFrameworkApi');
|
|
192
|
-
}
|
|
193
|
-
catch (error) {
|
|
194
|
-
throw new n8n_workflow_1.NodeOperationError(node, 'Failed to get credentials', {
|
|
195
|
-
description: error.message,
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
const req = this.getRequestObject();
|
|
120
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
121
|
+
const bodyData = this.getBodyData();
|
|
199
122
|
const events = this.getNodeParameter('events', []);
|
|
200
123
|
const options = this.getNodeParameter('options', {});
|
|
201
|
-
|
|
202
|
-
const
|
|
203
|
-
//
|
|
204
|
-
|
|
205
|
-
appId,
|
|
206
|
-
appPassword,
|
|
207
|
-
});
|
|
208
|
-
// Process the incoming activity
|
|
209
|
-
let activityData = null;
|
|
210
|
-
let shouldTrigger = false;
|
|
211
|
-
try {
|
|
212
|
-
await adapter.processActivity(req, req.res, async (context) => {
|
|
213
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
214
|
-
const activity = context.activity;
|
|
215
|
-
// Check for duplicate activity
|
|
216
|
-
const activityKey = `${activity.id}_${activity.timestamp}`;
|
|
217
|
-
if (processedActivities.has(activityKey)) {
|
|
218
|
-
// Already processed this activity, skip
|
|
219
|
-
shouldTrigger = false;
|
|
220
|
-
return;
|
|
221
|
-
}
|
|
222
|
-
// Check if we should process this activity type
|
|
223
|
-
if (!events.includes(activity.type)) {
|
|
224
|
-
shouldTrigger = false;
|
|
225
|
-
return;
|
|
226
|
-
}
|
|
227
|
-
// Ignore bot messages if configured
|
|
228
|
-
if (options.ignoreBotMessages && ((_a = activity.from) === null || _a === void 0 ? void 0 : _a.role) === 'bot') {
|
|
229
|
-
shouldTrigger = false;
|
|
230
|
-
return;
|
|
231
|
-
}
|
|
232
|
-
// Mark this activity as processed
|
|
233
|
-
processedActivities.set(activityKey, Date.now());
|
|
234
|
-
shouldTrigger = true;
|
|
235
|
-
// Send typing indicator if auto reply is enabled
|
|
236
|
-
if (options.autoReply && activity.type === 'message') {
|
|
237
|
-
await context.sendActivity({ type: 'typing' });
|
|
238
|
-
}
|
|
239
|
-
// Extract useful data from activity
|
|
240
|
-
activityData = {
|
|
241
|
-
type: activity.type,
|
|
242
|
-
text: activity.text,
|
|
243
|
-
timestamp: activity.timestamp,
|
|
244
|
-
id: activity.id,
|
|
245
|
-
conversation: {
|
|
246
|
-
id: (_b = activity.conversation) === null || _b === void 0 ? void 0 : _b.id,
|
|
247
|
-
name: (_c = activity.conversation) === null || _c === void 0 ? void 0 : _c.name,
|
|
248
|
-
conversationType: (_d = activity.conversation) === null || _d === void 0 ? void 0 : _d.conversationType,
|
|
249
|
-
tenantId: (_e = activity.conversation) === null || _e === void 0 ? void 0 : _e.tenantId,
|
|
250
|
-
},
|
|
251
|
-
from: {
|
|
252
|
-
id: (_f = activity.from) === null || _f === void 0 ? void 0 : _f.id,
|
|
253
|
-
name: (_g = activity.from) === null || _g === void 0 ? void 0 : _g.name,
|
|
254
|
-
aadObjectId: (_h = activity.from) === null || _h === void 0 ? void 0 : _h.aadObjectId,
|
|
255
|
-
role: (_j = activity.from) === null || _j === void 0 ? void 0 : _j.role,
|
|
256
|
-
},
|
|
257
|
-
recipient: {
|
|
258
|
-
id: (_k = activity.recipient) === null || _k === void 0 ? void 0 : _k.id,
|
|
259
|
-
name: (_l = activity.recipient) === null || _l === void 0 ? void 0 : _l.name,
|
|
260
|
-
},
|
|
261
|
-
channelId: activity.channelId,
|
|
262
|
-
serviceUrl: activity.serviceUrl,
|
|
263
|
-
locale: activity.locale,
|
|
264
|
-
};
|
|
265
|
-
// Add type-specific data
|
|
266
|
-
switch (activity.type) {
|
|
267
|
-
case 'message':
|
|
268
|
-
activityData.message = {
|
|
269
|
-
text: activity.text,
|
|
270
|
-
textFormat: activity.textFormat,
|
|
271
|
-
attachments: activity.attachments,
|
|
272
|
-
mentions: (_m = activity.entities) === null || _m === void 0 ? void 0 : _m.filter((e) => e.type === 'mention'),
|
|
273
|
-
};
|
|
274
|
-
break;
|
|
275
|
-
case 'conversationUpdate':
|
|
276
|
-
activityData.conversationUpdate = {
|
|
277
|
-
membersAdded: activity.membersAdded,
|
|
278
|
-
membersRemoved: activity.membersRemoved,
|
|
279
|
-
};
|
|
280
|
-
break;
|
|
281
|
-
case 'messageReaction':
|
|
282
|
-
activityData.messageReaction = {
|
|
283
|
-
reactionsAdded: activity.reactionsAdded,
|
|
284
|
-
reactionsRemoved: activity.reactionsRemoved,
|
|
285
|
-
replyToId: activity.replyToId,
|
|
286
|
-
};
|
|
287
|
-
break;
|
|
288
|
-
case 'messageUpdate':
|
|
289
|
-
activityData.messageUpdate = {
|
|
290
|
-
text: activity.text,
|
|
291
|
-
updatedText: activity.text,
|
|
292
|
-
};
|
|
293
|
-
break;
|
|
294
|
-
case 'messageDelete':
|
|
295
|
-
activityData.messageDelete = {
|
|
296
|
-
deletedMessageId: activity.id,
|
|
297
|
-
};
|
|
298
|
-
break;
|
|
299
|
-
}
|
|
300
|
-
// Include raw activity if requested
|
|
301
|
-
if (options.includeRawActivity) {
|
|
302
|
-
activityData.rawActivity = activity;
|
|
303
|
-
}
|
|
304
|
-
});
|
|
305
|
-
if (!shouldTrigger || !activityData) {
|
|
306
|
-
// Don't trigger workflow - Bot Framework Adapter already sent 200 OK
|
|
307
|
-
return {
|
|
308
|
-
noWebhookResponse: true,
|
|
309
|
-
};
|
|
310
|
-
}
|
|
311
|
-
// Return the activity data to the workflow
|
|
124
|
+
// Get the activity from body
|
|
125
|
+
const activity = bodyData;
|
|
126
|
+
// Validate activity object
|
|
127
|
+
if (!activity || !activity.type) {
|
|
312
128
|
return {
|
|
313
|
-
|
|
314
|
-
[
|
|
315
|
-
{
|
|
316
|
-
json: activityData,
|
|
317
|
-
},
|
|
318
|
-
],
|
|
319
|
-
],
|
|
129
|
+
webhookResponse: { status: 'ok', message: 'Invalid activity' },
|
|
320
130
|
};
|
|
321
131
|
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
132
|
+
// Check for duplicate activity
|
|
133
|
+
const activityKey = `${activity.id || 'unknown'}_${activity.timestamp || Date.now()}`;
|
|
134
|
+
if (processedActivities.has(activityKey)) {
|
|
135
|
+
return {
|
|
136
|
+
webhookResponse: { status: 'ok' },
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
// Check if we should process this activity type
|
|
140
|
+
if (!events.includes(activity.type)) {
|
|
141
|
+
return {
|
|
142
|
+
webhookResponse: { status: 'ok' },
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
// Ignore bot messages if configured
|
|
146
|
+
if (options.ignoreBotMessages && ((_a = activity.from) === null || _a === void 0 ? void 0 : _a.role) === 'bot') {
|
|
147
|
+
return {
|
|
148
|
+
webhookResponse: { status: 'ok' },
|
|
149
|
+
};
|
|
326
150
|
}
|
|
151
|
+
// Mark this activity as processed
|
|
152
|
+
processedActivities.set(activityKey, Date.now());
|
|
153
|
+
// Extract useful data from activity
|
|
154
|
+
const activityData = {
|
|
155
|
+
type: activity.type,
|
|
156
|
+
text: activity.text || '',
|
|
157
|
+
timestamp: activity.timestamp,
|
|
158
|
+
id: activity.id,
|
|
159
|
+
conversation: {
|
|
160
|
+
id: (_b = activity.conversation) === null || _b === void 0 ? void 0 : _b.id,
|
|
161
|
+
name: (_c = activity.conversation) === null || _c === void 0 ? void 0 : _c.name,
|
|
162
|
+
conversationType: (_d = activity.conversation) === null || _d === void 0 ? void 0 : _d.conversationType,
|
|
163
|
+
tenantId: (_e = activity.conversation) === null || _e === void 0 ? void 0 : _e.tenantId,
|
|
164
|
+
},
|
|
165
|
+
from: {
|
|
166
|
+
id: (_f = activity.from) === null || _f === void 0 ? void 0 : _f.id,
|
|
167
|
+
name: (_g = activity.from) === null || _g === void 0 ? void 0 : _g.name,
|
|
168
|
+
aadObjectId: (_h = activity.from) === null || _h === void 0 ? void 0 : _h.aadObjectId,
|
|
169
|
+
role: (_j = activity.from) === null || _j === void 0 ? void 0 : _j.role,
|
|
170
|
+
},
|
|
171
|
+
recipient: {
|
|
172
|
+
id: (_k = activity.recipient) === null || _k === void 0 ? void 0 : _k.id,
|
|
173
|
+
name: (_l = activity.recipient) === null || _l === void 0 ? void 0 : _l.name,
|
|
174
|
+
},
|
|
175
|
+
channelId: activity.channelId,
|
|
176
|
+
serviceUrl: activity.serviceUrl,
|
|
177
|
+
locale: activity.locale,
|
|
178
|
+
};
|
|
179
|
+
// Add type-specific data
|
|
180
|
+
switch (activity.type) {
|
|
181
|
+
case 'message':
|
|
182
|
+
activityData.message = {
|
|
183
|
+
text: activity.text || '',
|
|
184
|
+
textFormat: activity.textFormat,
|
|
185
|
+
attachments: activity.attachments || [],
|
|
186
|
+
mentions: ((_m = activity.entities) === null || _m === void 0 ? void 0 : _m.filter((e) => e.type === 'mention')) || [],
|
|
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 || '',
|
|
206
|
+
};
|
|
207
|
+
break;
|
|
208
|
+
case 'messageDelete':
|
|
209
|
+
activityData.messageDelete = {
|
|
210
|
+
deletedMessageId: activity.id,
|
|
211
|
+
};
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
// Include raw activity if requested
|
|
215
|
+
if (options.includeRawActivity) {
|
|
216
|
+
activityData.rawActivity = activity;
|
|
217
|
+
}
|
|
218
|
+
// Return the activity data to the workflow
|
|
219
|
+
return {
|
|
220
|
+
workflowData: [
|
|
221
|
+
[
|
|
222
|
+
{
|
|
223
|
+
json: activityData,
|
|
224
|
+
},
|
|
225
|
+
],
|
|
226
|
+
],
|
|
227
|
+
};
|
|
327
228
|
}
|
|
328
229
|
}
|
|
329
230
|
exports.MsTeamsBotFrameworkTrigger = MsTeamsBotFrameworkTrigger;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "n8n-nodes-msteams-botframework",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.12",
|
|
4
4
|
"description": "n8n node for MS Teams Azure Bot Framework",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"n8n-community-node-package",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
},
|
|
19
19
|
"repository": {
|
|
20
20
|
"type": "git",
|
|
21
|
-
"url": "https://github.com/weonVN/n8n-nodes-msteams-botframework.git"
|
|
21
|
+
"url": "git+https://github.com/weonVN/n8n-nodes-msteams-botframework.git"
|
|
22
22
|
},
|
|
23
23
|
"main": "index.js",
|
|
24
24
|
"scripts": {
|