Python حرفه‌ای: ارسال ایمیل

Professional Python: Sending a Mail

24 اسفند 1399
درسنامه درس 27 از سری پایتون حرفه‌ای
Python حرفه ای: ارسال ایمیل (قسمت 27)

چرا ایمیل ها را به صورت پویا ارسال کنیم؟

زبان برنامه نویسی پایتون این قابلیت را دارد که بتوانیم با آن ایمیل ارسال کنیم اما نکته ای وجود دارد. نسخه سوم زبان پایتون، قسمت ایمیل خود را کاملا به روز رسانی کرده است بنابراین اگر در اینترنت به دنبال آموزش برای ارسال ایمیل باشید، ممکن است به آموزش های عجیب و غریبی برخورد کنید که با گفته های من در این مقاله متفاوت است. دلیل این مسئله آن است که این آموزش ها معمولا قدیمی هستند و با پایتون ۳ کار نمی کنند.

حالا برویم سر اصل مطلب! چرا باید با زبان پایتون ایمیل ارسال کنیم؟ آیا نمی توانیم ایمیل هایمان را به شکل دستی ارسال کنیم؟ برای پاسخ به این سوال باید به قدرت زبان های برنامه نویسی و انجام عملیات های پویا توجه کنید. تصور کنید که می خواهید شرکت جدیدی را راه اندازی کنیم و برای کمپین تبلیغاتی خودمان لیست بزرگی از ایمیل های افراد مختلف را داریم (هزاران ایمیل). ارسال این حجم از ایمیل به صورت دستی غیرممکن است و روزها طول خواهد کشید. اینجاست که زبان پایتون وارد شده و می تواند این کار را به شکل بسیار بهتری برای ما انجام بدهد.

SMTP چیست؟

برای ارسال ایمیل با استفاده از زبان پایتون (نسخه ۳) به دو ماژول پیش ساخته به نام های smtplib و email احتیاج داریم:

import smtplib

from email.message import EmailMessage

روش جدید ارسال ایمیل با استفاده از EmailMessage است بنابراین آن را وارد اسکریپت خود کرده ایم اما smtp چیست؟ smtplib به ما اجازه می دهد که یک سرور SMTP ایجاد کنیم! هر زمان که می خواهید به یک فرد ایمیلی ارسال کنید، باید سروری داشته باشید که به شما اجازه می دهد با زبان ایمیل کار کنید و نهایتا آن ها را ارسال نمایید. به طور مثال HTTP یا HTTPS پروتکل های تعامل برای اکثر وب سایت های دنیا هستند. چه نوع تعاملی؟ تعامل بین مرورگر کاربر و سرور وب سایت! از طرف دیگر ایمیل ها نیز پروتکل خاص خودشان را برای تعامل با یکدیگر دارند که SMTP یا همان Simple Mail Transfer Protocol می باشد.

ساخت ایمیل در پایتون

زمانی که می خواهیم با استفاده از پایتون ایمیلی ارسال کنیم باید SMTP را تنظیم کرده باشیم که برای افراد تازه کار کمی آزاردهنده به نظر می رسد اما نگران نباشید، به زودی به آن عادت می کنید. شاید کار هایی که در این قسمت انجام می دهیم کمی پیچیده به نظر برسد اما در اصل کار خاصی را انجام نمی دهیم.

در قدم اول باید یک handler برای کار با ایمیل ها داشته باشیم بنابراین EmailMessage را صدا می زنیم و به یک متغیر می دهیم:

import smtplib

from email.message import EmailMessage




email = EmailMessage()

در مرحله بعدی باید آدرس گیرنده و ارسال کننده را به شیء email اضافه کنیم:

import smtplib

from email.message import EmailMessage




email = EmailMessage()

email['from'] = 'Amir Zouerami'

email['to'] = 'someEmail@someDomain.com'

email['subject'] = 'Learn Development for FREE!'

قسمت های from و to و subject را حتما همه شما می شناسید (به ترتیب «آدرس فرستنده» و «آدرس گیرنده» و «موضوع ایمیل»). در مرحله بعدی باید content (محتوا) ایمیل را ثبت کنیم. content همان محتوای ایمیل است و هر چیزی که می خواهید را در آن می نویسیم. این محتوا می تواند متن، HTML، تصویر یا هر چیز دیگری باشد:

import smtplib

from email.message import EmailMessage




email = EmailMessage()

email['from'] = 'Amir Zouerami'

email['to'] = 'someEmail@someDomain.com'

email['subject'] = 'Learn Development for FREE!'




email.set_content('This is the content of my email')

این شیء ایمیل کامل شده ما است که حاوی تمام فیلد های مورد نظر برای ساخت یک ایمیل صحیح است. در مرحله بعدی باید از سرور SMTP استفاده کنیم تا بتوانیم این ایمیل را ارسال کنیم.

استفاده از سرور SMTP برای ارسال ایمیل

در این قسمت باید سرور SMTP خودمان را به smtplib در پایتون بدهیم تا بتواند از آن برای ارسال ایمیل استفاده کند. سرویس های مختلفی وجود دارند که سرور SMTP به شما می دهند که مهم ترین آن ها دو سرویس زیر هستند:

  • سرویس GMAIL
  • سرویس Mailtrap

من کار با هر دو سرور را برایتان توضیح می دهم.

ارسال ایمیل با استفاده از Gmail

برای استفاده از سرورهای Gmail باید ابتدا قابلیت استفاده از آن را فعال کنیم. برای این کار به قسمت Account setting در حساب GMAIL خودتان رفته و در انتهای صفحه به دنبال گزینه ای به نام Less Secured Apps بگردید و آن را فعال کنید.

نکته: پس از اتمام تست حتما این گزینه را دوباره غیرفعال کنید چرا که امنیت ایمیل شما را کمی پایین می آورد.

import smtplib

from email.message import EmailMessage




email = EmailMessage()

email['from'] = 'Amir Zouerami'

email['to'] = 'someEmail@someDomain.com'

email['subject'] = 'Learn Development for FREE!'




email.set_content('This is the content of my email')







with smtplib.SMTP(host='smtp.gmail.com', port=587) as smtp:

    smtp.ehlo()

    smtp.starttls()

    smtp.login('someemail@gmail.com', 'mypassword0000')

    smtp.send_message(email)

    print('email was sent!')

آدرس سرور smpt گوگل به شکل smtp.gmail.com است بنابراین host را باید روی آن تنظیم کنیم. در مرحله بعدی port این آدرس را تنظیم می کنیم که معمولا روی سرورهای SMTP عدد ۵۸۷ است و گوگل نیز از این مسئله مستثنی نیست.  در مرحله بعدی باید متد های ehlo و starttls را صدا بزنیم تا سرور شروع به کار کند. در مرحله بعدی متد login را صدا می زنیم و اطلاعات حساب Gmail خودمان را به آن می دهیم. طبیعتا به جای مقادیری که در کد بالا مشاهده می کنید، باید اطلاعات حساب خودتان را قرار بدهید. در نهایت ایمیل را با متد send_message ارسال کرده ایم. با اجرای این کد می توانید ایمیل خود را ارسال نمایید.

ارسال ایمیل با استفاده از mailtrap

برای استفاده از mailtrap باید وارد وب سایت آن شده و ثبت نام کنید. با انجام این کار یک توکن برای نام کاربری و یک توکن به عنوان رمز عبور دریافت خواهید کرد. حالا می توانید از قالبی مانند قالب زیر استفاده کنید:

import smtplib




sender = "Private Person <from@example.com>"

receiver = "A Test User <to@example.com>"




message = f"""\

this is my training email.




Subject: Hi Mailtrap

To: {receiver}

From: {sender}




This is a test e-mail message."""




with smtplib.SMTP("smtp.mailtrap.io", 2525) as server:

    server.login("d6q5687c80c8v", "c48g778b6au272")

    server.sendmail(sender, receiver, message)

ما در اینجا از رشته های چند خطی برای تنظیم message (محتوای ایمیل) استفاده کرده ایم. توجه داشته باشید که mailtrap یک وب سایت ساده برای تست کردن کد های شما است و نباید در وب سایت یا برنامه واقعی خود از آن استفاده کنید. حتی Gmail نیز محدودیت های خاصی در تعداد ایمیل های ارسالی دارد بنابراین بهتر است از این دو مثال در سرورهای واقعی خود استفاده نکنید. زمانی که از شرکت های میزبانی یک سرور را خریداری می کنید، ایمیلی حاوی تمام اطلاعات سرور برایتان ارسال می شود و داخل این ایمیل، آدرس سرورهای SMTP و port هایشان نیز موجود است. این سرورها بهترین روش ارسال ایمیل در وب سایت های واقعی هستند.

ساخت ایمیل با محتوای HTML

در حال حاضر ایمیل های ما فقط دارای متن های بسیار ساده ای بودند بنابراین باید گزینه های بهتری را نیز بررسی کنیم. من در کنار فایل main.py خودم، یک فایل دیگر به نام index.html را ایجاد می کنم. محتویات این فایل HTML بسیار ساده و به شکل زیر می باشد:

<!DOCTYPE html>

<html lang="en">

  <head>

    <meta charset="UTF-8" />

    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

  </head>




  <body>

    <p style="background-color: #d4d4d4; padding: 10px; border-radius: 10px">

      This is a simple paragraph tag for $name

    </p>

  </body>

</html>

طبیعتا این دوره، دوره آموزش HTML نیست و به همین خاطر است که من یک صفحه HTML بسیار ساده را در این قسمت نوشته ام. نکته مهم برای ما یادگیری استفاده از HTML در قالب ایمیل است تا در آینده بتوانید هر نوع صفحه HTML را به عنوان ایمیل خود تنظیم کنید. اگر به تگ <p> در کد بالا دقت کنید متوجه وجود مقداری به شکل name$ می شوید. در یک صفحه HTML عادی این مقدار یک رشته عادی است و معنای خاصی ندارد اما ما می خواهیم به آن معنای خاصی بدهیم! چطور؟ ما می خواهیم این مقدار را طوری ویرایش کنیم که نماینده یک متغیر خاص به نام name باشد. برای انجام این کار به دو ماژول پیش ساخته پایتون نیاز داریم:

import smtplib

from email.message import EmailMessage

from string import Template

from pathlib import Path

کلاس Template به ما اجازه می دهد که مقدار خاصی را با علامت دلار ($) مشخص کنیم و سپس آن را با مقدار مورد نظر خودمان تعویض کنیم. اگر به documentation رسمی پایتون مراجعه کنیم مثال زیر را برای template مشاهده می کنیم:

>>> from string import Template

>>> s = Template('$who likes $what')

>>> s.substitute(who='tim', what='kung pao')

'tim likes kung pao'

>>> d = dict(who='tim')

>>> Template('Give $who $100').substitute(d)

Traceback (most recent call last):

...

ValueError: Invalid placeholder in string: line 1, col 11

>>> Template('$who likes $what').substitute(d)

Traceback (most recent call last):

...

KeyError: 'what'

>>> Template('$who likes $what').safe_substitute(d)

'tim likes $what'

به نظر من مثال بالا روش استفاده از template و خطاهای احتمالی آن را به خوبی نشان داده است.

سوالی اصلی در اینجا مطرح می شود که چطور فایل index.html را بخوانیم؟ برای انجام این کار از ماژول pathlib استفاده می کنیم. در نظر داشته باشید که می توانستیم به جای pathlib از ماژول os نیز استفاده کنیم اما به دلایل متعدد پیشنهاد می شود در پایتون همیشه از pathlib استفاده کنید چرا که قابلیت های بیشتری را نسبت به os ارائه می دهد. من از متد read_text در ماژول pathlib برای خواندن فایل index.html به صورت یک رشته استفاده می کنم:

import smtplib

from email.message import EmailMessage

from string import Template

from pathlib import Path




html = Template(Path('index.html').read_text())




email = EmailMessage()

email['from'] = 'Amir Zouerami'

email['to'] = 'someEmail@someDomain.com'

email['subject'] = 'Learn Development for FREE!'




email.set_content(html.substitute(name='Roxo'), 'html')







with smtplib.SMTP(host='smtp.gmail.com', port=587) as smtp:

    smtp.ehlo()

    smtp.starttls()

    smtp.login('someemail@gmail.com', 'mypassword0000')

    smtp.send_message(email)

    print('email was sent!')

همانطور که در کد بالا مشخص است من ابتدا با استفاده از متد read_text محتویات فایل index.html را به صورت یک رشته ساده خوانده ام و سپس این محتویات را به Template پاس داده ام. نتیجه نیز در html قرار دارد بنابراین می توانیم در هنگام set_content روی html متد substitute را صدا بزنیم و خصوصیت name را روی roxo قرار بدهیم. چرا خصوصیت name؟ به دلیل اینکه در ایمیل خود متن name$ را داشتیم بنابراین در صورتی که شما به جای name چیز دیگری را نوشته بودید باید در این قسمت نیز چیز دیگری را پاس بدهید. در نهایت به عنوان آرگومان دوم set_content باید رشته html را به آن بدهیم تا ایمیل ما به صورت HTML پردازش شود. اگر این کار را انجام ندهیم، تمام تگ های HTML نیز به صورت متن عادی برای گیرنده نمایش داده می شوند که طبیعتا مورد پسند ما نیست.

شما می توانید از هر روشی که خودتان دوست دارید برای ارسال این ایمیل ها استفاده کنید اما روشی که در این مقاله ارائه شد، به روز ترین روش در پایتون ۳ می باشد.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری پایتون حرفه‌ای توصیه می‌کند:
نویسنده شوید
دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.