imaplib
原生并不支持 IDLE
命令,这可能导致 AttributeError: Unknown IMAP4 command: 'idle'
错误。解决办法是使用支持 IDLE
命令的库,例如 imapclient
,或者通过扩展 imaplib
的方式实现。
以下是两种解决方案:
方法 1:使用 imapclient
imapclient
是一个高级封装库,支持 IDLE
命令且更易用。
安装 imapclient
pip install imapclient
实现代码
from imapclient import IMAPClient
import time
def getEmailData():
# 定义你的邮件处理逻辑
print("New email received!")
def monitor_inbox():
conf = load_config()
access_token = getAccessToken(conf['client_id'], conf['authority'], conf['scope'], conf['username'], conf['password'])
with IMAPClient(host="outlook.office365.com", use_uid=True, ssl=True) as client:
client.authenticate("XOAUTH2", lambda x: generate_auth_string(conf['username'], access_token))
client.select_folder("INBOX")
print("Listening for new emails...")
while True:
# 开始监听 IDLE 模式
response = client.idle(timeout=60) # 等待 60 秒
if response:
print("New email detected!")
getEmailData()
else:
print("No new emails detected.")
time.sleep(1)
if __name__ == "__main__":
monitor_inbox()
优点:
- 简洁易用,支持现代 IMAP 功能。
- 通过
idle
方法可以轻松实现实时监控。
方法 2:扩展 imaplib
支持 IDLE
如果不想使用额外的库,可以通过扩展 imaplib
实现 IDLE
功能。
自定义 IDLE 支持
import imaplib
import time
class IMAP4WithIdle(imaplib.IMAP4_SSL):
def idle(self):
tag = self._new_tag()
self.send("%s IDLE\r\n" % tag)
response = self._get_response()
if response != "+ idling":
raise imaplib.IMAP4.error("Failed to start IDLE mode")
return tag
def idle_done(self, tag):
self.send("DONE\r\n")
self._get_response()
self._get_tagged_response(tag)
def getEmailData():
# 定义你的邮件处理逻辑
print("New email received!")
def monitor_inbox():
conf = load_config()
access_token = getAccessToken(conf['client_id'], conf['authority'], conf['scope'], conf['username'], conf['password'])
with IMAP4WithIdle("outlook.office365.com") as imap:
imap.authenticate("XOAUTH2", lambda x: generate_auth_string(conf['username'], access_token))
imap.select("INBOX")
print("Listening for new emails...")
while True:
tag = imap.idle()
try:
# 等待新邮件
time.sleep(60) # 设置 60 秒超时
print("Checking for new emails...")
# 处理新邮件逻辑
getEmailData()
finally:
imap.idle_done(tag)
if __name__ == "__main__":
monitor_inbox()
优点:
- 无需安装额外库。
- 自定义扩展灵活,支持其他特殊功能。
缺点:
- 相比
imapclient
,实现略复杂。
注意事项
- 服务器支持:确保目标邮箱服务器支持
IDLE
(现代邮箱服务一般支持,如 Outlook、Gmail)。 - 超时管理:为了避免掉线,通常在一定时间后需要重新进入
IDLE
状态。 - 网络断开重连:加入断线重连逻辑以增强程序健壮性。
推荐使用第一种方法(imapclient
),它更现代化且支持更多功能。