n8n-nodes-microsoft-teams-bot 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.
Files changed (127) hide show
  1. package/dist/credentials/TeamsBotApi.credentials.d.ts +7 -0
  2. package/dist/credentials/TeamsBotApi.credentials.js +107 -0
  3. package/dist/credentials/TeamsBotApi.credentials.js.map +1 -0
  4. package/dist/credentials/TeamsGraphApi.credentials.d.ts +7 -0
  5. package/dist/credentials/TeamsGraphApi.credentials.js +58 -0
  6. package/dist/credentials/TeamsGraphApi.credentials.js.map +1 -0
  7. package/dist/index.d.ts +4 -0
  8. package/dist/index.js +23 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/nodes/TeamsBot/TeamsBot.node.d.ts +21 -0
  11. package/dist/nodes/TeamsBot/TeamsBot.node.js +457 -0
  12. package/dist/nodes/TeamsBot/TeamsBot.node.js.map +1 -0
  13. package/dist/nodes/TeamsBot/TeamsBot.node.json +73 -0
  14. package/dist/nodes/TeamsBot/TeamsBotTrigger.node.d.ts +21 -0
  15. package/dist/nodes/TeamsBot/TeamsBotTrigger.node.js +506 -0
  16. package/dist/nodes/TeamsBot/TeamsBotTrigger.node.js.map +1 -0
  17. package/dist/nodes/TeamsBot/TeamsBotTrigger.node.json +57 -0
  18. package/dist/nodes/TeamsBot/actions/buildCard.d.ts +6 -0
  19. package/dist/nodes/TeamsBot/actions/buildCard.js +176 -0
  20. package/dist/nodes/TeamsBot/actions/buildCard.js.map +1 -0
  21. package/dist/nodes/TeamsBot/actions/cards.d.ts +34 -0
  22. package/dist/nodes/TeamsBot/actions/cards.js +731 -0
  23. package/dist/nodes/TeamsBot/actions/cards.js.map +1 -0
  24. package/dist/nodes/TeamsBot/actions/channels.d.ts +18 -0
  25. package/dist/nodes/TeamsBot/actions/channels.js +199 -0
  26. package/dist/nodes/TeamsBot/actions/channels.js.map +1 -0
  27. package/dist/nodes/TeamsBot/actions/messages.d.ts +86 -0
  28. package/dist/nodes/TeamsBot/actions/messages.js +1259 -0
  29. package/dist/nodes/TeamsBot/actions/messages.js.map +1 -0
  30. package/dist/nodes/TeamsBot/actions/router.d.ts +2 -0
  31. package/dist/nodes/TeamsBot/actions/router.js +186 -0
  32. package/dist/nodes/TeamsBot/actions/router.js.map +1 -0
  33. package/dist/nodes/TeamsBot/actions/teams.d.ts +18 -0
  34. package/dist/nodes/TeamsBot/actions/teams.js +227 -0
  35. package/dist/nodes/TeamsBot/actions/teams.js.map +1 -0
  36. package/dist/nodes/TeamsBot/actions/users.d.ts +13 -0
  37. package/dist/nodes/TeamsBot/actions/users.js +184 -0
  38. package/dist/nodes/TeamsBot/actions/users.js.map +1 -0
  39. package/dist/nodes/TeamsBot/descriptions/buildCard.description.d.ts +7 -0
  40. package/dist/nodes/TeamsBot/descriptions/buildCard.description.js +682 -0
  41. package/dist/nodes/TeamsBot/descriptions/buildCard.description.js.map +1 -0
  42. package/dist/nodes/TeamsBot/descriptions/card.description.d.ts +2 -0
  43. package/dist/nodes/TeamsBot/descriptions/card.description.js +564 -0
  44. package/dist/nodes/TeamsBot/descriptions/card.description.js.map +1 -0
  45. package/dist/nodes/TeamsBot/descriptions/index.d.ts +3 -0
  46. package/dist/nodes/TeamsBot/descriptions/index.js +20 -0
  47. package/dist/nodes/TeamsBot/descriptions/index.js.map +1 -0
  48. package/dist/nodes/TeamsBot/descriptions/message.description.d.ts +2 -0
  49. package/dist/nodes/TeamsBot/descriptions/message.description.js +964 -0
  50. package/dist/nodes/TeamsBot/descriptions/message.description.js.map +1 -0
  51. package/dist/nodes/TeamsBot/descriptions/node.description.d.ts +2 -0
  52. package/dist/nodes/TeamsBot/descriptions/node.description.js +567 -0
  53. package/dist/nodes/TeamsBot/descriptions/node.description.js.map +1 -0
  54. package/dist/nodes/TeamsBot/errors/authentication.d.ts +100 -0
  55. package/dist/nodes/TeamsBot/errors/authentication.js +110 -0
  56. package/dist/nodes/TeamsBot/errors/authentication.js.map +1 -0
  57. package/dist/nodes/TeamsBot/errors/graphApi.d.ts +44 -0
  58. package/dist/nodes/TeamsBot/errors/graphApi.js +84 -0
  59. package/dist/nodes/TeamsBot/errors/graphApi.js.map +1 -0
  60. package/dist/nodes/TeamsBot/errors/messages.d.ts +187 -0
  61. package/dist/nodes/TeamsBot/errors/messages.js +190 -0
  62. package/dist/nodes/TeamsBot/errors/messages.js.map +1 -0
  63. package/dist/nodes/TeamsBot/methods/listSearch.d.ts +4 -0
  64. package/dist/nodes/TeamsBot/methods/listSearch.js +78 -0
  65. package/dist/nodes/TeamsBot/methods/listSearch.js.map +1 -0
  66. package/dist/nodes/TeamsBot/teams.svg +11 -0
  67. package/dist/nodes/TeamsBot/transport/TeamsApiClient.d.ts +305 -0
  68. package/dist/nodes/TeamsBot/transport/TeamsApiClient.js +458 -0
  69. package/dist/nodes/TeamsBot/transport/TeamsApiClient.js.map +1 -0
  70. package/dist/nodes/TeamsBot/transport/api/BotFrameworkApi.d.ts +350 -0
  71. package/dist/nodes/TeamsBot/transport/api/BotFrameworkApi.js +1265 -0
  72. package/dist/nodes/TeamsBot/transport/api/BotFrameworkApi.js.map +1 -0
  73. package/dist/nodes/TeamsBot/transport/api/GraphApi.d.ts +158 -0
  74. package/dist/nodes/TeamsBot/transport/api/GraphApi.js +443 -0
  75. package/dist/nodes/TeamsBot/transport/api/GraphApi.js.map +1 -0
  76. package/dist/nodes/TeamsBot/transport/api/GraphApiClient.d.ts +160 -0
  77. package/dist/nodes/TeamsBot/transport/api/GraphApiClient.js +268 -0
  78. package/dist/nodes/TeamsBot/transport/api/GraphApiClient.js.map +1 -0
  79. package/dist/nodes/TeamsBot/transport/api/index.d.ts +7 -0
  80. package/dist/nodes/TeamsBot/transport/api/index.js +26 -0
  81. package/dist/nodes/TeamsBot/transport/api/index.js.map +1 -0
  82. package/dist/nodes/TeamsBot/transport/index.d.ts +12 -0
  83. package/dist/nodes/TeamsBot/transport/index.js +30 -0
  84. package/dist/nodes/TeamsBot/transport/index.js.map +1 -0
  85. package/dist/nodes/TeamsBot/types/api-types.d.ts +258 -0
  86. package/dist/nodes/TeamsBot/types/api-types.js +3 -0
  87. package/dist/nodes/TeamsBot/types/api-types.js.map +1 -0
  88. package/dist/nodes/TeamsBot/types/cards.d.ts +252 -0
  89. package/dist/nodes/TeamsBot/types/cards.js +3 -0
  90. package/dist/nodes/TeamsBot/types/cards.js.map +1 -0
  91. package/dist/nodes/TeamsBot/types/index.d.ts +5 -0
  92. package/dist/nodes/TeamsBot/types/index.js +24 -0
  93. package/dist/nodes/TeamsBot/types/index.js.map +1 -0
  94. package/dist/nodes/TeamsBot/utils/AdaptiveCardBuilder.d.ts +147 -0
  95. package/dist/nodes/TeamsBot/utils/AdaptiveCardBuilder.js +333 -0
  96. package/dist/nodes/TeamsBot/utils/AdaptiveCardBuilder.js.map +1 -0
  97. package/dist/nodes/TeamsBot/utils/AdaptiveCardTemplates.d.ts +122 -0
  98. package/dist/nodes/TeamsBot/utils/AdaptiveCardTemplates.js +467 -0
  99. package/dist/nodes/TeamsBot/utils/AdaptiveCardTemplates.js.map +1 -0
  100. package/dist/nodes/TeamsBot/utils/CardTemplates.d.ts +94 -0
  101. package/dist/nodes/TeamsBot/utils/CardTemplates.js +446 -0
  102. package/dist/nodes/TeamsBot/utils/CardTemplates.js.map +1 -0
  103. package/dist/nodes/TeamsBot/utils/apiHelpers.d.ts +30 -0
  104. package/dist/nodes/TeamsBot/utils/apiHelpers.js +95 -0
  105. package/dist/nodes/TeamsBot/utils/apiHelpers.js.map +1 -0
  106. package/dist/nodes/TeamsBot/utils/constants.d.ts +86 -0
  107. package/dist/nodes/TeamsBot/utils/constants.js +60 -0
  108. package/dist/nodes/TeamsBot/utils/constants.js.map +1 -0
  109. package/dist/nodes/TeamsBot/utils/fileProcessing.d.ts +66 -0
  110. package/dist/nodes/TeamsBot/utils/fileProcessing.js +276 -0
  111. package/dist/nodes/TeamsBot/utils/fileProcessing.js.map +1 -0
  112. package/dist/nodes/TeamsBot/utils/graphNotificationParser.d.ts +91 -0
  113. package/dist/nodes/TeamsBot/utils/graphNotificationParser.js +162 -0
  114. package/dist/nodes/TeamsBot/utils/graphNotificationParser.js.map +1 -0
  115. package/dist/nodes/TeamsBot/utils/index.d.ts +24 -0
  116. package/dist/nodes/TeamsBot/utils/index.js +90 -0
  117. package/dist/nodes/TeamsBot/utils/index.js.map +1 -0
  118. package/dist/nodes/TeamsBot/utils/installation.d.ts +15 -0
  119. package/dist/nodes/TeamsBot/utils/installation.js +41 -0
  120. package/dist/nodes/TeamsBot/utils/installation.js.map +1 -0
  121. package/dist/nodes/TeamsBot/utils/subscriptionManager.d.ts +63 -0
  122. package/dist/nodes/TeamsBot/utils/subscriptionManager.js +100 -0
  123. package/dist/nodes/TeamsBot/utils/subscriptionManager.js.map +1 -0
  124. package/dist/nodes/TeamsBot/utils/validation.d.ts +93 -0
  125. package/dist/nodes/TeamsBot/utils/validation.js +281 -0
  126. package/dist/nodes/TeamsBot/utils/validation.js.map +1 -0
  127. package/package.json +79 -0
@@ -0,0 +1,1259 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.messageOperations = void 0;
4
+ const index_1 = require("../transport/index");
5
+ const messages_1 = require("../errors/messages");
6
+ const n8n_workflow_1 = require("n8n-workflow");
7
+ const utils_1 = require("../utils");
8
+ const fileProcessing_1 = require("../utils/fileProcessing");
9
+ const validation_1 = require("../utils/validation");
10
+ const constants_1 = require("../utils/constants");
11
+ /**
12
+ * Analyze reaction patterns from reaction data
13
+ */
14
+ function analyzeReactionPatterns(reactionData) {
15
+ const reactions = reactionData.reactions || [];
16
+ const analysis = {
17
+ totalReactions: reactions.length,
18
+ reactionBreakdown: {},
19
+ userEngagement: {},
20
+ temporalPatterns: {},
21
+ sentiment: 'neutral',
22
+ };
23
+ // Count reaction types
24
+ reactions.forEach((reaction) => {
25
+ var _a;
26
+ const type = reaction.type || 'unknown';
27
+ analysis.reactionBreakdown[type] = (analysis.reactionBreakdown[type] || 0) + 1;
28
+ // Track user engagement
29
+ const userId = ((_a = reaction.user) === null || _a === void 0 ? void 0 : _a.id) || 'unknown';
30
+ if (!analysis.userEngagement[userId]) {
31
+ analysis.userEngagement[userId] = {
32
+ totalReactions: 0,
33
+ reactionTypes: {},
34
+ firstReaction: reaction.timestamp,
35
+ lastReaction: reaction.timestamp,
36
+ };
37
+ }
38
+ analysis.userEngagement[userId].totalReactions++;
39
+ analysis.userEngagement[userId].reactionTypes[type] =
40
+ (analysis.userEngagement[userId].reactionTypes[type] || 0) + 1;
41
+ // Update timestamps
42
+ if (reaction.timestamp < analysis.userEngagement[userId].firstReaction) {
43
+ analysis.userEngagement[userId].firstReaction = reaction.timestamp;
44
+ }
45
+ if (reaction.timestamp > analysis.userEngagement[userId].lastReaction) {
46
+ analysis.userEngagement[userId].lastReaction = reaction.timestamp;
47
+ }
48
+ });
49
+ // Determine sentiment based on reaction types
50
+ const positiveReactions = ['like', 'heart', 'thumbsUp', 'laugh', 'celebrate'];
51
+ const negativeReactions = ['thumbsDown', 'sad', 'angry'];
52
+ let positiveCount = 0;
53
+ let negativeCount = 0;
54
+ Object.keys(analysis.reactionBreakdown).forEach(type => {
55
+ if (positiveReactions.includes(type))
56
+ positiveCount += analysis.reactionBreakdown[type];
57
+ if (negativeReactions.includes(type))
58
+ negativeCount += analysis.reactionBreakdown[type];
59
+ });
60
+ if (positiveCount > negativeCount)
61
+ analysis.sentiment = 'positive';
62
+ else if (negativeCount > positiveCount)
63
+ analysis.sentiment = 'negative';
64
+ return analysis;
65
+ }
66
+ /**
67
+ * Generate comprehensive reaction analytics for a conversation
68
+ */
69
+ function generateReactionAnalytics(messages, timeRangeHours) {
70
+ const cutoffTime = new Date(Date.now() - timeRangeHours * 60 * 60 * 1000);
71
+ const analytics = {
72
+ timeRange: `${timeRangeHours} hours`,
73
+ totalMessages: messages.length,
74
+ messagesWithReactions: 0,
75
+ totalReactions: 0,
76
+ reactionTypeDistribution: {},
77
+ topReactedMessages: [],
78
+ engagementRate: 0,
79
+ peakReactionHours: [],
80
+ };
81
+ let reactionCount = 0;
82
+ const hourlyReactions = {};
83
+ const messageReactionCounts = [];
84
+ messages.forEach(message => {
85
+ var _a;
86
+ const messageReactions = message.reactions || [];
87
+ const reactionCountForMessage = messageReactions.length;
88
+ if (reactionCountForMessage > 0) {
89
+ analytics.messagesWithReactions++;
90
+ reactionCount += reactionCountForMessage;
91
+ // Track message with most reactions
92
+ messageReactionCounts.push({
93
+ id: message.id,
94
+ count: reactionCountForMessage,
95
+ content: ((_a = message.body) === null || _a === void 0 ? void 0 : _a.content) || message.text || '',
96
+ });
97
+ // Track reaction types
98
+ messageReactions.forEach((reaction) => {
99
+ const type = reaction.reactionType || reaction.type || 'unknown';
100
+ analytics.reactionTypeDistribution[type] =
101
+ (analytics.reactionTypeDistribution[type] || 0) + 1;
102
+ // Track hourly distribution
103
+ const reactionTime = new Date(reaction.createdDateTime || message.createdDateTime);
104
+ if (reactionTime >= cutoffTime) {
105
+ const hour = reactionTime.getHours();
106
+ hourlyReactions[hour] = (hourlyReactions[hour] || 0) + 1;
107
+ }
108
+ });
109
+ }
110
+ });
111
+ analytics.totalReactions = reactionCount;
112
+ analytics.engagementRate = analytics.totalMessages > 0 ?
113
+ (analytics.messagesWithReactions / analytics.totalMessages) * 100 : 0;
114
+ // Find top reacted messages
115
+ messageReactionCounts
116
+ .sort((a, b) => b.count - a.count)
117
+ .slice(0, 5)
118
+ .forEach(item => {
119
+ analytics.topReactedMessages.push(item);
120
+ });
121
+ // Find peak reaction hours
122
+ const sortedHours = Object.entries(hourlyReactions)
123
+ .sort(([, a], [, b]) => b - a)
124
+ .slice(0, 3);
125
+ analytics.peakReactionHours = sortedHours.map(([hour, count]) => ({
126
+ hour: parseInt(hour),
127
+ reactionCount: count,
128
+ }));
129
+ return analytics;
130
+ }
131
+ /**
132
+ * Validates required parameters for message operations
133
+ */
134
+ function validateMessageParams(params, requiredFields, executeFunctions, itemIndex) {
135
+ // Always validate message
136
+ if (!params.message) {
137
+ throw messages_1.TeamsMessageError.invalidRecipient(executeFunctions.getNode(), 'Required parameter "message" is missing', { itemIndex });
138
+ }
139
+ // Validate recipient type and required fields
140
+ if (params.recipientType === 'channel') {
141
+ if (!params.teamId) {
142
+ throw messages_1.TeamsMessageError.invalidRecipient(executeFunctions.getNode(), 'Required parameter "teamId" is missing for channel messages', { itemIndex });
143
+ }
144
+ if (!params.channelId) {
145
+ throw messages_1.TeamsMessageError.invalidRecipient(executeFunctions.getNode(), 'Required parameter "channelId" is missing for channel messages', { itemIndex });
146
+ }
147
+ }
148
+ else if (params.recipientType === 'chat') {
149
+ if (!params.userId) {
150
+ throw messages_1.TeamsMessageError.invalidRecipient(executeFunctions.getNode(), 'Required parameter "userId" is missing for chat messages', { itemIndex });
151
+ }
152
+ }
153
+ else {
154
+ throw messages_1.TeamsMessageError.invalidRecipient(executeFunctions.getNode(), `Invalid recipient type: ${params.recipientType}`, { itemIndex });
155
+ }
156
+ }
157
+ /**
158
+ * Message operations for the Teams Bot node
159
+ */
160
+ exports.messageOperations = {
161
+ /**
162
+ * Sends a message to a channel or chat
163
+ */
164
+ async send() {
165
+ const items = this.getInputData();
166
+ const returnData = [];
167
+ const api = new index_1.TeamsApiClient(this);
168
+ await api.initialize();
169
+ for (let i = 0; i < items.length; i++) {
170
+ try {
171
+ // Get operation parameters
172
+ const message = this.getNodeParameter('message', i);
173
+ const recipientType = this.getNodeParameter('recipientType', i);
174
+ // Get required fields based on recipient type
175
+ let teamId;
176
+ let channelId;
177
+ let userId;
178
+ if (recipientType === 'channel') {
179
+ teamId = this.getNodeParameter('teamId', i);
180
+ channelId = this.getNodeParameter('channelId', i);
181
+ }
182
+ else if (recipientType === 'chat') {
183
+ userId = this.getNodeParameter('userId', i);
184
+ }
185
+ // Get message options
186
+ const options = this.getNodeParameter('options', i, {});
187
+ // Prepare message options
188
+ const messageOptions = {};
189
+ // Add text format if specified
190
+ if (options.format) {
191
+ messageOptions.textFormat = options.format;
192
+ }
193
+ // Validate parameters
194
+ const params = {
195
+ message,
196
+ recipientType,
197
+ teamId,
198
+ channelId,
199
+ userId,
200
+ };
201
+ validateMessageParams(params, ['message', 'recipientType'], this, i);
202
+ // Send message based on recipient type
203
+ let response;
204
+ try {
205
+ if (recipientType === 'channel') {
206
+ response = await api.sendChannelMessage(teamId, channelId, message, messageOptions);
207
+ }
208
+ else if (recipientType === 'chat') {
209
+ // Always handle auto-installation for direct messages
210
+ await (0, index_1.handleAutoInstall)(api, userId, i, this);
211
+ response = await api.sendMessage(userId, message, messageOptions);
212
+ }
213
+ else {
214
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unsupported recipient type: ${recipientType}`, { itemIndex: i });
215
+ }
216
+ // Ensure response is properly parsed before returning
217
+ returnData.push({
218
+ json: (0, utils_1.ensureObjectResponse)(response),
219
+ pairedItem: { item: i },
220
+ });
221
+ }
222
+ catch (error) {
223
+ if (this.continueOnFail()) {
224
+ const errorMessage = error instanceof Error ? error.message : String(error);
225
+ returnData.push({
226
+ json: {
227
+ error: errorMessage,
228
+ },
229
+ pairedItem: { item: i },
230
+ });
231
+ continue;
232
+ }
233
+ throw error;
234
+ }
235
+ }
236
+ catch (error) {
237
+ if (this.continueOnFail()) {
238
+ const errorMessage = error instanceof Error ? error.message : String(error);
239
+ returnData.push({
240
+ json: {
241
+ error: errorMessage,
242
+ },
243
+ pairedItem: { item: i },
244
+ });
245
+ continue;
246
+ }
247
+ throw error;
248
+ }
249
+ }
250
+ return [returnData];
251
+ },
252
+ /**
253
+ * Updates an existing message in a conversation
254
+ */
255
+ async update() {
256
+ const items = this.getInputData();
257
+ const returnData = [];
258
+ const api = new index_1.TeamsApiClient(this);
259
+ await api.initialize();
260
+ for (let i = 0; i < items.length; i++) {
261
+ try {
262
+ // Get operation parameters
263
+ const conversationId = this.getNodeParameter('conversationId', i);
264
+ const activityId = this.getNodeParameter('activityId', i);
265
+ const message = this.getNodeParameter('message', i);
266
+ // Optional parameters for message formatting
267
+ const textFormat = this.getNodeParameter('textFormat', i, 'markdown');
268
+ const attachmentsJson = this.getNodeParameter('attachments', i, '');
269
+ // Parse attachments if provided
270
+ let attachments;
271
+ if (attachmentsJson) {
272
+ try {
273
+ attachments = JSON.parse(attachmentsJson);
274
+ }
275
+ catch (error) {
276
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid JSON in attachments parameter: ${error}`, { itemIndex: i });
277
+ }
278
+ }
279
+ // Prepare message options
280
+ const options = {
281
+ textFormat,
282
+ attachments,
283
+ };
284
+ // Update the message
285
+ const response = await api.updateMessage(conversationId, activityId, message, options);
286
+ // Ensure response is properly parsed before returning
287
+ returnData.push({
288
+ json: (0, utils_1.ensureObjectResponse)(response),
289
+ pairedItem: { item: i },
290
+ });
291
+ }
292
+ catch (error) {
293
+ if (this.continueOnFail()) {
294
+ const errorMessage = error instanceof Error ? error.message : String(error);
295
+ returnData.push({
296
+ json: {
297
+ error: errorMessage,
298
+ },
299
+ pairedItem: { item: i },
300
+ });
301
+ continue;
302
+ }
303
+ throw error;
304
+ }
305
+ }
306
+ return [returnData];
307
+ },
308
+ /**
309
+ * Deletes a message from a conversation
310
+ */
311
+ async delete() {
312
+ const items = this.getInputData();
313
+ const returnData = [];
314
+ const api = new index_1.TeamsApiClient(this);
315
+ await api.initialize();
316
+ for (let i = 0; i < items.length; i++) {
317
+ try {
318
+ // Get operation parameters
319
+ const conversationId = this.getNodeParameter('conversationId', i);
320
+ const activityId = this.getNodeParameter('activityId', i);
321
+ // Delete the message
322
+ await api.deleteMessage(conversationId, activityId);
323
+ // Return success confirmation
324
+ returnData.push({
325
+ json: {
326
+ success: true,
327
+ message: `Message ${activityId} deleted successfully`,
328
+ conversationId,
329
+ activityId,
330
+ },
331
+ pairedItem: { item: i },
332
+ });
333
+ }
334
+ catch (error) {
335
+ if (this.continueOnFail()) {
336
+ const errorMessage = error instanceof Error ? error.message : String(error);
337
+ returnData.push({
338
+ json: {
339
+ error: errorMessage,
340
+ conversationId: this.getNodeParameter('conversationId', i),
341
+ activityId: this.getNodeParameter('activityId', i),
342
+ },
343
+ pairedItem: { item: i },
344
+ });
345
+ continue;
346
+ }
347
+ throw error;
348
+ }
349
+ }
350
+ return [returnData];
351
+ },
352
+ /**
353
+ * Replies to an existing message in a conversation
354
+ */
355
+ async reply() {
356
+ const items = this.getInputData();
357
+ const returnData = [];
358
+ const api = new index_1.TeamsApiClient(this);
359
+ await api.initialize();
360
+ for (let i = 0; i < items.length; i++) {
361
+ try {
362
+ // Get operation parameters
363
+ const conversationId = this.getNodeParameter('conversationId', i);
364
+ const replyToId = this.getNodeParameter('replyToId', i);
365
+ const message = this.getNodeParameter('message', i);
366
+ // Optional parameters for message formatting
367
+ const textFormat = this.getNodeParameter('textFormat', i, 'markdown');
368
+ const attachmentsJson = this.getNodeParameter('attachments', i, '');
369
+ // Parse attachments if provided
370
+ let attachments;
371
+ if (attachmentsJson) {
372
+ try {
373
+ attachments = JSON.parse(attachmentsJson);
374
+ }
375
+ catch (error) {
376
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid JSON in attachments parameter: ${error}`, { itemIndex: i });
377
+ }
378
+ }
379
+ // Prepare message options
380
+ const options = {
381
+ textFormat,
382
+ attachments,
383
+ };
384
+ // Reply to the message
385
+ const response = await api.replyToMessage(conversationId, replyToId, message, options);
386
+ // Ensure response is properly parsed before returning
387
+ returnData.push({
388
+ json: (0, utils_1.ensureObjectResponse)(response),
389
+ pairedItem: { item: i },
390
+ });
391
+ }
392
+ catch (error) {
393
+ if (this.continueOnFail()) {
394
+ const errorMessage = error instanceof Error ? error.message : String(error);
395
+ returnData.push({
396
+ json: {
397
+ error: errorMessage,
398
+ },
399
+ pairedItem: { item: i },
400
+ });
401
+ continue;
402
+ }
403
+ throw error;
404
+ }
405
+ }
406
+ return [returnData];
407
+ },
408
+ /**
409
+ * Sends a message and waits for a response
410
+ */
411
+ async sendAndWait() {
412
+ const items = this.getInputData();
413
+ const returnData = [];
414
+ const api = new index_1.TeamsApiClient(this);
415
+ await api.initialize();
416
+ for (let i = 0; i < items.length; i++) {
417
+ try {
418
+ // Get operation parameters
419
+ const message = this.getNodeParameter('message', i);
420
+ const recipientType = this.getNodeParameter('recipientType', i);
421
+ const timeout = this.getNodeParameter('timeout', i, 300); // Default 5 minutes
422
+ // Get required fields based on recipient type
423
+ let teamId;
424
+ let channelId;
425
+ let userId;
426
+ if (recipientType === 'channel') {
427
+ teamId = this.getNodeParameter('teamId', i);
428
+ channelId = this.getNodeParameter('channelId', i);
429
+ }
430
+ else if (recipientType === 'chat') {
431
+ userId = this.getNodeParameter('userId', i);
432
+ }
433
+ // Optional parameters for message formatting
434
+ const textFormat = this.getNodeParameter('textFormat', i, 'markdown');
435
+ const attachmentsJson = this.getNodeParameter('attachments', i, '');
436
+ // Parse attachments if provided
437
+ let attachments;
438
+ if (attachmentsJson) {
439
+ try {
440
+ attachments = JSON.parse(attachmentsJson);
441
+ }
442
+ catch (error) {
443
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid JSON in attachments parameter: ${error}`, { itemIndex: i });
444
+ }
445
+ }
446
+ // Prepare message options
447
+ const options = {
448
+ textFormat,
449
+ attachments,
450
+ };
451
+ // Send the message first
452
+ let response;
453
+ if (recipientType === 'channel') {
454
+ response = await api.sendChannelMessage(teamId, channelId, message, options);
455
+ }
456
+ else {
457
+ response = await api.sendMessage(userId, message, options);
458
+ }
459
+ // Store context for the send-and-wait operation
460
+ // Use 'global' scope so the trigger node can access it
461
+ const workflowStaticData = this.getWorkflowStaticData('global');
462
+ const conversation = response.conversation;
463
+ const waitContext = {
464
+ conversationId: (conversation === null || conversation === void 0 ? void 0 : conversation.id) || response.id,
465
+ originalMessageId: response.id,
466
+ timeout: Date.now() + (timeout * 1000),
467
+ recipientType,
468
+ teamId,
469
+ channelId,
470
+ userId,
471
+ };
472
+ // Store in workflow static data for the trigger to find
473
+ if (!workflowStaticData.waitingResponses) {
474
+ workflowStaticData.waitingResponses = {};
475
+ }
476
+ workflowStaticData.waitingResponses[response.id] = waitContext;
477
+ // Calculate wait till date (same as base implementation)
478
+ const waitTill = new Date(Date.now() + (timeout * 1000));
479
+ // Put execution to wait
480
+ await this.putExecutionToWait(waitTill);
481
+ // Return the sent message data
482
+ returnData.push({
483
+ json: (0, utils_1.ensureObjectResponse)(response),
484
+ pairedItem: { item: i },
485
+ });
486
+ }
487
+ catch (error) {
488
+ if (this.continueOnFail()) {
489
+ const errorMessage = error instanceof Error ? error.message : String(error);
490
+ returnData.push({
491
+ json: {
492
+ error: errorMessage,
493
+ },
494
+ pairedItem: { item: i },
495
+ });
496
+ continue;
497
+ }
498
+ throw error;
499
+ }
500
+ }
501
+ return [returnData];
502
+ },
503
+ /**
504
+ * Retrieves conversation history for context
505
+ */
506
+ async getHistory() {
507
+ var _a;
508
+ const items = this.getInputData();
509
+ const returnData = [];
510
+ const api = new index_1.TeamsApiClient(this);
511
+ await api.initialize();
512
+ for (let i = 0; i < items.length; i++) {
513
+ try {
514
+ // Get operation parameters
515
+ const recipientType = this.getNodeParameter('recipientType', i);
516
+ const count = this.getNodeParameter('count', i, 10);
517
+ const filter = this.getNodeParameter('filter', i, '');
518
+ let response;
519
+ if (recipientType === 'channel') {
520
+ const teamId = this.getNodeParameter('teamId', i);
521
+ const channelId = this.getNodeParameter('channelId', i);
522
+ response = await api.getChannelMessages(teamId, channelId, count, filter || undefined);
523
+ }
524
+ else {
525
+ const chatId = this.getNodeParameter('chatId', i);
526
+ response = await api.getChatMessages(chatId, count, filter || undefined);
527
+ }
528
+ // Format the response for easier consumption
529
+ const formattedResponse = {
530
+ messages: response.value || [],
531
+ totalCount: ((_a = response.value) === null || _a === void 0 ? void 0 : _a.length) || 0,
532
+ recipientType,
533
+ retrievedAt: new Date().toISOString(),
534
+ };
535
+ returnData.push({
536
+ json: formattedResponse,
537
+ pairedItem: { item: i },
538
+ });
539
+ }
540
+ catch (error) {
541
+ if (this.continueOnFail()) {
542
+ const errorMessage = error instanceof Error ? error.message : String(error);
543
+ returnData.push({
544
+ json: {
545
+ error: errorMessage,
546
+ messages: [],
547
+ totalCount: 0,
548
+ },
549
+ pairedItem: { item: i },
550
+ });
551
+ continue;
552
+ }
553
+ throw error;
554
+ }
555
+ }
556
+ return [returnData];
557
+ },
558
+ /**
559
+ * Gets a specific message by ID from a chat or channel
560
+ */
561
+ async get() {
562
+ const items = this.getInputData();
563
+ const returnData = [];
564
+ const api = new index_1.TeamsApiClient(this);
565
+ await api.initialize();
566
+ for (let i = 0; i < items.length; i++) {
567
+ try {
568
+ const recipientType = this.getNodeParameter('recipientType', i);
569
+ const messageId = this.getNodeParameter('messageId', i);
570
+ let response;
571
+ if (recipientType === 'channel') {
572
+ const teamId = this.getNodeParameter('teamId', i);
573
+ const channelId = this.getNodeParameter('channelId', i);
574
+ response = await api.getChannelMessage(teamId, channelId, messageId);
575
+ }
576
+ else {
577
+ const chatId = this.getNodeParameter('chatId', i);
578
+ response = await api.getChatMessage(chatId, messageId);
579
+ }
580
+ returnData.push({
581
+ json: response,
582
+ pairedItem: { item: i },
583
+ });
584
+ }
585
+ catch (error) {
586
+ if (this.continueOnFail()) {
587
+ const errorMessage = error instanceof Error ? error.message : String(error);
588
+ returnData.push({
589
+ json: {
590
+ error: errorMessage,
591
+ },
592
+ pairedItem: { item: i },
593
+ });
594
+ continue;
595
+ }
596
+ throw error;
597
+ }
598
+ }
599
+ return [returnData];
600
+ },
601
+ /**
602
+ * Gets all messages from a chat or channel with pagination support
603
+ */
604
+ async getAll() {
605
+ const items = this.getInputData();
606
+ const returnData = [];
607
+ const api = new index_1.TeamsApiClient(this);
608
+ await api.initialize();
609
+ for (let i = 0; i < items.length; i++) {
610
+ try {
611
+ const recipientType = this.getNodeParameter('recipientType', i);
612
+ const returnAll = this.getNodeParameter('returnAll', i, false);
613
+ let messages;
614
+ if (recipientType === 'channel') {
615
+ const teamId = this.getNodeParameter('teamId', i);
616
+ const channelId = this.getNodeParameter('channelId', i);
617
+ const limit = returnAll ? undefined : this.getNodeParameter('limit', i, 50);
618
+ messages = await api.getAllChannelMessages(teamId, channelId, returnAll, limit);
619
+ }
620
+ else {
621
+ const chatId = this.getNodeParameter('chatId', i);
622
+ const limit = returnAll ? undefined : this.getNodeParameter('limit', i, 50);
623
+ messages = await api.getAllChatMessages(chatId, returnAll, limit);
624
+ }
625
+ // Return messages as separate items
626
+ for (const message of messages) {
627
+ returnData.push({
628
+ json: message,
629
+ pairedItem: { item: i },
630
+ });
631
+ }
632
+ }
633
+ catch (error) {
634
+ if (this.continueOnFail()) {
635
+ const errorMessage = error instanceof Error ? error.message : String(error);
636
+ returnData.push({
637
+ json: {
638
+ error: errorMessage,
639
+ value: [],
640
+ },
641
+ pairedItem: { item: i },
642
+ });
643
+ continue;
644
+ }
645
+ throw error;
646
+ }
647
+ }
648
+ return [returnData];
649
+ },
650
+ /**
651
+ * Pins a message in a chat
652
+ */
653
+ async pin() {
654
+ const items = this.getInputData();
655
+ const returnData = [];
656
+ const api = new index_1.TeamsApiClient(this);
657
+ await api.initialize();
658
+ for (let i = 0; i < items.length; i++) {
659
+ try {
660
+ const chatId = this.getNodeParameter('chatId', i);
661
+ const messageId = this.getNodeParameter('messageId', i);
662
+ if (!chatId || !messageId) {
663
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Both chatId and messageId are required for pinning messages', { itemIndex: i });
664
+ }
665
+ const response = await api.pinChatMessage(chatId, messageId);
666
+ returnData.push({
667
+ json: (0, utils_1.ensureObjectResponse)(response),
668
+ pairedItem: { item: i },
669
+ });
670
+ }
671
+ catch (error) {
672
+ if (this.continueOnFail()) {
673
+ const errorMessage = error instanceof Error ? error.message : String(error);
674
+ returnData.push({
675
+ json: { error: errorMessage },
676
+ pairedItem: { item: i },
677
+ });
678
+ continue;
679
+ }
680
+ throw error;
681
+ }
682
+ }
683
+ return [returnData];
684
+ },
685
+ /**
686
+ * Unpins a message from a chat
687
+ */
688
+ async unpin() {
689
+ const items = this.getInputData();
690
+ const returnData = [];
691
+ const api = new index_1.TeamsApiClient(this);
692
+ await api.initialize();
693
+ for (let i = 0; i < items.length; i++) {
694
+ try {
695
+ const chatId = this.getNodeParameter('chatId', i);
696
+ const messageId = this.getNodeParameter('messageId', i);
697
+ if (!chatId || !messageId) {
698
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Both chatId and messageId are required for unpinning messages', { itemIndex: i });
699
+ }
700
+ await api.unpinChatMessage(chatId, messageId);
701
+ returnData.push({
702
+ json: {
703
+ success: true,
704
+ message: `Message ${messageId} unpinned from chat ${chatId}`,
705
+ },
706
+ pairedItem: { item: i },
707
+ });
708
+ }
709
+ catch (error) {
710
+ if (this.continueOnFail()) {
711
+ const errorMessage = error instanceof Error ? error.message : String(error);
712
+ returnData.push({
713
+ json: { error: errorMessage },
714
+ pairedItem: { item: i },
715
+ });
716
+ continue;
717
+ }
718
+ throw error;
719
+ }
720
+ }
721
+ return [returnData];
722
+ },
723
+ /**
724
+ * Gets all pinned messages in a chat
725
+ */
726
+ async getPinned() {
727
+ const items = this.getInputData();
728
+ const returnData = [];
729
+ const api = new index_1.TeamsApiClient(this);
730
+ await api.initialize();
731
+ for (let i = 0; i < items.length; i++) {
732
+ try {
733
+ const chatId = this.getNodeParameter('chatId', i);
734
+ if (!chatId) {
735
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'chatId is required for getting pinned messages', { itemIndex: i });
736
+ }
737
+ const response = await api.getPinnedChatMessages(chatId);
738
+ returnData.push({
739
+ json: (0, utils_1.ensureObjectResponse)(response),
740
+ pairedItem: { item: i },
741
+ });
742
+ }
743
+ catch (error) {
744
+ if (this.continueOnFail()) {
745
+ const errorMessage = error instanceof Error ? error.message : String(error);
746
+ returnData.push({
747
+ json: { error: errorMessage },
748
+ pairedItem: { item: i },
749
+ });
750
+ continue;
751
+ }
752
+ throw error;
753
+ }
754
+ }
755
+ return [returnData];
756
+ },
757
+ /**
758
+ * Pins a message in a channel (Note: This will throw an error as it's not supported)
759
+ */
760
+ async pinChannel() {
761
+ const items = this.getInputData();
762
+ const returnData = [];
763
+ const api = new index_1.TeamsApiClient(this);
764
+ await api.initialize();
765
+ for (let i = 0; i < items.length; i++) {
766
+ try {
767
+ const teamId = this.getNodeParameter('teamId', i);
768
+ const channelId = this.getNodeParameter('channelId', i);
769
+ const messageId = this.getNodeParameter('messageId', i);
770
+ if (!teamId || !channelId || !messageId) {
771
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'teamId, channelId, and messageId are required for pinning channel messages', { itemIndex: i });
772
+ }
773
+ // This will throw an error as channel pinning is not supported
774
+ const response = await api.pinChannelMessage(teamId, channelId, messageId);
775
+ returnData.push({
776
+ json: (0, utils_1.ensureObjectResponse)(response),
777
+ pairedItem: { item: i },
778
+ });
779
+ }
780
+ catch (error) {
781
+ if (this.continueOnFail()) {
782
+ const errorMessage = error instanceof Error ? error.message : String(error);
783
+ returnData.push({
784
+ json: { error: errorMessage },
785
+ pairedItem: { item: i },
786
+ });
787
+ continue;
788
+ }
789
+ throw error;
790
+ }
791
+ }
792
+ return [returnData];
793
+ },
794
+ /**
795
+ * Unpins a message from a channel (Note: This will throw an error as it's not supported)
796
+ */
797
+ async unpinChannel() {
798
+ const items = this.getInputData();
799
+ const returnData = [];
800
+ const api = new index_1.TeamsApiClient(this);
801
+ await api.initialize();
802
+ for (let i = 0; i < items.length; i++) {
803
+ try {
804
+ const teamId = this.getNodeParameter('teamId', i);
805
+ const channelId = this.getNodeParameter('channelId', i);
806
+ const messageId = this.getNodeParameter('messageId', i);
807
+ if (!teamId || !channelId || !messageId) {
808
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'teamId, channelId, and messageId are required for unpinning channel messages', { itemIndex: i });
809
+ }
810
+ // This will throw an error as channel unpinning is not supported
811
+ await api.unpinChannelMessage(teamId, channelId, messageId);
812
+ returnData.push({
813
+ json: {
814
+ success: true,
815
+ message: `Message ${messageId} unpinned from channel ${channelId}`,
816
+ },
817
+ pairedItem: { item: i },
818
+ });
819
+ }
820
+ catch (error) {
821
+ if (this.continueOnFail()) {
822
+ const errorMessage = error instanceof Error ? error.message : String(error);
823
+ returnData.push({
824
+ json: { error: errorMessage },
825
+ pairedItem: { item: i },
826
+ });
827
+ continue;
828
+ }
829
+ throw error;
830
+ }
831
+ }
832
+ return [returnData];
833
+ },
834
+ /**
835
+ * Analyze and process message reactions
836
+ */
837
+ async analyzeReactions() {
838
+ const items = this.getInputData();
839
+ const returnData = [];
840
+ const api = new index_1.TeamsApiClient(this);
841
+ await api.initialize();
842
+ for (let i = 0; i < items.length; i++) {
843
+ try {
844
+ const reactionData = this.getNodeParameter('reactionData', i);
845
+ let parsedReactions;
846
+ try {
847
+ parsedReactions = JSON.parse(reactionData);
848
+ }
849
+ catch (error) {
850
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid JSON in reaction data', { itemIndex: i });
851
+ }
852
+ // Analyze reaction patterns
853
+ const analysis = analyzeReactionPatterns(parsedReactions);
854
+ returnData.push({
855
+ json: {
856
+ reactionData: parsedReactions,
857
+ analysis,
858
+ timestamp: new Date().toISOString(),
859
+ },
860
+ pairedItem: { item: i },
861
+ });
862
+ }
863
+ catch (error) {
864
+ if (this.continueOnFail()) {
865
+ const errorMessage = error instanceof Error ? error.message : String(error);
866
+ returnData.push({
867
+ json: { error: errorMessage },
868
+ pairedItem: { item: i },
869
+ });
870
+ continue;
871
+ }
872
+ throw error;
873
+ }
874
+ }
875
+ return [returnData];
876
+ },
877
+ /**
878
+ * Get reaction analytics for a conversation
879
+ */
880
+ async getReactionAnalytics() {
881
+ const items = this.getInputData();
882
+ const returnData = [];
883
+ const api = new index_1.TeamsApiClient(this);
884
+ await api.initialize();
885
+ for (let i = 0; i < items.length; i++) {
886
+ try {
887
+ const conversationId = this.getNodeParameter('conversationId', i);
888
+ const timeRange = this.getNodeParameter('timeRange', i, 24); // hours
889
+ if (!conversationId) {
890
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Conversation ID is required', { itemIndex: i });
891
+ }
892
+ // Get message history to analyze reactions
893
+ const messageHistory = await api.getChatMessages(conversationId, 100);
894
+ // Analyze reactions across all messages
895
+ const analytics = generateReactionAnalytics(messageHistory.value || [], timeRange);
896
+ returnData.push({
897
+ json: {
898
+ conversationId,
899
+ analytics,
900
+ timeRangeHours: timeRange,
901
+ analyzedAt: new Date().toISOString(),
902
+ },
903
+ pairedItem: { item: i },
904
+ });
905
+ }
906
+ catch (error) {
907
+ if (this.continueOnFail()) {
908
+ const errorMessage = error instanceof Error ? error.message : String(error);
909
+ returnData.push({
910
+ json: { error: errorMessage },
911
+ pairedItem: { item: i },
912
+ });
913
+ continue;
914
+ }
915
+ throw error;
916
+ }
917
+ }
918
+ return [returnData];
919
+ },
920
+ /**
921
+ * Process and optimize file attachments
922
+ */
923
+ async processFile() {
924
+ var _a, _b;
925
+ const items = this.getInputData();
926
+ const returnData = [];
927
+ const api = new index_1.TeamsApiClient(this);
928
+ await api.initialize();
929
+ for (let i = 0; i < items.length; i++) {
930
+ try {
931
+ const fileData = this.getNodeParameter('fileData', i);
932
+ const fileName = this.getNodeParameter('fileName', i);
933
+ const contentType = this.getNodeParameter('contentType', i);
934
+ const enableOptimization = this.getNodeParameter('enableOptimization', i, true);
935
+ let fileContent;
936
+ let parsedAttachment;
937
+ try {
938
+ // Try to parse as JSON first (for structured attachment data)
939
+ parsedAttachment = JSON.parse(fileData);
940
+ // If it's a URL, we'll need to download it
941
+ if (parsedAttachment.contentUrl && !parsedAttachment.content) {
942
+ throw new Error('File content not available, would need download');
943
+ }
944
+ // Handle content field properly - it could be a string or object
945
+ const contentData = parsedAttachment.content;
946
+ let contentString = '';
947
+ if (typeof contentData === 'string') {
948
+ contentString = contentData;
949
+ }
950
+ else if (contentData && typeof contentData === 'object') {
951
+ contentString = contentData.data || '';
952
+ }
953
+ fileContent = Buffer.from(contentString, 'base64');
954
+ }
955
+ catch {
956
+ // Assume it's base64 encoded file content
957
+ fileContent = Buffer.from(fileData, 'base64');
958
+ parsedAttachment = {
959
+ name: fileName,
960
+ contentType,
961
+ content: { data: fileData },
962
+ size: fileContent.length,
963
+ };
964
+ }
965
+ // Validate file content
966
+ (0, fileProcessing_1.validateFileContent)(this.getNode(), fileContent, contentType, i);
967
+ // Extract file metadata
968
+ const metadata = await (0, fileProcessing_1.extractFileMetadata)(this.getNode(), fileContent, contentType, fileName, i);
969
+ let processingResult;
970
+ if (enableOptimization && contentType.startsWith('image/')) {
971
+ // Optimize image if enabled
972
+ processingResult = await (0, fileProcessing_1.optimizeImage)(this.getNode(), parsedAttachment, i);
973
+ }
974
+ else {
975
+ // Create basic processing result
976
+ processingResult = {
977
+ originalFile: {
978
+ name: fileName,
979
+ size: fileContent.length,
980
+ contentType,
981
+ },
982
+ status: constants_1.FileProcessingStatus.COMPLETE,
983
+ processingTime: 0,
984
+ };
985
+ }
986
+ (0, validation_1.validateFileProcessingResult)(this.getNode(), processingResult, i);
987
+ returnData.push({
988
+ json: {
989
+ fileName,
990
+ contentType,
991
+ originalSize: fileContent.length,
992
+ processedSize: ((_a = processingResult.processedFile) === null || _a === void 0 ? void 0 : _a.size) || fileContent.length,
993
+ metadata,
994
+ processingResult,
995
+ optimized: ((_b = processingResult.processedFile) === null || _b === void 0 ? void 0 : _b.optimized) || false,
996
+ processingTime: processingResult.processingTime,
997
+ },
998
+ pairedItem: { item: i },
999
+ });
1000
+ }
1001
+ catch (error) {
1002
+ if (this.continueOnFail()) {
1003
+ const errorMessage = error instanceof Error ? error.message : String(error);
1004
+ returnData.push({
1005
+ json: { error: errorMessage },
1006
+ pairedItem: { item: i },
1007
+ });
1008
+ continue;
1009
+ }
1010
+ throw error;
1011
+ }
1012
+ }
1013
+ return [returnData];
1014
+ },
1015
+ /**
1016
+ * Generate thumbnail for image attachments
1017
+ */
1018
+ async generateThumbnail() {
1019
+ var _a;
1020
+ const items = this.getInputData();
1021
+ const returnData = [];
1022
+ const api = new index_1.TeamsApiClient(this);
1023
+ await api.initialize();
1024
+ for (let i = 0; i < items.length; i++) {
1025
+ try {
1026
+ const imageData = this.getNodeParameter('imageData', i);
1027
+ const maxWidth = this.getNodeParameter('maxWidth', i, 200);
1028
+ const maxHeight = this.getNodeParameter('maxHeight', i, 200);
1029
+ let imageAttachment;
1030
+ try {
1031
+ imageAttachment = JSON.parse(imageData);
1032
+ }
1033
+ catch {
1034
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid image data format', { itemIndex: i });
1035
+ }
1036
+ // Validate that it's an image
1037
+ if (!((_a = imageAttachment.contentType) === null || _a === void 0 ? void 0 : _a.startsWith('image/'))) {
1038
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Thumbnail generation requires image content', { itemIndex: i });
1039
+ }
1040
+ // Generate thumbnail
1041
+ const thumbnailUrl = await (0, fileProcessing_1.generateThumbnail)(this.getNode(), imageAttachment, maxWidth, maxHeight, i);
1042
+ returnData.push({
1043
+ json: {
1044
+ originalImage: {
1045
+ name: imageAttachment.name,
1046
+ contentType: imageAttachment.contentType,
1047
+ size: imageAttachment.size,
1048
+ },
1049
+ thumbnail: {
1050
+ url: thumbnailUrl,
1051
+ maxWidth,
1052
+ maxHeight,
1053
+ },
1054
+ generated: true,
1055
+ },
1056
+ pairedItem: { item: i },
1057
+ });
1058
+ }
1059
+ catch (error) {
1060
+ if (this.continueOnFail()) {
1061
+ const errorMessage = error instanceof Error ? error.message : String(error);
1062
+ returnData.push({
1063
+ json: { error: errorMessage },
1064
+ pairedItem: { item: i },
1065
+ });
1066
+ continue;
1067
+ }
1068
+ throw error;
1069
+ }
1070
+ }
1071
+ return [returnData];
1072
+ },
1073
+ /**
1074
+ * Send message with file attachment (enhanced reply functionality)
1075
+ */
1076
+ async sendWithAttachment() {
1077
+ var _a;
1078
+ const items = this.getInputData();
1079
+ const returnData = [];
1080
+ const api = new index_1.TeamsApiClient(this);
1081
+ await api.initialize();
1082
+ for (let i = 0; i < items.length; i++) {
1083
+ try {
1084
+ const message = this.getNodeParameter('message', i);
1085
+ const recipientType = this.getNodeParameter('recipientType', i);
1086
+ const attachmentData = this.getNodeParameter('attachmentData', i);
1087
+ const enableProcessing = this.getNodeParameter('enableProcessing', i, true);
1088
+ let teamId;
1089
+ let channelId;
1090
+ let userId;
1091
+ if (recipientType === 'channel') {
1092
+ teamId = this.getNodeParameter('teamId', i);
1093
+ channelId = this.getNodeParameter('channelId', i);
1094
+ }
1095
+ else if (recipientType === 'chat') {
1096
+ userId = this.getNodeParameter('userId', i);
1097
+ }
1098
+ let attachment;
1099
+ try {
1100
+ attachment = JSON.parse(attachmentData);
1101
+ }
1102
+ catch {
1103
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid attachment data format', { itemIndex: i });
1104
+ }
1105
+ // Validate attachment
1106
+ await (0, validation_1.validateAttachment)(this.getNode(), attachment, i);
1107
+ // Process attachment if enabled
1108
+ if (enableProcessing && ((_a = attachment.contentType) === null || _a === void 0 ? void 0 : _a.startsWith('image/'))) {
1109
+ const processingResult = await (0, fileProcessing_1.optimizeImage)(this.getNode(), attachment, i);
1110
+ if (processingResult.processedFile) {
1111
+ attachment = {
1112
+ ...attachment,
1113
+ ...processingResult.processedFile,
1114
+ };
1115
+ }
1116
+ }
1117
+ const options = {
1118
+ attachments: [attachment],
1119
+ textFormat: 'markdown',
1120
+ };
1121
+ let response;
1122
+ if (recipientType === 'channel') {
1123
+ response = await api.sendChannelMessage(teamId, channelId, message, options);
1124
+ }
1125
+ else {
1126
+ response = await api.sendMessage(userId, message, options);
1127
+ }
1128
+ returnData.push({
1129
+ json: (0, utils_1.ensureObjectResponse)(response),
1130
+ pairedItem: { item: i },
1131
+ });
1132
+ }
1133
+ catch (error) {
1134
+ if (this.continueOnFail()) {
1135
+ const errorMessage = error instanceof Error ? error.message : String(error);
1136
+ returnData.push({
1137
+ json: { error: errorMessage },
1138
+ pairedItem: { item: i },
1139
+ });
1140
+ continue;
1141
+ }
1142
+ throw error;
1143
+ }
1144
+ }
1145
+ return [returnData];
1146
+ },
1147
+ /**
1148
+ * Reply to message with file attachment
1149
+ */
1150
+ async replyWithAttachment() {
1151
+ var _a;
1152
+ const items = this.getInputData();
1153
+ const returnData = [];
1154
+ const api = new index_1.TeamsApiClient(this);
1155
+ await api.initialize();
1156
+ for (let i = 0; i < items.length; i++) {
1157
+ try {
1158
+ const conversationId = this.getNodeParameter('conversationId', i);
1159
+ const activityId = this.getNodeParameter('activityId', i);
1160
+ const message = this.getNodeParameter('message', i);
1161
+ const attachmentData = this.getNodeParameter('attachmentData', i);
1162
+ const enableProcessing = this.getNodeParameter('enableProcessing', i, true);
1163
+ let attachment;
1164
+ try {
1165
+ attachment = JSON.parse(attachmentData);
1166
+ }
1167
+ catch {
1168
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid attachment data format', { itemIndex: i });
1169
+ }
1170
+ // Validate attachment
1171
+ await (0, validation_1.validateAttachment)(this.getNode(), attachment, i);
1172
+ // Process attachment if enabled
1173
+ if (enableProcessing && ((_a = attachment.contentType) === null || _a === void 0 ? void 0 : _a.startsWith('image/'))) {
1174
+ const processingResult = await (0, fileProcessing_1.optimizeImage)(this.getNode(), attachment, i);
1175
+ if (processingResult.processedFile) {
1176
+ attachment = {
1177
+ ...attachment,
1178
+ ...processingResult.processedFile,
1179
+ };
1180
+ }
1181
+ }
1182
+ const options = {
1183
+ attachments: [attachment],
1184
+ textFormat: 'markdown',
1185
+ };
1186
+ const response = await api.replyToMessage(conversationId, activityId, message, options);
1187
+ returnData.push({
1188
+ json: (0, utils_1.ensureObjectResponse)(response),
1189
+ pairedItem: { item: i },
1190
+ });
1191
+ }
1192
+ catch (error) {
1193
+ if (this.continueOnFail()) {
1194
+ const errorMessage = error instanceof Error ? error.message : String(error);
1195
+ returnData.push({
1196
+ json: { error: errorMessage },
1197
+ pairedItem: { item: i },
1198
+ });
1199
+ continue;
1200
+ }
1201
+ throw error;
1202
+ }
1203
+ }
1204
+ return [returnData];
1205
+ },
1206
+ /**
1207
+ * Monitor upload progress
1208
+ */
1209
+ async monitorUpload() {
1210
+ const items = this.getInputData();
1211
+ const returnData = [];
1212
+ const api = new index_1.TeamsApiClient(this);
1213
+ await api.initialize();
1214
+ for (let i = 0; i < items.length; i++) {
1215
+ try {
1216
+ const fileName = this.getNodeParameter('fileName', i);
1217
+ const fileSize = this.getNodeParameter('fileSize', i);
1218
+ const bytesUploaded = this.getNodeParameter('bytesUploaded', i, 0);
1219
+ const uploadSpeed = this.getNodeParameter('uploadSpeed', i, 0);
1220
+ // Create or update upload progress
1221
+ let progress;
1222
+ if (bytesUploaded === 0) {
1223
+ progress = (0, fileProcessing_1.createUploadProgress)(fileName, fileSize);
1224
+ }
1225
+ else {
1226
+ progress = (0, fileProcessing_1.createUploadProgress)(fileName, fileSize);
1227
+ progress = (0, fileProcessing_1.updateUploadProgress)(progress, bytesUploaded, uploadSpeed);
1228
+ }
1229
+ (0, validation_1.validateUploadProgress)(this.getNode(), progress, i);
1230
+ returnData.push({
1231
+ json: {
1232
+ fileName: progress.fileName,
1233
+ fileSize: progress.fileSize,
1234
+ bytesUploaded: progress.bytesUploaded,
1235
+ percentage: Math.round(progress.percentage * 100) / 100,
1236
+ status: progress.status,
1237
+ startTime: progress.startTime.toISOString(),
1238
+ estimatedTimeRemaining: progress.estimatedTimeRemaining,
1239
+ timeElapsed: Date.now() - progress.startTime.getTime(),
1240
+ },
1241
+ pairedItem: { item: i },
1242
+ });
1243
+ }
1244
+ catch (error) {
1245
+ if (this.continueOnFail()) {
1246
+ const errorMessage = error instanceof Error ? error.message : String(error);
1247
+ returnData.push({
1248
+ json: { error: errorMessage },
1249
+ pairedItem: { item: i },
1250
+ });
1251
+ continue;
1252
+ }
1253
+ throw error;
1254
+ }
1255
+ }
1256
+ return [returnData];
1257
+ },
1258
+ };
1259
+ //# sourceMappingURL=messages.js.map