但他们并不容易。建议我们Upgrade to a more secure app that uses the most up to date security measures
一切都很好,但这并没有帮助我弄清楚如何升级看起来像这样的代码:
server = smtplib.SMTP("smtp.gmail.com", 587)
server.ehlo()
server.starttls()
server.login(GMAIL_USER, GMAIL_PASSWORD)
server.sendmail(FROM, TO, MESSAGE)
server.close()
当然,我会开启“访问不太安全的应用程序”,但如果有人知道要替换这些代码的内容,我将不胜感激。
答案 0 :(得分:30)
这很痛苦,但我现在似乎有些事情......
我不认为它太难实现,因为我在转换软件包时遇到了磕磕绊绊而没有发生任何大规模的事情:只是通常的2to3。然而,经过几个小时,我厌倦了向上游游泳。在撰写本文时,我无法找到已发布的Python 3公共消费包.MSthon 2的体验很简单(相比之下)。
毫无疑问,随着时间的推移,这将会改变。最终,您需要下载client_secret.json
文件。你只能(可能)通过网络浏览器进行设置:
API's and Auth
- > Credentials
OAuth
下选择Create New Client ID
Installed Application
作为应用类型,其他 Download JSON
。去做。这是您的client_secret.json
- 密码可以这么说但等等不是全部!
您必须为您的应用程序提供一个"产品名称"避免一些奇怪的错误。 (看看我给你带来了多少痛苦; - )
API's & auth
- > Consent Screen
<强>快讯!哇。现在还有更多!
耶。现在我们可以更新电子邮件脚本。
您需要第一次以交互方式运行脚本。它将在您的计算机上打开Web浏览器,您将授予权限(点击按钮)。此练习会将文件保存到包含可重复使用令牌的计算机gmail.storage
。
[我没有幸运将令牌转移到没有图形浏览器功能的机器 - 返回HTTPError。我试图通过lynx图形浏览器来完成它。这也失败了,因为谷歌已经设定了最终的'#34;接受&#34;按钮到&#34;禁用&#34;!?我会提出另一个问题来跳过这个障碍(更多的抱怨)]
首先你需要一些库:
pip install --upgrade google-api-python-client
pip install --upgrade python-gflags
Storage
指令所期望的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)
希望这让我们全部开始。不像旧方式那么简单,但看起来复杂得多,现在我可以在肉体中看到它。
答案 1 :(得分:16)
看来John Mee的答案已经过时了。 它在2016年7月不起作用。 可能是由于Gmail的API更新。 我更新了他的代码(python 2),如下所示:
SELECT 'postgresql' AS dbms,
t.table_catalog,t.table_schema,
t.table_name,c.column_name,
c.ordinal_position,c.data_type,
c.character_maximum_length,
n.constraint_type,
k2.table_schema,
k2.table_name,
k2.column_name,
td.description AS table_description,
cd.description AS column_description
FROM information_schema.tables t
LEFT JOIN pg_catalog.pg_description td
ON (td.objoid = (quote_ident(t.table_schema)||'.'||quote_ident(t.table_name))::regclass AND td.objsubid = 0)
NATURAL LEFT JOIN information_schema.columns c
LEFT JOIN(
information_schema.key_column_usage k
NATURAL JOIN information_schema.table_constraints n
NATURAL LEFT JOIN information_schema.referential_constraints r)
ON c.table_catalog=k.table_catalog
AND c.table_schema=k.table_schema
AND c.table_name=k.table_name
AND c.column_name=k.column_name
LEFT JOIN information_schema.key_column_usage k2
ON k.position_in_unique_constraint=k2.ordinal_position
AND r.unique_constraint_catalog=k2.constraint_catalog
AND r.unique_constraint_schema=k2.constraint_schema
AND r.unique_constraint_name=k2.constraint_name
LEFT JOIN pg_catalog.pg_description cd
ON (cd.objoid = (quote_ident(t.table_schema)||'.'||quote_ident(t.table_name))::regclass AND cd.objsubid = c.ordinal_position)
WHERE t.TABLE_TYPE='BASE TABLE' AND t.table_schema NOT IN('information_schema','pg_catalog')
ORDER BY t.table_name;
请注意,如果您遇到错误 """Send an email message from the user's account.
"""
import base64
from email.mime.audio import MIMEAudio
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import mimetypes
import os
#from __future__ import print_function
import httplib2
import os
from apiclient import discovery
import oauth2client
from oauth2client import client
from oauth2client import tools
from apiclient import errors
SCOPES = 'https://www.googleapis.com/auth/gmail.compose'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'Gmail API Python Quickstart'
try:
import argparse
flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
flags = None
def SendMessage(service, user_id, message):
"""Send an email message.
Args:
service: Authorized Gmail API service instance.
user_id: User's email address. The special value "me"
can be used to indicate the authenticated user.
message: Message to be sent.
Returns:
Sent Message.
"""
try:
message = (service.users().messages().send(userId=user_id, body=message)
.execute())
print 'Message Id: %s' % message['id']
return message
except errors.HttpError, error:
print 'An error occurred: %s' % error
def CreateMessage(sender, to, subject, message_text):
"""Create a message for an email.
Args:
sender: Email address of the sender.
to: Email address of the receiver.
subject: The subject of the email message.
message_text: The text of the email message.
Returns:
An object containing a base64url encoded email object.
"""
message = MIMEText(message_text)
message['to'] = to
message['from'] = sender
message['subject'] = subject
return {'raw': base64.urlsafe_b64encode(message.as_string())}
def get_credentials():
"""Gets valid user credentials from storage.
If nothing has been stored, or if the stored credentials are invalid,
the OAuth2 flow is completed to obtain the new credentials.
Returns:
Credentials, the obtained credential.
"""
home_dir = os.path.expanduser('~')
credential_dir = os.path.join(home_dir, '.credentials')
if not os.path.exists(credential_dir):
os.makedirs(credential_dir)
credential_path = os.path.join(credential_dir,
'sendEmail.json')
store = oauth2client.file.Storage(credential_path)
credentials = store.get()
if not credentials or credentials.invalid:
flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
flow.user_agent = APPLICATION_NAME
if flags:
credentials = tools.run_flow(flow, store, flags)
else: # Needed only for compatibility with Python 2.6
credentials = tools.run(flow, store)
print('Storing credentials to ' + credential_path)
return credentials
if __name__ == "__main__":
try:
credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
service = discovery.build('gmail', 'v1', http=http)
SendMessage(service, "me", CreateMessage("send@gmail.com", "receive@gmail.com", "Test gmail automation", "Hello world"))
except Exception, e:
print e
raise
,可能的原因之一是程序中的范围未正确设置。
另一个可能的原因可能是您需要删除存储json文件(此程序中的“sendEmail.json”)并刷新您的程序。有关详细信息,请参阅此post。
答案 2 :(得分:5)
您是否考虑过使用Gmail API?该API具有内置的安全功能,并专门针对Gmail进行了优化。您可以在http://developers.google.com上找到API文档 - 例如,这里是Send API调用的文档:
https://developers.google.com/gmail/api/v1/reference/users/messages/send
答案 3 :(得分:4)
我包含了一些已针对python 3使用而更新的代码 - 一旦获得必要的权限和OAuth令牌工作,它似乎会发送电子邮件。它主要基于谷歌api网站样本
from __future__ import print_function
import base64
import os
from email.mime.text import MIMEText
import httplib2
from apiclient import discovery
from googleapiclient import errors
from oauth2client import client
from oauth2client import tools
from oauth2client.file import Storage
try:
import argparse
flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
flags = None
# If modifying these scopes, delete your previously saved credentials
# at ~/.credentials/gmail-python-quickstart.json
SCOPES = 'https://www.googleapis.com/auth/gmail.send'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'Gmail API Python Quickstart'
def get_credentials():
"""Gets valid user credentials from storage.
If nothing has been stored, or if the stored credentials are invalid,
the OAuth2 flow is completed to obtain the new credentials.
Returns:
Credentials, the obtained credential.
"""
home_dir = os.path.expanduser('~')
credential_dir = os.path.join(home_dir, '.credentials')
if not os.path.exists(credential_dir):
os.makedirs(credential_dir)
credential_path = os.path.join(credential_dir,
'gmail-python-quickstart.json')
store = Storage(credential_path)
credentials = store.get()
if not credentials or credentials.invalid:
flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
flow.user_agent = APPLICATION_NAME
if flags:
credentials = tools.run_flow(flow, store, flags)
else: # Needed only for compatibility with Python 2.6
credentials = tools.run(flow, store)
print('Storing credentials to ' + credential_path)
return credentials
to = 'test@email.com'
sender = 'test@email.com'
subject = 'test emails'
message_text = 'hello this is a text test message'
user_id = 'me'
def create_message(sender, to, subject, message_text):
"""Create a message for an email.
Args:
sender: Email address of the sender.
to: Email address of the receiver.
subject: The subject of the email message.
message_text: The text of the email message.
Returns:
An object containing a base64url encoded email object.
"""
message = MIMEText(message_text)
message['to'] = to
message['from'] = sender
message['subject'] = subject
return {'raw': (base64.urlsafe_b64encode(message.as_bytes()).decode())}
def send_message(service, user_id, message):
"""Send an email message.
Args:
service: Authorized Gmail API service instance.
user_id: User's email address. The special value "me"
can be used to indicate the authenticated user.
message: Message to be sent.
Returns:
Sent Message.
"""
try:
message = (service.users().messages().send(userId=user_id, body=message)
.execute())
print('Message Id: {}'.format(message['id']))
return message
except errors.HttpError as error:
print('An error occurred: {}'.format(error))
def main():
"""Shows basic usage of the Gmail API.
Creates a Gmail API service object and outputs a list of label names
of the user's Gmail account.
"""
credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
service = discovery.build('gmail', 'v1', http=http)
msg = create_message(sender,to,subject,message_text)
message = (service.users().messages().send(userId=user_id, body=msg)
.execute())
print('Message Id: {}'.format(message['id']))
results = service.users().messages().list(userId='me').execute()
labels = results.get('labels', [])
if not labels:
print('No labels found.')
else:
print('Labels:')
for label in labels:
print(label['name'])
if __name__ == '__main__':
main()
答案 4 :(得分:0)
更新的Python 3示例以及下面的GMail当前API。
请注意,要获取下面的credentials.json
文件,您需要在选择相关的GCP项目之后创建Oauth客户端ID凭据here。创建完成后,将显示客户端密钥和客户端密钥。关闭该提示,然后单击帐户旁边的向下箭头。这是您需要的文件。
import base64
import logging
import mimetypes
import os
import os.path
import pickle
from email.mime.text import MIMEText
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from googleapiclient import errors
from googleapiclient.discovery import build
def get_service():
"""Gets an authorized Gmail API service instance.
Returns:
An authorized Gmail API service instance..
"""
# If modifying these scopes, delete the file token.pickle.
SCOPES = [
'https://www.googleapis.com/auth/gmail.readonly',
'https://www.googleapis.com/auth/gmail.send',
]
creds = None
# The file token.pickle stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists('token.pickle'):
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.pickle', 'wb') as token:
pickle.dump(creds, token)
service = build('gmail', 'v1', credentials=creds)
return service
def send_message(service, sender, message):
"""Send an email message.
Args:
service: Authorized Gmail API service instance.
user_id: User's email address. The special value "me"
can be used to indicate the authenticated user.
message: Message to be sent.
Returns:
Sent Message.
"""
try:
sent_message = (service.users().messages().send(userId=sender, body=message)
.execute())
logging.info('Message Id: %s', sent_message['id'])
return sent_message
except errors.HttpError as error:
logging.error('An HTTP error occurred: %s', error)
def create_message(sender, to, subject, message_text):
"""Create a message for an email.
Args:
sender: Email address of the sender.
to: Email address of the receiver.
subject: The subject of the email message.
message_text: The text of the email message.
Returns:
An object containing a base64url encoded email object.
"""
message = MIMEText(message_text)
message['to'] = to
message['from'] = sender
message['subject'] = subject
s = message.as_string()
b = base64.urlsafe_b64encode(s.encode('utf-8'))
return {'raw': b.decode('utf-8')}
if __name__ == '__main__':
logging.basicConfig(
format="[%(levelname)s] %(message)s",
level=logging.INFO
)
try:
service = get_service()
message = create_message("from@gmail.com", "to@gmail.com", "Test subject", "Test body")
send_message(service, "from@gmail.com", message)
except Exception as e:
logging.error(e)
raise
答案 5 :(得分:-5)
protected string SendEmail(string toAddress, string subject, string body)
{
string result = "Message Sent Successfully..!!";
string senderID = "...........";// use sender's email id here..
const string senderPassword = "........."; // sender password here...
try
{
SmtpClient smtp = new SmtpClient
{
Host = "smtp.gmail.com", // smtp server address here...
Port = 587,
EnableSsl = true,
DeliveryMethod = SmtpDeliveryMethod.Network,
Credentials = new System.Net.NetworkCredential(senderID, senderPassword),
Timeout = 30000,
};
MailMessage message = new MailMessage(senderID, toAddress, subject, body);
smtp.Send(message);
}
catch (Exception ex)
{
result = "Error sending email.!!!";
}
return result;
}