华为云函数发送QQ邮件(多图)

736 阅读3分钟

突然想给之前的网站加个评论提醒的功能,秉着能省就省的精神,用了华为云函数,nodejs运行环境搞了个发送qq邮件的功能。

Untitled.png

准备工作

QQ邮箱开启服务

如果不想用qq号,可以创建一个英文邮箱账号。

Untitled (1).png

  1. 开启服务

Untitled (2).png

  1. 生成授权码,用于后面nodejs授权

Untitled (3).png

华为云

  1. 需要去官网注册一个华为云账号
  2. 然后在控制台搜索函数工作流

Untitled (16).png

  1. 创建函数
    区域默认就好,名称自己随便填,运行时选nodejs用的版本 Untitled (4).png Untitled (5).png

创建完成后,在函数列表可以看到,点击对应的函数就能进行编辑了 Untitled (6).png

代码上传

因为华为云的依赖好像没办法在线npm安装,需要上传对应的依赖包,所以这里我们先在自己用的编辑器(vscode)写好发送邮件的功能,然后打包成zip以后上传。

nodemailer

发送邮件的主要用的就是这个库,可以去官网看看详情,这里我们简单配置一下就可以使用了。

安装nodemailer

npm i nodemailer

新建一个mail.js

const nodemailer = require('nodemailer')

const transporter = nodemailer.createTransport({
  host: 'smtp.qq.com', //qq的smtp服务
  port: 465,
  secure: true,
  auth: {
    user: '你的qq邮箱,如果创建了英文账号也可以直接用',
    pass: '这里就是上面生成的授权码'
  }
});

module.exports = transporter

压缩依赖包

将mail.js和node_modules一起压缩到一个zip中 Untitled (17).png

上传依赖包

  1. 创建依赖包 Untitled (18).png

  2. 创建完成以后,进入函数列表,点击具体函数进入,到最下面添加依赖包 Untitled (7).png

编辑index.js

后面会说明为什么要解密

const transporter = require('./mail.js') //上传的依赖包
exports.handler = async (event, context) => {
    // FunctionGraph函数对来自APIG调用的返回结果进行了封装,
    // APIG触发器要求函数的返回结果中必须包含body(String)、statusCode(int)、headers(Map)和isBase64Encoded(boolean),才可以正确返回。
    const res = {
        statusCode: 200,
        body: `{ "message": "邮件发送成功", "code": 200}`,
        headers: {},
        isBase64Encoded: false
    }
    try {
        // 解码 Base64 编码字符串
        const decodedObj = JSON.parse(JSON.parse(Buffer.from(event.body, 'base64').toString('utf-8')));

        // 设置电子邮件的选项
        const mailOptions = {
            from: '发邮箱的账号',
            to: event.to, // 收邮箱的账号,发和收可以是同一个
            subject: decodedObj.subject, // 邮件标题
            text: decodedObj.text // 邮件内容
        };
        // 使用SMTP传输对象发送电子邮件
        const info = await transporter.sendMail(mailOptions);
        return res
    } catch (error) {
        res.body = `{ "message": ${error.message}}`
        return res
    }
}

结果

可以写个测试事件

Untitled (8).png

Untitled.jpeg

在为这结果开心以后,我把云函数发布了,然后调用发布以后的接口,结果不对劲了,怎么无主题,无内容?

Untitled (9).png

在一系列测试和翻文档才发现,获取参数的时候有个坑,参数是它自己提供的测试界面才有的,可以直接通过event.[参数名],所以在测试的时候一直时没问题的,而我们在调用部署以后的url时,直接通过event.[传的参数]是获取不到的,而且还是用了base64加密的。

Untitled (19).png

函数执行界面返回结果

Untitled (10).png

部署以后的api返回结果(大坑😅),所以得先对event用base64解密以后获取传入的参数

Untitled (11).png

发布

创建触发器

Untitled (12).png

创建分组

直接确定就行

Untitled (13).png

回函数那边刷新一下就有了

Untitled (14).png

确定以后,调用url就是可以用于请求的接口了

Untitled (15).png

axios请求示例

  axios.post( '上面的调用URL', 
    { subject: `评论标题`, text: '评论内容' },
    { headers: { 'Content-Type': 'text/plain' } 
  }).then(res=>{
    console.log(res)
  })

跨域

如果还是存在跨域问题,参考这里