@hyperbytes/wappler-imap-manager 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/CHANGELOG.md +4 -0
- package/LICENSE.md +21 -0
- package/README.md +10 -0
- package/package.json +22 -0
- package/server_connect/modules/imapcount.hjson +126 -0
- package/server_connect/modules/imapcount.js +53 -0
- package/server_connect/modules/imapcount.php +17 -0
- package/server_connect/modules/imapcreatefolder.hjson +124 -0
- package/server_connect/modules/imapcreatefolder.js +46 -0
- package/server_connect/modules/imapcreatefolder.php +17 -0
- package/server_connect/modules/imapdelete.hjson +148 -0
- package/server_connect/modules/imapdelete.js +73 -0
- package/server_connect/modules/imapdelete.php +17 -0
- package/server_connect/modules/imapdeletefolder.hjson +125 -0
- package/server_connect/modules/imapdeletefolder.js +65 -0
- package/server_connect/modules/imapdeletefolder.php +17 -0
- package/server_connect/modules/imapdirlist.hjson +122 -0
- package/server_connect/modules/imapdirlist.js +57 -0
- package/server_connect/modules/imapdirlist.php +17 -0
- package/server_connect/modules/imapexpunge.hjson +115 -0
- package/server_connect/modules/imapexpunge.js +63 -0
- package/server_connect/modules/imapexpunge.php +17 -0
- package/server_connect/modules/imapflag.hjson +153 -0
- package/server_connect/modules/imapflag.js +81 -0
- package/server_connect/modules/imapflag.php +17 -0
- package/server_connect/modules/imapgetattachments.hjson +159 -0
- package/server_connect/modules/imapgetattachments.js +94 -0
- package/server_connect/modules/imapgetattachments.php +17 -0
- package/server_connect/modules/imapgetrawheaders.hjson +120 -0
- package/server_connect/modules/imapgetrawheaders.js +121 -0
- package/server_connect/modules/imapgetrawheaders.php +17 -0
- package/server_connect/modules/imapmailcontent.hjson +192 -0
- package/server_connect/modules/imapmailcontent.js +113 -0
- package/server_connect/modules/imapmailcontent.php +17 -0
- package/server_connect/modules/imapmailheaders.hjson +174 -0
- package/server_connect/modules/imapmailheaders.js +184 -0
- package/server_connect/modules/imapmailheaders.php +71 -0
- package/server_connect/modules/imapmovefolder.hjson +158 -0
- package/server_connect/modules/imapmovefolder.js +86 -0
- package/server_connect/modules/imapmovefolder.php +17 -0
- package/server_connect/modules/imapremoveflag.hjson +151 -0
- package/server_connect/modules/imapremoveflag.js +72 -0
- package/server_connect/modules/imapremoveflag.php +17 -0
- package/server_connect/modules/imapsaveasdraft.hjson +202 -0
- package/server_connect/modules/imapsaveasdraft.js +184 -0
- package/server_connect/modules/imapsaveflag.php +17 -0
- package/server_connect/modules/imapsendmail.hjson +190 -0
- package/server_connect/modules/imapsendmail.js +171 -0
- package/server_connect/modules/imapsendmail.php +17 -0
- package/server_connect/modules/imapstore.hjson +160 -0
- package/server_connect/modules/imapstore.js +63 -0
- package/server_connect/modules/imapstore.php +17 -0
- package/server_connect/modules/imapsubscribe.hjson +128 -0
- package/server_connect/modules/imapsubscribe.js +43 -0
- package/server_connect/modules/imapsubscribe.php +17 -0
- package/server_connect/modules/imapsubscribedlist.hjson +122 -0
- package/server_connect/modules/imapsubscribedlist.js +57 -0
- package/server_connect/modules/imapsubscribedlist.php +17 -0
- package/server_connect/modules/imaptrashperms.hjson +115 -0
- package/server_connect/modules/imaptrashperms.js +51 -0
- package/server_connect/modules/imaptrashperms.php +17 -0
- package/server_connect/modules/imapunsubscribedlist.hjson +122 -0
- package/server_connect/modules/imapunsubscribedlist.js +80 -0
- package/server_connect/modules/imapunsubscribedlist.php +17 -0
- package/server_connect/modules/testfile.hjsonx +134 -0
- package/server_connect/modules/testfile.js +28 -0
- package/server_connect/modules/testfile_bug.hjsonx +141 -0
- package/server_connect/modules/testfile_bug.js +8 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
const Imap = require('imap');
|
|
2
|
+
|
|
3
|
+
exports.imapremoveflag = async function (options, name) {
|
|
4
|
+
const IMAP_HOST = this.parseOptional(options.imap_host, '*', process.env.IMAP_HOST);
|
|
5
|
+
const IMAP_PASSWORD = this.parseOptional(options.imap_password, '*', process.env.IMAP_PASSWORD);
|
|
6
|
+
const IMAP_USER = this.parseOptional(options.imap_usesr, '*', process.env.IMAP_USER);
|
|
7
|
+
const IMAP_PORT = this.parseOptional(options.imap_port, '*', process.env.IMAP_PORT);
|
|
8
|
+
const imap_tlsstring = this.parseOptional(options.imap_tls, '*', process.env.IMAP_TLS).toLowerCase();
|
|
9
|
+
const IMAP_TLS = (imap_tlsstring == 'true');
|
|
10
|
+
|
|
11
|
+
const uid = this.parseRequired(options.uid, '*', "No message UID specified");
|
|
12
|
+
const uidvalidity = Number(this.parseRequired(options.uidvalidity, '*', "No message UIDValidity specified"));
|
|
13
|
+
const mailbox = this.parseRequired(options.mailbox, '*', "No mailbox specified");
|
|
14
|
+
let flag = this.parseRequired(options.flag, '*', "No Flag specified");
|
|
15
|
+
flag = normalizeBackslash(flag);
|
|
16
|
+
|
|
17
|
+
const config = {
|
|
18
|
+
user: IMAP_USER,
|
|
19
|
+
password: IMAP_PASSWORD,
|
|
20
|
+
host: IMAP_HOST,
|
|
21
|
+
port: IMAP_PORT,
|
|
22
|
+
tls: IMAP_TLS
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const removeFlagFromEmail = (uid, flagName, mailboxName, expectedUidValidity) => {
|
|
26
|
+
return new Promise((resolve) => {
|
|
27
|
+
const imap = new Imap(config);
|
|
28
|
+
|
|
29
|
+
imap.once('ready', () => {
|
|
30
|
+
imap.openBox(mailboxName, false, (err, box) => {
|
|
31
|
+
if (err) {
|
|
32
|
+
imap.end();
|
|
33
|
+
return resolve({ uid: null, mailbox: mailboxName, flag: null, status: 401 });
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Validate UIDVALIDITY before proceeding
|
|
37
|
+
if (Number(box.uidvalidity) !== Number(expectedUidValidity)) {
|
|
38
|
+
imap.end();
|
|
39
|
+
return resolve({ uid: null, mailbox: mailboxName, flag: null, status: 401 });
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
imap.delFlags(uid, flagName, (err) => {
|
|
43
|
+
if (err) {
|
|
44
|
+
imap.end();
|
|
45
|
+
return resolve({ uid: uid, mailbox: mailboxName, flag: flagName, status: 401 });
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
console.log(`Successfully removed flag ${flagName} from email UID ${uid} in ${mailboxName}`);
|
|
49
|
+
imap.end();
|
|
50
|
+
resolve({ uid: uid, mailbox: mailboxName, flag: flagName, status: 200 });
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
imap.once('error', () => resolve({ uid: null, mailbox: mailboxName, flag: null, status: 401 }));
|
|
56
|
+
|
|
57
|
+
imap.once('end', () => console.log('IMAP connection closed'));
|
|
58
|
+
|
|
59
|
+
imap.connect();
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
return removeFlagFromEmail(uid, flag, mailbox, uidvalidity);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
function normalizeBackslash(inputString) {
|
|
67
|
+
if (inputString.startsWith("\\\\")) {
|
|
68
|
+
return inputString.replace(/^\\\\/, "\\");
|
|
69
|
+
}
|
|
70
|
+
return inputString;
|
|
71
|
+
}
|
|
72
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace modules;
|
|
4
|
+
|
|
5
|
+
use \lib\core\Module;
|
|
6
|
+
|
|
7
|
+
class custom extends Module
|
|
8
|
+
{
|
|
9
|
+
public function imapremoveflag($options, $name) {
|
|
10
|
+
|
|
11
|
+
$myObj->response = "This function is not yet available in PHP";
|
|
12
|
+
|
|
13
|
+
return json_encode($myObj);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
?>
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
[{
|
|
2
|
+
type: 'imapsaveasdraft-imapsaveasdraft',
|
|
3
|
+
module : 'imapsaveasdraft',
|
|
4
|
+
action : 'imapsaveasdraft',
|
|
5
|
+
groupTitle : 'Mailer',
|
|
6
|
+
groupIcon : 'fas fa-envelope comp-general',
|
|
7
|
+
title : 'IMAP Save as Draft (not funtional)',
|
|
8
|
+
icon : 'fas fa-solid fa-pen comp-exec',
|
|
9
|
+
dataPickObject: true,
|
|
10
|
+
usedModules : {
|
|
11
|
+
node: {
|
|
12
|
+
'imap' : '^8.8.19',
|
|
13
|
+
'mailparser' : '^3.7.2',
|
|
14
|
+
'imap-simple' : '^5.1.0',
|
|
15
|
+
'mailtrap' : '^4.1.0',
|
|
16
|
+
'mailcomposer':'^1.0.0'
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
dataScheme: [
|
|
20
|
+
{ type:"number", name: "status"},
|
|
21
|
+
{ type:"text", name: "message"},
|
|
22
|
+
{ type:"number", name: "uid"},
|
|
23
|
+
{ type:"text", name: "folder"}
|
|
24
|
+
],
|
|
25
|
+
properties : [
|
|
26
|
+
{
|
|
27
|
+
group: 'IMAP Inputs',
|
|
28
|
+
variables: [
|
|
29
|
+
|
|
30
|
+
{ name: 'actionName',
|
|
31
|
+
optionName: 'name',
|
|
32
|
+
title: 'Name',
|
|
33
|
+
type: 'text',
|
|
34
|
+
required: true,
|
|
35
|
+
baseName: "imap"
|
|
36
|
+
},
|
|
37
|
+
{ name: 'selector', optionName: 'selector', title: 'IAMP Settings Selection',
|
|
38
|
+
type: 'droplist',
|
|
39
|
+
values: [
|
|
40
|
+
{title: 'Use ENV ', value: 'ENV' ,show:[],hide:['imap_msg','imap_host','imap_user','imap_password','imap_port','imap_tls']},
|
|
41
|
+
{title: 'Enable Manual Overrides', value: 'MANUAL',hide:[],show:['imap_msg','imap_host','imap_user','imap_password','imap_port','imap_tls'] },
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
],
|
|
45
|
+
defaultValue: 'ENV',
|
|
46
|
+
help: 'Choose your TLS settings.',
|
|
47
|
+
initValue: "ENV"
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
{name: 'imap_msg',
|
|
51
|
+
optionName: 'imap_msg',
|
|
52
|
+
title: 'IMAP password',
|
|
53
|
+
type: 'static',
|
|
54
|
+
help: 'IMAP .ENV OVERRIDE SETTINGS'
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
{name: 'imap_host',
|
|
58
|
+
optionName: 'imap_host',
|
|
59
|
+
title: 'IMAP Host',
|
|
60
|
+
type: 'text',
|
|
61
|
+
defaultValue: "", initDisplay: 'none',
|
|
62
|
+
serverDataBindings: true,
|
|
63
|
+
help: 'The IMAP Host Server'
|
|
64
|
+
},
|
|
65
|
+
{name: 'imap_user',
|
|
66
|
+
optionName: 'imap_user',
|
|
67
|
+
title: 'IMAP User',
|
|
68
|
+
type: 'text',
|
|
69
|
+
defaultValue: "", initDisplay: 'none',
|
|
70
|
+
serverDataBindings: true,
|
|
71
|
+
help: 'The IMAP user'
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
{name: 'imap_password',
|
|
75
|
+
optionName: 'imap_password',
|
|
76
|
+
title: 'IMAP password',
|
|
77
|
+
type: 'text',
|
|
78
|
+
defaultValue: "", initDisplay: 'none',
|
|
79
|
+
serverDataBindings: true,
|
|
80
|
+
help: 'The IMAP password'
|
|
81
|
+
},
|
|
82
|
+
{name: 'imap_port',
|
|
83
|
+
optionName: 'imap_port',
|
|
84
|
+
title: 'IMAP Port',
|
|
85
|
+
type: 'text',
|
|
86
|
+
defaultValue: "", initDisplay: 'none',
|
|
87
|
+
serverDataBindings: true,
|
|
88
|
+
help: 'The IMAP port'
|
|
89
|
+
},
|
|
90
|
+
{ name: 'imap_tls', optionName: 'imap_tls', title: 'TLS Settings',
|
|
91
|
+
type: 'droplist',
|
|
92
|
+
values: [
|
|
93
|
+
{title: 'Use ENV if available', value: 'ENV' },
|
|
94
|
+
{title: 'True', value: 'True' },
|
|
95
|
+
{title: 'False', value: 'False' },
|
|
96
|
+
|
|
97
|
+
],
|
|
98
|
+
defaultValue: 'ENV', initDisplay: 'none',
|
|
99
|
+
help: 'Choose your TLS settings.',
|
|
100
|
+
initValue: "ENV"
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
{name: 'imap_msg2',
|
|
104
|
+
optionName: 'imap_msg2',
|
|
105
|
+
title: '',
|
|
106
|
+
type: 'static',
|
|
107
|
+
help: 'API ACTION SETTINGS'
|
|
108
|
+
},
|
|
109
|
+
{ name: 'uid',
|
|
110
|
+
optionName: 'uid',
|
|
111
|
+
title: 'uid',
|
|
112
|
+
type: 'text',
|
|
113
|
+
required: false,
|
|
114
|
+
defaultValue: "",
|
|
115
|
+
serverDataBindings: true,
|
|
116
|
+
help: 'The uid of the original draft'
|
|
117
|
+
},
|
|
118
|
+
{ name: 'from',
|
|
119
|
+
optionName: 'from',
|
|
120
|
+
title: 'From',
|
|
121
|
+
type: 'text',
|
|
122
|
+
required: false,
|
|
123
|
+
defaultValue: "",
|
|
124
|
+
serverDataBindings: true,
|
|
125
|
+
help: 'The from email'
|
|
126
|
+
},
|
|
127
|
+
{ name: 'to',
|
|
128
|
+
optionName: 'to',
|
|
129
|
+
title: 'To',
|
|
130
|
+
type: 'text',
|
|
131
|
+
required: false,
|
|
132
|
+
defaultValue: "",
|
|
133
|
+
serverDataBindings: true,
|
|
134
|
+
help: 'The to email'
|
|
135
|
+
},
|
|
136
|
+
{ name: 'cc',
|
|
137
|
+
optionName: 'cc',
|
|
138
|
+
title: 'CC',
|
|
139
|
+
type: 'text',
|
|
140
|
+
required: false,
|
|
141
|
+
defaultValue: "",
|
|
142
|
+
serverDataBindings: true,
|
|
143
|
+
help: 'The cc email'
|
|
144
|
+
},
|
|
145
|
+
{ name: 'bcc',
|
|
146
|
+
optionName: 'bcc',
|
|
147
|
+
title: 'Bcc',
|
|
148
|
+
type: 'text',
|
|
149
|
+
required: false,
|
|
150
|
+
defaultValue: "",
|
|
151
|
+
serverDataBindings: true,
|
|
152
|
+
help: 'The BCC email'
|
|
153
|
+
},
|
|
154
|
+
{ name: 'mailsubject',
|
|
155
|
+
optionName: 'mailsubject',
|
|
156
|
+
title: 'Subject',
|
|
157
|
+
type: 'text',
|
|
158
|
+
required: false,
|
|
159
|
+
defaultValue: "",
|
|
160
|
+
serverDataBindings: true,
|
|
161
|
+
help: 'The subject of the email'
|
|
162
|
+
},
|
|
163
|
+
{ name: 'body',
|
|
164
|
+
optionName: 'body',
|
|
165
|
+
title: 'Body',
|
|
166
|
+
type: 'textarea',
|
|
167
|
+
required: false,
|
|
168
|
+
defaultValue: "",
|
|
169
|
+
serverDataBindings: true,
|
|
170
|
+
help: 'The body of the email'
|
|
171
|
+
},
|
|
172
|
+
{ name: 'attachments',
|
|
173
|
+
optionName: 'attachments',
|
|
174
|
+
title: 'Attachments Path',
|
|
175
|
+
type: 'textarea',
|
|
176
|
+
required: false,
|
|
177
|
+
defaultValue: "",
|
|
178
|
+
serverDataBindings: true,
|
|
179
|
+
help: 'The attachments file upload content'
|
|
180
|
+
},
|
|
181
|
+
{ name: 'mailbox',
|
|
182
|
+
optionName: 'mailbox',
|
|
183
|
+
title: 'Move to mailbox',
|
|
184
|
+
type: 'text',
|
|
185
|
+
required: false,
|
|
186
|
+
defaultValue: 'Drafts',
|
|
187
|
+
serverDataBindings: true,
|
|
188
|
+
help: 'Mailbox for the saved email'
|
|
189
|
+
},
|
|
190
|
+
{ name: 'output',
|
|
191
|
+
optionName: 'output',
|
|
192
|
+
title: 'Output',
|
|
193
|
+
type: 'boolean',
|
|
194
|
+
defaultValue: false
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
]
|
|
198
|
+
},
|
|
199
|
+
|
|
200
|
+
]
|
|
201
|
+
}
|
|
202
|
+
]
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
const Imap = require('imap-simple');
|
|
2
|
+
const nodemailer = require('nodemailer');
|
|
3
|
+
const mailcomposer = require('mailcomposer');
|
|
4
|
+
const { simpleParser } = require('mailparser'); // Used for debugging email content
|
|
5
|
+
|
|
6
|
+
exports.imapsaveasdraft = async function (options) {
|
|
7
|
+
console.log('Starting IMAP draft save process...');
|
|
8
|
+
|
|
9
|
+
// Parse IMAP configuration
|
|
10
|
+
const IMAP_HOST = this.parseOptional(options.imap_host, '*', process.env.IMAP_HOST);
|
|
11
|
+
const IMAP_PASSWORD = this.parseOptional(options.imap_password, '*', process.env.IMAP_PASSWORD);
|
|
12
|
+
const IMAP_USER = this.parseOptional(options.imap_user, '*', process.env.IMAP_USER);
|
|
13
|
+
const IMAP_PORT = this.parseOptional(options.imap_port, '*', process.env.IMAP_PORT);
|
|
14
|
+
const imap_tlsstring = this.parseOptional(options.imap_tls, '*', process.env.IMAP_TLS).toLowerCase();
|
|
15
|
+
const IMAP_TLS = (imap_tlsstring === 'true');
|
|
16
|
+
|
|
17
|
+
// Validate essential IMAP configuration
|
|
18
|
+
if (!IMAP_HOST || !IMAP_USER || !IMAP_PASSWORD) {
|
|
19
|
+
console.error('IMAP host, user, or password not configured.');
|
|
20
|
+
return {
|
|
21
|
+
status: 401,
|
|
22
|
+
message: 'IMAP configuration incomplete.',
|
|
23
|
+
error: 'IMAP host, user, or password not configured.',
|
|
24
|
+
uid: '',
|
|
25
|
+
folder: this.parseOptional(options.mailbox, '*', 'Drafts')
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Parse email details
|
|
30
|
+
const to = this.parseOptional(options.to, "*", "");
|
|
31
|
+
console.log('To: ' + to);
|
|
32
|
+
const mailfrom = this.parseOptional(options.from, "*", "");
|
|
33
|
+
console.log('From: ' + mailfrom);
|
|
34
|
+
const cc = this.parseOptional(options.cc, "*", "");
|
|
35
|
+
console.log('CC: ' + cc);
|
|
36
|
+
const bcc = this.parseOptional(options.bcc, "*", "");
|
|
37
|
+
console.log('BCC: ' + bcc);
|
|
38
|
+
const subject = this.parseOptional(options.mailsubject, "*", "default subject");
|
|
39
|
+
console.log('Subject: ' + subject);
|
|
40
|
+
const body = this.parseOptional(options.body, "*", ""); // Assuming this is HTML body
|
|
41
|
+
console.log('Body: ' + body);
|
|
42
|
+
const attachments = this.parseOptional(options.attachments, '*', []);
|
|
43
|
+
console.log('Attachments: ' + attachments);
|
|
44
|
+
let folder = this.parseOptional(options.mailbox, '*', 'Drafts'); // Default to 'Drafts'
|
|
45
|
+
console.log('Folder: ' + folder);
|
|
46
|
+
|
|
47
|
+
// Check if a UID is provided – meaning the draft is to be updated
|
|
48
|
+
const providedUid = this.parseOptional(options.uid, "*", "");
|
|
49
|
+
console.log('UID: ' + providedUid);
|
|
50
|
+
console.log(`Attempting to save draft to folder: ${folder}`);
|
|
51
|
+
|
|
52
|
+
const imapConfig = {
|
|
53
|
+
imap: {
|
|
54
|
+
user: IMAP_USER,
|
|
55
|
+
password: IMAP_PASSWORD,
|
|
56
|
+
host: IMAP_HOST,
|
|
57
|
+
port: IMAP_PORT,
|
|
58
|
+
tls: IMAP_TLS,
|
|
59
|
+
tlsOptions: { rejectUnauthorized: false },
|
|
60
|
+
authTimeout: 5000
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
let connection;
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
// 1. Construct the email message using mailcomposer
|
|
68
|
+
const mailOptions = {
|
|
69
|
+
from: mailfrom,
|
|
70
|
+
to: to,
|
|
71
|
+
cc: cc,
|
|
72
|
+
bcc: bcc,
|
|
73
|
+
subject: subject,
|
|
74
|
+
html: body, // Use 'text' if it's plain text
|
|
75
|
+
attachments: attachments
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const mail = mailcomposer(mailOptions);
|
|
79
|
+
|
|
80
|
+
const rawEmail = await new Promise((resolve, reject) => {
|
|
81
|
+
mail.build((err, message) => {
|
|
82
|
+
if (err) {
|
|
83
|
+
console.error('Error building email:', err);
|
|
84
|
+
return {
|
|
85
|
+
status: 400,
|
|
86
|
+
message: 'Error building email.',
|
|
87
|
+
uid: '',
|
|
88
|
+
folder: folder
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
resolve(message);
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
console.log('Raw email constructed.');
|
|
96
|
+
|
|
97
|
+
// Debug: Parse the raw email to verify its content
|
|
98
|
+
const parsedEmail = await simpleParser(rawEmail);
|
|
99
|
+
console.log('Parsed Email Content:', {
|
|
100
|
+
subject: parsedEmail.subject,
|
|
101
|
+
text: parsedEmail.text,
|
|
102
|
+
html: parsedEmail.html,
|
|
103
|
+
headers: parsedEmail.headers
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// 2. Connect to IMAP server
|
|
107
|
+
console.log(`Connecting to IMAP server ${IMAP_HOST}:${IMAP_PORT}...`);
|
|
108
|
+
connection = await Imap.connect(imapConfig);
|
|
109
|
+
console.log('Successfully connected to IMAP server.');
|
|
110
|
+
|
|
111
|
+
// 3. Open the target mailbox
|
|
112
|
+
await connection.openBox(folder);
|
|
113
|
+
console.log(`Mailbox "${folder}" opened.`);
|
|
114
|
+
// Retrieve UID validity of the destination mailbox (if available)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
// 4. If a UID is provided, update the existing draft; otherwise, append a new one.
|
|
118
|
+
if (providedUid) {
|
|
119
|
+
console.log(`UID provided (${providedUid}). Updating existing draft...`);
|
|
120
|
+
// Attempt to delete the existing draft for that UID
|
|
121
|
+
try {
|
|
122
|
+
await connection.deleteMessage(providedUid);
|
|
123
|
+
console.log(`Existing draft with UID ${providedUid} deleted.`);
|
|
124
|
+
} catch (delErr) {
|
|
125
|
+
console.warn(`Could not delete existing draft with UID ${providedUid}: ${delErr}`);
|
|
126
|
+
// You might decide to abort here if deletion is mandatory
|
|
127
|
+
}
|
|
128
|
+
// Append the new draft (note: the server will normally assign a new UID,
|
|
129
|
+
// but we are returning the provided UID per the requirement).
|
|
130
|
+
console.log(`Appending updated draft to folder: ${folder}...`);
|
|
131
|
+
const updateAppendResult = await connection.append(rawEmail, {
|
|
132
|
+
mailbox: folder,
|
|
133
|
+
flags: ['\\Draft']
|
|
134
|
+
});
|
|
135
|
+
console.log('Updated draft appended.', updateAppendResult);
|
|
136
|
+
|
|
137
|
+
return {
|
|
138
|
+
status: 200,
|
|
139
|
+
message: 'Draft updated successfully.',
|
|
140
|
+
uid: providedUid,
|
|
141
|
+
folder: folder
|
|
142
|
+
};
|
|
143
|
+
} else {
|
|
144
|
+
console.log(`Appending email as a draft to folder: ${folder}...`);
|
|
145
|
+
const appendResult = await connection.append(rawEmail, {
|
|
146
|
+
mailbox: folder,
|
|
147
|
+
flags: ['\\Draft']
|
|
148
|
+
});
|
|
149
|
+
console.log('Email appended to drafts folder.', appendResult);
|
|
150
|
+
|
|
151
|
+
// Retrieve UID of the saved message
|
|
152
|
+
const searchResult = await connection.search(['ALL'], { bodies: ['HEADER.FIELDS (MESSAGE-ID)'] });
|
|
153
|
+
const uid = searchResult.length > 0 ? searchResult[searchResult.length - 1].attributes.uid : '';
|
|
154
|
+
|
|
155
|
+
return {
|
|
156
|
+
status: 200,
|
|
157
|
+
message: 'Draft saved successfully.',
|
|
158
|
+
uid: uid,
|
|
159
|
+
folder: folder
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
} catch (err) {
|
|
164
|
+
console.error('IMAP draft save failed:', err);
|
|
165
|
+
return {
|
|
166
|
+
status: 400,
|
|
167
|
+
message: 'Failed to save draft.',
|
|
168
|
+
error: err.toString(),
|
|
169
|
+
uid: '',
|
|
170
|
+
folder: folder
|
|
171
|
+
};
|
|
172
|
+
} finally {
|
|
173
|
+
if (connection) {
|
|
174
|
+
try {
|
|
175
|
+
await connection.end();
|
|
176
|
+
console.log('IMAP connection closed.');
|
|
177
|
+
} catch (endErr) {
|
|
178
|
+
console.error('Error ending IMAP connection:', endErr);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace modules;
|
|
4
|
+
|
|
5
|
+
use \lib\core\Module;
|
|
6
|
+
|
|
7
|
+
class custom extends Module
|
|
8
|
+
{
|
|
9
|
+
public function imapsaveflag($options, $name) {
|
|
10
|
+
|
|
11
|
+
$myObj->response = "This function is not yet available in PHP";
|
|
12
|
+
|
|
13
|
+
return json_encode($myObj);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
?>
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
[{
|
|
2
|
+
type: 'imapsendmail-imapsendmail',
|
|
3
|
+
module : 'imapsendmail',
|
|
4
|
+
action : 'imapsendmail',
|
|
5
|
+
groupTitle : 'Mailer',
|
|
6
|
+
groupIcon : 'fas fa-envelope comp-general',
|
|
7
|
+
title : 'IMAP Send Email',
|
|
8
|
+
icon : 'fas fa-solid fa-paper-plane comp-exec',
|
|
9
|
+
dataPickObject: true,
|
|
10
|
+
usedModules : {
|
|
11
|
+
node: {
|
|
12
|
+
'imap' : '^8.8.19',
|
|
13
|
+
'mailparser' : '^3.7.2',
|
|
14
|
+
'nodemailer' : '^6.10.1'
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
dataScheme: [
|
|
18
|
+
{ type: "number",name: "status"},
|
|
19
|
+
{ type: "text",name: "messageId"}
|
|
20
|
+
]
|
|
21
|
+
properties : [
|
|
22
|
+
{
|
|
23
|
+
group: 'IMAP Inputs',
|
|
24
|
+
variables: [
|
|
25
|
+
|
|
26
|
+
{ name: 'actionName',
|
|
27
|
+
optionName: 'name',
|
|
28
|
+
title: 'Name',
|
|
29
|
+
type: 'text',
|
|
30
|
+
required: true,
|
|
31
|
+
baseName: "imap"
|
|
32
|
+
},
|
|
33
|
+
{ name: 'selector', optionName: 'selector', title: 'IAMP Settings Selection',
|
|
34
|
+
type: 'droplist',
|
|
35
|
+
values: [
|
|
36
|
+
{title: 'Use ENV ', value: 'ENV' ,show:[],hide:['imap_msg','imap_host','imap_user','imap_password','imap_port','imap_tls']},
|
|
37
|
+
{title: 'Enable Manual Overrides', value: 'MANUAL',hide:[],show:['imap_msg','imap_host','imap_user','imap_password','imap_port','imap_tls'] },
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
],
|
|
41
|
+
defaultValue: 'ENV',
|
|
42
|
+
help: 'Choose your TLS settings.',
|
|
43
|
+
initValue: "ENV"
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
{name: 'imap_msg',
|
|
47
|
+
optionName: 'imap_msg',
|
|
48
|
+
title: 'IMAP password',
|
|
49
|
+
type: 'static',
|
|
50
|
+
help: 'IMAP .ENV OVERRIDE SETTINGS'
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
{name: 'imap_host',
|
|
54
|
+
optionName: 'imap_host',
|
|
55
|
+
title: 'IMAP Host',
|
|
56
|
+
type: 'text',
|
|
57
|
+
defaultValue: "", initDisplay: 'none',
|
|
58
|
+
serverDataBindings: true,
|
|
59
|
+
help: 'The IMAP Host Server'
|
|
60
|
+
},
|
|
61
|
+
{name: 'imap_user',
|
|
62
|
+
optionName: 'imap_user',
|
|
63
|
+
title: 'IMAP User',
|
|
64
|
+
type: 'text',
|
|
65
|
+
defaultValue: "", initDisplay: 'none',
|
|
66
|
+
serverDataBindings: true,
|
|
67
|
+
help: 'The IMAP user'
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
{name: 'imap_password',
|
|
71
|
+
optionName: 'imap_password',
|
|
72
|
+
title: 'IMAP password',
|
|
73
|
+
type: 'text',
|
|
74
|
+
defaultValue: "", initDisplay: 'none',
|
|
75
|
+
serverDataBindings: true,
|
|
76
|
+
help: 'The IMAP password'
|
|
77
|
+
},
|
|
78
|
+
{name: 'imap_port',
|
|
79
|
+
optionName: 'imap_port',
|
|
80
|
+
title: 'IMAP Port',
|
|
81
|
+
type: 'text',
|
|
82
|
+
defaultValue: "", initDisplay: 'none',
|
|
83
|
+
serverDataBindings: true,
|
|
84
|
+
help: 'The IMAP port'
|
|
85
|
+
},
|
|
86
|
+
{ name: 'imap_tls', optionName: 'imap_tls', title: 'TLS Settings',
|
|
87
|
+
type: 'droplist',
|
|
88
|
+
values: [
|
|
89
|
+
{title: 'Use ENV if available', value: 'ENV' },
|
|
90
|
+
{title: 'True', value: 'True' },
|
|
91
|
+
{title: 'False', value: 'False' },
|
|
92
|
+
|
|
93
|
+
],
|
|
94
|
+
defaultValue: 'ENV', initDisplay: 'none',
|
|
95
|
+
help: 'Choose your TLS settings.',
|
|
96
|
+
initValue: "ENV"
|
|
97
|
+
},
|
|
98
|
+
|
|
99
|
+
{name: 'imap_msg2',
|
|
100
|
+
optionName: 'imap_msg2',
|
|
101
|
+
title: '',
|
|
102
|
+
type: 'static',
|
|
103
|
+
help: 'API ACTION SETTINGS'
|
|
104
|
+
},
|
|
105
|
+
{ name: 'smtp_file',
|
|
106
|
+
optionName: 'smtp_file',
|
|
107
|
+
title: 'SMTP Global Config',
|
|
108
|
+
type: 'text',
|
|
109
|
+
required: true,
|
|
110
|
+
defaultValue: "",
|
|
111
|
+
serverDataBindings: true,
|
|
112
|
+
help: 'The name of the Mailer send config setting'
|
|
113
|
+
},
|
|
114
|
+
{ name: 'from',
|
|
115
|
+
optionName: 'from',
|
|
116
|
+
title: 'From eMail address',
|
|
117
|
+
type: 'text',
|
|
118
|
+
required: true,
|
|
119
|
+
defaultValue: "",
|
|
120
|
+
serverDataBindings: true,
|
|
121
|
+
help: 'The address email will come from'
|
|
122
|
+
},
|
|
123
|
+
{ name: 'to',
|
|
124
|
+
optionName: 'to',
|
|
125
|
+
title: 'To eMail address',
|
|
126
|
+
type: 'text',
|
|
127
|
+
required: true,
|
|
128
|
+
defaultValue: "",
|
|
129
|
+
serverDataBindings: true,
|
|
130
|
+
help: 'The address email will go to'
|
|
131
|
+
},
|
|
132
|
+
{ name: 'cc',
|
|
133
|
+
optionName: 'cc',
|
|
134
|
+
title: 'cc eMail address',
|
|
135
|
+
type: 'text',
|
|
136
|
+
defaultValue: "",
|
|
137
|
+
serverDataBindings: true,
|
|
138
|
+
help: 'The address email will go to'
|
|
139
|
+
},
|
|
140
|
+
{ name: 'bcc',
|
|
141
|
+
optionName: 'bcc',
|
|
142
|
+
title: ' bcc eMail address',
|
|
143
|
+
type: 'text',
|
|
144
|
+
defaultValue: "",
|
|
145
|
+
serverDataBindings: true,
|
|
146
|
+
help: 'The address email will go to'
|
|
147
|
+
},
|
|
148
|
+
{ name: 'subject',
|
|
149
|
+
optionName: 'subject',
|
|
150
|
+
title: 'eMail Subject',
|
|
151
|
+
type: 'text',
|
|
152
|
+
defaultValue: "",
|
|
153
|
+
serverDataBindings: true,
|
|
154
|
+
help: 'The email subject'
|
|
155
|
+
},
|
|
156
|
+
{ name: 'body',
|
|
157
|
+
optionName: 'body',
|
|
158
|
+
title: 'The eMail body',
|
|
159
|
+
type: 'text',
|
|
160
|
+
required: true,
|
|
161
|
+
defaultValue: "",
|
|
162
|
+
serverDataBindings: true,
|
|
163
|
+
help: 'The email body'
|
|
164
|
+
},
|
|
165
|
+
{ name: 'attachments',
|
|
166
|
+
optionName: 'attachments',
|
|
167
|
+
title: 'The eMail attachments',
|
|
168
|
+
type: 'text',
|
|
169
|
+
defaultValue: "",
|
|
170
|
+
serverDataBindings: true,
|
|
171
|
+
help: 'The email attachments'
|
|
172
|
+
},
|
|
173
|
+
{ name: 'save_to_send',
|
|
174
|
+
optionName: 'save_to_send',
|
|
175
|
+
title: 'Save To Sent items',
|
|
176
|
+
type: 'boolean',
|
|
177
|
+
defaultValue: false },
|
|
178
|
+
{ name: 'output',
|
|
179
|
+
optionName: 'output',
|
|
180
|
+
title: 'Output',
|
|
181
|
+
type: 'boolean',
|
|
182
|
+
defaultValue: false
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
]
|
|
186
|
+
},
|
|
187
|
+
|
|
188
|
+
]
|
|
189
|
+
}
|
|
190
|
+
]
|