如何使用 IMAP 发送邮件?

Posted

技术标签:

【中文标题】如何使用 IMAP 发送邮件?【英文标题】:How can you send mail using IMAP? 【发布时间】:2010-12-10 07:12:27 【问题描述】:

我正在为手机开发一个轻量级的 Gmail 客户端,通过 IMAP 访问 Gmail。我想从草稿文件夹发送草稿,但它有一些附件,我无法下载所有附件以通过 SMTP 发送。

将其移动/复制到“已发送邮件”不会发送它,只是将其移动到该文件夹​​。

如何在不从客户端获取所有内容和附件的情况下直接发送草稿?是否有任何 IMAP 命令可以做到这一点?

【问题讨论】:

有一个来自Trojita作者的草稿提供了这个功能:tools.ietf.org/html/draft-kundrat-imap-submit-02 【参考方案1】:

IMAP 是一种邮箱协议。它(本机)不支持发送邮件,只支持访问它。为了发送邮件,您必须使用 SMTP。可能有一个用于发送邮件的 IMAP 扩展,并且 Google Mail 可能支持该扩展,但我对此表示怀疑。因此,如果您想发送带有附件的电子邮件,您实际上必须拥有可供您发送的邮件的全部内容。

【讨论】:

事实上 Google Mail 不支持该“扩展”。这就是为什么我尝试将邮件直接移动到“已发送邮件”框。【参考方案2】:

发送电子邮件是某些 imap 服务器的一项特殊功能。它在 imap 协议中没有任何内容。您只需将您的电子邮件复制到服务器上的一个特殊 imap 目录中,然后它就会发送它们。我怀疑gmail是否支持这一点。

【讨论】:

什么服务器支持这个?我从来没有听说过这个,并想进一步调查一下。谢谢! 只晚了几年...显然Courier Mail Server 支持这一点。【参考方案3】:

IMAP 旨在接收电子邮件,而不是发送电子邮件。没有用于发送电子邮件 AFAIK 的 IMAP 命令。但是,至少有一个 IMAP 服务器支持特殊的“发件箱”文件夹。当您将邮件放入此文件夹时,它将自动发送。

检查Courier-IMAP documentation on Sending mail via an IMAP connection。请注意,这是一种非标准方法,我不知道有任何其他服务器支持此方法。

RFC 4468 扩展了 SMTP,因此它可以从 IMAP 服务器获取邮件内容,但我不知道任何有效且广泛使用的实现。

谈 gmail:坚持使用 SMTP 可能是最安全的方法。

【讨论】:

我很想知道这是为什么;单独的连接用于接收和发送是否纯粹是历史性的?是因为 POP 曾经是标准吗? 这主要是因为 SMTP 已经很成熟,所以不需要通过将电子邮件提交支持构建到另一个为不同目的而设计的协议中来复制其目的。使用不同的协议进行提交和阅读并没有什么坏处——就电子邮件而言,它们是两个截然不同的任务。 您是否没有将邮件发送两次:一次发送到 SMPT 进行传递,一次发送到 IMAP 进行存储。这将是低效的。【参考方案4】:

顺便说一句,现在任何现代邮件客户端(包括基于 Web 的邮件客户端)都支持 Sent 文件夹,您通常必须同时使用 SMTP 和 IMAP 来发送一封邮件。在通过 SMTP 发送电子邮件和 成功 将电子邮件保存到 IMAP Sent 文件夹之间存在竞争条件。使用 IMAP 发送电子邮件是避免这种竞争条件的一种方法。

【讨论】:

【参考方案5】:

我使用 Python 3 使用 IMAP 向我自己的电子邮件地址发送了一封电子邮件到 gmail 帐户。所做的是将消息附加到邮箱。您需要使用一些 Python 的本地库。还要研究这个documentation for imaplib,这个代码在上传消息部分: 要将新消息添加到邮箱,构造一个 Message 实例并将其传递给 append() 方法,以及消息的时间戳

然后检查您的 gmail 收件箱,您会看到新邮件。

import imaplib
import time
import email.message
import imaplib_connect

new_message = email.message.Message()
new_message.set_unixfrom('name')
new_message['Subject'] = 'Test'
new_message['From'] = 'name@gmail.com'
new_message['To'] = 'name@gmail.com'
new_message.set_payload('This is an example message body.\n')

print(new_message)

with imaplib_connect.open_connection() as c:
    c.append('INBOX', '',
             imaplib.Time2Internaldate(time.time()),
             str(new_message).encode('utf-8'))

# Show the headers for all messages in the mailbox
c.select('INBOX')
typ, [msg_ids] = c.search(None, 'ALL')
for num in msg_ids.split():
    typ, msg_data = c.fetch(num, '(BODY.PEEK[HEADER])')
    for response_part in msg_data:
        if isinstance(response_part, tuple):
            print('\n:'.format(num))
            print(response_part[1])

【讨论】:

您不会“发送”电子邮件——您实际上是在您的“收件箱”邮箱中附加一封电子邮件,以显示您已收到它。这不是 OP 要求的。 encode('utf-8') 部分终于让它为我工作了。

以上是关于如何使用 IMAP 发送邮件?的主要内容,如果未能解决你的问题,请参考以下文章

使用 phpmailer 发送的邮件不会转到“已发送”IMAP 文件夹

如何使用 mailkit/mimekit IMAP 下载/保存所有收件箱/发送的电子邮件?

使用 IMAP 发送邮件:如何检测邮件已从一个文件夹移动到另一个文件夹?

如何用IMAP协议收取未读邮件

java 实现 email 邮件发送最简单优雅的方式(网易 163 为例)

发啥我手机发送电子邮件发不出去呢?他老是提示“网络服务器错误”,请高手指点。手机该怎样设置?