一些应用需要发送邮件,可以直接允许这些应用的服务器访问SMTP,自行配置和开发邮件发送的功能界面。还有一种方式是把SMTP封装成web服务,应用以https访问调用接口,这样可以更安全(可以仅允许该接口服务器访问SMTP中继)更有效地管理应用的邮件发送(可以得到详细的邮件发送日志信息用于后续分析)。下面我们用nodejs来写一个web接口。
var args = require('./SendMailArgs.json');
const smtpc = require("smtpc");
const express = require('express');
const app = express();
app.use(express.json());
const moment = require('moment');
app.post('/sendmail',(req,res)=>{
let str = req.get("Authorization"); //Header
if ((str==undefined)||(str=="")) { return res.json("msg":"Header中缺少Authorization属性"); }
let getapikey = str.match(/^apikey\s(\w*)$/); //apikey
if (getapikey==null) { return res.json("msg":"Authorization中缺少apikey属性"); }
let matchkey=args.apikeys.find(item=>(item.key===getapikey)); //apikeys是已分配的apikey的json数组
if (matchkey==undefined) { return res.json("msg":"apikey无效"); }
let obj=req.body;
if ((obj.sendto==undefined)||(obj.sendto=="")) { return res.json("msg":"缺少必要信息"); }
smtpc.sendmail({
"host" : args.mailhost,
"from" : (obj.sendfrom==undefined)?args.defaultmailfrom:obj.sendfrom,
"to" : obj.sendto,
"content" : {
"subject" : (obj.topic==undefined)?"无标题":obj.topic,
"content-type" : "text/html",
"content" : (obj.information==undefined)?"无内容":obj.information
},
"success" : function () { console.log(moment().format("YYYY-MM-DD HH:mm:ss")+" 发送通知邮件 "+obj.sendto); res.json("msg":"邮件已发送"); },
"failure" : function (err) { console.log(err); res.json("msg":"邮件发送失败"); }
});
})
var argvport=(process.argv.length==2)?2525:eval(process.argv.slice(2)[0]);
var server=app.listen(argvport,function(){
console.log(moment().format("YYYY/MM/DD HH:mm:ss")+" 简单邮件通知web接口启动 @port "+server.address().port);
})
SendMailArgs.json中包含邮件中继地址mailhost,json对象数组apikeys ;给需要调用接口发送邮件的各应用服务器分配apikey,以识别发送端,可以增加功能以记录详细的发送日志。应用可以自行定制开发邮件发送界面或无界面,调用接口即可实现邮件发送。
下面是bash环境下直接用curl调用的例子,注意实际场景测试运行时,相关参数要替换成实际场景中的值。
curl -i -X POST http://yourserver:2525/ -H 'Content-Type: application/json' -H 'Authorization: apikey yourapikey' -d '{"sendfrom":"sender@test.com.cn", "sendto":"receiver@test.com.cn", "topic":"topic","information":"content"}'