十分钟编写自己的邮件发送接口

我们总是做着重复的事情

最近实习在cdn运维平台上开发了几个新的模块。其中有一个功能就是邮件发送,用到了flask-mail这个模块,想起来自己以前写邮件通知,都是重复写一样的代码,为什么不自己写个接口,curl一下就可以发送消息了。参数通过query string的形式提交到后端就好了。

友情提示:get不安全,你也可以使用post或者加一个authorization


主要代码

由于用flask-mail太简单了,说实话我也没有开发过接口的经验,写的可能不太规范,这里只是给出一种思路,实现功能的主要代码

api server的主要模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# coding: utf-8
from flask import Flask, request, jsonify
from flask_mail import Mail, Message
import tasks
app = Flask(__name__)
app.config.update(
SECRET_KEY='ssoiqh234', # encrypt for cookie
MAIL_SERVER='smtp.163.com',
MAIL_PORT=465,
MAIL_USE_SSL=True,
MAIL_DEFAULT_SENDER='xxx@163.com',
MAIL_USERNAME='xxx@163.com',
MAIL_PASSWORD='xxxxxx' #在网易邮件页面上授权的key
)
mail = Mail(app)
# curl http://xxx.zhxfei.com/ops/sendmail?receiver={}&title={}&text={}
@app.route('ops/sendmail', methods=['GET', 'POST'])
def new_mail():
if request.method == 'GET':
email_to_lst = request.args.get('receiver')
email_title = request.args.get('title')
email_area = request.args.get('text')
if not email_to_lst or not email_title or not email_area:
if email_to_lst:
msg = Message(subject=email_title,
body=email_area,
recipients=email_to_lst)
tasks.send_email.delay(msg, email_title, email_to_lst, email_area)
return jsonify({'success': {
'message': 'Request Send Succeed'
}}), 200
return jsonify({
'error': {
'message': 'Request Format Error'
}
}), 401
return jsonify({
'error': {
'message': 'HTTP method not allowed'
}
}), 403
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)

由于mail这种io操作会阻塞住接口的调用,所以为了视图函数可以快速的加载,可以将其通过celery做成异步的任务丢到任务队列中。而worker就负责发邮件就好了。

1
2
3
4
@celery.task
def send_email(msg, *args):
with app.app_context():
mail.send(msg)

使用: curl http://xxx.zhxfei.com/ops/sendmail?receiver={}&title={}&text={}

就可以测试

由于任务是异步提交的,上面的代码是只要异步调用成功调用,就会返回一个发送成功的message,这是不严谨的,我们可以通过celery的一些高级特性来解决问题。

比如说:

  • celery flower来监控任务的运行状态,celery flower自身也提供了接口获取当前的tasks信息,我们可以写个脚本去遍历,当检测到failedtasks,进行提醒。当然他的界面也很直观的看出。tasks的参数(如上面的*args会在页面中显示)
  • 使用celery的信号机制,当task_failure信号触发,可以发送提醒通知

好了,十分钟我也只能做这些…回头验证,接口规范再完善下

坚持原创技术分享,您的支持将鼓励我继续创作!