@littlebearapps/outlook-assistant 3.3.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/.env.example +22 -0
- package/LICENSE +21 -0
- package/README.md +422 -0
- package/advanced/index.js +652 -0
- package/auth/index.js +32 -0
- package/auth/oauth-server.js +233 -0
- package/auth/token-manager.js +105 -0
- package/auth/token-storage.js +359 -0
- package/auth/tools.js +159 -0
- package/calendar/accept.js +72 -0
- package/calendar/cancel.js +72 -0
- package/calendar/create.js +115 -0
- package/calendar/decline.js +72 -0
- package/calendar/delete.js +67 -0
- package/calendar/index.js +130 -0
- package/calendar/list.js +108 -0
- package/categories/index.js +955 -0
- package/config.js +95 -0
- package/contacts/index.js +754 -0
- package/email/attachments.js +365 -0
- package/email/conversations.js +666 -0
- package/email/delta.js +210 -0
- package/email/export.js +572 -0
- package/email/folder-utils.js +192 -0
- package/email/headers.js +344 -0
- package/email/index.js +537 -0
- package/email/list.js +136 -0
- package/email/mark-as-read.js +114 -0
- package/email/mime.js +286 -0
- package/email/read.js +161 -0
- package/email/search.js +628 -0
- package/email/send.js +169 -0
- package/folder/create.js +137 -0
- package/folder/delete.js +108 -0
- package/folder/index.js +112 -0
- package/folder/list.js +289 -0
- package/folder/move.js +186 -0
- package/folder/stats.js +322 -0
- package/index.js +162 -0
- package/llms.txt +76 -0
- package/outlook-auth-server.js +384 -0
- package/package.json +97 -0
- package/rules/create.js +273 -0
- package/rules/index.js +276 -0
- package/rules/list.js +216 -0
- package/settings/index.js +678 -0
- package/utils/field-presets.js +311 -0
- package/utils/graph-api.js +268 -0
- package/utils/mock-data.js +154 -0
- package/utils/odata-helpers.js +33 -0
- package/utils/response-formatter.js +457 -0
- package/utils/safety.js +123 -0
package/email/send.js
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Send email functionality
|
|
3
|
+
*/
|
|
4
|
+
const _config = require('../config'); // Reserved for future use
|
|
5
|
+
const { callGraphAPI } = require('../utils/graph-api');
|
|
6
|
+
const { ensureAuthenticated } = require('../auth');
|
|
7
|
+
const {
|
|
8
|
+
checkRateLimit,
|
|
9
|
+
checkRecipientAllowlist,
|
|
10
|
+
formatDryRunPreview,
|
|
11
|
+
} = require('../utils/safety');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Send email handler
|
|
15
|
+
* @param {object} args - Tool arguments
|
|
16
|
+
* @returns {object} - MCP response
|
|
17
|
+
*/
|
|
18
|
+
async function handleSendEmail(args) {
|
|
19
|
+
const {
|
|
20
|
+
to,
|
|
21
|
+
cc,
|
|
22
|
+
bcc,
|
|
23
|
+
subject,
|
|
24
|
+
body,
|
|
25
|
+
importance = 'normal',
|
|
26
|
+
saveToSentItems = true,
|
|
27
|
+
dryRun = false,
|
|
28
|
+
} = args;
|
|
29
|
+
|
|
30
|
+
// Validate required parameters
|
|
31
|
+
if (!to) {
|
|
32
|
+
return {
|
|
33
|
+
content: [
|
|
34
|
+
{
|
|
35
|
+
type: 'text',
|
|
36
|
+
text: 'Recipient (to) is required.',
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (!subject) {
|
|
43
|
+
return {
|
|
44
|
+
content: [
|
|
45
|
+
{
|
|
46
|
+
type: 'text',
|
|
47
|
+
text: 'Subject is required.',
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (!body) {
|
|
54
|
+
return {
|
|
55
|
+
content: [
|
|
56
|
+
{
|
|
57
|
+
type: 'text',
|
|
58
|
+
text: 'Body content is required.',
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
// Format recipients
|
|
66
|
+
const toRecipients = to.split(',').map((email) => {
|
|
67
|
+
email = email.trim();
|
|
68
|
+
return {
|
|
69
|
+
emailAddress: {
|
|
70
|
+
address: email,
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
const ccRecipients = cc
|
|
76
|
+
? cc.split(',').map((email) => {
|
|
77
|
+
email = email.trim();
|
|
78
|
+
return {
|
|
79
|
+
emailAddress: {
|
|
80
|
+
address: email,
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
})
|
|
84
|
+
: [];
|
|
85
|
+
|
|
86
|
+
const bccRecipients = bcc
|
|
87
|
+
? bcc.split(',').map((email) => {
|
|
88
|
+
email = email.trim();
|
|
89
|
+
return {
|
|
90
|
+
emailAddress: {
|
|
91
|
+
address: email,
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
})
|
|
95
|
+
: [];
|
|
96
|
+
|
|
97
|
+
// Check recipient allowlist (all recipients combined)
|
|
98
|
+
const allRecipients = [...toRecipients, ...ccRecipients, ...bccRecipients];
|
|
99
|
+
const allowlistError = checkRecipientAllowlist(allRecipients);
|
|
100
|
+
if (allowlistError) return allowlistError;
|
|
101
|
+
|
|
102
|
+
// Prepare email object
|
|
103
|
+
const emailObject = {
|
|
104
|
+
message: {
|
|
105
|
+
subject,
|
|
106
|
+
body: {
|
|
107
|
+
contentType:
|
|
108
|
+
/<(html|div|p|h[1-6]|br|table|ul|ol|li|span|a\s|img|strong|em|b|i)\b/i.test(
|
|
109
|
+
body
|
|
110
|
+
)
|
|
111
|
+
? 'html'
|
|
112
|
+
: 'text',
|
|
113
|
+
content: body,
|
|
114
|
+
},
|
|
115
|
+
toRecipients,
|
|
116
|
+
ccRecipients: ccRecipients.length > 0 ? ccRecipients : undefined,
|
|
117
|
+
bccRecipients: bccRecipients.length > 0 ? bccRecipients : undefined,
|
|
118
|
+
importance,
|
|
119
|
+
},
|
|
120
|
+
saveToSentItems,
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
// Dry-run mode: return preview without sending
|
|
124
|
+
if (dryRun) {
|
|
125
|
+
return formatDryRunPreview(emailObject);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Check rate limit (only for actual sends, not dry runs)
|
|
129
|
+
const rateLimitError = checkRateLimit('send-email');
|
|
130
|
+
if (rateLimitError) return rateLimitError;
|
|
131
|
+
|
|
132
|
+
// Get access token
|
|
133
|
+
const accessToken = await ensureAuthenticated();
|
|
134
|
+
|
|
135
|
+
// Make API call to send email
|
|
136
|
+
await callGraphAPI(accessToken, 'POST', 'me/sendMail', emailObject);
|
|
137
|
+
|
|
138
|
+
return {
|
|
139
|
+
content: [
|
|
140
|
+
{
|
|
141
|
+
type: 'text',
|
|
142
|
+
text: `Email sent successfully!\n\nSubject: ${subject}\nRecipients: ${toRecipients.length}${ccRecipients.length > 0 ? ` + ${ccRecipients.length} CC` : ''}${bccRecipients.length > 0 ? ` + ${bccRecipients.length} BCC` : ''}\nMessage Length: ${body.length} characters`,
|
|
143
|
+
},
|
|
144
|
+
],
|
|
145
|
+
};
|
|
146
|
+
} catch (error) {
|
|
147
|
+
if (error.message === 'Authentication required') {
|
|
148
|
+
return {
|
|
149
|
+
content: [
|
|
150
|
+
{
|
|
151
|
+
type: 'text',
|
|
152
|
+
text: "Authentication required. Please use the 'auth' tool with action=authenticate first.",
|
|
153
|
+
},
|
|
154
|
+
],
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return {
|
|
159
|
+
content: [
|
|
160
|
+
{
|
|
161
|
+
type: 'text',
|
|
162
|
+
text: `Error sending email: ${error.message}`,
|
|
163
|
+
},
|
|
164
|
+
],
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
module.exports = handleSendEmail;
|
package/folder/create.js
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create folder functionality
|
|
3
|
+
*/
|
|
4
|
+
const { callGraphAPI } = require('../utils/graph-api');
|
|
5
|
+
const { ensureAuthenticated } = require('../auth');
|
|
6
|
+
const { getFolderIdByName } = require('../email/folder-utils');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Create folder handler
|
|
10
|
+
* @param {object} args - Tool arguments
|
|
11
|
+
* @returns {object} - MCP response
|
|
12
|
+
*/
|
|
13
|
+
async function handleCreateFolder(args) {
|
|
14
|
+
const folderName = args.name;
|
|
15
|
+
const parentFolder = args.parentFolder || '';
|
|
16
|
+
|
|
17
|
+
if (!folderName) {
|
|
18
|
+
return {
|
|
19
|
+
content: [
|
|
20
|
+
{
|
|
21
|
+
type: 'text',
|
|
22
|
+
text: 'Folder name is required.',
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
// Get access token
|
|
30
|
+
const accessToken = await ensureAuthenticated();
|
|
31
|
+
|
|
32
|
+
// Create folder with appropriate parent
|
|
33
|
+
const result = await createMailFolder(
|
|
34
|
+
accessToken,
|
|
35
|
+
folderName,
|
|
36
|
+
parentFolder
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
content: [
|
|
41
|
+
{
|
|
42
|
+
type: 'text',
|
|
43
|
+
text: result.message,
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
};
|
|
47
|
+
} catch (error) {
|
|
48
|
+
if (error.message === 'Authentication required') {
|
|
49
|
+
return {
|
|
50
|
+
content: [
|
|
51
|
+
{
|
|
52
|
+
type: 'text',
|
|
53
|
+
text: "Authentication required. Please use the 'authenticate' tool first.",
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
content: [
|
|
61
|
+
{
|
|
62
|
+
type: 'text',
|
|
63
|
+
text: `Error creating folder: ${error.message}`,
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Create a new mail folder
|
|
72
|
+
* @param {string} accessToken - Access token
|
|
73
|
+
* @param {string} folderName - Name of the folder to create
|
|
74
|
+
* @param {string} parentFolderName - Name of the parent folder (optional)
|
|
75
|
+
* @returns {Promise<object>} - Result object with status and message
|
|
76
|
+
*/
|
|
77
|
+
async function createMailFolder(accessToken, folderName, parentFolderName) {
|
|
78
|
+
try {
|
|
79
|
+
// Check if a folder with this name already exists
|
|
80
|
+
const existingFolder = await getFolderIdByName(accessToken, folderName);
|
|
81
|
+
if (existingFolder) {
|
|
82
|
+
return {
|
|
83
|
+
success: false,
|
|
84
|
+
message: `A folder named "${folderName}" already exists.`,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// If parent folder specified, find its ID
|
|
89
|
+
let endpoint = 'me/mailFolders';
|
|
90
|
+
if (parentFolderName) {
|
|
91
|
+
const parentId = await getFolderIdByName(accessToken, parentFolderName);
|
|
92
|
+
if (!parentId) {
|
|
93
|
+
return {
|
|
94
|
+
success: false,
|
|
95
|
+
message: `Parent folder "${parentFolderName}" not found. Please specify a valid parent folder or leave it blank to create at the root level.`,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
endpoint = `me/mailFolders/${parentId}/childFolders`;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Create the folder
|
|
103
|
+
const folderData = {
|
|
104
|
+
displayName: folderName,
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const response = await callGraphAPI(
|
|
108
|
+
accessToken,
|
|
109
|
+
'POST',
|
|
110
|
+
endpoint,
|
|
111
|
+
folderData
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
if (response && response.id) {
|
|
115
|
+
const locationInfo = parentFolderName
|
|
116
|
+
? `inside "${parentFolderName}"`
|
|
117
|
+
: 'at the root level';
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
success: true,
|
|
121
|
+
message: `Successfully created folder "${folderName}" ${locationInfo}.`,
|
|
122
|
+
folderId: response.id,
|
|
123
|
+
};
|
|
124
|
+
} else {
|
|
125
|
+
return {
|
|
126
|
+
success: false,
|
|
127
|
+
message:
|
|
128
|
+
"Failed to create folder. The server didn't return a folder ID.",
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
} catch (error) {
|
|
132
|
+
console.error(`Error creating folder "${folderName}": ${error.message}`);
|
|
133
|
+
throw error;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
module.exports = handleCreateFolder;
|
package/folder/delete.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Delete folder functionality
|
|
3
|
+
*/
|
|
4
|
+
const { callGraphAPI } = require('../utils/graph-api');
|
|
5
|
+
const { ensureAuthenticated } = require('../auth');
|
|
6
|
+
const { getFolderIdByName } = require('../email/folder-utils');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Protected folder names that cannot be deleted
|
|
10
|
+
*/
|
|
11
|
+
const PROTECTED_FOLDERS = [
|
|
12
|
+
'inbox',
|
|
13
|
+
'drafts',
|
|
14
|
+
'sentitems',
|
|
15
|
+
'deleteditems',
|
|
16
|
+
'junkemail',
|
|
17
|
+
'archive',
|
|
18
|
+
'outbox',
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Delete folder handler
|
|
23
|
+
* @param {object} args - Tool arguments
|
|
24
|
+
* @param {string} [args.folderId] - Folder ID to delete
|
|
25
|
+
* @param {string} [args.folderName] - Folder name to delete (resolved to ID)
|
|
26
|
+
* @returns {object} - MCP response
|
|
27
|
+
*/
|
|
28
|
+
async function handleDeleteFolder(args) {
|
|
29
|
+
const { folderId, folderName } = args;
|
|
30
|
+
|
|
31
|
+
if (!folderId && !folderName) {
|
|
32
|
+
return {
|
|
33
|
+
content: [
|
|
34
|
+
{
|
|
35
|
+
type: 'text',
|
|
36
|
+
text: 'Either folderId or folderName is required.',
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Guard against deleting protected folders
|
|
43
|
+
if (folderName && PROTECTED_FOLDERS.includes(folderName.toLowerCase())) {
|
|
44
|
+
return {
|
|
45
|
+
content: [
|
|
46
|
+
{
|
|
47
|
+
type: 'text',
|
|
48
|
+
text: `Cannot delete protected folder "${folderName}". Protected folders: Inbox, Drafts, Sent Items, Deleted Items, Junk Email, Archive, Outbox.`,
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
const accessToken = await ensureAuthenticated();
|
|
56
|
+
|
|
57
|
+
let resolvedId = folderId;
|
|
58
|
+
|
|
59
|
+
// Resolve folder name to ID if needed
|
|
60
|
+
if (!resolvedId && folderName) {
|
|
61
|
+
resolvedId = await getFolderIdByName(accessToken, folderName);
|
|
62
|
+
if (!resolvedId) {
|
|
63
|
+
return {
|
|
64
|
+
content: [
|
|
65
|
+
{
|
|
66
|
+
type: 'text',
|
|
67
|
+
text: `Folder "${folderName}" not found. Use folders (action=list) to see available folders.`,
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Delete the folder
|
|
75
|
+
await callGraphAPI(accessToken, 'DELETE', `me/mailFolders/${resolvedId}`);
|
|
76
|
+
|
|
77
|
+
const displayName = folderName || resolvedId;
|
|
78
|
+
return {
|
|
79
|
+
content: [
|
|
80
|
+
{
|
|
81
|
+
type: 'text',
|
|
82
|
+
text: `Folder "${displayName}" deleted successfully.`,
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
};
|
|
86
|
+
} catch (error) {
|
|
87
|
+
if (error.message === 'Authentication required') {
|
|
88
|
+
return {
|
|
89
|
+
content: [
|
|
90
|
+
{
|
|
91
|
+
type: 'text',
|
|
92
|
+
text: "Authentication required. Please use the 'auth' tool with action=authenticate first.",
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
content: [
|
|
99
|
+
{
|
|
100
|
+
type: 'text',
|
|
101
|
+
text: `Error deleting folder: ${error.message}`,
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
module.exports = handleDeleteFolder;
|
package/folder/index.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Folder management module for Outlook Assistant server
|
|
3
|
+
*/
|
|
4
|
+
const handleListFolders = require('./list');
|
|
5
|
+
const handleCreateFolder = require('./create');
|
|
6
|
+
const handleMoveEmails = require('./move');
|
|
7
|
+
const handleGetFolderStats = require('./stats');
|
|
8
|
+
const handleDeleteFolder = require('./delete');
|
|
9
|
+
|
|
10
|
+
// Consolidated folder tool definition
|
|
11
|
+
const folderTools = [
|
|
12
|
+
{
|
|
13
|
+
name: 'folders',
|
|
14
|
+
description:
|
|
15
|
+
'Manage mail folders. action=list (default) lists folders. action=create creates a folder. action=move moves emails between folders. action=stats gets folder counts for pagination planning. action=delete removes a folder.',
|
|
16
|
+
annotations: {
|
|
17
|
+
title: 'Mail Folders',
|
|
18
|
+
readOnlyHint: false,
|
|
19
|
+
destructiveHint: true,
|
|
20
|
+
openWorldHint: false,
|
|
21
|
+
},
|
|
22
|
+
inputSchema: {
|
|
23
|
+
type: 'object',
|
|
24
|
+
properties: {
|
|
25
|
+
action: {
|
|
26
|
+
type: 'string',
|
|
27
|
+
enum: ['list', 'create', 'move', 'stats', 'delete'],
|
|
28
|
+
description: 'Action to perform (default: list)',
|
|
29
|
+
},
|
|
30
|
+
// list params
|
|
31
|
+
includeItemCounts: {
|
|
32
|
+
type: 'boolean',
|
|
33
|
+
description: 'Include counts of total and unread items (action=list)',
|
|
34
|
+
},
|
|
35
|
+
includeChildren: {
|
|
36
|
+
type: 'boolean',
|
|
37
|
+
description: 'Include child folders in hierarchy (action=list)',
|
|
38
|
+
},
|
|
39
|
+
// create params
|
|
40
|
+
name: {
|
|
41
|
+
type: 'string',
|
|
42
|
+
description: 'Name of the folder to create (action=create, required)',
|
|
43
|
+
},
|
|
44
|
+
parentFolder: {
|
|
45
|
+
type: 'string',
|
|
46
|
+
description: 'Parent folder name, default is root (action=create)',
|
|
47
|
+
},
|
|
48
|
+
// move params
|
|
49
|
+
emailIds: {
|
|
50
|
+
type: 'string',
|
|
51
|
+
description:
|
|
52
|
+
'Comma-separated list of email IDs to move (action=move, required)',
|
|
53
|
+
},
|
|
54
|
+
targetFolder: {
|
|
55
|
+
type: 'string',
|
|
56
|
+
description: 'Folder name to move emails to (action=move, required)',
|
|
57
|
+
},
|
|
58
|
+
sourceFolder: {
|
|
59
|
+
type: 'string',
|
|
60
|
+
description: 'Source folder name, default is inbox (action=move)',
|
|
61
|
+
},
|
|
62
|
+
// stats params
|
|
63
|
+
folder: {
|
|
64
|
+
type: 'string',
|
|
65
|
+
description:
|
|
66
|
+
'Folder name (inbox, sent, drafts, etc.). Default: inbox (action=stats)',
|
|
67
|
+
},
|
|
68
|
+
outputVerbosity: {
|
|
69
|
+
type: 'string',
|
|
70
|
+
enum: ['minimal', 'standard', 'full'],
|
|
71
|
+
description: 'Output detail level (action=stats, default: standard)',
|
|
72
|
+
},
|
|
73
|
+
// delete params
|
|
74
|
+
folderId: {
|
|
75
|
+
type: 'string',
|
|
76
|
+
description: 'Folder ID to delete (action=delete)',
|
|
77
|
+
},
|
|
78
|
+
folderName: {
|
|
79
|
+
type: 'string',
|
|
80
|
+
description:
|
|
81
|
+
'Folder name to delete — resolved to ID (action=delete). Cannot delete protected folders (Inbox, Drafts, Sent, etc.)',
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
required: [],
|
|
85
|
+
},
|
|
86
|
+
handler: async (args) => {
|
|
87
|
+
const action = args.action || 'list';
|
|
88
|
+
switch (action) {
|
|
89
|
+
case 'create':
|
|
90
|
+
return handleCreateFolder(args);
|
|
91
|
+
case 'move':
|
|
92
|
+
return handleMoveEmails(args);
|
|
93
|
+
case 'stats':
|
|
94
|
+
return handleGetFolderStats(args);
|
|
95
|
+
case 'delete':
|
|
96
|
+
return handleDeleteFolder(args);
|
|
97
|
+
case 'list':
|
|
98
|
+
default:
|
|
99
|
+
return handleListFolders(args);
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
];
|
|
104
|
+
|
|
105
|
+
module.exports = {
|
|
106
|
+
folderTools,
|
|
107
|
+
handleListFolders,
|
|
108
|
+
handleCreateFolder,
|
|
109
|
+
handleMoveEmails,
|
|
110
|
+
handleGetFolderStats,
|
|
111
|
+
handleDeleteFolder,
|
|
112
|
+
};
|