最近在学习next.js ,看完文档后准备上手写一个发送邮件小demo
申请google应用专项密码
google账号 -> 安全性 -> 两步认证
点击申请应用专项密码
复制这个密码,关闭这个窗口就会不见的!
创建next 项目 create next app
在环境变量文件中.env
记录密码还有自己的邮箱地址
大多数使用node.js发送邮件用的nodemailer
库
Send emails from Node.js -- easy as cake! 🍰✉️
安装 nodemailer
bash
bun add nodemailer
yarn add nodemailer
npm i nodemailer
因为是ts项目,还需要安装types
bash
bun add @types/nodemailer
发送邮件 sendMail
- 形参
to
name
subject
body
分别表示收件地址、收件人名字、主题、正文由参数传递 nodemailer.createTransport
创建邮件传输对象- auth认证需要SMTP服务器的邮箱地址和密码 就是之前环境变量储存的
transport.verify
验证邮件传输对象的配置是否有效 返回true
orfalse
transport.sendMail
发送邮件from
是环境变量的邮件地址,其他参数来自形参
ts
// src/lib/mail.ts
import nodemailer from 'nodemailer'
export async function sendMail({
to,
name,
subject,
body,
}: {
to: string
name: string
subject: string
body: string
}) {
const { SMTP_EMAIL, SMTP_PASSWORD } = process.env
const transport = nodemailer.createTransport({
service: 'gmail',
auth: {
user: SMTP_EMAIL,
pass: SMTP_PASSWORD,
},
})
try {
const testResult = await transport.verify()
console.log(testResult)
} catch (error) {
console.error({ error })
return
}
try {
const sendResult = await transport.sendMail({
from: SMTP_EMAIL,
to,
subject,
html: body,
})
console.log(sendResult)
} catch (error) {
console.log(error)
}
}
客户端pages
使用server action,异步调用sendMail函数,传递对应参数。body正文中可以嵌入html,这里我们之后可以定制化我们需要的邮件内容
tsx
// app/pages.tsx
import styles from '@/app/page.module.css'
import { sendMail } from '@/lib/mail'
export default function Home() {
const send = async () => {
'use server'
console.log('已发送')
await sendMail({
to: 'oxy601@126.com',
name: 'odd text email',
subject: 'Test Mail',
body: '<h1>hello world<h1/>',
})
}
return (
<>
<main className={styles.main}>
<form>
<button className={styles.btn} formAction={send}>
test
</button>
</form>
</main>
</>
)
}
click 试一下
打印了true就应该没啥问题了
如果网不好或者连了不恰当的代理也可能连接超时
不止于hello world
beefree.io/ 有很多email模板 选择其中一个模板定制化
双括号 {{}}
方便之后用handlebars
库插入变量
exit ---> export -> copy html
储存在src/template之下并导出
handlebars
Handlebars 是一个简单而强大的模板库,用于构建动态 HTML Template, 使用 Mustache 的语法插入变量
bash
bun add handlebars
使用邮件模板
handlebars.compile(Template)
编译之前复制的Template模板,给它的返回值template
变量传递需要的变量name
, url
js
// lib/mail.ts
import * as handlebars from 'handlebars'
import { Template } from '@/template/demo'
export function compileTemplate(name: string, url: string) {
const template = handlebars.compile(Template)
const htmlBody = template({
name: name,
url: url,
})
return htmlBody
}
在pages中调用compileTemplate函数
tsx
// app/pages.tsx
import { compileTemplate } from '@/lib/mail'
export default function Home() {
const send = async () => {
'use server'
console.log('已发送')
await sendMail({
to: 'oxy601@126.com',
name: 'odd text email',
subject: 'Test Mail',
body: compileTemplate('oddpro', 'https://juejin.cn/user/831701770570621'),
})
}
return (...)
}
看看效果
符合预期 收工!