如何使用tls/ssl使用python发送office365的SMTP电子邮件

TKe*_*err 10 python email ssl office365

我正在尝试使用python从我的office365公司帐户发送电子邮件.我是python的新手.此代码以前在使用我的hotmail帐户时有效,但是现在我需要发送机密信息,我必须使用我的公司电子邮件.

我尝试了几件事.

  • 验证我的用户名和密码是否正确.
  • 同时使用python2和python3.两者都给出了同样的错误:535 5.7.3 Authentication unsuccessful
  • 我之前使用mailserver.starttls()时遇到上述错误,经过一些研究后,我试图通过
    证书.mailserver.starttls(certFile中= 'office365.cer')

我不清楚证书部分,但我的步骤包括,在线查找如何导出证书.使用chrome浏览器,microsoftonline.com有一个链证书.我可以导出root和根目录下面的级别,但不能导出最后一级.我不知道如何传递这两个文件,所以我只是传递了根证书.此时我收到错误:ssl.SSLError: [SSL] PEM lib (_ssl.c:3309)

我陷入了困境.任何帮助表示赞赏.代码如下

import smtplib

mailserver = smtplib.SMTP('smtp.office365.com',587)
mailserver.ehlo()
mailserver.starttls(certfile='office365.cer')
mailserver.ehlo()
mailserver.login('user@company.co', 'password')
mailserver.sendmail('user@company.co','user@company.co','python email')
mailserver.quit()
Run Code Online (Sandbox Code Playgroud)

Gal*_*man 15

好吧,你快到了.以下代码将解决这个问题:

import smtplib

mailserver = smtplib.SMTP('smtp.office365.com',587)
mailserver.ehlo()
mailserver.starttls()
mailserver.login('user@company.co', 'password')
mailserver.sendmail('user@company.co','user@company.co','python email')
mailserver.quit()
Run Code Online (Sandbox Code Playgroud)

使用以下链接获取更多信息:

http://www.aventistech.com/2016/03/07/python-send-email-via-office-365-tls/

https://docs.python.org/3/library/smtplib.html

https://gist.github.com/jasonjoh/3ec367594c3fa662ee983a617bdc7deb

  • 注意:使用 smtplib.SMTP() 而不是 smtplib.SMTP_SSL() !使用 smtplib.SMTP_SSL() 您仍然会收到“[SSL: WRONG_VERSION_NUMBER]”错误。用 smtplib.SMTP() 替换它对我有用。 (6认同)
  • 我可以问一个问题吗?Gal Silberman的回答“对我有用”,因为收件人从我那里收到一封电子邮件,但是,该电子邮件为空(他们甚至看不到“ python email”字符串)。谁会知道为什么会这样吗?我没有收到错误,因此很难诊断。 (3认同)
  • @Kela,您应该使用所做的所有事情在不同的线程中提出一个新问题。 (2认同)
  • 也许这是显而易见的,但如果您的公司帐户需要多重身份验证,则用户名和密码不足以进行身份​​验证。 (2认同)

小智 11

我找到了一个适合我的图书馆:

https://github.com/Narcolapser/python-o365

https://pypi.python.org/pypi/O365

使用PIP安装它,然后:

from O365 import Message
o365_auth = ('YourAccount@office365.com','YourPassword')
m = Message(auth=o365_auth)
m.setRecipients('reciving@office365.com')
m.setSubject('I made an email script.')
m.setBody('Talk to the computer, cause the human does not want to hear it any more.')
m.sendMessage()
Run Code Online (Sandbox Code Playgroud)

  • 我只想向将来看到这一点的任何人指出;虽然这个库可以工作,但它不使用 SMTP。它使用 Microsoft Outlook/Graph API 来访问您的 Office 365 帐户并发送电子邮件。如果您想使用 SMTP,请参阅下面的 Gal 回答。 (3认同)
  • @Datanovice [SMTP](https://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol)是用于发送电子邮件的协议,通过smtplib,您可以使用SMTP协议将电子邮件直接发送到Office365邮件服务器。使用nacho-parra的答案,您正在使用Python模块(O365),该模块使用向Microsoft Graph API发送HTTP请求,然后再向其发送电子邮件。结果基本相同(发送电子邮件),但方法不同。最初的问题是询问有关使用SMTP发送的信息,因此gal-silberman的答案实际上是显示如何完成此操作的答案。 (3认同)
  • @Datanovice SMTP对于发送基本电子邮件绝对简单,图形API不仅可以发送电子邮件,还可以使您做更多的事情。就API的速率限制而言,它们相当慷慨,但它们确实有一些[限制](https://docs.microsoft.com/zh-cn/graph/throttling)。只有当我遇到限制时才从电子邮件收件箱中检索超过10,000条消息。SMTP服务器也可以由提供商设置自己的限制,请参阅[here](https://support.microsoft.com/en-us/help/4458479/improvements-in-smtp-authenticated-submission-client-protocol )。 (2认同)

And*_*nth 8

对我来说,@Prometheus 提供的答案是“RuntimeError:未找到身份验证令牌。需要身份验证流程”,如评论中所述。可能是因为我的公司电子邮件启用了 2fa。所以我必须遵循https://github.com/janscas/pyo365#authenticationhttps://pypi.org/project/O365/#authentication中提供的步骤

要使用 oauth,您首先需要在 Microsoft 应用程序注册门户上注册您的应用程序。

  1. 登录Microsoft 应用程序注册门户
  2. 创建应用程序,记下您的应用程序 ID (client_id)
  3. 在“应用程序机密”部分下生成新密码 (client_secret) 在“平台”部分下,添加新的 Web 平台并将https://login.microsoftonline.com/common/oauth2/nativeclient设置为重定向 URL
  4. 转到 API 权限 > 添加权限 > Microsoft Graph > 委派权限,添加以下权限:
    • IMAP.AccessAsUser.All

    • 邮件发送

    • POP.AccessAsUser.All

    • 用户.阅读

    • SMTP发送

    • Offline_access # 如果您希望刷新令牌在 o365_token.txt 中可用。否则您需要每 1 小时获取一次访问令牌。 在此输入图像描述

  5. 运行下面的 python 脚本以获取访问令牌,该令牌将存储在当前目录中名为 o365_token.txt 的文件中
from O365 import Account

scopes =  ["IMAP.AccessAsUser.All", "POP.AccessAsUser.All", "SMTP.Send", "Mail.Send", "offline_access"]

account = Account(credentials=('client_id_of_azureapp', 'client_secret_of_azureapp'))
result = account.authenticate(scopes=scopes)  # request a token for this scopes
Run Code Online (Sandbox Code Playgroud)
  1. 使用以下脚本通过提供上一步中生成的 authtoken 文件来发送电子邮件。
from O365 import Account
from O365.utils.token import FileSystemTokenBackend
tk = FileSystemTokenBackend(token_path=".", token_filename="o365_token.txt")

credentials = ('client_id', 'client_secret')

account = Account(credentials, auth_flow_type = 'public',token_backend=tk)
m = account.new_message()
m.to.add('user@company.com')
m.subject = 'Testing!'
m.body = "George Best quote: I've stopped drinking, but only while I'm asleep."
m.send()
Run Code Online (Sandbox Code Playgroud)

注意:如果您获得管理员同意或者您是管理员或天蓝色帐户,您可以跳过步骤 4、5、6 并直接使用以下代码。

from O365 import Account
from O365.utils.token import FileSystemTokenBackend
tk = FileSystemTokenBackend(token_path=".", token_filename="o365_token.txt")

credentials = ('client_id', 'client_secret') # from step 2,3
account = Account(credentials, auth_flow_type = 'credentials', tenant_id="your_app_tenant_id") # tenant_id (required) available just below client_id in azure

if account.authenticate():
    print('Authenticated!')

mailbox = account.mailbox("user@company.com") # Your email (required) from which you want to send email (your app should have permission to this email)
m = mailbox.new_message()
m.to.add('touser@company.com')
m.subject = 'Testing!'
m.body = "George Best quote: I've stopped drinking, but only while I'm asleep."
m.send()
Run Code Online (Sandbox Code Playgroud)