草庐IT

python - 如何在不启用 'insecure access' 的情况下通过 gmail 发送电子邮件?

coder 2023-05-24 原文

Google 正在插入我们提高脚本访问其 gmail smtp 服务器的安全性。对于那件事我没有任何疑问。事实上,我很乐意提供帮助。

但他们并没有让事情变得容易。建议我们升级到使用最新安全措施的更安全的应用程序很好,但这并不能帮助我弄清楚如何升级看起来像这样的代码:

server = smtplib.SMTP("smtp.gmail.com", 587)
server.ehlo()
server.starttls()
server.login(GMAIL_USER, GMAIL_PASSWORD)
server.sendmail(FROM, TO, MESSAGE)
server.close()

当然,我会打开“访问安全性较低的应用程序”,但如果有人想出用什么替换此代码,我将不胜感激。

最佳答案

这很痛苦,但我现在似乎有什么事情发生了......

不支持 Python3(目前)

我认为这不会太难实现,因为我在转换包时磕磕绊绊而没有遇到任何大问题:只是通常的 2to3 东西。然而,几个小时后,我厌倦了逆流而上。在撰写本文时,我找不到公开的 Python 3 软件包。python 2 的体验是直截了当的(相比之下)。

浏览 Google 网站是成功的一半

毫无疑问,随着时间的推移,这种情况会发生变化。最终你需要下载一个 client_secret.json 文件。您只能(可能)通过网络浏览器进行此设置:

  1. 您需要一个 google 帐户 - google 应用程序或 gmail。所以,如果你还没有,那就去买一个吧。
  2. 访问 developers console
  3. 创建一个新项目,然后等待 4 或 400 秒以完成。
  4. 导航到 API 和 Auth -> Credentials
  5. OAuth 下选择 Create New Client ID
  6. 选择Installed Application作为应用程序类型和Other
  7. 您现在应该有一个按钮下载 JSON。去做。这是你的 client_secret.json——可以说是密码

但等等,这还不是全部!

您必须为您的应用程序提供一个“产品名称”以避免出现一些奇怪的错误。 (看看我受了多少苦才给你这个 ;-)

  1. 导航到 API's & auth -> 同意屏幕
  2. 选择您的电子邮件
  3. 输入产品名称。它是什么并不重要。 “Foobar”会很好。
  4. 保存

快讯!哇。现在还有更多!

  1. 导航到 API 和身份验证 -> API -> Gmail API
  2. 点击按钮启用 API

是的。现在我们可以更新电子邮件脚本了。

Python 2

您需要第一次以交互方式运行脚本。它将在您的机器上打开一个网络浏览器,您将授予权限(点击一个按钮)。此练习会将包含可重复使用 token 的文件保存到您的计算机 gmail.storage

[我没有运气将 token 转移到没有图形浏览器功能的机器上——返回一个 HTTPError。我试图通过 lynx 图形浏览器来解决它。那也失败了,因为谷歌已将最终的“接受”按钮设置为“禁用”!?我会提出另一个问题来跳过这个障碍(更多提示)]

首先你需要一些库:

pip install --upgrade google-api-python-client
pip install --upgrade python-gflags
  • 您需要更改收件地址和发件人地址
  • 确保您在 Storage 指令期望的任何地方都有 client_token.json 文件
  • 目录需要是可写的,这样才能保存 gmail.storage 文件

最后是一些代码:

import base64
import httplib2

from email.mime.text import MIMEText

from apiclient.discovery import build
from oauth2client.client import flow_from_clientsecrets
from oauth2client.file import Storage
from oauth2client.tools import run


# Path to the client_secret.json file downloaded from the Developer Console
CLIENT_SECRET_FILE = 'client_secret.json'

# Check https://developers.google.com/gmail/api/auth/scopes for all available scopes
OAUTH_SCOPE = 'https://www.googleapis.com/auth/gmail.compose'

# Location of the credentials storage file
STORAGE = Storage('gmail.storage')

# Start the OAuth flow to retrieve credentials
flow = flow_from_clientsecrets(CLIENT_SECRET_FILE, scope=OAUTH_SCOPE)
http = httplib2.Http()

# Try to retrieve credentials from storage or run the flow to generate them
credentials = STORAGE.get()
if credentials is None or credentials.invalid:
  credentials = run(flow, STORAGE, http=http)

# Authorize the httplib2.Http object with our credentials
http = credentials.authorize(http)

# Build the Gmail service from discovery
gmail_service = build('gmail', 'v1', http=http)

# create a message to send
message = MIMEText("Message goes here.")
message['to'] = "yourvictim@goes.here"
message['from'] = "you@go.here"
message['subject'] = "your subject goes here"
body = {'raw': base64.b64encode(message.as_string())}

# send it
try:
  message = (gmail_service.users().messages().send(userId="me", body=body).execute())
  print('Message Id: %s' % message['id'])
  print(message)
except Exception as error:
  print('An error occurred: %s' % error)

希望这能让我们都开始。不像旧方法那么简单,但现在我可以亲眼看到它确实看起来不那么复杂。

关于python - 如何在不启用 'insecure access' 的情况下通过 gmail 发送电子邮件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25944883/

有关python - 如何在不启用 'insecure access' 的情况下通过 gmail 发送电子邮件?的更多相关文章

  1. ruby - 如何在 Ruby 中顺序创建 PI - 2

    出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits

  2. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  3. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  4. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  5. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  6. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  7. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  8. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  9. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  10. ruby - 默认情况下使选项为 false - 2

    这是在Ruby中设置默认值的常用方法:classQuietByDefaultdefinitialize(opts={})@verbose=opts[:verbose]endend这是一个容易落入的陷阱:classVerboseNoMatterWhatdefinitialize(opts={})@verbose=opts[:verbose]||trueendend正确的做法是:classVerboseByDefaultdefinitialize(opts={})@verbose=opts.include?(:verbose)?opts[:verbose]:trueendend编写Verb

随机推荐