新增tg和第三方邮件转发
This commit is contained in:
@@ -5,13 +5,30 @@ import settingService from '../service/setting-service';
|
||||
import attService from '../service/att-service';
|
||||
import constant from '../const/constant';
|
||||
import fileUtils from '../utils/file-utils';
|
||||
import {attConst, emailConst, isDel} from '../const/entity-const';
|
||||
import { attConst, emailConst, isDel, settingConst } from '../const/entity-const';
|
||||
import emailUtils from '../utils/email-utils';
|
||||
import dayjs from 'dayjs';
|
||||
import utc from 'dayjs/plugin/utc'
|
||||
import timezone from 'dayjs/plugin/timezone'
|
||||
dayjs.extend(utc)
|
||||
dayjs.extend(timezone)
|
||||
|
||||
export async function email(message, env, ctx) {
|
||||
|
||||
try {
|
||||
|
||||
if (!await settingService.isReceive({ env })) {
|
||||
const {
|
||||
receive,
|
||||
tgBotToken,
|
||||
tgChatId,
|
||||
tgBotStatus,
|
||||
forwardStatus,
|
||||
forwardEmail,
|
||||
ruleEmail,
|
||||
ruleType
|
||||
} = await settingService.query({ env });
|
||||
|
||||
if (receive === settingConst.receive.CLOSE) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -28,14 +45,18 @@ export async function email(message, env, ctx) {
|
||||
|
||||
const email = await PostalMime.parse(content);
|
||||
|
||||
const toName = email.to.find(item => item.address === message.to)?.name || '';
|
||||
|
||||
const params = {
|
||||
toEmail: message.to,
|
||||
toName: toName,
|
||||
sendEmail: email.from.address,
|
||||
name: email.from.name,
|
||||
subject: email.subject,
|
||||
content: email.html,
|
||||
text: email.text,
|
||||
cc: email.cc ? JSON.stringify(email.cc) : '[]',
|
||||
bcc:email.bcc ? JSON.stringify(email.bcc) : '[]',
|
||||
bcc: email.bcc ? JSON.stringify(email.bcc) : '[]',
|
||||
recipient: JSON.stringify(email.to),
|
||||
inReplyTo: email.inReplyTo,
|
||||
relation: email.references,
|
||||
@@ -49,32 +70,96 @@ export async function email(message, env, ctx) {
|
||||
const attachments = [];
|
||||
const cidAttachments = [];
|
||||
|
||||
for(let item of email.attachments) {
|
||||
for (let item of email.attachments) {
|
||||
let attachment = { ...item };
|
||||
attachment.key = constant.ATTACHMENT_PREFIX + await fileUtils.getBuffHash(attachment.content) + fileUtils.getExtFileName(item.filename);
|
||||
attachment.size = item.content.length ?? item.content.byteLength;
|
||||
attachments.push(attachment);
|
||||
if (attachment.contentId) {
|
||||
cidAttachments.push(attachment)
|
||||
cidAttachments.push(attachment);
|
||||
}
|
||||
}
|
||||
|
||||
const emailRow = await emailService.receive({ env }, params, cidAttachments);
|
||||
let emailRow = await emailService.receive({ env }, params, cidAttachments);
|
||||
|
||||
attachments.forEach(attachment => {
|
||||
attachment.emailId = emailRow.emailId;
|
||||
attachment.userId = emailRow.userId;
|
||||
attachment.accountId = emailRow.accountId;
|
||||
attachment.type = attachment.contentId ? attConst.type.EMBED : attConst.type.ATT
|
||||
})
|
||||
attachment.type = attachment.contentId ? attConst.type.EMBED : attConst.type.ATT;
|
||||
});
|
||||
|
||||
if (attachments.length > 0) {
|
||||
await attService.addAtt({ env }, attachments);
|
||||
}
|
||||
|
||||
await emailService.completeReceive({ env },account ? emailConst.status.RECEIVE : emailConst.status.NOONE, emailRow.emailId);
|
||||
emailRow = await emailService.completeReceive({ env }, account ? emailConst.status.RECEIVE : emailConst.status.NOONE, emailRow.emailId);
|
||||
|
||||
|
||||
if (ruleType === settingConst.ruleType.RULE) {
|
||||
|
||||
const emails = ruleEmail.split(',');
|
||||
|
||||
if (!emails.includes(message.to)) {
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (tgBotStatus === settingConst.tgBotStatus.OPEN && tgChatId) {
|
||||
|
||||
const tgMessage = `<b>${params.subject}</b>
|
||||
|
||||
<b>发件人:</b>${params.name} <${params.sendEmail}>
|
||||
<b>收件人:\u200B</b>${message.to}
|
||||
<b>时间:</b>${dayjs.utc(emailRow.createTime).tz('Asia/Shanghai').format('YYYY-MM-DD HH:mm')}
|
||||
|
||||
${emailUtils.htmlToText(params.content) || ''}
|
||||
`;
|
||||
|
||||
const tgChatIds = tgChatId.split(',');
|
||||
|
||||
await Promise.all(tgChatIds.map(async chatId => {
|
||||
try {
|
||||
const res = await fetch(`https://api.telegram.org/bot${tgBotToken}/sendMessage`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
chat_id: chatId,
|
||||
parse_mode: 'HTML',
|
||||
text: tgMessage
|
||||
})
|
||||
});
|
||||
if (!res.ok) {
|
||||
console.error(`转发 Telegram 失败: chatId=${chatId}, 状态码=${res.status}`);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(`转发 Telegram 失败: chatId=${chatId}`, e);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
if (forwardStatus === settingConst.forwardStatus.OPEN && forwardEmail) {
|
||||
|
||||
const emails = forwardEmail.split(',');
|
||||
|
||||
await Promise.all(emails.map(async email => {
|
||||
|
||||
try {
|
||||
await message.forward(email);
|
||||
} catch (e) {
|
||||
console.error(`转发邮箱 ${email} 失败:`, e);
|
||||
}
|
||||
|
||||
}));
|
||||
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
|
||||
console.error('邮件接收异常: ', e);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user