@postalsys/email-text-tools 1.1.1 → 1.2.1
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/.ncurc.js +8 -0
- package/examples/reply.js +23 -0
- package/index.js +2 -1
- package/lib/extract-reply.js +89 -0
- package/package.json +8 -6
package/.ncurc.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('fs').promises;
|
|
4
|
+
const extractReply = require('../lib/extract-reply');
|
|
5
|
+
const simpleParser = require('mailparser').simpleParser;
|
|
6
|
+
|
|
7
|
+
async function main() {
|
|
8
|
+
const eml = await fs.readFile(process.argv[2]);
|
|
9
|
+
|
|
10
|
+
const parsed = await simpleParser(eml);
|
|
11
|
+
|
|
12
|
+
const replyText = await extractReply(
|
|
13
|
+
{
|
|
14
|
+
html: parsed.html,
|
|
15
|
+
text: parsed.text
|
|
16
|
+
},
|
|
17
|
+
process.env.OPENAI_API_KEY
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
console.log(replyText);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
main();
|
package/index.js
CHANGED
|
@@ -5,5 +5,6 @@ const htmlToText = require('./lib/html-to-text');
|
|
|
5
5
|
const inlineHtml = require('./lib/inline-html');
|
|
6
6
|
const inlineText = require('./lib/inline-text');
|
|
7
7
|
const mimeHtml = require('./lib/mime-html');
|
|
8
|
+
const extractReply = require('./lib/extract-reply');
|
|
8
9
|
|
|
9
|
-
module.exports = { textToHtml, htmlToText, inlineHtml, inlineText, mimeHtml };
|
|
10
|
+
module.exports = { textToHtml, htmlToText, inlineHtml, inlineText, mimeHtml, extractReply };
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const packageData = require('../package.json');
|
|
4
|
+
const htmlToText = require('../lib/html-to-text');
|
|
5
|
+
const nodeFetch = require('node-fetch');
|
|
6
|
+
const fetchCmd = global.fetch || nodeFetch;
|
|
7
|
+
|
|
8
|
+
const MAX_TEXT_LENGTH = 6 * 1024;
|
|
9
|
+
const OPENAI_API_URL = 'https://api.openai.com/v1/chat/completions';
|
|
10
|
+
|
|
11
|
+
async function extractReply(message, apiToken) {
|
|
12
|
+
let text = message.text;
|
|
13
|
+
if (!text && message.html) {
|
|
14
|
+
text = htmlToText(message.text);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
text = text.trim();
|
|
18
|
+
if (text.length > MAX_TEXT_LENGTH) {
|
|
19
|
+
text = text.substring(0, MAX_TEXT_LENGTH);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let headers = {
|
|
23
|
+
'User-Agent': `${packageData.name}/${packageData.version}`,
|
|
24
|
+
Authorization: `Bearer ${apiToken}`,
|
|
25
|
+
'Content-Type': 'application/json'
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
let payload = {
|
|
29
|
+
model: 'gpt-3.5-turbo',
|
|
30
|
+
messages: [
|
|
31
|
+
{
|
|
32
|
+
role: 'user',
|
|
33
|
+
content: `Extract the reply text without the final courtesy closing from the following email message:
|
|
34
|
+
|
|
35
|
+
${text}`
|
|
36
|
+
}
|
|
37
|
+
]
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
let res = await fetchCmd(OPENAI_API_URL, {
|
|
41
|
+
method: 'post',
|
|
42
|
+
headers,
|
|
43
|
+
body: JSON.stringify(payload)
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
let data = await res.json();
|
|
47
|
+
|
|
48
|
+
if (!res.ok) {
|
|
49
|
+
if (data && data.error) {
|
|
50
|
+
let error = new Error(data.error.message || data.error);
|
|
51
|
+
if (data.error.code) {
|
|
52
|
+
error.code = data.error.code;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
error.statusCode = res.status;
|
|
56
|
+
throw error;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
let error = new Error('Failed to run API request');
|
|
60
|
+
error.statusCode = res.status;
|
|
61
|
+
throw error;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (!data) {
|
|
65
|
+
throw new Error(`Failed to POST API request`);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
let output =
|
|
69
|
+
data &&
|
|
70
|
+
data.choices &&
|
|
71
|
+
data.choices
|
|
72
|
+
.filter(msg => msg && msg.message && msg.message.role === 'assistant' && msg.message.content)
|
|
73
|
+
.sort((a, b) => ((a && a.index) || 0) - ((b && b.index) || 0))
|
|
74
|
+
.map(msg => msg.message.content)
|
|
75
|
+
.join('\n')
|
|
76
|
+
.trim()
|
|
77
|
+
.replace(/^\s*"|"\s*$/g, '')
|
|
78
|
+
.trim();
|
|
79
|
+
|
|
80
|
+
const response = {
|
|
81
|
+
id: data && data.id,
|
|
82
|
+
tokens: data && data.usage && data.usage.total_tokens,
|
|
83
|
+
replyText: output
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
return response;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
module.exports = extractReply;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@postalsys/email-text-tools",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "Email text tools",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -19,19 +19,21 @@
|
|
|
19
19
|
"homepage": "https://github.com/postalsys/email-text-tools#readme",
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"eslint-config-nodemailer": "1.2.0",
|
|
22
|
-
"eslint-config-prettier": "8.
|
|
22
|
+
"eslint-config-prettier": "8.7.0",
|
|
23
|
+
"mailparser": "3.6.4"
|
|
23
24
|
},
|
|
24
25
|
"dependencies": {
|
|
25
26
|
"dompurify": "3.0.1",
|
|
26
27
|
"handlebars": "4.7.7",
|
|
27
28
|
"he": "1.2.0",
|
|
28
|
-
"html-to-text": "
|
|
29
|
+
"html-to-text": "9.0.4",
|
|
29
30
|
"js-beautify": "1.14.7",
|
|
30
31
|
"jsdom": "21.1.0",
|
|
31
32
|
"juice": "8.1.0",
|
|
32
33
|
"linkify-it": "4.0.1",
|
|
33
|
-
"moment-timezone": "0.5.
|
|
34
|
-
"node-
|
|
35
|
-
"
|
|
34
|
+
"moment-timezone": "0.5.41",
|
|
35
|
+
"node-fetch": "2.6.7",
|
|
36
|
+
"node-html-parser": "6.1.5",
|
|
37
|
+
"tlds": "1.236.0"
|
|
36
38
|
}
|
|
37
39
|
}
|