mirror of
https://github.com/dreamhunter2333/cloudflare_temp_email.git
synced 2026-09-05 15:38:34 +08:00
feat: add auto reply (#49)
* feat: add auto reply * feat: add auto reply * feat: update readme * feat: add auto reply
This commit is contained in:
@@ -1,3 +1,6 @@
|
||||
import { createMimeMessage } from "mimetext";
|
||||
import { EmailMessage } from "cloudflare:email";
|
||||
|
||||
const PostalMime = require("postal-mime");
|
||||
const simpleParser = require('mailparser').simpleParser;
|
||||
global.setImmediate = (callback) => callback();
|
||||
@@ -44,6 +47,34 @@ async function email(message, env, ctx) {
|
||||
message.setReject(`Failed save message to ${message.to}`);
|
||||
console.log(`Failed save message from ${message.from} to ${message.to}`);
|
||||
}
|
||||
try {
|
||||
const results = await env.DB.prepare(
|
||||
`SELECT * FROM auto_reply_mails where address = ? and enabled = 1`
|
||||
).bind(message.to).first();
|
||||
if (results && results.source_prefix && message.from.startsWith(results.source_prefix)) {
|
||||
const msg = createMimeMessage();
|
||||
msg.setHeader("In-Reply-To", message.headers.get("Message-ID"));
|
||||
msg.setSender({
|
||||
name: results.name || results.address,
|
||||
addr: results.address
|
||||
});
|
||||
msg.setRecipient(message.from);
|
||||
msg.setSubject(results.subject || "Auto-reply");
|
||||
msg.addMessage({
|
||||
contentType: 'text/plain',
|
||||
data: results.message || "This is an auto-reply message, please reconact later."
|
||||
});
|
||||
|
||||
const replyMessage = new EmailMessage(
|
||||
message.to,
|
||||
message.from,
|
||||
msg.asRaw()
|
||||
);
|
||||
await message.reply(replyMessage);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("reply email error", error);
|
||||
}
|
||||
} else {
|
||||
message.setReject(`Unknown address ${message.to}`);
|
||||
console.log(`Unknown address ${message.to}`);
|
||||
|
||||
+55
-10
@@ -32,14 +32,59 @@ api.get('/api/mails', async (c) => {
|
||||
})
|
||||
|
||||
api.get('/api/settings', async (c) => {
|
||||
return c.json(c.get("jwtPayload"));
|
||||
const { address } = c.get("jwtPayload")
|
||||
const results = await c.env.DB.prepare(
|
||||
`SELECT * FROM auto_reply_mails where address = ?`
|
||||
).bind(address).first();
|
||||
if (!results) {
|
||||
return c.json({
|
||||
auto_reply: {},
|
||||
address: address
|
||||
});
|
||||
}
|
||||
return c.json({
|
||||
auto_reply: {
|
||||
subject: results.subject,
|
||||
message: results.message,
|
||||
enabled: results.enabled == 1,
|
||||
source_prefix: results.source_prefix,
|
||||
name: results.name,
|
||||
},
|
||||
address: address
|
||||
});
|
||||
})
|
||||
|
||||
|
||||
api.post('/api/settings', async (c) => {
|
||||
const { address } = c.get("jwtPayload")
|
||||
const { auto_reply } = await c.req.json();
|
||||
const { name, subject, source_prefix, message, enabled } = auto_reply;
|
||||
if ((!subject || !message) && enabled) {
|
||||
return c.text("Invalid subject or message", 400)
|
||||
}
|
||||
else if (subject.length > 255 || message.length > 255) {
|
||||
return c.text("Subject or message too long", 400)
|
||||
}
|
||||
const { success } = await c.env.DB.prepare(
|
||||
`INSERT OR REPLACE INTO
|
||||
auto_reply_mails
|
||||
(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)
|
||||
}
|
||||
return c.json({
|
||||
success: success
|
||||
})
|
||||
})
|
||||
|
||||
api.get('/open_api/settings', async (c) => {
|
||||
// check header x-custom-auth
|
||||
let needAuth = false;
|
||||
if (c.env.PASSWORDS && c.env.PASSWORDS.length > 0) {
|
||||
const auth = c.req.headers.get("x-custom-auth");
|
||||
const auth = c.req.raw.headers.get("x-custom-auth");
|
||||
needAuth = !c.env.PASSWORDS.includes(auth);
|
||||
}
|
||||
return c.json({
|
||||
@@ -63,7 +108,7 @@ api.get('/api/new_address', async (c) => {
|
||||
const emailAddress = c.env.PREFIX + name + "@" + domain
|
||||
try {
|
||||
const { success } = await c.env.DB.prepare(
|
||||
`INSERT INTO address (name) VALUES (?)`
|
||||
`INSERT INTO address(name) VALUES(?)`
|
||||
).bind(name + "@" + domain).run();
|
||||
if (!success) {
|
||||
return c.text("Failed to create address", 500)
|
||||
@@ -92,7 +137,7 @@ api.get('/admin/address', async (c) => {
|
||||
return c.text("Invalid offset", 400)
|
||||
}
|
||||
const { results } = await c.env.DB.prepare(
|
||||
`SELECT * FROM address order by id desc limit ? offset ?`
|
||||
`SELECT * FROM address order by id desc limit ? offset ? `
|
||||
).bind(limit, offset).all();
|
||||
let count = 0;
|
||||
if (offset == 0) {
|
||||
@@ -113,7 +158,7 @@ api.get('/admin/address', async (c) => {
|
||||
api.delete('/admin/delete_address/:id', async (c) => {
|
||||
const { id } = c.req.param();
|
||||
const { success } = await c.env.DB.prepare(
|
||||
`DELETE FROM address WHERE id = ?`
|
||||
`DELETE FROM address WHERE id = ? `
|
||||
).bind(id).run();
|
||||
if (!success) {
|
||||
return c.text("Failed to delete address", 500)
|
||||
@@ -126,7 +171,7 @@ api.delete('/admin/delete_address/:id', async (c) => {
|
||||
api.get('/admin/show_password/:id', async (c) => {
|
||||
const { id } = c.req.param();
|
||||
const name = await c.env.DB.prepare(
|
||||
`SELECT name FROM address WHERE id = ?`
|
||||
`SELECT name FROM address WHERE id = ? `
|
||||
).bind(id).first("name");
|
||||
// compute address
|
||||
const emailAddress = c.env.PREFIX + name
|
||||
@@ -148,12 +193,12 @@ api.get('/admin/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 FROM mails where address = ? order by id desc limit ? offset ? `
|
||||
).bind(address, limit, offset).all();
|
||||
let count = 0;
|
||||
if (offset == 0) {
|
||||
const { count: mailCount } = await c.env.DB.prepare(
|
||||
`SELECT count(*) as count FROM mails where address = ?`
|
||||
`SELECT count(*) as count FROM mails where address = ? `
|
||||
).bind(address).first();
|
||||
count = mailCount;
|
||||
}
|
||||
@@ -173,7 +218,7 @@ api.get('/admin/mails_unknow', async (c) => {
|
||||
}
|
||||
const { results } = await c.env.DB.prepare(`
|
||||
SELECT id, source, subject, message FROM mails
|
||||
where address NOT IN (select concat('${c.env.PREFIX}', name) from address)
|
||||
where address NOT IN(select concat('${c.env.PREFIX}', name) from address)
|
||||
order by id desc limit ? offset ? `
|
||||
).bind(limit, offset).all();
|
||||
let count = 0;
|
||||
@@ -181,7 +226,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;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ app.use('/*', cors());
|
||||
app.use('/api/*', async (c, next) => {
|
||||
// check header x-custom-auth
|
||||
if (c.env.PASSWORDS && c.env.PASSWORDS.length > 0) {
|
||||
const auth = c.req.headers.get("x-custom-auth");
|
||||
const auth = c.req.raw.headers.get("x-custom-auth");
|
||||
if (!auth || !c.env.PASSWORDS.includes(auth)) {
|
||||
return c.text("Need Password", 401)
|
||||
}
|
||||
@@ -25,7 +25,7 @@ app.use('/api/*', async (c, next) => {
|
||||
app.use('/admin/*', async (c, next) => {
|
||||
// check header x-admin-auth
|
||||
if (c.env.ADMIN_PASSWORDS && c.env.ADMIN_PASSWORDS.length > 0) {
|
||||
const adminAuth = c.req.headers.get("x-admin-auth");
|
||||
const adminAuth = c.req.raw.headers.get("x-admin-auth");
|
||||
if (adminAuth && c.env.ADMIN_PASSWORDS.includes(adminAuth)) {
|
||||
await next();
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user