feat: attachment viewing function (#58)

This commit is contained in:
Dream Hunter
2024-01-13 23:57:52 +08:00
committed by GitHub
parent 2952a641a5
commit 97a1f0a968
11 changed files with 604 additions and 472 deletions

View File

@@ -35,18 +35,22 @@ async function email(message, env, ctx) {
const parser = new PostalMime.default();
parsedEmail = await parser.parse(rawEmail);
}
const message_id = message.headers.get("Message-ID");
// process email
const { success } = await env.DB.prepare(
`INSERT INTO mails (source, address, subject, message) VALUES (?, ?, ?, ?)`
`INSERT INTO mails (source, address, subject, message, message_id) VALUES (?, ?, ?, ?, ?)`
).bind(
message.from, message.to,
parsedEmail.subject || "",
parsedEmail.html || parsedEmail.textAsHtml || parsedEmail.text || ""
parsedEmail.html || parsedEmail.textAsHtml || parsedEmail.text || "",
message_id
).run();
if (!success) {
message.setReject(`Failed save message to ${message.to}`);
console.log(`Failed save message from ${message.from} to ${message.to}`);
}
// auto reply email
try {
const results = await env.DB.prepare(
`SELECT * FROM auto_reply_mails where address = ? and enabled = 1`
@@ -75,6 +79,27 @@ async function email(message, env, ctx) {
} catch (error) {
console.log("reply email error", error);
}
// process attachments
try {
if (
parsedEmail.attachments
&& parsedEmail.attachments.length > 0
) {
const { success } = await env.DB.prepare(
`INSERT INTO attachments (source, address, message_id, data) VALUES (?, ?, ?, ?)`
).bind(
message.from, message.to, message_id,
JSON.stringify(parsedEmail.attachments)
).run();
if (!success) {
message.setReject(`Failed save attachment to ${message.to}`);
console.log(`Failed save attachment from ${message.from} to ${message.to}`);
}
}
}
catch (error) {
console.log("save attachment error", error);
}
} else {
message.setReject(`Unknown address ${message.to}`);
console.log(`Unknown address ${message.to}`);

View File

@@ -16,7 +16,7 @@ api.get('/api/mails', async (c) => {
return c.text("Invalid offset", 400)
}
const { results } = await c.env.DB.prepare(
`SELECT id, source, subject, message FROM mails where address = ? order by id desc limit ? offset ?`
`SELECT id, source, subject, message, message_id FROM mails where address = ? order by id desc limit ? offset ?`
).bind(address, limit, offset).all();
let count = 0;
if (offset == 0) {
@@ -25,6 +25,23 @@ api.get('/api/mails', async (c) => {
).bind(address).first();
count = mailCount;
}
// add attachments
let attachmentResults = [];
const message_ids = results.map((r) => r.message_id).filter((r) => r);
console.log("message_ids", message_ids.map((id) => `'${id}'`).join(","));
if (message_ids && message_ids.length > 0) {
const { results: innerAttachmentResults } = await c.env.DB.prepare(
`SELECT id, message_id FROM attachments where message_id in (${message_ids.map((id) => `'${id}'`).join(",")})`
).all();
attachmentResults = innerAttachmentResults || [];
}
results.forEach((r) => {
const attachment_id = attachmentResults.filter((ar) => ar.message_id == r.message_id).map((ar) => ar.id);
if (attachment_id && attachment_id.length > 0) {
r.attachment_id = attachment_id[0];
}
delete r.message_id;
})
return c.json({
results: results,
count: count
@@ -34,7 +51,7 @@ api.get('/api/mails', async (c) => {
api.get('/api/settings', async (c) => {
const { address } = c.get("jwtPayload")
const results = await c.env.DB.prepare(
`SELECT * FROM auto_reply_mails where address = ?`
`SELECT * FROM auto_reply_mails where address = ? `
).bind(address).first();
if (!results) {
return c.json({
@@ -68,9 +85,9 @@ api.post('/api/settings', async (c) => {
const { success } = await c.env.DB.prepare(
`INSERT OR REPLACE INTO
auto_reply_mails
(name, address, source_prefix, subject, message, enabled)
(name, address, source_prefix, subject, message, enabled)
VALUES
(?, ?, ?, ?, ?, ?)`
(?, ?, ?, ?, ?, ?)`
).bind(name || '', address, source_prefix || '', subject || '', message || '', enabled ? 1 : 0).run();
if (!success) {
return c.text("Failed to save settings", 500)
@@ -226,7 +243,7 @@ api.get('/admin/mails_unknow', async (c) => {
const { count: mailCount } = await c.env.DB.prepare(`
SELECT count(*) as count FROM mails
where address NOT IN
(select concat('${c.env.PREFIX}', name) from address)`
(select concat('${c.env.PREFIX}', name) from address)`
).first();
count = mailCount;
}
@@ -236,5 +253,16 @@ api.get('/admin/mails_unknow', async (c) => {
})
});
// attachments
api.get("/api/attachment/:attachment_id", async (c) => {
const { attachment_id } = c.req.param();
const { data } = await c.env.DB.prepare(
`SELECT data FROM attachments where id = ? `
).bind(attachment_id).first();
if (!data) {
return c.text("Not found", 404)
}
return c.json(JSON.parse(data))
})
export { api }