使用Python3和Gmail API发送带有附件的电子邮件,我最终得到的不是损坏的文件就是ConnectionAbortedError

使用Python3和Gmail API发送带有附件的电子邮件,我最终得到的不是损坏的文件就是ConnectionAbortedError,python,python-3.x,base64,gmail-api,Python,Python 3.x,Base64,Gmail Api,我正在使用Python3中的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

我正在使用Python3中的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编码期间

我看到添加
编码器.encode_base64(msg)
(在我的例子中,就在
filename=os.path.basename(file)
的上面/下面)解决了这个问题,但是当我添加这一行时,我得到:
ConnectionAbortedError:[WinError 10053]主机中的软件中止了已建立的连接

显然,当它不喜欢一个文件时,它会这样做

知道我做错了什么吗

与正确编码的混淆是由于从Python2更改为Python3造成的 中描述的编码过程基于Python 2。我假设您使用的是Python 3

为了使指南适应新的Python版本,需要实现两个修改

  • 修改
    返回{'raw':base64.urlsafe\u b64encode(message.as\u string())}
    返回{'raw':base64.urlsafe_b64encode(message.as_bytes()).decode()}。你已经这样做了
  • msg.set\u有效载荷(内容)
    请求之后,您需要添加一行额外的编码器。encode\u base64(msg)。这就是你错过的 现在您添加了它,请注意,
    编码器
    是包
    电子邮件
    的一个模块。如果还没有 完成后,您需要从电子邮件导入编码器向代码添加

    与正确编码的混淆是由于从Python2更改为Python3造成的 中描述的编码过程基于Python 2。我假设您使用的是Python 3

    为了使指南适应新的Python版本,需要实现两个修改

  • 修改
    返回{'raw':base64.urlsafe\u b64encode(message.as\u string())}
    返回{'raw':base64.urlsafe_b64encode(message.as_bytes()).decode()}
  • 。你已经这样做了
  • msg.set\u有效载荷(内容)
    请求之后,您需要添加一行额外的编码器。encode\u base64(msg)。这就是你错过的 现在您添加了它,请注意,
    编码器
    是包
    电子邮件
    的一个模块。如果还没有 完成后,您需要从电子邮件导入编码器向代码添加


    谢谢:)我已经导入了
    编码器
    -正如我在添加行
    编码器时提到的。encode_base64(msg)
    我得到了“ConnectionAbortedError:[WinError 10053]主机中的软件中止了已建立的连接”。这是我无法理解的,因为它似乎对其他人有效。我甚至尝试过关闭防病毒和防火墙,以防引起一些问题,但仍然得到相同的错误:(听起来你的配置/网络设置有问题。你在其他设备上尝试过吗?可能有用吗?谢谢:)我已经导入了
    编码器
    ——正如我在添加行
    编码器时提到的那样。encode_base64(msg)
    我得到了“ConnectionAbortedError:[WinError 10053]主机中的软件中止了一个已建立的连接”。这是我无法理解的,因为它似乎适用于其他人。我甚至尝试过关闭防病毒和防火墙,以防引起一些问题,但仍然得到相同的错误:(听起来你的配置/网络设置有问题。你在其他设备上尝试过吗?可能有用吗?