Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

邮箱添加pop3 #195

Merged
merged 3 commits into from
Feb 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
# 你的CF路由填写的域名
DOMAIN=xxxxx.me
# 邮件服务地址
# 注册临时邮件服务 https://tempmail.plus
TEMP_MAIL=xxxxxx
# 设置的PIN码
TEMP_MAIL_EPIN=xxxxxx
# 使用的后缀
[email protected]
BROWSER_USER_AGENT=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.92 Safari/537.36
DOMAIN='wozhangsan.me' # 你的 Cloudflare 域名
TEMP_MAIL=null # 设置为 null 启用 IMAP 模式

# IMAP服务器配置
IMAP_SERVER=imap.xxxxx.com # 例如:QQ邮箱,Gmail
IMAP_PORT=993 # 993
[email protected] # 接收邮箱地址
IMAP_PASS=xxxxxxxxxxxxx # 邮箱授权码
# IMAP_DIR= # [可选] 默认为收件箱(inbox)
IMAP_PROTOCOL=POP3 # 指定使用 POP3 协议

# 代理
# BROWSER_PROXY='http://127.0.0.1:2080'
BROWSER_USER_AGENT=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.92 Safari/537.36

# 无头模式 默认开启
# BROWSER_HEADLESS='True'

# 使用其他浏览器(如Edge)
# BROWSER_PATH='C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe'

Empty file modified build.mac.command
100644 → 100755
Empty file.
8 changes: 8 additions & 0 deletions config.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ def get_imap(self):
def get_domain(self):
return self.domain

def get_protocol(self):
"""获取邮件协议类型
Returns:
str: 'IMAP' 或 'POP3'
"""
return os.getenv('IMAP_PROTOCOL', 'POP3')

def check_config(self):
"""检查配置项是否有效
Expand Down
74 changes: 73 additions & 1 deletion get_email_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import requests
import email
import imaplib
import poplib
from email.parser import Parser


class EmailVerificationHandler:
Expand All @@ -14,6 +16,8 @@ def __init__(self,account):
self.epin = Config().get_temp_mail_epin()
self.session = requests.Session()
self.emailExtension = Config().get_temp_mail_ext()
# 获取协议类型,默认为 POP3
self.protocol = Config().get_protocol() or 'POP3'
self.account = account

def get_verification_code(self, max_retries=5, retry_interval=60):
Expand All @@ -38,7 +42,10 @@ def get_verification_code(self, max_retries=5, retry_interval=60):
self._cleanup_mail(first_id)
return verify_code
else:
verify_code = self._get_mail_code_by_imap()
if self.protocol.upper() == 'IMAP':
verify_code = self._get_mail_code_by_imap()
else:
verify_code = self._get_mail_code_by_pop3()
if verify_code is not None:
return verify_code

Expand Down Expand Up @@ -131,6 +138,71 @@ def _extract_imap_body(self, email_message):
logging.error(f"解码邮件正文失败: {e}")
return ""

# 使用 POP3 获取邮件
def _get_mail_code_by_pop3(self, retry = 0):
if retry > 0:
time.sleep(3)
if retry >= 20:
raise Exception("获取验证码超时")

pop3 = None
try:
# 连接到服务器
pop3 = poplib.POP3_SSL(self.imap['imap_server'], int(self.imap['imap_port']))
pop3.user(self.imap['imap_user'])
pop3.pass_(self.imap['imap_pass'])

# 获取最新的10封邮件
num_messages = len(pop3.list()[1])
for i in range(max(1, num_messages-9), num_messages+1):
response, lines, octets = pop3.retr(i)
msg_content = b'\r\n'.join(lines).decode('utf-8')
msg = Parser().parsestr(msg_content)

# 检查发件人
if '[email protected]' in msg.get('From', ''):
# 提取邮件正文
body = self._extract_pop3_body(msg)
if body:
# 查找验证码
code_match = re.search(r"\b\d{6}\b", body)
if code_match:
code = code_match.group()
pop3.quit()
return code

pop3.quit()
return self._get_mail_code_by_pop3(retry=retry + 1)

except Exception as e:
print(f"发生错误: {e}")
if pop3:
try:
pop3.quit()
except:
pass
return None

def _extract_pop3_body(self, email_message):
# 提取邮件正文
if email_message.is_multipart():
for part in email_message.walk():
content_type = part.get_content_type()
content_disposition = str(part.get("Content-Disposition"))
if content_type == "text/plain" and "attachment" not in content_disposition:
try:
body = part.get_payload(decode=True).decode('utf-8', errors='ignore')
return body
except Exception as e:
logging.error(f"解码邮件正文失败: {e}")
else:
try:
body = email_message.get_payload(decode=True).decode('utf-8', errors='ignore')
return body
except Exception as e:
logging.error(f"解码邮件正文失败: {e}")
return ""

# 手动输入验证码
def _get_latest_mail_code(self):
# 获取邮件列表
Expand Down
5 changes: 3 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
DrissionPage==4.1.0.9
colorama==0.4.6
python-dotenv==1.0.0
pyinstaller
python-dotenv
pyinstaller
requests
58 changes: 58 additions & 0 deletions test_email.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import os
from dotenv import load_dotenv
from get_email_code import EmailVerificationHandler
import logging

def test_temp_mail():
"""测试临时邮箱方式"""
handler = EmailVerificationHandler()
print("\n=== 测试临时邮箱模式 ===")
print(f"临时邮箱: {os.getenv('TEMP_MAIL')}@mailto.plus")
code = handler.get_verification_code()
if code:
print(f"成功获取验证码: {code}")
else:
print("未能获取验证码")

def test_email_server():
"""测试邮箱服务器方式(POP3/IMAP)"""
handler = EmailVerificationHandler()
protocol = os.getenv('IMAP_PROTOCOL', 'POP3')
print(f"\n=== 测试 {protocol} 模式 ===")
print(f"邮箱服务器: {os.getenv('IMAP_SERVER')}")
print(f"邮箱账号: {os.getenv('IMAP_USER')}")
code = handler.get_verification_code()
if code:
print(f"成功获取验证码: {code}")
else:
print("未能获取验证码")

def print_config():
"""打印当前配置"""
print("\n当前环境变量配置:")
print(f"TEMP_MAIL: {os.getenv('TEMP_MAIL')}")
if os.getenv('TEMP_MAIL') == 'null':
print(f"IMAP_SERVER: {os.getenv('IMAP_SERVER')}")
print(f"IMAP_PORT: {os.getenv('IMAP_PORT')}")
print(f"IMAP_USER: {os.getenv('IMAP_USER')}")
print(f"IMAP_PROTOCOL: {os.getenv('IMAP_PROTOCOL', 'POP3')}")
print(f"DOMAIN: {os.getenv('DOMAIN')}")

def main():
# 加载环境变量
load_dotenv()

# 打印初始配置
print_config()

try:
# 根据配置决定测试哪种模式
if os.getenv('TEMP_MAIL') != 'null':
test_temp_mail()
else:
test_email_server()
except Exception as e:
print(f"测试过程中发生错误: {str(e)}")

if __name__ == "__main__":
main()