How to send mail with office 365 mail in python?

Hello,

I'm trying to make a django app that can send mail using an office 365 account.

Is there a simple way to do it?

Appreciate any help!
Errang GenevreAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

clockwatcherCommented:
Sending through Office 365 is pretty much the same as sending through anywhere else-- just need to use TLS , port 587 and authentication.

Here's a routine pulled from some of my code to do a send.  It works for me with Office 365.  It might need some changes for python3.

sendmail.py
 
import smtplib, os
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.MIMEImage import MIMEImage
from email.Utils import COMMASPACE, formatdate
from email import Encoders
import ConfigParser

def send_mail(send_from, send_to, subject, text, files=None, 
                          data_attachments=None, server="smtp.office365.com", port=587, 
                          tls=True, html=False, images=None,
                          username=None, password=None, 
                          config_file=None, config=None):

    if files is None:
        files = []

    if images is None:
        images = []

    if data_attachments is None:
        data_attachments = []

    if config_file is not None:
        config = ConfigParser.ConfigParser()
        config.read(config_file)

    if config is not None:
        server = config.get('smtp', 'server')
        port = config.get('smtp', 'port')
        tls = config.get('smtp', 'tls').lower() in ('true', 'yes', 'y')
        username = config.get('smtp', 'username')
        password = config.get('smtp', 'password')

    msg = MIMEMultipart('related')
    msg['From'] = send_from
    msg['To'] = send_to if isinstance(send_to, basestring) else COMMASPACE.join(send_to)
    msg['Date'] = formatdate(localtime=True)
    msg['Subject'] = subject

    msg.attach( MIMEText(text, 'html' if html else 'plain') )

    for f in files:
        part = MIMEBase('application', "octet-stream")
        part.set_payload( open(f,"rb").read() )
        Encoders.encode_base64(part)
        part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(f))
        msg.attach(part)

    for f in data_attachments:
        part = MIMEBase('application', "octet-stream")
        part.set_payload( f['data'] )
        Encoders.encode_base64(part)
        part.add_header('Content-Disposition', 'attachment; filename="%s"' % f['filename'])
        msg.attach(part)

    for (n, i) in enumerate(images):
        fp = open(i, 'rb')
        msgImage = MIMEImage(fp.read())
        fp.close()
        msgImage.add_header('Content-ID', '<image{0}>'.format(str(n+1)))
        msg.attach(msgImage)

    smtp = smtplib.SMTP(server, int(port))
    if tls:
        smtp.starttls()

    if username is not None:
        smtp.login(username, password)
    smtp.sendmail(send_from, send_to, msg.as_string())
    smtp.close()

Open in new window

Using it:
from sendmail import send_mail

send_mail('my365user@wherever.com', 'you@there.com', 'Subject', 'Message Body', 
                   username='my365user@wherever.com', password='my365password')

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Errang GenevreAuthor Commented:
Sweet, thanks; I was trying to find what the backend server was, for some reason I wasn't able to see the "smtp.office365.com". I found it on the account once I knew what I was looking for.

But I'm getting this error now: 550, '5.7.60 SMTP; Client does not have permissions to send as this sender'

I looked online and it says that we need to get the public IP address of the server I'm using; but when I looked at the OpenShift SSH server; I only saw these IP addresses configured in the environment variables:
OPENSHIFT_HAPROXY_STATUS_IP=127.4.165.3
OPENSHIFT_PYTHON_IP=127.4.165.1
OPENSHIFT_HAPROXY_IP=127.4.165.2

If they're following the same conventions as the rest of the world.. 127.x.x.x would be a local IP address, right?

Is there any way to fix this error by adding the dns name somewhere on the account? Or does an admin have to do it, I've been given this account by the IT manager.
0
clockwatcherCommented:
The error would seem to indicate that the user you're authenticating as doesn't have the email address that you're trying to send as.  Are you trying to send from a different email address than what you're authenticating with?
0
HTML5 and CSS3 Fundamentals

Build a website from the ground up by first learning the fundamentals of HTML5 and CSS3, the two popular programming languages used to present content online. HTML deals with fonts, colors, graphics, and hyperlinks, while CSS describes how HTML elements are to be displayed.

Errang GenevreAuthor Commented:
Yes, initially my code was working with Gmail accounts; with this function call:
send_mail(subject, message, 'sender@something.com', [user_email], False)

Open in new window


But I looked at your code and changed it to (the username and password fields were giving me errors, so I looked at https://docs.djangoproject.com/en/1.8/_modules/django/core/mail/#send_mail ; should I be using another send_mail function?):
send_mail('sender@something.com', 'receiver@something.com', subject, message,
              auth_user= 'sender@something.com', auth_password='password')

Open in new window


I get a success message; but the email doesn't show up in the "Sent" folder on the microsoft account, and it doesn't show up in the email address  it was supposed to send to; is it just slow? Or am I getting a false success message?
0
Errang GenevreAuthor Commented:
Sorry, just realized you had a send_mail function (been looking at this stuff for way too long...); I tried your method too; I got a few errors with the email.xxx imports, so I removed them and the corresponding code in your function and I got the same result.

It succeeds, but I don't get an email.
0
clockwatcherCommented:
Sorry.  Without any kind of error, pretty tough to troubleshoot.  But I would highly doubt that Microsoft's SMTP service would give you a false success message.  

You can turn on debugging in the smtplib by calling set_debuglevel on the SMTP object.  In the code that I posted that would be done by inserting a:

smtp.set_debuglevel(1)

In line 66.  It will dump the SMTP traffic to stderr.

I don't use django enough to tell you where to look or enable it there.   But personally, I would verify that you can get sending email through Office 365 via python working outside of django first.
0
Errang GenevreAuthor Commented:
Fantastic! It works... I've placed a bit too much trust in IntelliJ; its showing errors, but it compiles properly.

If its not too much trouble, I'm trying to become a better programmer; I was searching online, and found https://realpython.com does it seem like it is worth it? Or are there better alternatives?

Appreciate any feedback!
0
clockwatcherCommented:
There's really no substitute for just getting in there and working with the language and from the questions I've seen from you looks to me like you have a fairly good grasp of things.   Sixty bucks isn't a huge investment but at a glance I'm guessing you won't find much in there that will challenge you.  

Another EE user was using codeacademy.com.  It's free and from the little bit I looked, it looked a fairly good site for basic stuff.  Again I don't know that it will give you much of a challenge.   It was for general python and not targeted specifically at django which I'm guessing might be more what you're after but for free it's probably worth a look.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Python

From novice to tech pro — start learning today.