Tutorial RESTful API dengan Flask Python Part 8— Mengirimkan Email dengan SMTP Gmail
Hello fellas, kembali lagi bersama saya, Kiddy. Pada artikel kali ini saya mau berbagi insight mengenai cara mengirimkan email menggunakan Flask Python.
Kalo agan sudah membuka tutorial ini saya anggap agan udah paham konsep SMTP dan sudah pernah mencobanya di Laravel ya, jadi kalo bingung jangan salahkan saya xixixi.
Ohiya, di tutorial ini saya pake projek ini, jadi saya sarankan agan mengclone dari repo saya, kalo agan mau agak “wild” dan udah paham konsep programming dengan baik diskip aja ngga apa hehehe.
Pertama, jangan lupa aktivasi virtualenv nya dulu.
Kedua, install library-nya dengan cara:
pip install Flask-Mail
Kita akan menggunakan Flask-Mail salah satu library sakti yang digunakan buat Flask.
Ketiga, __init__.py kita mesti dimodif sedikit dulu untuk inisialisasi Mail-nya.
from flask_mail import Mail
app = Flask(__name__)
mail = Mail(app)
Khusus untuk tutorial ini, saya akan membuat kasus dimana pengguna akan mendapatkan email saat mendaftarkan diri melalui api /users (POST).
Jangan lupa menambahkan konfigurasi Mail kita di config.py.
MAIL_SERVER = str(os.environ.get("MAIL_SERVER"))
MAIL_PORT = str(os.environ.get("MAIL_PORT"))
MAIL_USERNAME = str(os.environ.get("MAIL_USERNAME"))
MAIL_PASSWORD = str(os.environ.get("MAIL_PASSWORD"))
MAIL_USE_TLS = True
MAIL_USE_SSL = False
Sekarang kita buat sebuah folder bernama templates didalam folder app, gunanya untuk menyimpan template milik kita.
Nah, sekarang kita buat sebuah file baru bernama mail.html didalam folder templates, lalu paste codenya dibawah ini.
<!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]>
<xml>
<o:OfficeDocumentSettings>
<o:AllowPNG/>
<o:PixelsPerInch>96</o:PixelsPerInch>
</o:OfficeDocumentSettings>
</xml>
<![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=Open+Sans:300,400,500,700" rel="stylesheet" type="text/css">
<style type="text/css">
@import url(https://fonts.googleapis.com/css?family=Open+Sans: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%;
}
}
</style>
<style type="text/css">
</style>
</head>
<body style="background-color:#ffffff;">
<div style="background-color:#ffffff;">
<!--[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:#34495e;background-color:#34495e;margin:0px auto;max-width:600px;">
<table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="background:#34495e;background-color:#34495e;width:100%;">
<tbody>
<tr>
<td style="direction:ltr;font-size:0px;padding:20px 0;padding-bottom:0px;padding-top:10px;text-align:center;">
<!--[if mso | IE]>
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
<tr>
<td
class="" style="vertical-align:top;width:600px;"
>
<![endif]-->
<div class="mj-column-per-100 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%">
<tr>
<td align="center" style="font-size:0px;padding:10px 25px;padding-top:50px;padding-right:25px;padding-bottom:30px;padding-left:25px;word-break:break-word;">
<div style="font-family:open Sans Helvetica, Arial, sans-serif;font-size:45px;font-weight:bold;line-height:1;text-align:center;color:#ffffff;">Welcome aboard</div>
</td>
</tr>
</table>
</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:#7f8c8d;background-color:#7f8c8d;margin:0px auto;max-width:600px;">
<table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="background:#7f8c8d;background-color:#7f8c8d;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="vertical-align:middle;width:600px;"
>
<![endif]-->
<div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:middle;width:100%;">
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:middle;" width="100%">
<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:open Sans Helvetica, Arial, sans-serif;font-size:22px;line-height:1;text-align:left;color:#ffffff;"><span style="color:#FEEB35">Dear {{ name }}</span><br /><br /> Welcome to {{ app_name }}.</div>
</td>
</tr>
<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:open Sans Helvetica, Arial, sans-serif;font-size:15px;line-height:1;text-align:left;color:#ffffff;">We're really excited you've decided to give us a try. In case you have any questions, feel free to reach out to us at {{ app_contact }}. You can login to your account with your email {{ email }}</div>
</td>
</tr>
<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:open Sans Helvetica, Arial, sans-serif;font-size:15px;line-height:1;text-align:left;color:#ffffff;">Thanks, <br /> The {{ app_name }} Team</div>
</td>
</tr>
</table>
</div>
<!--[if mso | IE]>
</td>
</tr>
</table>
<![endif]-->
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]>
</td>
</tr>
</table>
<![endif]-->
</div>
</body>
</html>
Ohiya, untuk web ini dibuat dengan MJML. Web framework yang bisa membuat email responsif dengan gampang, disarankan banget pake ini, karena templatenya pun banyak!
Kalo mau pake templatenya tinggal klik aja disini.
Sekarang kita masuk ke bagian codenya, silahkan ubah sedikit di UserController.py pada method store().
def store():
try:
name = request.json['name']
email = request.json['email']
password = request.json['password']
users = Users(name=name, email=email)
users.setPassword(password)
db.session.add(users)
db.session.commit()
msg = Message("Hello, {} welcome to Belajar Flask Python".format(name),
sender="kiddy@mail.com")
msg.add_recipient(email)
# msg.body = "testing"
msg.html = render_template('mail.html', app_name="Learn Flask with Kiddy", app_contact="kiddy@mail.com",
name=name, email=email)
mail.send(msg)
return response.ok('', 'Successfully create data!')
except Exception as e:
print(e)
Jangan lupa import si librarnya.
from app import mail
from flask_mail import Message
from flask import render_template
Tak jelasin dulu deh. Pertama kita inisialisasi object Message kedalam variable msg. Disana kita masukkan “Hello, {} welcome to Belajar Flask Python” sebagai Title email, dan sendernya siapa, tapi karena kita menggunakan Gmail, otomatis sendernya ya si email yang mengirim, kecuali kita pake service 3rd party seperti Mailgun, atau Sendgrid.
Berpacu pada dokumentasi https://pythonhosted.org/Flask-Mail/
Kedua, pada saat inisialisasi class Message, sebenernya kita bisa nginput recipients lebih dari satu dengan menggunakan default array.
You can set the recipient emails immediately, or individually:
msg.recipients = ["you@example.com"]
msg.add_recipient("somebodyelse@example.com")
Yang dimana kita sebenrnya bisa set penerimanya duluan, atau satu-satu, kalo mau bulk (sekaligus) ya pakein array. Kita juga bisa put recipients di constructor si Message, kalo kita put di konstruktor recipientsnya wajib ARRAY.
msg = Message("Hello",
sender="from@example.com",
recipients=["to@example.com"])
If the sender is a two-element tuple, this will be split into name and address:
msg = Message("Hello",
sender=("Me", "me@example.com"))
Nah kita bisa nih namain si Sender Alias pengirim dengan nama sesuka kita, tapi inget karena kita pake Gmail, pengirimnya pasti si akun Gmailnya ini, kecuali pake SMTP pihak ketiga.
If you have set MAIL_DEFAULT_SENDER you don’t need to set the message sender explicity, as it will use this configuration value by default.
Kalo di Config class kita ada MAIL_DEFAULT_SENDER, maka si Sendernya ngga perlu kita inisialisasi lagi gaes.
Sedangkan, msg.body yang saya comment tuh gunanya cuma buat RAW Email aja, but since kita pake template ya kita comment aja, ngga perlu saya jelasin kan bedanya raw email dengan html email?
# msg.body = "testing"
Finally, to send the message, you use the Mail instance configured with your Flask application:
mail.send(msg)
Nah ini fungsi yang akan menjalankan si emailnya, kalo agan perhatikan nanti di command console kalian keliatan kok processnya.
Sebelum nyoba kita wajib nambahin dulu di .flaskenv kita beberapa parameter tambahan yaitu:
MAIL_SERVER=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=xxx@gmail.com
MAIL_PASSWORD=xxx
Nah sebelum digas perhatikan dulu. Kalo agan pernah mengikuti tutorial saya yang ngirim email pake Laravel disini
Disitu saya jelaskan kalo email yang digunakan wajib tidak menggunakan two step verification, karena kalo pake pasti error.
Setelah itu akun juga wajib dimatikan Less secure appnya. Bagi akun yang menggunakan two step verification pasti ngga akan bisa, seperit akun email saya yang lain.
Nah pastikan akun kalian tidak menggunakan two step verification dan nyalakan Less Secure App, gunanya adalah agar google bisa berkomunikasi dengan layanan diluar, karena kita menggunakan SMTP-nya Gmail, ya ini wajib dinyalakan.
Dimana cara nyettingnya? Disini:
https://myaccount.google.com/u/0/lesssecureapps?pageId=none
Kalo udah beres semua, sekarang kita coba aja nih.
Hasilnya akan nongol di Email kalian.
Gampang toh? Iyalaaa~ Ngga pake ribet ngirim email dari Flask Python, malah cepat, gampang, dan pastinya Python punya performa yang ajib!
Ohiya kalo ada yang mau clone jangan sungkan untuk clone reponya disini, sudah saya update beserta Mail servicenya kok.
Sekian dari saya, hepi coding semuanya!