이 python 3 스크립트는 이메일을 작성하고 URL을 사용하여 하나의 파일을 첨부하여 전송하는 것으로 가정합니다. 그것은 이메일을 보내지 만, 뭔가 내가 구글 문서를 읽어 않았다 create_message_with_attachment()
python 3.6 gmail api - 첨부 파일이있는 이메일 보내기
TypeError: Attach is not valid on a message with a non-multipart payload
으로 잘못. 스택 스레드는 멋진 첨부 파일 스타일에 초점을 맞추고, 그 위에는 파이썬 버전의 다른 구문을 혼합합니다.
코드는 여러 출처의 패치 워크입니다. 나는 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)'와'encoder를 추가하여보고 된 티켓에서 [solution] (https://github.com/google/google-api-python-client/issues/93)을 따라 할 수 있습니다. encode_base64 (msg)'. 희망이 도움이 –
@ Mr.Rebot는 소중한 링크에 대해 많은 감사합니다! 나는 그 코드에 대한 나의 해석을 사용하여 코드를 업데이트했다. (그 사람은 전체 코드를 게시하지 않았기 때문에 "나는 또한 아래 두번째 라인을 추가해야했다"는 것을 정말로 이해하지 못했다.) 코드는'TypeError : Attach가 유효하지 않다. non-multipart 페이로드가있는 메시지' 작동하는 함수에서'raw = .... '부분을 추가해야하는지 이해할 수 없습니다 (내 질문 하단의 create_message_without_attachment() 참조) – JinSnow
여기에서 답변을 찾을 수 있습니다. http://stackoverflow.com/a/37267330/1486850 – JinSnow