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.
- package/dist/credentials/TeamsBotApi.credentials.d.ts +7 -0
- package/dist/credentials/TeamsBotApi.credentials.js +107 -0
- package/dist/credentials/TeamsBotApi.credentials.js.map +1 -0
- package/dist/credentials/TeamsGraphApi.credentials.d.ts +7 -0
- package/dist/credentials/TeamsGraphApi.credentials.js +58 -0
- package/dist/credentials/TeamsGraphApi.credentials.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/nodes/TeamsBot/TeamsBot.node.d.ts +21 -0
- package/dist/nodes/TeamsBot/TeamsBot.node.js +457 -0
- package/dist/nodes/TeamsBot/TeamsBot.node.js.map +1 -0
- package/dist/nodes/TeamsBot/TeamsBot.node.json +73 -0
- package/dist/nodes/TeamsBot/TeamsBotTrigger.node.d.ts +21 -0
- package/dist/nodes/TeamsBot/TeamsBotTrigger.node.js +506 -0
- package/dist/nodes/TeamsBot/TeamsBotTrigger.node.js.map +1 -0
- package/dist/nodes/TeamsBot/TeamsBotTrigger.node.json +57 -0
- package/dist/nodes/TeamsBot/actions/buildCard.d.ts +6 -0
- package/dist/nodes/TeamsBot/actions/buildCard.js +176 -0
- package/dist/nodes/TeamsBot/actions/buildCard.js.map +1 -0
- package/dist/nodes/TeamsBot/actions/cards.d.ts +34 -0
- package/dist/nodes/TeamsBot/actions/cards.js +731 -0
- package/dist/nodes/TeamsBot/actions/cards.js.map +1 -0
- package/dist/nodes/TeamsBot/actions/channels.d.ts +18 -0
- package/dist/nodes/TeamsBot/actions/channels.js +199 -0
- package/dist/nodes/TeamsBot/actions/channels.js.map +1 -0
- package/dist/nodes/TeamsBot/actions/messages.d.ts +86 -0
- package/dist/nodes/TeamsBot/actions/messages.js +1259 -0
- package/dist/nodes/TeamsBot/actions/messages.js.map +1 -0
- package/dist/nodes/TeamsBot/actions/router.d.ts +2 -0
- package/dist/nodes/TeamsBot/actions/router.js +186 -0
- package/dist/nodes/TeamsBot/actions/router.js.map +1 -0
- package/dist/nodes/TeamsBot/actions/teams.d.ts +18 -0
- package/dist/nodes/TeamsBot/actions/teams.js +227 -0
- package/dist/nodes/TeamsBot/actions/teams.js.map +1 -0
- package/dist/nodes/TeamsBot/actions/users.d.ts +13 -0
- package/dist/nodes/TeamsBot/actions/users.js +184 -0
- package/dist/nodes/TeamsBot/actions/users.js.map +1 -0
- package/dist/nodes/TeamsBot/descriptions/buildCard.description.d.ts +7 -0
- package/dist/nodes/TeamsBot/descriptions/buildCard.description.js +682 -0
- package/dist/nodes/TeamsBot/descriptions/buildCard.description.js.map +1 -0
- package/dist/nodes/TeamsBot/descriptions/card.description.d.ts +2 -0
- package/dist/nodes/TeamsBot/descriptions/card.description.js +564 -0
- package/dist/nodes/TeamsBot/descriptions/card.description.js.map +1 -0
- package/dist/nodes/TeamsBot/descriptions/index.d.ts +3 -0
- package/dist/nodes/TeamsBot/descriptions/index.js +20 -0
- package/dist/nodes/TeamsBot/descriptions/index.js.map +1 -0
- package/dist/nodes/TeamsBot/descriptions/message.description.d.ts +2 -0
- package/dist/nodes/TeamsBot/descriptions/message.description.js +964 -0
- package/dist/nodes/TeamsBot/descriptions/message.description.js.map +1 -0
- package/dist/nodes/TeamsBot/descriptions/node.description.d.ts +2 -0
- package/dist/nodes/TeamsBot/descriptions/node.description.js +567 -0
- package/dist/nodes/TeamsBot/descriptions/node.description.js.map +1 -0
- package/dist/nodes/TeamsBot/errors/authentication.d.ts +100 -0
- package/dist/nodes/TeamsBot/errors/authentication.js +110 -0
- package/dist/nodes/TeamsBot/errors/authentication.js.map +1 -0
- package/dist/nodes/TeamsBot/errors/graphApi.d.ts +44 -0
- package/dist/nodes/TeamsBot/errors/graphApi.js +84 -0
- package/dist/nodes/TeamsBot/errors/graphApi.js.map +1 -0
- package/dist/nodes/TeamsBot/errors/messages.d.ts +187 -0
- package/dist/nodes/TeamsBot/errors/messages.js +190 -0
- package/dist/nodes/TeamsBot/errors/messages.js.map +1 -0
- package/dist/nodes/TeamsBot/methods/listSearch.d.ts +4 -0
- package/dist/nodes/TeamsBot/methods/listSearch.js +78 -0
- package/dist/nodes/TeamsBot/methods/listSearch.js.map +1 -0
- package/dist/nodes/TeamsBot/teams.svg +11 -0
- package/dist/nodes/TeamsBot/transport/TeamsApiClient.d.ts +305 -0
- package/dist/nodes/TeamsBot/transport/TeamsApiClient.js +458 -0
- package/dist/nodes/TeamsBot/transport/TeamsApiClient.js.map +1 -0
- package/dist/nodes/TeamsBot/transport/api/BotFrameworkApi.d.ts +350 -0
- package/dist/nodes/TeamsBot/transport/api/BotFrameworkApi.js +1265 -0
- package/dist/nodes/TeamsBot/transport/api/BotFrameworkApi.js.map +1 -0
- package/dist/nodes/TeamsBot/transport/api/GraphApi.d.ts +158 -0
- package/dist/nodes/TeamsBot/transport/api/GraphApi.js +443 -0
- package/dist/nodes/TeamsBot/transport/api/GraphApi.js.map +1 -0
- package/dist/nodes/TeamsBot/transport/api/GraphApiClient.d.ts +160 -0
- package/dist/nodes/TeamsBot/transport/api/GraphApiClient.js +268 -0
- package/dist/nodes/TeamsBot/transport/api/GraphApiClient.js.map +1 -0
- package/dist/nodes/TeamsBot/transport/api/index.d.ts +7 -0
- package/dist/nodes/TeamsBot/transport/api/index.js +26 -0
- package/dist/nodes/TeamsBot/transport/api/index.js.map +1 -0
- package/dist/nodes/TeamsBot/transport/index.d.ts +12 -0
- package/dist/nodes/TeamsBot/transport/index.js +30 -0
- package/dist/nodes/TeamsBot/transport/index.js.map +1 -0
- package/dist/nodes/TeamsBot/types/api-types.d.ts +258 -0
- package/dist/nodes/TeamsBot/types/api-types.js +3 -0
- package/dist/nodes/TeamsBot/types/api-types.js.map +1 -0
- package/dist/nodes/TeamsBot/types/cards.d.ts +252 -0
- package/dist/nodes/TeamsBot/types/cards.js +3 -0
- package/dist/nodes/TeamsBot/types/cards.js.map +1 -0
- package/dist/nodes/TeamsBot/types/index.d.ts +5 -0
- package/dist/nodes/TeamsBot/types/index.js +24 -0
- package/dist/nodes/TeamsBot/types/index.js.map +1 -0
- package/dist/nodes/TeamsBot/utils/AdaptiveCardBuilder.d.ts +147 -0
- package/dist/nodes/TeamsBot/utils/AdaptiveCardBuilder.js +333 -0
- package/dist/nodes/TeamsBot/utils/AdaptiveCardBuilder.js.map +1 -0
- package/dist/nodes/TeamsBot/utils/AdaptiveCardTemplates.d.ts +122 -0
- package/dist/nodes/TeamsBot/utils/AdaptiveCardTemplates.js +467 -0
- package/dist/nodes/TeamsBot/utils/AdaptiveCardTemplates.js.map +1 -0
- package/dist/nodes/TeamsBot/utils/CardTemplates.d.ts +94 -0
- package/dist/nodes/TeamsBot/utils/CardTemplates.js +446 -0
- package/dist/nodes/TeamsBot/utils/CardTemplates.js.map +1 -0
- package/dist/nodes/TeamsBot/utils/apiHelpers.d.ts +30 -0
- package/dist/nodes/TeamsBot/utils/apiHelpers.js +95 -0
- package/dist/nodes/TeamsBot/utils/apiHelpers.js.map +1 -0
- package/dist/nodes/TeamsBot/utils/constants.d.ts +86 -0
- package/dist/nodes/TeamsBot/utils/constants.js +60 -0
- package/dist/nodes/TeamsBot/utils/constants.js.map +1 -0
- package/dist/nodes/TeamsBot/utils/fileProcessing.d.ts +66 -0
- package/dist/nodes/TeamsBot/utils/fileProcessing.js +276 -0
- package/dist/nodes/TeamsBot/utils/fileProcessing.js.map +1 -0
- package/dist/nodes/TeamsBot/utils/graphNotificationParser.d.ts +91 -0
- package/dist/nodes/TeamsBot/utils/graphNotificationParser.js +162 -0
- package/dist/nodes/TeamsBot/utils/graphNotificationParser.js.map +1 -0
- package/dist/nodes/TeamsBot/utils/index.d.ts +24 -0
- package/dist/nodes/TeamsBot/utils/index.js +90 -0
- package/dist/nodes/TeamsBot/utils/index.js.map +1 -0
- package/dist/nodes/TeamsBot/utils/installation.d.ts +15 -0
- package/dist/nodes/TeamsBot/utils/installation.js +41 -0
- package/dist/nodes/TeamsBot/utils/installation.js.map +1 -0
- package/dist/nodes/TeamsBot/utils/subscriptionManager.d.ts +63 -0
- package/dist/nodes/TeamsBot/utils/subscriptionManager.js +100 -0
- package/dist/nodes/TeamsBot/utils/subscriptionManager.js.map +1 -0
- package/dist/nodes/TeamsBot/utils/validation.d.ts +93 -0
- package/dist/nodes/TeamsBot/utils/validation.js +281 -0
- package/dist/nodes/TeamsBot/utils/validation.js.map +1 -0
- package/package.json +79 -0
|
@@ -0,0 +1,731 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.cardOperations = void 0;
|
|
27
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
28
|
+
const index_1 = require("../transport/index");
|
|
29
|
+
const utils_1 = require("../utils");
|
|
30
|
+
const ACData = __importStar(require("adaptivecards-templating"));
|
|
31
|
+
/**
|
|
32
|
+
* Validates card operation parameters and card JSON format
|
|
33
|
+
* @param {CardOperationParams} params - Parameters to validate
|
|
34
|
+
* @param {string[]} requiredFields - List of required parameter fields
|
|
35
|
+
* @param {IExecuteFunctions} executeFunctions - n8n execution functions
|
|
36
|
+
* @param {number} itemIndex - Index of the current item being processed
|
|
37
|
+
* @throws {NodeOperationError} When validation fails
|
|
38
|
+
*/
|
|
39
|
+
function validateCardParams(params, requiredFields, executeFunctions, itemIndex) {
|
|
40
|
+
// Validate required fields
|
|
41
|
+
for (const field of requiredFields) {
|
|
42
|
+
if (!params[field]) {
|
|
43
|
+
throw new n8n_workflow_1.NodeOperationError(executeFunctions.getNode(), `Required parameter "${field}" is missing`, { itemIndex });
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Validate recipient type and related fields
|
|
47
|
+
if (params.recipientType === 'channel') {
|
|
48
|
+
if (!params.teamId) {
|
|
49
|
+
throw new n8n_workflow_1.NodeOperationError(executeFunctions.getNode(), 'Required parameter "teamId" is missing for channel messages', { itemIndex });
|
|
50
|
+
}
|
|
51
|
+
if (!params.channelId) {
|
|
52
|
+
throw new n8n_workflow_1.NodeOperationError(executeFunctions.getNode(), 'Required parameter "channelId" is missing for channel messages', { itemIndex });
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else if (params.recipientType === 'chat') {
|
|
56
|
+
if (!params.userId) {
|
|
57
|
+
throw new n8n_workflow_1.NodeOperationError(executeFunctions.getNode(), 'Required parameter "userId" is missing for chat messages', { itemIndex });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
throw new n8n_workflow_1.NodeOperationError(executeFunctions.getNode(), `Invalid recipient type: ${params.recipientType}`, { itemIndex });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Parses JSON card string into an object
|
|
66
|
+
* @param {string} card - JSON string of the card
|
|
67
|
+
* @param {IExecuteFunctions} executeFunctions - n8n execution functions
|
|
68
|
+
* @param {number} itemIndex - Index of the current item being processed
|
|
69
|
+
* @returns {AdaptiveCard} Parsed card object
|
|
70
|
+
* @throws {NodeOperationError} When card parsing fails
|
|
71
|
+
*/
|
|
72
|
+
function parseCard(card, executeFunctions, itemIndex) {
|
|
73
|
+
try {
|
|
74
|
+
return typeof card === 'string' ? JSON.parse(card) : card;
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
throw new n8n_workflow_1.NodeOperationError(executeFunctions.getNode(), `Invalid card format: ${error.message}`, { itemIndex });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Validates adaptive card structure with enhanced checks
|
|
82
|
+
* @param {AdaptiveCard} card - Card object to validate
|
|
83
|
+
* @param {IExecuteFunctions} executeFunctions - n8n execution functions
|
|
84
|
+
* @param {number} itemIndex - Index of the current item being processed
|
|
85
|
+
* @throws {NodeOperationError} When card validation fails
|
|
86
|
+
*/
|
|
87
|
+
function validateCard(card, executeFunctions, itemIndex) {
|
|
88
|
+
try {
|
|
89
|
+
// Basic structure validation
|
|
90
|
+
if (!card.type || card.type !== 'AdaptiveCard') {
|
|
91
|
+
throw new Error('Card must have a valid type "AdaptiveCard"');
|
|
92
|
+
}
|
|
93
|
+
if (!card.version) {
|
|
94
|
+
throw new Error('Card must have a version property');
|
|
95
|
+
}
|
|
96
|
+
// Schema is required but might be missing in user-provided cards
|
|
97
|
+
if (!card.$schema) {
|
|
98
|
+
// Add it automatically rather than throwing an error
|
|
99
|
+
card.$schema = 'http://adaptivecards.io/schemas/adaptive-card.json';
|
|
100
|
+
}
|
|
101
|
+
// Check for body property
|
|
102
|
+
if (!card.body || !Array.isArray(card.body)) {
|
|
103
|
+
throw new Error('Card must have a body array');
|
|
104
|
+
}
|
|
105
|
+
// Enhanced validations
|
|
106
|
+
// Check schema version
|
|
107
|
+
const version = card.version;
|
|
108
|
+
// Validate card body components
|
|
109
|
+
validateCardComponents(card.body);
|
|
110
|
+
// Validate actions if present
|
|
111
|
+
if (card.actions && Array.isArray(card.actions)) {
|
|
112
|
+
validateCardActions(card.actions);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
throw new n8n_workflow_1.NodeOperationError(executeFunctions.getNode(), `Invalid card: ${error.message}`, { itemIndex });
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Validates card body components
|
|
121
|
+
* @param {unknown[]} components - Array of card components to validate
|
|
122
|
+
* @throws {Error} When validation fails
|
|
123
|
+
*/
|
|
124
|
+
function validateCardComponents(components) {
|
|
125
|
+
for (let i = 0; i < components.length; i++) {
|
|
126
|
+
const component = components[i];
|
|
127
|
+
// All components must have a type
|
|
128
|
+
if (!component.type) {
|
|
129
|
+
throw new Error(`Component at index ${i} is missing required 'type' property`);
|
|
130
|
+
}
|
|
131
|
+
// Validate specific component types
|
|
132
|
+
switch (component.type) {
|
|
133
|
+
case 'TextBlock':
|
|
134
|
+
if (component.text === undefined) {
|
|
135
|
+
throw new Error(`TextBlock at index ${i} is missing required 'text' property`);
|
|
136
|
+
}
|
|
137
|
+
break;
|
|
138
|
+
case 'Image':
|
|
139
|
+
if (!component.url) {
|
|
140
|
+
throw new Error(`Image at index ${i} is missing required 'url' property`);
|
|
141
|
+
}
|
|
142
|
+
break;
|
|
143
|
+
case 'Container':
|
|
144
|
+
if (!component.items || !Array.isArray(component.items)) {
|
|
145
|
+
throw new Error(`Container at index ${i} must have an 'items' array`);
|
|
146
|
+
}
|
|
147
|
+
validateCardComponents(component.items);
|
|
148
|
+
break;
|
|
149
|
+
case 'ColumnSet':
|
|
150
|
+
if (!component.columns || !Array.isArray(component.columns)) {
|
|
151
|
+
throw new Error(`ColumnSet at index ${i} must have a 'columns' array`);
|
|
152
|
+
}
|
|
153
|
+
// Validate each column in the column set
|
|
154
|
+
for (let j = 0; j < component.columns.length; j++) {
|
|
155
|
+
const column = component.columns[j];
|
|
156
|
+
if (!column.items || !Array.isArray(column.items)) {
|
|
157
|
+
throw new Error(`Column at index ${j} in ColumnSet ${i} must have an 'items' array`);
|
|
158
|
+
}
|
|
159
|
+
validateCardComponents(column.items);
|
|
160
|
+
}
|
|
161
|
+
break;
|
|
162
|
+
case 'FactSet':
|
|
163
|
+
if (!component.facts || !Array.isArray(component.facts)) {
|
|
164
|
+
throw new Error(`FactSet at index ${i} must have a 'facts' array`);
|
|
165
|
+
}
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Validates card actions
|
|
172
|
+
* @param {unknown[]} actions - Array of card actions to validate
|
|
173
|
+
* @throws {Error} When validation fails
|
|
174
|
+
*/
|
|
175
|
+
function validateCardActions(actions) {
|
|
176
|
+
for (let i = 0; i < actions.length; i++) {
|
|
177
|
+
const action = actions[i];
|
|
178
|
+
// All actions must have a type
|
|
179
|
+
if (!action.type) {
|
|
180
|
+
throw new Error(`Action at index ${i} is missing required 'type' property`);
|
|
181
|
+
}
|
|
182
|
+
// Validate specific action types
|
|
183
|
+
switch (action.type) {
|
|
184
|
+
case 'Action.OpenUrl':
|
|
185
|
+
if (!action.url) {
|
|
186
|
+
throw new Error(`Action.OpenUrl at index ${i} is missing required 'url' property`);
|
|
187
|
+
}
|
|
188
|
+
if (!action.title) {
|
|
189
|
+
throw new Error(`Action.OpenUrl at index ${i} is missing required 'title' property`);
|
|
190
|
+
}
|
|
191
|
+
break;
|
|
192
|
+
case 'Action.Submit':
|
|
193
|
+
if (!action.title) {
|
|
194
|
+
throw new Error(`Action.Submit at index ${i} is missing required 'title' property`);
|
|
195
|
+
}
|
|
196
|
+
break;
|
|
197
|
+
case 'Action.ShowCard':
|
|
198
|
+
if (!action.title) {
|
|
199
|
+
throw new Error(`Action.ShowCard at index ${i} is missing required 'title' property`);
|
|
200
|
+
}
|
|
201
|
+
if (!action.card) {
|
|
202
|
+
throw new Error(`Action.ShowCard at index ${i} is missing required 'card' property`);
|
|
203
|
+
}
|
|
204
|
+
// Validate the nested card (but not recursively to avoid potential infinite loops)
|
|
205
|
+
{
|
|
206
|
+
const nestedCard = action.card;
|
|
207
|
+
if (!nestedCard.type || nestedCard.type !== 'AdaptiveCard') {
|
|
208
|
+
throw new Error(`Nested card in Action.ShowCard at index ${i} must have a valid type "AdaptiveCard"`);
|
|
209
|
+
}
|
|
210
|
+
if (!nestedCard.body || !Array.isArray(nestedCard.body)) {
|
|
211
|
+
throw new Error(`Nested card in Action.ShowCard at index ${i} must have a body array`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Card operations for the Teams Bot node
|
|
220
|
+
*/
|
|
221
|
+
exports.cardOperations = {
|
|
222
|
+
/**
|
|
223
|
+
* Sends an adaptive card to a channel or chat
|
|
224
|
+
* @returns {Promise<INodeExecutionData[][]>} Promise resolving to output data
|
|
225
|
+
*/
|
|
226
|
+
async send() {
|
|
227
|
+
const items = this.getInputData();
|
|
228
|
+
const returnData = [];
|
|
229
|
+
const api = new index_1.TeamsApiClient(this);
|
|
230
|
+
await api.initialize();
|
|
231
|
+
for (let i = 0; i < items.length; i++) {
|
|
232
|
+
try {
|
|
233
|
+
// Get operation parameters
|
|
234
|
+
const cardJson = this.getNodeParameter('card', i);
|
|
235
|
+
const recipientType = this.getNodeParameter('recipientType', i);
|
|
236
|
+
// Get options
|
|
237
|
+
const options = this.getNodeParameter('options', i, {});
|
|
238
|
+
// Get recipient-specific parameters
|
|
239
|
+
let teamId;
|
|
240
|
+
let channelId;
|
|
241
|
+
let userId;
|
|
242
|
+
if (recipientType === 'channel') {
|
|
243
|
+
teamId = this.getNodeParameter('teamId', i);
|
|
244
|
+
channelId = this.getNodeParameter('channelId', i);
|
|
245
|
+
}
|
|
246
|
+
else if (recipientType === 'chat') {
|
|
247
|
+
userId = this.getNodeParameter('userId', i);
|
|
248
|
+
}
|
|
249
|
+
// Prepare parameters for validation
|
|
250
|
+
const params = {
|
|
251
|
+
card: cardJson,
|
|
252
|
+
recipientType,
|
|
253
|
+
teamId,
|
|
254
|
+
channelId,
|
|
255
|
+
userId,
|
|
256
|
+
};
|
|
257
|
+
// Validate parameters
|
|
258
|
+
validateCardParams(params, ['card', 'recipientType'], this, i);
|
|
259
|
+
// Parse and validate card
|
|
260
|
+
const parsedCard = parseCard(cardJson, this, i);
|
|
261
|
+
validateCard(parsedCard, this, i);
|
|
262
|
+
// Convert to JSON string
|
|
263
|
+
const cardString = JSON.stringify(parsedCard);
|
|
264
|
+
// Send card based on recipient type
|
|
265
|
+
let response;
|
|
266
|
+
if (recipientType === 'channel') {
|
|
267
|
+
// Always handle auto-installation for channel
|
|
268
|
+
await (0, index_1.handleAutoInstall)(api, teamId, i, this);
|
|
269
|
+
// Send card to channel
|
|
270
|
+
response = await api.sendAdaptiveCardToChannel(teamId, channelId, cardString);
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
// Always handle auto-installation for user
|
|
274
|
+
await (0, index_1.handleAutoInstall)(api, userId, i, this);
|
|
275
|
+
// Use the BotFrameworkApi directly to send the card in one operation
|
|
276
|
+
// This prevents sending an empty message followed by a card
|
|
277
|
+
response = await api.sendAdaptiveCardToUser(userId, cardString);
|
|
278
|
+
// Ensure we got a proper object response
|
|
279
|
+
response = (0, utils_1.ensureObjectResponse)(response);
|
|
280
|
+
}
|
|
281
|
+
// Ensure response is properly parsed before returning
|
|
282
|
+
returnData.push({
|
|
283
|
+
json: response,
|
|
284
|
+
pairedItem: { item: i },
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
catch (error) {
|
|
288
|
+
if (this.continueOnFail()) {
|
|
289
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
290
|
+
returnData.push({
|
|
291
|
+
json: {
|
|
292
|
+
error: errorMessage,
|
|
293
|
+
},
|
|
294
|
+
pairedItem: { item: i },
|
|
295
|
+
});
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
throw error;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return [returnData];
|
|
302
|
+
},
|
|
303
|
+
/**
|
|
304
|
+
* Sends a notification card to a channel or chat
|
|
305
|
+
* @returns {Promise<INodeExecutionData[][]>} Promise resolving to output data
|
|
306
|
+
*/
|
|
307
|
+
async sendNotification() {
|
|
308
|
+
const items = this.getInputData();
|
|
309
|
+
const returnData = [];
|
|
310
|
+
const api = new index_1.TeamsApiClient(this);
|
|
311
|
+
await api.initialize();
|
|
312
|
+
for (let i = 0; i < items.length; i++) {
|
|
313
|
+
try {
|
|
314
|
+
// Get operation parameters
|
|
315
|
+
const title = this.getNodeParameter('title', i);
|
|
316
|
+
const message = this.getNodeParameter('message', i);
|
|
317
|
+
const recipientType = this.getNodeParameter('recipientType', i);
|
|
318
|
+
// Get options
|
|
319
|
+
const options = this.getNodeParameter('options', i, {});
|
|
320
|
+
const notificationType = options.notificationType || 'default';
|
|
321
|
+
const imageUrl = options.imageUrl;
|
|
322
|
+
const actionUrl = options.actionUrl;
|
|
323
|
+
const actionLabel = options.actionLabel || 'View Details';
|
|
324
|
+
// Get recipient-specific parameters
|
|
325
|
+
let teamId;
|
|
326
|
+
let channelId;
|
|
327
|
+
let userId;
|
|
328
|
+
if (recipientType === 'channel') {
|
|
329
|
+
teamId = this.getNodeParameter('teamId', i);
|
|
330
|
+
channelId = this.getNodeParameter('channelId', i);
|
|
331
|
+
}
|
|
332
|
+
else if (recipientType === 'chat') {
|
|
333
|
+
userId = this.getNodeParameter('userId', i);
|
|
334
|
+
}
|
|
335
|
+
// Create notification card from template with data binding
|
|
336
|
+
const notificationTemplate = utils_1.CardTemplates.notification();
|
|
337
|
+
const templateEngine = new ACData.Template(notificationTemplate);
|
|
338
|
+
// Prepare data for template
|
|
339
|
+
const cardData = {
|
|
340
|
+
title,
|
|
341
|
+
message,
|
|
342
|
+
notificationType,
|
|
343
|
+
imageUrl: imageUrl || undefined,
|
|
344
|
+
actionUrl: actionUrl || undefined,
|
|
345
|
+
actionLabel,
|
|
346
|
+
};
|
|
347
|
+
// Apply data binding
|
|
348
|
+
const boundCard = templateEngine.expand({ $root: cardData });
|
|
349
|
+
const cardString = JSON.stringify(boundCard);
|
|
350
|
+
// Prepare parameters for validation
|
|
351
|
+
const params = {
|
|
352
|
+
card: cardString,
|
|
353
|
+
recipientType,
|
|
354
|
+
teamId,
|
|
355
|
+
channelId,
|
|
356
|
+
userId,
|
|
357
|
+
};
|
|
358
|
+
// Validate parameters
|
|
359
|
+
validateCardParams(params, ['recipientType'], this, i);
|
|
360
|
+
// Send card based on recipient type
|
|
361
|
+
let response;
|
|
362
|
+
if (recipientType === 'channel') {
|
|
363
|
+
// Always handle auto-installation for channel
|
|
364
|
+
await (0, index_1.handleAutoInstall)(api, teamId, i, this);
|
|
365
|
+
// Send card to channel
|
|
366
|
+
response = await api.sendAdaptiveCardToChannel(teamId, channelId, cardString);
|
|
367
|
+
}
|
|
368
|
+
else {
|
|
369
|
+
// Always handle auto-installation for user
|
|
370
|
+
await (0, index_1.handleAutoInstall)(api, userId, i, this);
|
|
371
|
+
// Use the BotFrameworkApi directly to send the card in one operation
|
|
372
|
+
// This prevents sending an empty message followed by a card
|
|
373
|
+
response = await api.sendAdaptiveCardToUser(userId, cardString);
|
|
374
|
+
// Ensure we got a proper object response
|
|
375
|
+
response = (0, utils_1.ensureObjectResponse)(response);
|
|
376
|
+
}
|
|
377
|
+
// Ensure response is properly parsed before returning
|
|
378
|
+
returnData.push({
|
|
379
|
+
json: response,
|
|
380
|
+
pairedItem: { item: i },
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
catch (error) {
|
|
384
|
+
if (this.continueOnFail()) {
|
|
385
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
386
|
+
returnData.push({
|
|
387
|
+
json: {
|
|
388
|
+
error: errorMessage,
|
|
389
|
+
},
|
|
390
|
+
pairedItem: { item: i },
|
|
391
|
+
});
|
|
392
|
+
continue;
|
|
393
|
+
}
|
|
394
|
+
throw error;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
return [returnData];
|
|
398
|
+
},
|
|
399
|
+
/**
|
|
400
|
+
* Sends an approval card to a channel or chat
|
|
401
|
+
* @returns {Promise<INodeExecutionData[][]>} Promise resolving to output data
|
|
402
|
+
*/
|
|
403
|
+
async sendApproval() {
|
|
404
|
+
const items = this.getInputData();
|
|
405
|
+
const returnData = [];
|
|
406
|
+
const api = new index_1.TeamsApiClient(this);
|
|
407
|
+
await api.initialize();
|
|
408
|
+
for (let i = 0; i < items.length; i++) {
|
|
409
|
+
try {
|
|
410
|
+
// Get operation parameters
|
|
411
|
+
const title = this.getNodeParameter('title', i);
|
|
412
|
+
const description = this.getNodeParameter('description', i);
|
|
413
|
+
const requestId = this.getNodeParameter('requestId', i);
|
|
414
|
+
const recipientType = this.getNodeParameter('recipientType', i);
|
|
415
|
+
// Get options
|
|
416
|
+
const options = this.getNodeParameter('options', i, {});
|
|
417
|
+
const requestedBy = options.requestedBy;
|
|
418
|
+
const dueDate = options.dueDate;
|
|
419
|
+
const additionalInfo = options.additionalInfo;
|
|
420
|
+
const approveLabel = options.approveLabel || 'Approve';
|
|
421
|
+
const rejectLabel = options.rejectLabel || 'Reject';
|
|
422
|
+
// Get recipient-specific parameters
|
|
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
|
+
// Create approval card from template with data binding
|
|
434
|
+
const approvalTemplate = utils_1.CardTemplates.approval();
|
|
435
|
+
const templateEngine = new ACData.Template(approvalTemplate);
|
|
436
|
+
// Prepare data for template
|
|
437
|
+
const cardData = {
|
|
438
|
+
title,
|
|
439
|
+
description,
|
|
440
|
+
requestId,
|
|
441
|
+
requestedBy: requestedBy || undefined,
|
|
442
|
+
dueDate: dueDate || undefined,
|
|
443
|
+
additionalInfo: additionalInfo || undefined,
|
|
444
|
+
approveLabel,
|
|
445
|
+
rejectLabel,
|
|
446
|
+
};
|
|
447
|
+
// Apply data binding
|
|
448
|
+
const boundCard = templateEngine.expand({ $root: cardData });
|
|
449
|
+
const cardString = JSON.stringify(boundCard);
|
|
450
|
+
// Prepare parameters for validation
|
|
451
|
+
const params = {
|
|
452
|
+
card: cardString,
|
|
453
|
+
recipientType,
|
|
454
|
+
teamId,
|
|
455
|
+
channelId,
|
|
456
|
+
userId,
|
|
457
|
+
};
|
|
458
|
+
// Validate parameters
|
|
459
|
+
validateCardParams(params, ['recipientType'], this, i);
|
|
460
|
+
// Send card based on recipient type
|
|
461
|
+
let response;
|
|
462
|
+
if (recipientType === 'channel') {
|
|
463
|
+
// Always handle auto-installation for channel
|
|
464
|
+
await (0, index_1.handleAutoInstall)(api, teamId, i, this);
|
|
465
|
+
// Send card to channel
|
|
466
|
+
response = await api.sendAdaptiveCardToChannel(teamId, channelId, cardString);
|
|
467
|
+
}
|
|
468
|
+
else {
|
|
469
|
+
// Always handle auto-installation for user
|
|
470
|
+
await (0, index_1.handleAutoInstall)(api, userId, i, this);
|
|
471
|
+
// Use the BotFrameworkApi directly to send the card in one operation
|
|
472
|
+
// This prevents sending an empty message followed by a card
|
|
473
|
+
response = await api.sendAdaptiveCardToUser(userId, cardString);
|
|
474
|
+
// Ensure we got a proper object response
|
|
475
|
+
response = (0, utils_1.ensureObjectResponse)(response);
|
|
476
|
+
}
|
|
477
|
+
// Ensure response is properly parsed before returning
|
|
478
|
+
returnData.push({
|
|
479
|
+
json: response,
|
|
480
|
+
pairedItem: { item: i },
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
catch (error) {
|
|
484
|
+
if (this.continueOnFail()) {
|
|
485
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
486
|
+
returnData.push({
|
|
487
|
+
json: {
|
|
488
|
+
error: errorMessage,
|
|
489
|
+
},
|
|
490
|
+
pairedItem: { item: i },
|
|
491
|
+
});
|
|
492
|
+
continue;
|
|
493
|
+
}
|
|
494
|
+
throw error;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
return [returnData];
|
|
498
|
+
},
|
|
499
|
+
/**
|
|
500
|
+
* Updates an existing adaptive card in a conversation
|
|
501
|
+
*/
|
|
502
|
+
async update() {
|
|
503
|
+
const items = this.getInputData();
|
|
504
|
+
const returnData = [];
|
|
505
|
+
const api = new index_1.TeamsApiClient(this);
|
|
506
|
+
await api.initialize();
|
|
507
|
+
for (let i = 0; i < items.length; i++) {
|
|
508
|
+
try {
|
|
509
|
+
// Get operation parameters
|
|
510
|
+
const conversationId = this.getNodeParameter('conversationId', i);
|
|
511
|
+
const activityId = this.getNodeParameter('activityId', i);
|
|
512
|
+
const cardJson = this.getNodeParameter('card', i);
|
|
513
|
+
// Validate parameters
|
|
514
|
+
validateCardParams({ card: cardJson }, ['card'], this, i);
|
|
515
|
+
// Update the card
|
|
516
|
+
const response = await api.updateCard(conversationId, activityId, cardJson);
|
|
517
|
+
// Ensure response is properly parsed before returning
|
|
518
|
+
returnData.push({
|
|
519
|
+
json: (0, utils_1.ensureObjectResponse)(response),
|
|
520
|
+
pairedItem: { item: i },
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
catch (error) {
|
|
524
|
+
if (this.continueOnFail()) {
|
|
525
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
526
|
+
returnData.push({
|
|
527
|
+
json: {
|
|
528
|
+
error: errorMessage,
|
|
529
|
+
},
|
|
530
|
+
pairedItem: { item: i },
|
|
531
|
+
});
|
|
532
|
+
continue;
|
|
533
|
+
}
|
|
534
|
+
throw error;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
return [returnData];
|
|
538
|
+
},
|
|
539
|
+
/**
|
|
540
|
+
* Updates an existing adaptive card in a channel
|
|
541
|
+
*/
|
|
542
|
+
async updateInChannel() {
|
|
543
|
+
const items = this.getInputData();
|
|
544
|
+
const returnData = [];
|
|
545
|
+
const api = new index_1.TeamsApiClient(this);
|
|
546
|
+
await api.initialize();
|
|
547
|
+
for (let i = 0; i < items.length; i++) {
|
|
548
|
+
try {
|
|
549
|
+
// Get operation parameters
|
|
550
|
+
const teamId = this.getNodeParameter('teamId', i);
|
|
551
|
+
const channelId = this.getNodeParameter('channelId', i);
|
|
552
|
+
const activityId = this.getNodeParameter('activityId', i);
|
|
553
|
+
const cardJson = this.getNodeParameter('card', i);
|
|
554
|
+
// Validate parameters
|
|
555
|
+
validateCardParams({ card: cardJson }, ['card'], this, i);
|
|
556
|
+
// Update the card in the channel
|
|
557
|
+
const response = await api.updateAdaptiveCardInChannel(teamId, channelId, activityId, cardJson);
|
|
558
|
+
// Ensure response is properly parsed before returning
|
|
559
|
+
returnData.push({
|
|
560
|
+
json: (0, utils_1.ensureObjectResponse)(response),
|
|
561
|
+
pairedItem: { item: i },
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
catch (error) {
|
|
565
|
+
if (this.continueOnFail()) {
|
|
566
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
567
|
+
returnData.push({
|
|
568
|
+
json: {
|
|
569
|
+
error: errorMessage,
|
|
570
|
+
},
|
|
571
|
+
pairedItem: { item: i },
|
|
572
|
+
});
|
|
573
|
+
continue;
|
|
574
|
+
}
|
|
575
|
+
throw error;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
return [returnData];
|
|
579
|
+
},
|
|
580
|
+
/**
|
|
581
|
+
* Processes card action data from user interactions
|
|
582
|
+
* Enhanced to extract user info, timestamp, and conversation context from trigger data
|
|
583
|
+
*/
|
|
584
|
+
async processAction() {
|
|
585
|
+
const items = this.getInputData();
|
|
586
|
+
const returnData = [];
|
|
587
|
+
for (let i = 0; i < items.length; i++) {
|
|
588
|
+
try {
|
|
589
|
+
// Get action data from the trigger or input
|
|
590
|
+
const actionData = this.getNodeParameter('actionData', i, '');
|
|
591
|
+
if (!actionData) {
|
|
592
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'No action data provided. This operation should be used with card action triggers.', { itemIndex: i });
|
|
593
|
+
}
|
|
594
|
+
let parsedActionData;
|
|
595
|
+
try {
|
|
596
|
+
parsedActionData = JSON.parse(actionData);
|
|
597
|
+
}
|
|
598
|
+
catch (error) {
|
|
599
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid action data JSON: ${error instanceof Error ? error.message : String(error)}`, { itemIndex: i });
|
|
600
|
+
}
|
|
601
|
+
// Get input item data (from trigger node) to extract additional metadata
|
|
602
|
+
const inputItem = items[i];
|
|
603
|
+
const inputJson = (inputItem === null || inputItem === void 0 ? void 0 : inputItem.json) || {};
|
|
604
|
+
// Type guard helper for IDataObject
|
|
605
|
+
const isDataObject = (value) => {
|
|
606
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
607
|
+
};
|
|
608
|
+
// Extract user information from trigger data
|
|
609
|
+
// Teams Bot Framework sends user info in resourceData.from or activity.from
|
|
610
|
+
const userInfo = {};
|
|
611
|
+
const resourceData = isDataObject(inputJson.resourceData) ? inputJson.resourceData : {};
|
|
612
|
+
const from = isDataObject(resourceData.from) ? resourceData.from :
|
|
613
|
+
isDataObject(inputJson.from) ? inputJson.from :
|
|
614
|
+
isDataObject(parsedActionData.from) ? parsedActionData.from : {};
|
|
615
|
+
if (from.user || from.id) {
|
|
616
|
+
// Extract from Teams message format
|
|
617
|
+
const user = isDataObject(from.user) ? from.user : {};
|
|
618
|
+
userInfo.id = user.id || from.id || user.userIdentity;
|
|
619
|
+
userInfo.name = user.displayName || from.name || user.name;
|
|
620
|
+
userInfo.email = user.userIdentity || user.email || from.email;
|
|
621
|
+
userInfo.userPrincipalName = user.userPrincipalName || from.userPrincipalName;
|
|
622
|
+
}
|
|
623
|
+
else if (from.id) {
|
|
624
|
+
// Extract from Bot Framework activity format
|
|
625
|
+
userInfo.id = from.id;
|
|
626
|
+
userInfo.name = from.name;
|
|
627
|
+
}
|
|
628
|
+
// Extract timestamp from trigger data
|
|
629
|
+
// Prefer timestamp from trigger (actual action time) over current time
|
|
630
|
+
let actionTimestamp;
|
|
631
|
+
if (typeof resourceData.lastModifiedDateTime === 'string') {
|
|
632
|
+
actionTimestamp = resourceData.lastModifiedDateTime;
|
|
633
|
+
}
|
|
634
|
+
else if (typeof resourceData.createdDateTime === 'string') {
|
|
635
|
+
actionTimestamp = resourceData.createdDateTime;
|
|
636
|
+
}
|
|
637
|
+
else if (typeof inputJson.timestamp === 'string') {
|
|
638
|
+
actionTimestamp = inputJson.timestamp;
|
|
639
|
+
}
|
|
640
|
+
else if (typeof resourceData.timestamp === 'string') {
|
|
641
|
+
actionTimestamp = resourceData.timestamp;
|
|
642
|
+
}
|
|
643
|
+
else if (typeof parsedActionData.timestamp === 'string') {
|
|
644
|
+
actionTimestamp = parsedActionData.timestamp;
|
|
645
|
+
}
|
|
646
|
+
else {
|
|
647
|
+
// Fallback to current time if no timestamp available
|
|
648
|
+
actionTimestamp = new Date().toISOString();
|
|
649
|
+
}
|
|
650
|
+
// Extract conversation context from trigger data
|
|
651
|
+
const conversationContext = {};
|
|
652
|
+
const conversation = isDataObject(resourceData.conversation) ? resourceData.conversation :
|
|
653
|
+
isDataObject(inputJson.conversation) ? inputJson.conversation :
|
|
654
|
+
isDataObject(parsedActionData.conversation) ? parsedActionData.conversation : {};
|
|
655
|
+
if (conversation.id) {
|
|
656
|
+
conversationContext.id = conversation.id;
|
|
657
|
+
conversationContext.name = conversation.name;
|
|
658
|
+
conversationContext.isGroup = conversation.isGroup;
|
|
659
|
+
conversationContext.conversationType = conversation.conversationType;
|
|
660
|
+
}
|
|
661
|
+
// Extract message/activity context
|
|
662
|
+
const messageContext = {};
|
|
663
|
+
if (inputJson.messageId || resourceData.id) {
|
|
664
|
+
messageContext.messageId = inputJson.messageId || resourceData.id;
|
|
665
|
+
}
|
|
666
|
+
if (inputJson.activityId || resourceData.id) {
|
|
667
|
+
messageContext.activityId = inputJson.activityId || resourceData.id;
|
|
668
|
+
}
|
|
669
|
+
if (resourceData.replyToId || inputJson.replyToId) {
|
|
670
|
+
messageContext.replyToId = resourceData.replyToId || inputJson.replyToId;
|
|
671
|
+
}
|
|
672
|
+
// Extract team/channel context if available
|
|
673
|
+
const contextInfo = {};
|
|
674
|
+
const channelIdentity = isDataObject(resourceData.channelIdentity) ? resourceData.channelIdentity : {};
|
|
675
|
+
if (inputJson.teamId || channelIdentity.teamId) {
|
|
676
|
+
contextInfo.teamId = inputJson.teamId || channelIdentity.teamId;
|
|
677
|
+
}
|
|
678
|
+
if (inputJson.channelId || channelIdentity.channelId) {
|
|
679
|
+
contextInfo.channelId = inputJson.channelId || channelIdentity.channelId;
|
|
680
|
+
}
|
|
681
|
+
if (inputJson.chatId || resourceData.chatId) {
|
|
682
|
+
contextInfo.chatId = inputJson.chatId || resourceData.chatId;
|
|
683
|
+
}
|
|
684
|
+
// Process the action data and return structured information with enhanced metadata
|
|
685
|
+
const processedAction = {
|
|
686
|
+
// Core action data
|
|
687
|
+
actionType: parsedActionData.type || 'submit',
|
|
688
|
+
actionId: parsedActionData.id || parsedActionData.actionId,
|
|
689
|
+
actionData: parsedActionData.data || parsedActionData.value || {},
|
|
690
|
+
// Enhanced metadata
|
|
691
|
+
timestamp: actionTimestamp,
|
|
692
|
+
// User information (if available from trigger)
|
|
693
|
+
user: Object.keys(userInfo).length > 0 ? userInfo : undefined,
|
|
694
|
+
// Conversation context (if available)
|
|
695
|
+
conversation: Object.keys(conversationContext).length > 0 ? conversationContext : undefined,
|
|
696
|
+
// Message context (if available)
|
|
697
|
+
message: Object.keys(messageContext).length > 0 ? messageContext : undefined,
|
|
698
|
+
// Team/channel context (if available)
|
|
699
|
+
context: Object.keys(contextInfo).length > 0 ? contextInfo : undefined,
|
|
700
|
+
// Original trigger event type (if available)
|
|
701
|
+
eventType: inputJson.eventType || resourceData.eventType || undefined,
|
|
702
|
+
};
|
|
703
|
+
// Remove undefined fields to keep output clean
|
|
704
|
+
Object.keys(processedAction).forEach(key => {
|
|
705
|
+
if (processedAction[key] === undefined) {
|
|
706
|
+
delete processedAction[key];
|
|
707
|
+
}
|
|
708
|
+
});
|
|
709
|
+
returnData.push({
|
|
710
|
+
json: processedAction,
|
|
711
|
+
pairedItem: { item: i },
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
catch (error) {
|
|
715
|
+
if (this.continueOnFail()) {
|
|
716
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
717
|
+
returnData.push({
|
|
718
|
+
json: {
|
|
719
|
+
error: errorMessage,
|
|
720
|
+
},
|
|
721
|
+
pairedItem: { item: i },
|
|
722
|
+
});
|
|
723
|
+
continue;
|
|
724
|
+
}
|
|
725
|
+
throw error;
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
return [returnData];
|
|
729
|
+
},
|
|
730
|
+
};
|
|
731
|
+
//# sourceMappingURL=cards.js.map
|