簡體   English   中英

使用 python 3 和 Gmail API 發送帶有附件的電子郵件,我最終遇到文件損壞或 ConnectionAbortedError

[英]Using python 3 and Gmail API to send emails with attachments, I end up with either corrupted files or ConnectionAbortedError

我正在使用 Python 3 中的 Gmail API 根據他們的示例代碼發送帶有附件的電子郵件

我有以下內容來創建消息:

def create_message_with_attachment(
    sender, to, subject, message_text, files):
  """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.
    file: The path to the file to be attached.

  Returns:
    An object containing a base64url encoded email object.
  """
  message = MIMEMultipart()
  message['to'] = to
  message['from'] = sender
  message['subject'] = subject

  msg = MIMEText(message_text)
  message.attach(msg)

  for file in files:

    content_type, encoding = mimetypes.guess_type(file)

    if content_type is None or encoding is not None:
      content_type = 'application/octet-stream'
    main_type, sub_type = content_type.split('/', 1)
    if main_type == 'text':
      fp = open(file, 'rb')
      msg = MIMEText(fp.read(), _subtype=sub_type)
      fp.close()
    elif main_type == 'image':
      fp = open(file, 'rb')
      msg = MIMEImage(fp.read(), _subtype=sub_type)
      fp.close()
    elif main_type == 'audio':
      fp = open(file, 'rb')
      msg = MIMEAudio(fp.read(), _subtype=sub_type)
      fp.close()
    else:
      fp = open(file, 'rb')
      msg = MIMEBase(main_type, sub_type)
      msg.set_payload(fp.read())
      fp.close()
    filename = os.path.basename(file)
    msg.add_header('Content-Disposition', 'attachment', filename=filename)
    message.attach(msg)

  raw = base64.urlsafe_b64encode(message.as_bytes())
  raw = raw.decode()
  body = {'raw': raw}
  return body

並發送以下內容:

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 ('Sent! Message Id: %s' % message['id'])
        return message
    except httplib2.HttpLib2Error as error:
        return None
        print ('An error occurred: %s' % error)

當我發送這樣創建的郵件(我需要發送 pdf 文件,但也嘗試使用 zip 文件並獲得相同的結果)時,它可以工作,但文件已損壞。 我假設這發生在 base64 編碼期間。

我在另一篇文章中看到添加encoders.encode_base64(msg) (在我的例子中就在filename = os.path.basename(file)上方/下方)解決了這個問題,但是當我添加那一行時,我得到: ConnectionAbortedError: [WinError 10053] An established connection was aborted by the software in your host machine

顯然,當它不喜歡文件時會這樣做嗎?

知道我做錯了什么嗎?

與正確編碼的混淆是由於從 Python 2 更改為 Python 3

Google 文檔中描述的用於發送電子郵件的編碼過程基於 Python 2。我假設您使用的是 Python 3。

為了使指南適應新的 Python 版本,需要進行兩個修改。

  1. 修改return {'raw': base64.urlsafe_b64encode(message.as_string())} return {'raw': base64.urlsafe_b64encode(message.as_bytes()).decode()} 你已經這樣做了。
  2. msg.set_payload(contents)請求之后,您需要添加額外的行msg.set_payload(contents) encoders.encode_base64(msg) 這就是你所缺少的。

現在您添加了它,請注意encoders是包email一個模塊。 如果尚未完成,您需要from email import encoders添加到您的代碼中

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM