n8n-nodes-msteams-botframework 1.0.0 → 1.1.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 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
- Node này cho phép bạn:
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,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.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "n8n node for MS Teams Azure Bot Framework",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",
@@ -38,7 +38,8 @@
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"
42
43
  ]
43
44
  },
44
45
  "devDependencies": {