n8n-nodes-msteams-botframework 1.0.0 → 1.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 +10 -1
- package/dist/nodes/MsTeamsBotFramework/MsTeamsAIBot.node.d.ts +5 -0
- package/dist/nodes/MsTeamsBotFramework/MsTeamsAIBot.node.js +255 -0
- package/dist/nodes/MsTeamsBotFramework/MsTeamsBotFrameworkTrigger.node.d.ts +12 -0
- package/dist/nodes/MsTeamsBotFramework/MsTeamsBotFrameworkTrigger.node.js +239 -0
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -4,13 +4,22 @@ Custom n8n node để tương tác với Microsoft Teams thông qua Azure Bot Fr
|
|
|
4
4
|
|
|
5
5
|
## Tính năng
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
### MS Teams Bot (Action Node)
|
|
8
8
|
- ✉️ Gửi tin nhắn text đến channel hoặc user
|
|
9
9
|
- 🎴 Gửi Adaptive Cards
|
|
10
10
|
- 💬 Reply vào tin nhắn cụ thể
|
|
11
11
|
- ✏️ Cập nhật tin nhắn đã gửi
|
|
12
12
|
- 🗑️ Xóa tin nhắn
|
|
13
13
|
|
|
14
|
+
### MS Teams Bot Trigger (NEW in v1.1.0) 🎣
|
|
15
|
+
- 📥 Nhận tin nhắn từ Teams qua webhook
|
|
16
|
+
- 👥 Nhận thông báo khi có người join/leave
|
|
17
|
+
- 👍 Nhận reactions vào tin nhắn
|
|
18
|
+
- ✏️ Nhận thông báo khi message được edit
|
|
19
|
+
- 🗑️ Nhận thông báo khi message bị xóa
|
|
20
|
+
- 🤖 Tự động filter bot messages
|
|
21
|
+
- ⌨️ Tự động gửi typing indicator
|
|
22
|
+
|
|
14
23
|
## Yêu cầu
|
|
15
24
|
|
|
16
25
|
- n8n version 0.187.0 trở lên
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.MsTeamsAIBot = void 0;
|
|
7
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
8
|
+
const axios_1 = __importDefault(require("axios"));
|
|
9
|
+
const conversationMemories = {};
|
|
10
|
+
class MsTeamsAIBot {
|
|
11
|
+
constructor() {
|
|
12
|
+
this.description = {
|
|
13
|
+
displayName: 'MS Teams AI Bot',
|
|
14
|
+
name: 'msTeamsAIBot',
|
|
15
|
+
icon: 'file:msteams.svg',
|
|
16
|
+
group: ['transform'],
|
|
17
|
+
version: 1,
|
|
18
|
+
subtitle: '={{$parameter["aiProvider"]}} AI Chatbot',
|
|
19
|
+
description: 'AI-powered Teams bot with chat models, memory, and function calling',
|
|
20
|
+
defaults: {
|
|
21
|
+
name: 'MS Teams AI Bot',
|
|
22
|
+
},
|
|
23
|
+
inputs: ['main'],
|
|
24
|
+
outputs: ['main'],
|
|
25
|
+
credentials: [
|
|
26
|
+
{
|
|
27
|
+
name: 'msTeamsBotFrameworkApi',
|
|
28
|
+
required: true,
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
properties: [
|
|
32
|
+
{
|
|
33
|
+
displayName: 'AI Provider',
|
|
34
|
+
name: 'aiProvider',
|
|
35
|
+
type: 'options',
|
|
36
|
+
options: [
|
|
37
|
+
{
|
|
38
|
+
name: 'OpenAI',
|
|
39
|
+
value: 'openai',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: 'Anthropic (Claude)',
|
|
43
|
+
value: 'anthropic',
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
default: 'openai',
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
displayName: 'OpenAI API Key',
|
|
50
|
+
name: 'openaiApiKey',
|
|
51
|
+
type: 'string',
|
|
52
|
+
typeOptions: { password: true },
|
|
53
|
+
displayOptions: { show: { aiProvider: ['openai'] } },
|
|
54
|
+
default: '',
|
|
55
|
+
description: 'OpenAI API Key',
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
displayName: 'Model',
|
|
59
|
+
name: 'openaiModel',
|
|
60
|
+
type: 'options',
|
|
61
|
+
displayOptions: { show: { aiProvider: ['openai'] } },
|
|
62
|
+
options: [
|
|
63
|
+
{ name: 'GPT-4 Turbo', value: 'gpt-4-turbo-preview' },
|
|
64
|
+
{ name: 'GPT-4', value: 'gpt-4' },
|
|
65
|
+
{ name: 'GPT-3.5 Turbo', value: 'gpt-3.5-turbo' },
|
|
66
|
+
],
|
|
67
|
+
default: 'gpt-3.5-turbo',
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
displayName: 'Anthropic API Key',
|
|
71
|
+
name: 'anthropicApiKey',
|
|
72
|
+
type: 'string',
|
|
73
|
+
typeOptions: { password: true },
|
|
74
|
+
displayOptions: { show: { aiProvider: ['anthropic'] } },
|
|
75
|
+
default: '',
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
displayName: 'Model',
|
|
79
|
+
name: 'anthropicModel',
|
|
80
|
+
type: 'options',
|
|
81
|
+
displayOptions: { show: { aiProvider: ['anthropic'] } },
|
|
82
|
+
options: [
|
|
83
|
+
{ name: 'Claude 3 Opus', value: 'claude-3-opus-20240229' },
|
|
84
|
+
{ name: 'Claude 3 Sonnet', value: 'claude-3-sonnet-20240229' },
|
|
85
|
+
{ name: 'Claude 3 Haiku', value: 'claude-3-haiku-20240307' },
|
|
86
|
+
],
|
|
87
|
+
default: 'claude-3-sonnet-20240229',
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
displayName: 'System Prompt',
|
|
91
|
+
name: 'systemPrompt',
|
|
92
|
+
type: 'string',
|
|
93
|
+
typeOptions: { rows: 4 },
|
|
94
|
+
default: 'You are a helpful AI assistant in Microsoft Teams. Be concise and professional.',
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
displayName: 'Enable Memory',
|
|
98
|
+
name: 'enableMemory',
|
|
99
|
+
type: 'boolean',
|
|
100
|
+
default: true,
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
displayName: 'Memory Limit',
|
|
104
|
+
name: 'memoryLimit',
|
|
105
|
+
type: 'number',
|
|
106
|
+
displayOptions: { show: { enableMemory: [true] } },
|
|
107
|
+
default: 10,
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
displayName: 'Options',
|
|
111
|
+
name: 'options',
|
|
112
|
+
type: 'collection',
|
|
113
|
+
default: {},
|
|
114
|
+
options: [
|
|
115
|
+
{
|
|
116
|
+
displayName: 'Temperature',
|
|
117
|
+
name: 'temperature',
|
|
118
|
+
type: 'number',
|
|
119
|
+
default: 0.7,
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
displayName: 'Max Tokens',
|
|
123
|
+
name: 'maxTokens',
|
|
124
|
+
type: 'number',
|
|
125
|
+
default: 500,
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
displayName: 'Auto Reply',
|
|
129
|
+
name: 'autoReply',
|
|
130
|
+
type: 'boolean',
|
|
131
|
+
default: true,
|
|
132
|
+
},
|
|
133
|
+
],
|
|
134
|
+
},
|
|
135
|
+
],
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
async execute() {
|
|
139
|
+
var _a, _b, _c;
|
|
140
|
+
const items = this.getInputData();
|
|
141
|
+
const returnData = [];
|
|
142
|
+
const credentials = await this.getCredentials('msTeamsBotFrameworkApi');
|
|
143
|
+
for (let i = 0; i < items.length; i++) {
|
|
144
|
+
try {
|
|
145
|
+
const item = items[i].json;
|
|
146
|
+
const aiProvider = this.getNodeParameter('aiProvider', i);
|
|
147
|
+
const systemPrompt = this.getNodeParameter('systemPrompt', i);
|
|
148
|
+
const enableMemory = this.getNodeParameter('enableMemory', i);
|
|
149
|
+
const memoryLimit = this.getNodeParameter('memoryLimit', i, 10);
|
|
150
|
+
const options = this.getNodeParameter('options', i, {});
|
|
151
|
+
const userMessage = item.text;
|
|
152
|
+
const conversationId = (_a = item.conversation) === null || _a === void 0 ? void 0 : _a.id;
|
|
153
|
+
const serviceUrl = item.serviceUrl;
|
|
154
|
+
if (!conversationMemories[conversationId]) {
|
|
155
|
+
conversationMemories[conversationId] = [];
|
|
156
|
+
}
|
|
157
|
+
if (enableMemory) {
|
|
158
|
+
conversationMemories[conversationId].push({
|
|
159
|
+
role: 'user',
|
|
160
|
+
content: userMessage,
|
|
161
|
+
});
|
|
162
|
+
if (conversationMemories[conversationId].length > memoryLimit * 2) {
|
|
163
|
+
conversationMemories[conversationId] = conversationMemories[conversationId].slice(-memoryLimit * 2);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
const messages = [{ role: 'system', content: systemPrompt }];
|
|
167
|
+
if (enableMemory) {
|
|
168
|
+
messages.push(...conversationMemories[conversationId]);
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
messages.push({ role: 'user', content: userMessage });
|
|
172
|
+
}
|
|
173
|
+
let aiResponse;
|
|
174
|
+
if (aiProvider === 'openai') {
|
|
175
|
+
const apiKey = this.getNodeParameter('openaiApiKey', i);
|
|
176
|
+
const model = this.getNodeParameter('openaiModel', i);
|
|
177
|
+
const response = await axios_1.default.post('https://api.openai.com/v1/chat/completions', {
|
|
178
|
+
model,
|
|
179
|
+
messages,
|
|
180
|
+
temperature: options.temperature || 0.7,
|
|
181
|
+
max_tokens: options.maxTokens || 500,
|
|
182
|
+
}, { headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' } });
|
|
183
|
+
aiResponse = response.data.choices[0].message.content;
|
|
184
|
+
}
|
|
185
|
+
else if (aiProvider === 'anthropic') {
|
|
186
|
+
const apiKey = this.getNodeParameter('anthropicApiKey', i);
|
|
187
|
+
const model = this.getNodeParameter('anthropicModel', i);
|
|
188
|
+
const systemMessage = ((_b = messages.find((m) => m.role === 'system')) === null || _b === void 0 ? void 0 : _b.content) || '';
|
|
189
|
+
const conversationMessages = messages.filter((m) => m.role !== 'system');
|
|
190
|
+
const response = await axios_1.default.post('https://api.anthropic.com/v1/messages', {
|
|
191
|
+
model,
|
|
192
|
+
messages: conversationMessages,
|
|
193
|
+
system: systemMessage,
|
|
194
|
+
max_tokens: options.maxTokens || 500,
|
|
195
|
+
}, {
|
|
196
|
+
headers: {
|
|
197
|
+
'x-api-key': apiKey,
|
|
198
|
+
'anthropic-version': '2023-06-01',
|
|
199
|
+
'Content-Type': 'application/json',
|
|
200
|
+
},
|
|
201
|
+
});
|
|
202
|
+
aiResponse = response.data.content
|
|
203
|
+
.filter((c) => c.type === 'text')
|
|
204
|
+
.map((c) => c.text)
|
|
205
|
+
.join('\n');
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `AI provider "${aiProvider}" not implemented`);
|
|
209
|
+
}
|
|
210
|
+
if (enableMemory) {
|
|
211
|
+
conversationMemories[conversationId].push({
|
|
212
|
+
role: 'assistant',
|
|
213
|
+
content: aiResponse,
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
if (options.autoReply !== false) {
|
|
217
|
+
const tokenResponse = await axios_1.default.post('https://login.microsoftonline.com/botframework.com/oauth2/v2.0/token', new URLSearchParams({
|
|
218
|
+
grant_type: 'client_credentials',
|
|
219
|
+
client_id: credentials.appId,
|
|
220
|
+
client_secret: credentials.appPassword,
|
|
221
|
+
scope: 'https://api.botframework.com/.default',
|
|
222
|
+
}), { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } });
|
|
223
|
+
await axios_1.default.post(`${serviceUrl}v3/conversations/${conversationId}/activities`, {
|
|
224
|
+
type: 'message',
|
|
225
|
+
text: aiResponse,
|
|
226
|
+
channelId: 'msteams',
|
|
227
|
+
conversation: { id: conversationId },
|
|
228
|
+
}, {
|
|
229
|
+
headers: {
|
|
230
|
+
'Authorization': `Bearer ${tokenResponse.data.access_token}`,
|
|
231
|
+
'Content-Type': 'application/json',
|
|
232
|
+
},
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
returnData.push({
|
|
236
|
+
json: {
|
|
237
|
+
userMessage,
|
|
238
|
+
aiResponse,
|
|
239
|
+
conversationId,
|
|
240
|
+
memorySize: ((_c = conversationMemories[conversationId]) === null || _c === void 0 ? void 0 : _c.length) || 0,
|
|
241
|
+
},
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
catch (error) {
|
|
245
|
+
if (this.continueOnFail()) {
|
|
246
|
+
returnData.push({ json: { error: error.message } });
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
throw error;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return [returnData];
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
exports.MsTeamsAIBot = MsTeamsAIBot;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { IHookFunctions, IWebhookFunctions, INodeType, INodeTypeDescription, IWebhookResponseData } from 'n8n-workflow';
|
|
2
|
+
export declare class MsTeamsBotFrameworkTrigger implements INodeType {
|
|
3
|
+
description: INodeTypeDescription;
|
|
4
|
+
webhookMethods: {
|
|
5
|
+
default: {
|
|
6
|
+
checkExists(this: IHookFunctions): Promise<boolean>;
|
|
7
|
+
create(this: IHookFunctions): Promise<boolean>;
|
|
8
|
+
delete(this: IHookFunctions): Promise<boolean>;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
webhook(this: IWebhookFunctions): Promise<IWebhookResponseData>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MsTeamsBotFrameworkTrigger = void 0;
|
|
4
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
+
const botbuilder_1 = require("botbuilder");
|
|
6
|
+
class MsTeamsBotFrameworkTrigger {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.description = {
|
|
9
|
+
displayName: 'MS Teams Bot Trigger',
|
|
10
|
+
name: 'msTeamsBotFrameworkTrigger',
|
|
11
|
+
icon: 'file:msteams.svg',
|
|
12
|
+
group: ['trigger'],
|
|
13
|
+
version: 1,
|
|
14
|
+
subtitle: 'Receive MS Teams messages',
|
|
15
|
+
description: 'Receive messages and events from MS Teams via webhook',
|
|
16
|
+
defaults: {
|
|
17
|
+
name: 'MS Teams Bot Trigger',
|
|
18
|
+
},
|
|
19
|
+
inputs: [],
|
|
20
|
+
outputs: ['main'],
|
|
21
|
+
credentials: [
|
|
22
|
+
{
|
|
23
|
+
name: 'msTeamsBotFrameworkApi',
|
|
24
|
+
required: true,
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
webhooks: [
|
|
28
|
+
{
|
|
29
|
+
name: 'default',
|
|
30
|
+
httpMethod: 'POST',
|
|
31
|
+
responseMode: 'onReceived',
|
|
32
|
+
path: 'webhook',
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
properties: [
|
|
36
|
+
{
|
|
37
|
+
displayName: 'Events',
|
|
38
|
+
name: 'events',
|
|
39
|
+
type: 'multiOptions',
|
|
40
|
+
options: [
|
|
41
|
+
{
|
|
42
|
+
name: 'Message Received',
|
|
43
|
+
value: 'message',
|
|
44
|
+
description: 'Trigger when a message is received',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: 'Conversation Update',
|
|
48
|
+
value: 'conversationUpdate',
|
|
49
|
+
description: 'Trigger when someone joins/leaves conversation',
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
name: 'Message Reaction',
|
|
53
|
+
value: 'messageReaction',
|
|
54
|
+
description: 'Trigger when someone reacts to a message',
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: 'Message Update',
|
|
58
|
+
value: 'messageUpdate',
|
|
59
|
+
description: 'Trigger when a message is updated',
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
name: 'Message Delete',
|
|
63
|
+
value: 'messageDelete',
|
|
64
|
+
description: 'Trigger when a message is deleted',
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
default: ['message'],
|
|
68
|
+
required: true,
|
|
69
|
+
description: 'The events to listen to',
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
displayName: 'Options',
|
|
73
|
+
name: 'options',
|
|
74
|
+
type: 'collection',
|
|
75
|
+
placeholder: 'Add Option',
|
|
76
|
+
default: {},
|
|
77
|
+
options: [
|
|
78
|
+
{
|
|
79
|
+
displayName: 'Ignore Bot Messages',
|
|
80
|
+
name: 'ignoreBotMessages',
|
|
81
|
+
type: 'boolean',
|
|
82
|
+
default: true,
|
|
83
|
+
description: 'Whether to ignore messages from bots',
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
displayName: 'Include Raw Activity',
|
|
87
|
+
name: 'includeRawActivity',
|
|
88
|
+
type: 'boolean',
|
|
89
|
+
default: false,
|
|
90
|
+
description: 'Whether to include the raw Bot Framework activity in output',
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
displayName: 'Auto Reply',
|
|
94
|
+
name: 'autoReply',
|
|
95
|
+
type: 'boolean',
|
|
96
|
+
default: false,
|
|
97
|
+
description: 'Whether to automatically send a typing indicator',
|
|
98
|
+
},
|
|
99
|
+
],
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
};
|
|
103
|
+
this.webhookMethods = {
|
|
104
|
+
default: {
|
|
105
|
+
async checkExists() {
|
|
106
|
+
return true;
|
|
107
|
+
},
|
|
108
|
+
async create() {
|
|
109
|
+
return true;
|
|
110
|
+
},
|
|
111
|
+
async delete() {
|
|
112
|
+
return true;
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
async webhook() {
|
|
118
|
+
const credentials = await this.getCredentials('msTeamsBotFrameworkApi');
|
|
119
|
+
const req = this.getRequestObject();
|
|
120
|
+
const events = this.getNodeParameter('events', []);
|
|
121
|
+
const options = this.getNodeParameter('options', {});
|
|
122
|
+
const appId = credentials.appId;
|
|
123
|
+
const appPassword = credentials.appPassword;
|
|
124
|
+
// Create Bot Framework Adapter
|
|
125
|
+
const adapter = new botbuilder_1.BotFrameworkAdapter({
|
|
126
|
+
appId,
|
|
127
|
+
appPassword,
|
|
128
|
+
});
|
|
129
|
+
// Process the incoming activity
|
|
130
|
+
let activityData = null;
|
|
131
|
+
let shouldTrigger = false;
|
|
132
|
+
try {
|
|
133
|
+
await adapter.processActivity(req, req.res, async (context) => {
|
|
134
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
135
|
+
const activity = context.activity;
|
|
136
|
+
// Check if we should process this activity type
|
|
137
|
+
if (!events.includes(activity.type)) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
// Ignore bot messages if configured
|
|
141
|
+
if (options.ignoreBotMessages && ((_a = activity.from) === null || _a === void 0 ? void 0 : _a.role) === 'bot') {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
shouldTrigger = true;
|
|
145
|
+
// Send typing indicator if auto reply is enabled
|
|
146
|
+
if (options.autoReply && activity.type === 'message') {
|
|
147
|
+
await context.sendActivity({ type: 'typing' });
|
|
148
|
+
}
|
|
149
|
+
// Extract useful data from activity
|
|
150
|
+
activityData = {
|
|
151
|
+
type: activity.type,
|
|
152
|
+
text: activity.text,
|
|
153
|
+
timestamp: activity.timestamp,
|
|
154
|
+
id: activity.id,
|
|
155
|
+
conversation: {
|
|
156
|
+
id: (_b = activity.conversation) === null || _b === void 0 ? void 0 : _b.id,
|
|
157
|
+
name: (_c = activity.conversation) === null || _c === void 0 ? void 0 : _c.name,
|
|
158
|
+
conversationType: (_d = activity.conversation) === null || _d === void 0 ? void 0 : _d.conversationType,
|
|
159
|
+
tenantId: (_e = activity.conversation) === null || _e === void 0 ? void 0 : _e.tenantId,
|
|
160
|
+
},
|
|
161
|
+
from: {
|
|
162
|
+
id: (_f = activity.from) === null || _f === void 0 ? void 0 : _f.id,
|
|
163
|
+
name: (_g = activity.from) === null || _g === void 0 ? void 0 : _g.name,
|
|
164
|
+
aadObjectId: (_h = activity.from) === null || _h === void 0 ? void 0 : _h.aadObjectId,
|
|
165
|
+
role: (_j = activity.from) === null || _j === void 0 ? void 0 : _j.role,
|
|
166
|
+
},
|
|
167
|
+
recipient: {
|
|
168
|
+
id: (_k = activity.recipient) === null || _k === void 0 ? void 0 : _k.id,
|
|
169
|
+
name: (_l = activity.recipient) === null || _l === void 0 ? void 0 : _l.name,
|
|
170
|
+
},
|
|
171
|
+
channelId: activity.channelId,
|
|
172
|
+
serviceUrl: activity.serviceUrl,
|
|
173
|
+
locale: activity.locale,
|
|
174
|
+
};
|
|
175
|
+
// Add type-specific data
|
|
176
|
+
switch (activity.type) {
|
|
177
|
+
case 'message':
|
|
178
|
+
activityData.message = {
|
|
179
|
+
text: activity.text,
|
|
180
|
+
textFormat: activity.textFormat,
|
|
181
|
+
attachments: activity.attachments,
|
|
182
|
+
mentions: (_m = activity.entities) === null || _m === void 0 ? void 0 : _m.filter((e) => e.type === 'mention'),
|
|
183
|
+
};
|
|
184
|
+
break;
|
|
185
|
+
case 'conversationUpdate':
|
|
186
|
+
activityData.conversationUpdate = {
|
|
187
|
+
membersAdded: activity.membersAdded,
|
|
188
|
+
membersRemoved: activity.membersRemoved,
|
|
189
|
+
};
|
|
190
|
+
break;
|
|
191
|
+
case 'messageReaction':
|
|
192
|
+
activityData.messageReaction = {
|
|
193
|
+
reactionsAdded: activity.reactionsAdded,
|
|
194
|
+
reactionsRemoved: activity.reactionsRemoved,
|
|
195
|
+
replyToId: activity.replyToId,
|
|
196
|
+
};
|
|
197
|
+
break;
|
|
198
|
+
case 'messageUpdate':
|
|
199
|
+
activityData.messageUpdate = {
|
|
200
|
+
text: activity.text,
|
|
201
|
+
updatedText: activity.text,
|
|
202
|
+
};
|
|
203
|
+
break;
|
|
204
|
+
case 'messageDelete':
|
|
205
|
+
activityData.messageDelete = {
|
|
206
|
+
deletedMessageId: activity.id,
|
|
207
|
+
};
|
|
208
|
+
break;
|
|
209
|
+
}
|
|
210
|
+
// Include raw activity if requested
|
|
211
|
+
if (options.includeRawActivity) {
|
|
212
|
+
activityData.rawActivity = activity;
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
if (!shouldTrigger) {
|
|
216
|
+
// Return empty response if we shouldn't trigger
|
|
217
|
+
return {
|
|
218
|
+
workflowData: [],
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
// Return the activity data to the workflow
|
|
222
|
+
return {
|
|
223
|
+
workflowData: [
|
|
224
|
+
[
|
|
225
|
+
{
|
|
226
|
+
json: activityData,
|
|
227
|
+
},
|
|
228
|
+
],
|
|
229
|
+
],
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
catch (error) {
|
|
233
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to process Teams webhook: ${error.message}`, {
|
|
234
|
+
description: error.message,
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
exports.MsTeamsBotFrameworkTrigger = MsTeamsBotFrameworkTrigger;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "n8n-nodes-msteams-botframework",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "n8n node for MS Teams Azure Bot Framework",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"n8n-community-node-package",
|
|
@@ -38,7 +38,9 @@
|
|
|
38
38
|
"dist/credentials/MsTeamsBotFrameworkApi.credentials.js"
|
|
39
39
|
],
|
|
40
40
|
"nodes": [
|
|
41
|
-
"dist/nodes/MsTeamsBotFramework/MsTeamsBotFramework.node.js"
|
|
41
|
+
"dist/nodes/MsTeamsBotFramework/MsTeamsBotFramework.node.js",
|
|
42
|
+
"dist/nodes/MsTeamsBotFramework/MsTeamsBotFrameworkTrigger.node.js",
|
|
43
|
+
"dist/nodes/MsTeamsBotFramework/MsTeamsAIBot.node.js"
|
|
42
44
|
]
|
|
43
45
|
},
|
|
44
46
|
"devDependencies": {
|