mirror of
https://github.com/schroinerxy/cloud-mail.git
synced 2026-06-21 19:35:50 +08:00
新增自定义显示TG邮件消息内容
This commit is contained in:
@@ -87,16 +87,11 @@ function autoScale() {
|
||||
if (!shadowContent) return
|
||||
|
||||
const parentWidth = parent.offsetWidth
|
||||
const parentHeight = parent.offsetHeight
|
||||
|
||||
const childWidth = shadowContent.scrollWidth
|
||||
const childHeight = shadowContent.scrollHeight
|
||||
|
||||
if (childWidth === 0 || childHeight === 0) return
|
||||
if (childWidth === 0) return
|
||||
|
||||
const scaleX = parentWidth / childWidth
|
||||
const scaleY = parentHeight / childHeight
|
||||
const scale = Math.min(scaleX, scaleY)
|
||||
const scale = parentWidth / childWidth
|
||||
|
||||
const hostElement = shadowRoot.host
|
||||
hostElement.style.zoom = scale
|
||||
|
||||
+20
-15
@@ -137,7 +137,7 @@ const en = {
|
||||
websiteReg: 'Sign Up',
|
||||
loginDomain: 'Sign-In Box Domain',
|
||||
multipleEmail: 'Multiple Accounts',
|
||||
multipleEmailDesc: 'Enable this feature to allow users to add multiple accounts.',
|
||||
multipleEmailDesc: 'Enable this feature to allow users to add multiple accounts',
|
||||
customization: 'Customization',
|
||||
websiteTitle: 'Title',
|
||||
loginBoxOpacity: 'Login Box Opacity',
|
||||
@@ -145,7 +145,7 @@ const en = {
|
||||
emailSetting: 'Email',
|
||||
receiveEmail: 'Receive Email',
|
||||
autoRefresh: 'Auto Refresh',
|
||||
autoRefreshDesc: 'Automatically fetch the latest emails from the server.',
|
||||
autoRefreshDesc: 'Automatically fetch the latest emails from the server',
|
||||
sendEmail: 'Send Email',
|
||||
resendToken: 'Resend Token',
|
||||
oss: 'Object Storage',
|
||||
@@ -165,7 +165,7 @@ const en = {
|
||||
version: 'Version',
|
||||
community: 'Community',
|
||||
changeTitle: 'Change Title',
|
||||
addResendTokenDesc: 'Input to add; leave empty to delete.',
|
||||
addResendTokenDesc: 'Input to add; leave empty to delete',
|
||||
addOsDomain: 'Add Domain',
|
||||
domainDesc: 'Domain',
|
||||
addTurnstileSecret: 'Add turnstile secret',
|
||||
@@ -173,14 +173,14 @@ const en = {
|
||||
tgBotDesc: 'Forward received emails to a Telegram bot',
|
||||
tgBotToken: 'Bot token',
|
||||
toBotTokenDesc: 'Multiple user chat_ids, separated by commas',
|
||||
otherEmailDesc: 'emails can be forwarded to external email, but must be verified via cloudflare.',
|
||||
otherEmailInputDesc: 'Separate multiple email addresses with commas.',
|
||||
forwardingRulesDesc: 'Rule-based forwarding only forwards emails received by the specified address.',
|
||||
ruleEmailsInputDesc: 'Separate multiple email addresses with commas.',
|
||||
otherEmailDesc: 'emails can be forwarded to external email, but must be verified via cloudflare',
|
||||
otherEmailInputDesc: 'Separate multiple email addresses with commas',
|
||||
forwardingRulesDesc: 'Rule-based forwarding only forwards emails received by the specified address',
|
||||
ruleEmailsInputDesc: 'Separate multiple email addresses with commas',
|
||||
resendTokenList: 'Token List',
|
||||
domain: 'Domain',
|
||||
optional: 'Optional',
|
||||
subjectInputDesc: 'Please enter the email subject.',
|
||||
subjectInputDesc: 'Please enter the email subject',
|
||||
changeUserName: 'Change Username',
|
||||
sendSeparately: 'Separately',
|
||||
send: 'Send',
|
||||
@@ -251,14 +251,14 @@ const en = {
|
||||
supportDesc: 'Buy me tea',
|
||||
featDesc: 'Feature Description',
|
||||
emailInterception: 'Email Interception',
|
||||
emailInterceptionDesc: 'Enter a domain or email address to prevent users from receiving emails from certain websites (Enter * to block all).',
|
||||
emailInterceptionDesc: 'Enter a domain or email address to prevent users from receiving emails from certain websites (Enter * to block all)',
|
||||
availableDomains: 'Available Domains',
|
||||
availableDomainsDesc: 'Restrict users to email domains specified. Domains not on the approved list will be blocked from registration, adding email addresses, and sending/receiving emails. If left blank, all domains will be allowed by default.',
|
||||
availableDomainsDesc: 'Restrict users to email domains specified. Domains not on the approved list will be blocked from registration, adding email addresses, and sending/receiving emails. If left blank, all domains will be allowed by default',
|
||||
backgroundUrlDesc: 'Image URL',
|
||||
localUpload: ' Local upload',
|
||||
imageLink: 'Image URL',
|
||||
imageLinkErrorMsg: 'Invalid image URL',
|
||||
backgroundWarning: 'Image file size affects website load speed.',
|
||||
backgroundWarning: 'Image file size affects website load speed',
|
||||
rulesVerify: 'Rules',
|
||||
rulesVerifyTitle: 'Trigger After {count} Daily Uses per IP',
|
||||
botVerifyMsg: 'Please verify that you are human',
|
||||
@@ -278,7 +278,7 @@ const en = {
|
||||
verifyModuleFailed: 'Verification module failed to load. Please refresh the page',
|
||||
popUp: 'Pop Up',
|
||||
noRecipientTitle: 'No Recipient',
|
||||
noRecipientDesc: 'Emails can be received even without a registered email address.',
|
||||
noRecipientDesc: 'Emails can be received even without a registered email address',
|
||||
preview: 'Preview',
|
||||
help: 'Help',
|
||||
document: 'Document',
|
||||
@@ -292,12 +292,17 @@ const en = {
|
||||
include: 'Include',
|
||||
delAllEmailConfirm: 'Do you really want to delete it?',
|
||||
s3Configuration: 'S3 Configuration',
|
||||
s3Desc: 'If another S3-compatible storage is configured, R2 will take priority if it’s already connected',
|
||||
confirmDeletionOfContacts: 'Confirm clearing contacts?',
|
||||
recentContacts: 'Recent contacts',
|
||||
selectContacts: 'Select',
|
||||
forcePathStyleDesc: 'Some self-hosted object storages require path-style access to be enabled.',
|
||||
kvStorageDesc: 'Replace object storage with KV, and update the access domain to a Worker custom domain.',
|
||||
kvStorage: 'KV Storage'
|
||||
forcePathStyleDesc: 'Some self-hosted object storages require path-style access to be enabled',
|
||||
kvStorageDesc: 'Replace object storage with KV, and update the access domain to a Worker custom domain',
|
||||
kvStorage: 'KV Storage',
|
||||
customDomainDesc: 'Worker custom domain',
|
||||
show: 'Show',
|
||||
hide: 'Hide',
|
||||
onlyName: 'Only name'
|
||||
}
|
||||
|
||||
export default en
|
||||
|
||||
@@ -299,6 +299,9 @@ const zh = {
|
||||
forcePathStyleDesc: '路径样式访问,一些自建的对象存储需要打开',
|
||||
kvStorageDesc: '使用KV替代对象存储,访问域名改成worker自定义域',
|
||||
kvStorage: 'KV 存储',
|
||||
customDomainDesc: 'Worker 自定义域'
|
||||
customDomainDesc: 'Worker 自定义域',
|
||||
show: '显示',
|
||||
hide: '隐藏',
|
||||
onlyName: '仅名字'
|
||||
}
|
||||
export default zh
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
fit="cover"
|
||||
>
|
||||
<template #error>
|
||||
<div class="error-image" @click="openSetBackground">
|
||||
<div class="error-image">
|
||||
<Icon icon="ph:image" width="24" height="24"/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -486,6 +486,28 @@
|
||||
<el-input-tag tag-type="warning" :placeholder="$t('toBotTokenDesc')" v-model="tgChatId"
|
||||
@add-tag="addChatTag"></el-input-tag>
|
||||
<el-input tag-type="warning" :placeholder="$t('customDomainDesc')" v-model="customDomain" ></el-input>
|
||||
<div class="tg-msg-label">
|
||||
<span>{{t('from')}}</span>
|
||||
<el-select v-model="tgMsgFrom" >
|
||||
<el-option
|
||||
v-for="item in tgMsgFromOption"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="tg-msg-label">
|
||||
<span>{{t('recipient')}}</span>
|
||||
<el-select v-model="tgMsgTo" >
|
||||
<el-option
|
||||
v-for="item in tgMsgToOption"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
@@ -787,6 +809,12 @@ const emailColumnWidth = ref(0)
|
||||
const tokenColumnWidth = ref(0)
|
||||
const ruleType = ref(0)
|
||||
const ruleEmail = ref([])
|
||||
const tgMsgFrom = ref('')
|
||||
const tgMsgTo = ref('')
|
||||
|
||||
const tgMsgFromOption = [{label: t('show'), value: 'show'}, {label: t('hide'), value: 'hide'}, {label: t('onlyName'), value:'only-name'}]
|
||||
const tgMsgToOption = [{label: t('show'), value: 'show'}, {label: t('hide'), value: 'hide'}]
|
||||
const tgMsgLabelWidth = computed(() => locale.value === 'en' ? '120px' : '100px');
|
||||
|
||||
getSettings()
|
||||
getUpdate()
|
||||
@@ -901,6 +929,8 @@ function openTgSetting() {
|
||||
tgBotStatus.value = setting.value.tgBotStatus
|
||||
tgBotToken.value = setting.value.tgBotToken
|
||||
customDomain.value = setting.value.customDomain
|
||||
tgMsgFrom.value = setting.value.tgMsgFrom
|
||||
tgMsgTo.value = setting.value.tgMsgTo
|
||||
tgChatId.value = []
|
||||
if (setting.value.tgChatId) {
|
||||
const list = setting.value.tgChatId.split(',')
|
||||
@@ -1036,7 +1066,9 @@ function tgBotSave() {
|
||||
tgBotToken: tgBotToken.value,
|
||||
customDomain: customDomain.value,
|
||||
tgBotStatus: tgBotStatus.value,
|
||||
tgChatId: tgChatId.value + ''
|
||||
tgChatId: tgChatId.value + '',
|
||||
tgMsgFrom: tgMsgFrom.value,
|
||||
tgMsgTo: tgMsgTo.value
|
||||
}
|
||||
editSetting(form)
|
||||
}
|
||||
@@ -1496,6 +1528,7 @@ function editSetting(settingForm, refreshStatus = true) {
|
||||
|
||||
.forward-set-title {
|
||||
top: 1px;
|
||||
padding-right: 5px;
|
||||
position: relative;
|
||||
font-size: 16px;
|
||||
font-weight: bold;;
|
||||
@@ -1548,11 +1581,24 @@ function editSetting(settingForm, refreshStatus = true) {
|
||||
.forward-set-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 15px;
|
||||
|
||||
.el-switch {
|
||||
align-self: end;
|
||||
}
|
||||
|
||||
> *:nth-child(-n+2) {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.tg-msg-label {
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
.el-select {
|
||||
width: v-bind(tgMsgLabelWidth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.forward {
|
||||
|
||||
@@ -6,3 +6,4 @@ app.get('/telegram/getEmail/:token', async (c) => {
|
||||
c.header('Cache-Control', 'public, max-age=604800, immutable');
|
||||
return c.html(content)
|
||||
});
|
||||
|
||||
|
||||
@@ -42,6 +42,8 @@ export const setting = sqliteTable('setting', {
|
||||
s3SecretKey: text('s3_secret_key').default('').notNull(),
|
||||
kvStorage: integer('kv_storage').default(1).notNull(),
|
||||
forcePathStyle: integer('force_path_style').default(1).notNull(),
|
||||
customDomain: text('custom_domain').default('').notNull()
|
||||
customDomain: text('custom_domain').default('').notNull(),
|
||||
tgMsgFrom: text('tg_msg_from').default('only-name').notNull(),
|
||||
tgMsgTo: text('tg_msg_to').default('show').notNull()
|
||||
});
|
||||
export default setting
|
||||
|
||||
@@ -32,7 +32,9 @@ const init = {
|
||||
await c.env.db.batch([
|
||||
c.env.db.prepare(`ALTER TABLE setting ADD COLUMN force_path_style INTEGER NOT NULL DEFAULT 1;`),
|
||||
c.env.db.prepare(`ALTER TABLE setting ADD COLUMN kv_storage INTEGER NOT NULL DEFAULT 1;`),
|
||||
c.env.db.prepare(`ALTER TABLE setting ADD COLUMN custom_domain TEXT NOT NULL DEFAULT '';`)
|
||||
c.env.db.prepare(`ALTER TABLE setting ADD COLUMN custom_domain TEXT NOT NULL DEFAULT '';`),
|
||||
c.env.db.prepare(`ALTER TABLE setting ADD COLUMN tg_msg_to TEXT NOT NULL DEFAULT 'show';`),
|
||||
c.env.db.prepare(`ALTER TABLE setting ADD COLUMN tg_msg_from TEXT NOT NULL DEFAULT 'only-name';`)
|
||||
]);
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
|
||||
@@ -15,26 +15,6 @@ import verifyUtils from '../utils/verify-utils';
|
||||
|
||||
const telegramService = {
|
||||
|
||||
async getEmailById(c, params) {
|
||||
|
||||
const { emailId } = params
|
||||
|
||||
const emailRow = await orm(c).select().from(email).where(eq(email.emailId, emailId)).get();
|
||||
|
||||
if (emailRow) {
|
||||
|
||||
if (emailRow.content) {
|
||||
return emailHtmlTemplate(emailRow.content || '')
|
||||
} else {
|
||||
return emailTextTemplate(emailRow.text || '')
|
||||
}
|
||||
|
||||
} else {
|
||||
return emailTextTemplate('The email does not exist')
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
async getEmailContent(c, params) {
|
||||
|
||||
const { token } = params
|
||||
@@ -50,7 +30,8 @@ const telegramService = {
|
||||
if (emailRow) {
|
||||
|
||||
if (emailRow.content) {
|
||||
return emailHtmlTemplate(emailRow.content || '')
|
||||
const { r2Domain } = await settingService.query(c);
|
||||
return emailHtmlTemplate(emailRow.content || '', r2Domain)
|
||||
} else {
|
||||
return emailTextTemplate(emailRow.text || '')
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { parseHTML } from 'linkedom';
|
||||
import domainUtils from '../utils/domain-uitls';
|
||||
|
||||
export default function emailHtmlTemplate(html) {
|
||||
export default function emailHtmlTemplate(html, domain) {
|
||||
|
||||
const { document } = parseHTML(html);
|
||||
document.querySelectorAll('script').forEach(script => script.remove());
|
||||
html = document.documentElement.outerHTML;
|
||||
html = html.replace(/{{domain}}/g, domainUtils.toOssDomain(domain) + '/');
|
||||
|
||||
return `<!DOCTYPE html>
|
||||
<html lang='en' >
|
||||
@@ -105,6 +107,7 @@ export default function emailHtmlTemplate(html) {
|
||||
}
|
||||
|
||||
function autoScale(shadowRoot, container) {
|
||||
|
||||
if (!shadowRoot || !container) return;
|
||||
|
||||
const parent = container;
|
||||
@@ -113,16 +116,11 @@ export default function emailHtmlTemplate(html) {
|
||||
if (!shadowContent) return;
|
||||
|
||||
const parentWidth = parent.offsetWidth;
|
||||
const parentHeight = parent.offsetHeight;
|
||||
|
||||
const childWidth = shadowContent.scrollWidth;
|
||||
const childHeight = shadowContent.scrollHeight;
|
||||
|
||||
if (childWidth === 0 || childHeight === 0) return;
|
||||
if (childWidth === 0) return;
|
||||
|
||||
const scaleX = parentWidth / childWidth;
|
||||
const scaleY = parentHeight / childHeight;
|
||||
const scale = Math.min(scaleX, scaleY);
|
||||
const scale = parentWidth / childWidth;
|
||||
|
||||
const hostElement = shadowRoot.host;
|
||||
hostElement.style.zoom = scale;
|
||||
|
||||
@@ -1,7 +1,31 @@
|
||||
export default function emailMsgTemplate(email) {
|
||||
return `<b>${email.subject}</b>
|
||||
export default function emailMsgTemplate(email, tgMsgTo, tgMsgFrom) {
|
||||
|
||||
let template = `<b>${email.subject}</b>`
|
||||
|
||||
if (tgMsgFrom === 'only-name') {
|
||||
template += `
|
||||
|
||||
发件人:${email.name}`
|
||||
}
|
||||
|
||||
if (tgMsgFrom === 'show') {
|
||||
template += `
|
||||
|
||||
发件人:${email.name} <${email.sendEmail}>`
|
||||
}
|
||||
|
||||
if(tgMsgTo === 'show' && tgMsgFrom === 'hide') {
|
||||
template += `
|
||||
|
||||
发件人:${email.name} <${email.sendEmail}>
|
||||
收件人:\u200B${email.toEmail}`
|
||||
return template
|
||||
}
|
||||
|
||||
if(tgMsgTo === 'show') {
|
||||
template += `
|
||||
收件人:\u200B${email.toEmail}`
|
||||
}
|
||||
|
||||
return template;
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user