mirror of
https://github.com/dreamhunter2333/cloudflare_temp_email.git
synced 2026-09-04 23:17:34 +08:00
feat: |Worker| support send mail by SMTP (#580)
This commit is contained in:
+2
-1
@@ -27,7 +27,8 @@
|
||||
"mimetext": "^3.0.27",
|
||||
"postal-mime": "^2.4.3",
|
||||
"resend": "^4.1.1",
|
||||
"telegraf": "4.16.3"
|
||||
"telegraf": "4.16.3",
|
||||
"worker-mailer": "^1.0.1"
|
||||
},
|
||||
"pnpm": {
|
||||
"patchedDependencies": {
|
||||
|
||||
Generated
+8
@@ -37,6 +37,9 @@ importers:
|
||||
telegraf:
|
||||
specifier: 4.16.3
|
||||
version: 4.16.3(patch_hash=7d0a1784bb35f50fee25f26a14017734b9461612c635e71734b59527280c9563)
|
||||
worker-mailer:
|
||||
specifier: ^1.0.1
|
||||
version: 1.0.1
|
||||
devDependencies:
|
||||
'@cloudflare/workers-types':
|
||||
specifier: ^4.20250129.0
|
||||
@@ -1578,6 +1581,9 @@ packages:
|
||||
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
worker-mailer@1.0.1:
|
||||
resolution: {integrity: sha512-y6U9B2cWGGasj7B+6ZtRBsdTPRAZ0P73ykKq5hsIHXReUB8WAq7feS4JoN2xmAZl7yQpVz/GTLqmqLyDmsOUnw==}
|
||||
|
||||
workerd@1.20250124.0:
|
||||
resolution: {integrity: sha512-EnT9gN3M9/UHRFPZptKgK36DLOW8WfJV7cjNs3zstVbmF5cpFaHCAzX7tXWBO6zyvW/+EjklJPFtOvfatiZsuQ==}
|
||||
engines: {node: '>=16'}
|
||||
@@ -3564,6 +3570,8 @@ snapshots:
|
||||
|
||||
word-wrap@1.2.5: {}
|
||||
|
||||
worker-mailer@1.0.1: {}
|
||||
|
||||
workerd@1.20250124.0:
|
||||
optionalDependencies:
|
||||
'@cloudflare/workerd-darwin-64': 1.20250124.0
|
||||
|
||||
@@ -2,9 +2,10 @@ import { Context, Hono } from 'hono'
|
||||
import { Jwt } from 'hono/utils/jwt'
|
||||
import { createMimeMessage } from 'mimetext';
|
||||
import { Resend } from 'resend';
|
||||
import { WorkerMailer, WorkerMailerOptions } from 'worker-mailer';
|
||||
|
||||
import { CONSTANTS } from '../constants'
|
||||
import { getJsonSetting, getDomains, getIntValue, getBooleanValue, getStringValue } from '../utils';
|
||||
import { getJsonSetting, getDomains, getIntValue, getBooleanValue, getStringValue, getJsonObjectValue } from '../utils';
|
||||
import { GeoData } from '../models'
|
||||
import { handleListQuery } from '../common'
|
||||
import { HonoCustomType } from '../types';
|
||||
@@ -89,6 +90,32 @@ const sendMailByResend = async (
|
||||
console.log(`Resend success: ${JSON.stringify(data)}`);
|
||||
}
|
||||
|
||||
const sendMailBySmtp = async (
|
||||
c: Context<HonoCustomType>, address: string,
|
||||
reqJson: {
|
||||
from_name: string, to_mail: string, to_name: string,
|
||||
subject: string, content: string, is_html: boolean
|
||||
},
|
||||
smtpOptions: WorkerMailerOptions
|
||||
): Promise<void> => {
|
||||
await WorkerMailer.send(
|
||||
smtpOptions,
|
||||
{
|
||||
from: {
|
||||
name: reqJson.from_name,
|
||||
email: address
|
||||
},
|
||||
to: {
|
||||
name: reqJson.to_name,
|
||||
email: reqJson.to_mail
|
||||
},
|
||||
subject: reqJson.subject,
|
||||
text: reqJson.is_html ? undefined : reqJson.content,
|
||||
html: reqJson.is_html ? reqJson.content : undefined
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
export const sendMail = async (
|
||||
c: Context<HonoCustomType>, address: string,
|
||||
reqJson: {
|
||||
@@ -138,15 +165,20 @@ export const sendMail = async (
|
||||
throw new Error("to_mail address is blocked")
|
||||
}
|
||||
if (!subject) {
|
||||
throw new Error("Invalid subject")
|
||||
throw new Error("Subject is empty")
|
||||
}
|
||||
if (!content) {
|
||||
throw new Error("Invalid content")
|
||||
throw new Error("Content is empty")
|
||||
}
|
||||
|
||||
// send to verified address list, do not update balance
|
||||
const resendEnabled = c.env.RESEND_TOKEN || c.env[
|
||||
`RESEND_TOKEN_${mailDomain.replace(/\./g, "_").toUpperCase()}`
|
||||
];
|
||||
// send by smtp
|
||||
const smtpConfigMap = getJsonObjectValue<Record<string, WorkerMailerOptions>>(c.env.SMTP_CONFIG);
|
||||
const smtpConfig = smtpConfigMap ? smtpConfigMap[mailDomain] : null;
|
||||
// send by verified address list
|
||||
let sendByVerifiedAddressList = false;
|
||||
if (c.env.SEND_MAIL) {
|
||||
const verifiedAddressList = await getJsonSetting(c, CONSTANTS.VERIFIED_ADDRESS_LIST_KEY) || [];
|
||||
@@ -155,6 +187,8 @@ export const sendMail = async (
|
||||
sendByVerifiedAddressList = true;
|
||||
}
|
||||
}
|
||||
|
||||
// send mail workflow
|
||||
if (sendByVerifiedAddressList) {
|
||||
// do not update balance
|
||||
}
|
||||
@@ -162,9 +196,16 @@ export const sendMail = async (
|
||||
else if (resendEnabled) {
|
||||
await sendMailByResend(c, address, reqJson);
|
||||
}
|
||||
else {
|
||||
throw new Error("Please enable resend or verified address list")
|
||||
else if (smtpConfig) {
|
||||
await sendMailBySmtp(c, address, reqJson, smtpConfig);
|
||||
}
|
||||
else {
|
||||
if (c.env.SEND_MAIL) {
|
||||
throw new Error(`Please enable resend or smtp for domain ${mailDomain}. Or add ${to_mail} to verified address list`);
|
||||
}
|
||||
throw new Error(`Please enable resend or smtp for domain ${mailDomain}`);
|
||||
}
|
||||
|
||||
// update balance
|
||||
if (!sendByVerifiedAddressList && needCheckBalance) {
|
||||
try {
|
||||
|
||||
Vendored
+4
-1
@@ -66,7 +66,10 @@ export type Bindings = {
|
||||
|
||||
// resend
|
||||
RESEND_TOKEN: string | undefined
|
||||
[key: `RESEND_TOKEN_${string}`]: string | undefined;
|
||||
[key: `RESEND_TOKEN_${string}`]: string | undefined
|
||||
|
||||
// SMTP config
|
||||
SMTP_CONFIG: string | object | undefined
|
||||
|
||||
// telegram config
|
||||
TELEGRAM_BOT_TOKEN: string
|
||||
|
||||
Reference in New Issue
Block a user