对我来说,@Prometheus提供的答案会导致出现“RuntimeError: No auth token found. Authentication Flow needed”的错误,正如评论中所述。可能是因为我的公司电子邮件启用了2fa。因此,我必须遵循https://github.com/janscas/pyo365#authentication和https://pypi.org/project/O365/#authentication提供的步骤。
要使用OAuth,您首先需要在Microsoft应用程序注册门户上注册您的应用程序。
- 登录Microsoft Application Registration Portal
- 创建应用程序,注意您的应用程序ID(client_id)
- 在“应用程序秘密”部分下生成新密码(client_secret),在“平台”部分下添加一个新的Web平台并将https://login.microsoftonline.com/common/oauth2/nativeclient设置为重定向URL
- 进入API权限>添加权限>Microsoft Graph>委派权限,添加以下权限:
- 运行以下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)
- 使用以下脚本,通过提供在前一步骤中生成的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()
注意:
如果您拥有管理员同意或者是管理员或Azure账户,您可以跳过第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')
account = Account(credentials, auth_flow_type = 'credentials', tenant_id="your_app_tenant_id")
if account.authenticate():
print('Authenticated!')
mailbox = account.mailbox("user@company.com")
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()
mailserver.ehlo()
不是必需的。根据starttls()
的文档:“如果在此会话中没有先前的 EHLO 或 HELO 命令,则此方法首先尝试 ESMTP EHLO。” - tomatoeshiftmailserver = smtplib.SMTP('smtp.office365.com',587)
终端继续输出空白行,执行等待... - Deepak V