⭐背景
大家好,我是yma16,本文分享 node_koa封装smtp,使用coze调用api发送优雅的邮件(gmail/outlook)。
背景: 每个用户都有一个邮箱,通过发送邮件传递消息可以引流和召回流失用户。
面向对象:广告投递、毕业寄语等。
noe_koa系列往期文章
node_koa后端——初始化配置jwt和swagger的koa框架
node_koa后端——生成验证码存入redis并使用smtp发送邮件🎈
✏️ 配置邮件api
nodemail封装成发送邮件的api
node的发送邮箱的配置
const nodemailer = require('nodemailer')
//创建一个SMTP客户端配置对象
const transporter = nodemailer.createTransport({
// 默认支持的邮箱服务包括:”QQ”、”163”、”126”、”iCloud”、”Hotmail”、”Yahoo”等
service: "QQ",
auth: {
// 发件人邮箱账号
user: '1432448610@qq.com',
//发件人邮箱的授权码 需要在自己的邮箱设置中生成,并不是邮件的登录密码
pass: '******'
}
})
const sendEmail=(toUserEmail,title,content)=>{
return new Promise(resolve=>{
// 配置收件人信息
const receiver = {
// 发件人 邮箱 '昵称<发件人邮箱>'
from: `1432448610@qq.com`,
// 主题
subject:title,
// 收件人 的邮箱 可以是其他邮箱 不一定是qq邮箱
to:toUserEmail,
// 可以使用html标签
html: content
};
// 发送邮件
transporter.sendMail(receiver, (error, info) => {
if (error) {
resolve({
code:0,
msg:error
})
}
transporter.close()
resolve({
code:200,
msg:'success'
})
})
})
};
module.exports={
sendEmail
}
然后再迁移到云服务器linux中,使用node运行脚本,最后使用nginx代理抛出api接口。
⭐ 创建一个coze通过工作流调用api
✏️ 编排设置
主要逻辑是让用户输入之后走工作流,测试过程中会出现不走工作流的情况,多添加一些提示词。
# 角色
执行 工作流`send_email`处理输入信息
### 技能: 执行`send_email` 工作流
- 执行`send_email` 工作流
# 限制
必须使用 `send_email` 工作流
✏️ 工作流配置
进入工作流“send_email”
配置大模型的参数 主要提取关键词:
- 用户提问 question
- 发送邮箱 email
- 画图内容 draw_text
- 大模型的回答 answer
💖动漫风格图片
添加插件 ImageToolPro通过文字生成
在前置节点的文本添加js代码块简单配置动漫风格前缀文字
💖js代码块处理兼容性的html格式
async function main({ params }: Args): Promise<Output> {
const html_tmeplate = `<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
<head>
<title>
</title>
<!--[if !mso]><!-->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!--<![endif]-->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style type="text/css">
#outlook a {
padding: 0;
}
body {
margin: 0;
padding: 0;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
table,
td {
border-collapse: collapse;
mso-table-lspace: 0pt;
mso-table-rspace: 0pt;
}
img {
border: 0;
height: auto;
line-height: 100%;
outline: none;
text-decoration: none;
-ms-interpolation-mode: bicubic;
}
p {
display: block;
margin: 13px 0;
}
</style>
<!--[if mso]>
<noscript>
<xml>
<o:OfficeDocumentSettings>
<o:AllowPNG/>
<o:PixelsPerInch>96</o:PixelsPerInch>
</o:OfficeDocumentSettings>
</xml>
</noscript>
<![endif]-->
<!--[if lte mso 11]>
<style type="text/css">
.mj-outlook-group-fix { width:100% !important; }
</style>
<![endif]-->
<!--[if !mso]><!-->
<link href="https://fonts.googleapis.com/css?family=Ubuntu:300,400,500,700" rel="stylesheet" type="text/css">
<style type="text/css">
@import url(https://fonts.googleapis.com/css?family=Ubuntu:300,400,500,700);
</style>
<!--<![endif]-->
<style type="text/css">
@media only screen and (min-width:480px) {
.mj-column-per-100 {
width: 100% !important;
max-width: 100%;
}
.mj-column-per-50 {
width: 50% !important;
max-width: 50%;
}
.mj-column-per-25 {
width: 25% !important;
max-width: 25%;
}
.mj-column-per-75 {
width: 75% !important;
max-width: 75%;
}
.mj-column-per-33-333333333333336 {
width: 33.33333333333333336% !important;
max-width: 33.33333333333333336%;
}
}
</style>
<style media="screen and (min-width:480px)">
.moz-text-html .mj-column-per-100 {
width: 100% !important;
max-width: 100%;
}
.moz-text-html .mj-column-per-50 {
width: 50% !important;
max-width: 50%;
}
.moz-text-html .mj-column-per-25 {
width: 25% !important;
max-width: 25%;
}
.moz-text-html .mj-column-per-75 {
width: 75% !important;
max-width: 75%;
}
.moz-text-html .mj-column-per-33-333333333333336 {
width: 33.33333333333333336% !important;
max-width: 33.33333333333333336%;
}
</style>
<style type="text/css">
@media only screen and (max-width:480px) {
table.mj-full-width-mobile {
width: 100% !important;
}
td.mj-full-width-mobile {
width: auto !important;
}
}
</style>
</head>
<body style="word-spacing:normal;background-color:#e0f2ff;">
<div>
<!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
<div style="background-color:#ffffff;margin:0px auto;max-width:600px;margin-top: 20px;">
<table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;">
<tbody>
<tr>
<td style="direction:ltr;font-size:0px;padding:20px 0;padding-bottom:20px;padding-top:20px;text-align:center;">
<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="width:600px;" ><![endif]-->
<div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0;line-height:0;text-align:left;display:inline-block;width:100%;direction:ltr;">
<!--[if mso | IE]><table border="0" cellpadding="0" cellspacing="0" role="presentation" ><tr><td style="vertical-align:top;width:300px;" ><![endif]-->
<div class="mj-column-per-50 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:50%;">
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%">
<tbody>
<tr>
<td align="left" style="font-size:0px;padding:10px 25px;padding-right:25px;padding-left:25px;word-break:break-word;">
<div style="font-family:Ubuntu, Helvetica, Arial, sans-serif;font-size:11px;line-height:1;text-align:left;color:#000000;">[[coze]]</div>
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]></td><td style="vertical-align:top;width:300px;" ><![endif]-->
<div class="mj-column-per-50 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:50%;">
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%">
<tbody>
<tr>
<td align="right" style="font-size:0px;padding:10px 25px;padding-right:25px;padding-left:25px;word-break:break-word;">
<div style="font-family:Ubuntu, Helvetica, Arial, sans-serif;font-size:11px;line-height:1;text-align:right;color:#000000;">[[auto_email]]</div>
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]></td></tr></table><![endif]-->
</div>
<!--[if mso | IE]></td></tr></table><![endif]-->
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]></td></tr></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
<div style="background-color:#ffffff;margin:0px auto;max-width:600px;">
<table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;">
<tbody>
<tr>
<td style="direction:ltr;font-size:0px;padding:20px 0;padding-bottom:0px;padding-top:0;text-align:center;">
<!--[if mso | IE]></td><td class="" style="vertical-align:top;width:450px;" ><![endif]-->
<div class="mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%">
<tbody>
<tr>
<td align="left" style="font-size:0px;padding:0 25px;word-break:break-word;">
<div style="font-family:Ubuntu, Helvetica, Arial, sans-serif;font-size:19px;font-weight:bold;line-height:1;text-align:left;color:#000000;">${params.question}</div>
</td>
</tr>
<tr>
<td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;">
<div style="font-family:Ubuntu, Helvetica, Arial, sans-serif;font-size:11px;line-height:1;text-align:left;color:#000000;">${params.answer}</div>
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]></td></tr></table><![endif]-->
</td>
</tr>
</tbody>
</table>
</div>
<div style="background-color:#ffffff;margin:0px auto;max-width:600px;">
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;">
<tbody>
<tr>
<td style="width:100%;margin-top: 20px;text-align: center;">
<a href="${params.imgae_url}" target="_blank">
<img src="${params.imgae_url}" style="border-radius:3px;display:block;" width="600px">
</a>
</td>
</tr>
</tbody>
</table>
</div>
<div style="background-color:#ffffff;margin:0px auto;max-width:600px;">
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;border-top: 1px dotted #dcdcdc">
<tbody>
<tr>
<td style="width:100%;margin-top: 20px;">
<span>
</span>
</td>
</tr>
</tbody>
</table>
</div>
<div style="background-color:#ffffff;margin:0px auto;max-width:600px;">
<table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;" width="100%">
<tbody>
<tr>
<td style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; direction: ltr; font-size: 0px; padding: 20px 0; text-align: center;" align="center">
<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:200px;" ><![endif]-->
<div class="mj-column-per-33-333333333333336 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:33.333%;text-align: center;">
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; vertical-align: top;" width="100%" valign="top">
<tbody>
<tr>
<td align="center" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; font-size: 0px; word-break: break-word;">
<a href="https://juejin.cn/user/4156607956004408" target="_blank" style="text-decoration: none;">
<img src="https://lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/static/favicons/apple-touch-icon.png" style="border-radius:3px;display:block;" width="32" height="32">
</a>d
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]></td><td class="" style="vertical-align:top;width:200px;" ><![endif]-->
<div class="mj-column-per-33-333333333333336 mj-outlook-group-fix" style="font-size:0px;text-align:center;direction:ltr;display:inline-block;vertical-align:top;width:33.333%;text-align: center;">
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; vertical-align: top;" width="100%" valign="top">
<tbody>
<tr>
<td align="center" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; font-size: 0px; word-break: break-word;">
<a href="https://yongma16.xyz/staticFile/common/img/weChatInfo.jpg" target="_blank" style="width:100%;text-align: center;">
<img src="https://res.wx.qq.com/a/wx_fed/assets/res/NTI4MWU5.ico" style="border-radius:3px;display:inline-block;" width="32" height="32">
</a>
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]></td><td class="" style="vertical-align:top;width:200px;" ><![endif]-->
<div class="mj-column-per-33-333333333333336 mj-outlook-group-fix" style="font-size:0px;text-align:center;direction:ltr;display:inline-block;vertical-align:top;width:33.333%;">
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; vertical-align: top;" width="100%" valign="top">
<tbody>
<tr>
<td align="center" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; font-size: 0px; word-break: break-word;text-align: center;">
<a href="https://blog.csdn.net/qq_38870145?spm=1000.2115.3001.5343" target="_blank" style="text-decoration: none;">
<img src="https://g.csdnimg.cn/static/logo/favicon32.ico" style="border-radius:3px;display:inline-block;" height="32">
</a>
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]></td></tr></table><![endif]-->
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
`
const ret = {
"html_content": html_tmeplate
};
return ret;
}
💖发送邮件配置
python代码块调用smtp的 api 发送邮件
import requests_async as requests
async def main(args: Args) -> Output:
params = args.params
data={
"toUserEmail": params["email"],
"title": params["title"],
"content": params["content"]
}
res=await requests.post('你的公网smtp服务api',data=data)
ret: Output = {
"res": str(res)
}
return ret
💖测试运行
用户输入生成一份毕业祝福语 发送给 codeyma16@outlook.com
选择bot名称运行,运行成功!
outlook成功收到的邮箱
🎈 bot链接
⭐结束
本文分享到这结束,如有错误或者不足之处欢迎指出!
👍 点赞,是我创作的动力!
⭐️ 收藏,是我努力的方向!
✏️ 评论,是我进步的财富!
💖 最后,感谢你的阅读!