Python: Sending email from custom domain - python

I am trying to send an email from a custom domain in Python. I have figured out how to send emails from other domains, like gmail.com, using smtplib [example code]. Now I want to figure out how to send an email from a custom domain like catsareonwheels.com.
I thought I would be able to use smtpd to send emails from a server, but that library appears only to serve as a proxy fora Mail Transfer Agent. From what I can tell, there are MTA's written in Pure Python [e.g. Slimta], but I have not been able to find any examples of snippets that actually demonstrate how to send an email from a custom domain with Python.
If anyone can help point me toward literature that might help me determine how best to achieve this goal, I'd be very grateful.

TO SEND AN EMAIL FROM A CUSTOM DOMAIN, YOU DO THE FOLLOWING:
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import smtplib
msg = MIMEMultipart()
msg["From"] = "<your_mail_account>"
msg["To"] = "<destiny_account>"
body_text = "HOLA MUNDO :)"
body_part = MIMEText(body_text, 'plain')
msg.attach(body_part)
with smtplib.SMTP(host="smtp.<CUSTOM_DOMAIN>.com", port=587) as smtp_obj: # ENVIAR DESDE UN DOMINIO PERSONALIZADO.
smtp_obj.ehlo()
smtp_obj.starttls()
smtp_obj.ehlo()
smtp_obj.login("<your_mail_account>", "<your_password>")
smtp_obj.sendmail(msg['From'], [msg['To'],], msg.as_string())
print("¡Datos enviados con éxito!")
That's all :) Hope you like it!

After trying all the SMTP server settings that I have found on other posts I have found the right settings browsing through domain cPanel:
Go to "List Email Accounts"
On the right sido of the account you want to use click on "Connect devices"
Check "Mail Client Manual Settings"

What do you exactly mean by "custom domain"?
If you have some hosting witch provides you an email service then you can use smtplib as well.
Lets say I bought a hosting and a domain use-smtplib.com. I've created an email account myname#use-smtplib.com in admin panel.
Then configuration should look somehow like this:
with smtplib.SMTP_SSL('mail.use-smtplib.com', '465') as smtp:
smtp.login('myname#use-smtplib.com', 'my_strong_password')
subject = "Message from python"
msg = "Hello from python"
smtp.sendmail('myname#use-smtplib.com', 'recipient#gmail.com', msg)
Exact configuration may be different depending on your email provider. Domains starting with mail.domain.com and smtp.domain.com are pretty common.

Related

I can't Read Outlook Email with Python on Linux

I need to do an email automation. For this I need to read an email from Outlook and then send it after configuring some data.
The problem is that all the tutorials I've seen say to use the Outlook application installed on the computer. As I use Linux I can't do this. To read the email using Gmail, I did the following:
import datetime
from imap_tools import MailBox, AND
user = "myemail#gmail.com"
password = "anypassword"
#This password is an "App Password" that I need to configure within Gmail.
my_email = MailBox("imap.gmail.com").login(user, password)
today = datetime.date.today()
list_emails = my_email.fetch(AND(from_="", date=today, subject=""))
for email in list_emails:
print(email.text)
How can I adapt the code for Outlook?
PS: In Gmail it is possible to set an "App Password". I didn't get this in Outlook.

How to store a password in my python script but have it obscured from any users when deployed to Github?

I've been trying to work this one out for a while now but keep finding imperfect solutions - I think what I want to do is possible but maybe I'm not phrasing my Google search correctly.
I have a Python script that sends a user an email notification - in order to send said email I need to provide a password in the script to send the email. The code works perfectly but it requires that I pass the password into the script:
def send_email():
import smtplib
import ssl
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
sender_email = "my-generic-email#gmail.com"
receiver_email = "recipient#gmail.com"
password = "my_password_here"
message = MIMEMultipart("alternative")
message["Subject"] = "subject_here"
message["From"] = sender_email
message["To"] = receiver_email
# Create the plain-text and HTML version of your message
text = f"""\
Plain text body here
"""
# Create secure connection with server and send email
context = ssl.create_default_context()
with smtplib.SMTP_SSL("smtp.gmail.com", 465, context=context) as server:
server.login(sender_email, password)
server.sendmail(
sender_email, receiver_email, message.as_string()
)
I don't want to store the password as plain text for obvious reasons. I've thought of environment variables but this wouldn't work as this is going to be deployed on GitHub for other people to use (or install as an EXE) so this would break the email functionality.
I've tried looking at PyCryptodome but anything I've found so far suggests encrypting the password with a key but then storing the key in the script to decrypt the password when you use it. This seems like a bad idea to me as surely any novice (like me!) would be able to easily decrypt this because the key is stored in the script.
Is anyone able to help push me in the right direction? I'm completely out of ideas as frankly I know hardly anything about password storing/security so not even sure what I should be Googling!
If others have to use your password to be able to use your script, it's impossible. If the computer can read it, then the user will also find a way to read it.
I recommend using a E-Mail service where the user can enter their own API key or just let them enter their own GMail credentials.
Correct me if I'm wrong, but I think there's no way to use your password in this case unless you write an API and send the E-Mail from your server. But don't forget that in this case, the user might be able to use your API as a way to send spam.
TL;DR: Let the users use their own passwords.

Python reading email from outlook account using imaplib/imapclient vs exchangelib?

I am setting up a script to read incoming emails from an outlook.com account and I've tested a few approaches with imaplib and was unsuccessful. Yet when I tried with Exchangelib I was able to do this. I'm not entirely sure why Exchangelib works and imaplib doesn't. I feel like I might be breaking some best practices here as I don't know how Exchangelib is able to connect to the mailbox through some sort of trickery of network connections?
For reference the IMAP code that doesn't work (though it works when I attempt to connect to my personal gmail account)
from imapclient import IMAPClient
import mailparser
with IMAPClient('outlook.office365.com', ssl=True) as server:
server.login("username", "password")
server.select_folder('INBOX')
messages = server.search(['FROM', ])
# for each unseen email in the inbox
for uid, message_data in server.fetch(messages, 'RFC822').items():
email_message = mailparser.parse_from_string(message_data[b'RFC822'])
print("email ", email_message)
I get the below error
imapclient.exceptions.LoginError: b'LOGIN failed.'
When I use exchangelib it works succesfully. Reference code below:
from exchangelib import Credentials, Account
credentials = Credentials("username", "password")
account = Account(username, credentials=credentials, autodiscover=True)
for item in account.inbox.all().order_by('-datetime_received')[:100]:
print(item.subject, item.sender, item.datetime_received)
Is there any reason why I can't connect with imaplib/imapclient vs exchangelib? Perhaps some security related reason that I'm not aware of?
I think you might need to pass in the full email-ID when using imapclient/imaplib vs just the username when using exchangelib.

Using HTML templates to send emails in python

I'm trying to write a separate mail service, which is decoupled with our Flask application. I'm looking for a way to send welcome emails when users first log into our Flask application. I'm using Celery and RabbitMQ to do it asynchronously.
Here is my email function:
sen = 'example#gmail.com'
pwd = 'my_password'
#celery.task
def send_email(nickname, email):
msg = MIMEMultipart('alternative')
msg['Subject'] = 'my_sub'
msg['From'] = sen
msg['To'] = email
html = <b>test_body</b>
part1 = MIMEText(html, 'html')
msg.attach(part1)
server = smtplib.SMTP("smtp.gmail.com", 587)
server.ehlo()
server.starttls()
server.login(sen, pwd)
server.sendmail(sen, [email], msg.as_string())
server.close()
Initially I was using Flask's render_template to get the HTML body and subject. But I don't want to use the Flask extension (I have my reasons). So my questions are:
How can I use email templates so that the subject and body fields can be configured easily?
How can I put the default email sender and password in a config file/email template (might be related to q1)?
It seems to be that I have a lot of code to send a simple email. Can you suggest some optimization techniques (omitting steps)?
I've wrritten a simple module(mail.py) to send emails using templates(HTML/TEXT). Hope that helps!
https://github.com/ludmal/pylib
It may be simpler to use an external service.
A service (e.g. Mailchimp) is simple to integrate. You can design the template in their layer, and trigger emails by sending merge data from your app to the service API. Functionally it's a lot like rendering a template locally and mailing it out via SMTP, but they have sophisticated tools for adapting message format to devices, tracking bounces, improving deliverability, reporting etc.
Services like this often have a free tier for up to 1000's of emails per month.

Django sending email

In PHP I can send an email simply by calling mail(). In Django, I need to specify SMTP backends and other things.
Is there a simpler way to send email from Django?
There are several good mail-sending functions in the django.core.mail module.
For a tutorial please see Sending e-mail:
Although Python makes sending e-mail
relatively easy via the smtplib
library, Django provides a couple of
light wrappers over it. These wrappers
are provided to make sending e-mail
extra quick, to make it easy to test
e-mail sending during development, and
to provide support for platforms that
can’t use SMTP.
The simplest function that would most likely suit your purposes is the send_mail function:
send_mail(
subject,
message,
from_email,
recipient_list,
fail_silently=False,
auth_user=None,
auth_password=None,
connection=None)
In PHP you can only send mail with a simple mail() command on non-Windows systems. These will expect a local MTA like Postfix to be installed and correctly configured, as should be the case for most web servers. If you want to depend on third-party or decentralized mail service depends on how critical email is for your application. Serious dependency on speedy and reliable email transmission usually results in sending mail via SMTP to a central mail server (the "big pipe").
Still, if you want to have the same function as in PHP, try this:
import subprocess
def send_mail(from_addr, to_addr, subject, body):
cmdline = ["/usr/sbin/sendmail", "-f"]
cmdline.append(from_addr)
cmdline.append(to_addr)
mailer = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
dialog = "From: %s\nTo: %s\nSubject: %s\n\n%s\n.\n" % (from_addr, to_addr, subject, body)
return mailer.communicate(dialog)
And use it like:
send_mail ("Me <myself#mydomain.com>", "Recip Ient <other#hisdomain.com>", "Teh' Subject", "Mail body")
Either way, you need some backend (read MTA). Of the top of my head I can think of two things:
As already pointed out, you can for example use sendmail http://djangosnippets.org/snippets/1864/
Even better, use a Python MTA. There's Lamson, a Python email server (MTA): http://lamsonproject.org/docs/hooking_into_django.html

Categories