このpython 3スクリプトは、電子メールを作成し、それにURLを使って1つのファイルを添付して送信することを想定しています。これは、電子メールを送信しますが、何かが、私はGoogleのドキュメントを読んでなかったcreate_message_with_attachment()
python 3.6 gmail api - 添付ファイル付きのメールを送信
TypeError: Attach is not valid on a message with a non-multipart payload
とうまくいきません。それについて話しているスタックスレッドは、複雑なアタッチメントスタイルに重点を置いています。その上には、Pythonバージョンのさまざまな構文があります。
コードはいくつかのソースのパッチワークです。私は一緒にcreate_message_with_attachment()
に参加するのに苦労します。私はこれを含める必要がある場合、私は知らない例えば
は
raw = base64.urlsafe_b64encode(msg.as_bytes())
raw = raw.decode()
body = {'raw': raw}
return body
(。それが一番下にこのコードCfの上で動作create_message_without_attachment()からです)添付ファイルのコードを作成するメッセージ:
import httplib2
import os
import oauth2client
from oauth2client import client, tools
import base64
from email import encoders
#needed for attachment
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
#needed for gmail service
from apiclient import errors, discovery
#The scope URL for read/write access to the gmail api
SCOPES = 'https://www.googleapis.com/auth/gmail.send'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'Gmail API Python Send Email'
def get_credentials():
# If needed create folder for credential
home_dir = os.path.expanduser('~') #>> C:\Users\me
credential_dir = os.path.join(home_dir, '.credentials') # >>C:\Users\me\.credentials (it's a folder)
if not os.path.exists(credential_dir):
os.makedirs(credential_dir) #create folder if doesnt exist
credential_path = os.path.join(credential_dir, 'gmail-python-email-send.json')
#Store the credential
store = oauth2client.file.Storage(credential_path)
credentials = store.get()
if not credentials or credentials.invalid:
# Create a flow object. (it assists with OAuth 2.0 steps to get user authorization + credentials)
flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
flow.user_agent = APPLICATION_NAME
credentials = tools.run_flow(flow, store)
print('Storing credentials to ' + credential_path)
return credentials
def SendMessage(sender, to, subject, msgHtml, msgPlain):
credentials = get_credentials()
http = httplib2.Http() # Create an httplib2.Http object to handle our HTTP requests, and authorize it using credentials.authorize()
# http is the authorized httplib2.Http()
http = credentials.authorize(http)
service = discovery.build('gmail', 'v1', http=http)
message_with_attach = create_message_without_attachment(sender, to, subject, msgHtml, msgPlain)
SendMessageInternal(service, "me", message_with_attach)
def SendMessageInternal(service, user_id, message):
try:
message = (service.users().messages().send(userId=user_id, body=message).execute()) ####need to get user_id before
message_ID = message['id']
print(f'Message Id: {message_ID}')
return [message, message_ID] #return value as list
except errors.HttpError as error:
print(f'An error occurred: {error}')
def create_message_with_attachment(sender, to, subject, msgHtml, msgPlain):
# multipart container can contain other MIME parts. (attachment will be independent of the multipart/alternative)
msg = MIMEMultipart('alternative')
msg['To'] = to
msg['From'] = sender
msg['Subject'] = subject
# convert both part to a MIME compatible string
part1 = MIMEText(msgPlain, 'plain')
part2 = MIMEText(msgHtml, 'html')
# create .txt attachment
filePath=r"C:\Users\me\Desktop\test_Attachment.txt"
myFile=open(filePath, "rb")
attachment= MIMEApplication(myFile.read())
msg.set_payload(myFile) #
myFile.close()
msg.set_payload(myFile) #
myFile.close()
#This will add a header that looks like: "Content-Disposition: attachment; filename="test_Attachment.txt" "
attachment.add_header('content-disposition', 'attachment', filename = ('utf-8', '', 'test_Attachment.txt'))
# Attach parts into message container.
msg.attach(attachment)
msg.attach(part1)
msg.attach(part2)
# Encode the payload using Base64.
raw = encoders.encode_base64(msg)
return raw
def main():
to = "[email protected]"
sender = "[email protected]"
subject = "subject test1"
msgHtml = r'Hi<br/>Html <b>hello</b>'
msgPlain = "Hi\nPlain Email"
message_text= "this is message text"
SendMessage(sender, to, subject, msgHtml, msgPlain)
if __name__ == '__main__':
main()
この機能は、添付ファイルなしで電子メールを送信するために、このコードで成功:
def create_message_without_attachment (sender, to, subject, msgHtml, msgPlain):
msg = MIMEMultipart('alternative')
msg['Subject'] = subject
msg['From'] = sender
msg['To'] = to
msg.attach(MIMEText(msgPlain, 'plain'))
msg.attach(MIMEText(msgHtml, 'html'))
raw = base64.urlsafe_b64encode(msg.as_bytes())
raw = raw.decode()
body = {'raw': raw}
return body
ログを追加できますか? 'msg.set_payload(contents)'と 'encoders 'を追加することで、この報告されたチケットの[解決策](https://github.com/google/google-api-python-client/issues/93)に従うことができます。 encode_base64(msg) 'これが役に立ったと思っています –
@ Mr.Rebotは貴重なリンクに感謝します!私はそれについての私の解釈を使用してコードを更新しました(この男はコード全体を投稿しなかったので、私は実際に彼の次の行を追加する必要もありませんでした)。非マルチパートペイロードを持つメッセージ ' 私はまた、 'raw = ....'部分を動作している関数から追加するべきかどうかわかりません(私の質問の下にあるcreate_message_without_attachment()を参照) – JinSnow
ここで答えが見つかります:http://stackoverflow.com/a/37267330/1486850 – JinSnow