Skip to content
This repository was archived by the owner on Apr 20, 2025. It is now read-only.

Commit fbe8e6f

Browse files
authored
Merge pull request #195 from wawzysys/email-verification-pop3
邮箱添加pop3
2 parents d16aaee + 548d9b3 commit fbe8e6f

File tree

6 files changed

+154
-15
lines changed

6 files changed

+154
-15
lines changed

Diff for: .env.example

+12-12
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
# 你的CF路由填写的域名
2-
DOMAIN=xxxxx.me
3-
# 邮件服务地址
4-
# 注册临时邮件服务 https://tempmail.plus
5-
TEMP_MAIL=xxxxxx
6-
# 设置的PIN码
7-
TEMP_MAIL_EPIN=xxxxxx
8-
# 使用的后缀
9-
TEMP_MAIL_EXT=@mailto.plus
10-
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
1+
DOMAIN='wozhangsan.me' # 你的 Cloudflare 域名
2+
TEMP_MAIL=null # 设置为 null 启用 IMAP 模式
3+
4+
# IMAP服务器配置
5+
IMAP_SERVER=imap.xxxxx.com # 例如:QQ邮箱,Gmail
6+
IMAP_PORT=993 # 993
7+
IMAP_USER=xxxx@xxxx.com # 接收邮箱地址
8+
IMAP_PASS=xxxxxxxxxxxxx # 邮箱授权码
9+
# IMAP_DIR= # [可选] 默认为收件箱(inbox)
10+
IMAP_PROTOCOL=POP3 # 指定使用 POP3 协议
1111

12-
# 代理
13-
# BROWSER_PROXY='http://127.0.0.1:2080'
12+
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
1413

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

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

Diff for: build.mac.command

100644100755
File mode changed.

Diff for: config.py

+8
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,14 @@ def get_imap(self):
6666
def get_domain(self):
6767
return self.domain
6868

69+
def get_protocol(self):
70+
"""获取邮件协议类型
71+
72+
Returns:
73+
str: 'IMAP' 或 'POP3'
74+
"""
75+
return os.getenv('IMAP_PROTOCOL', 'POP3')
76+
6977
def check_config(self):
7078
"""检查配置项是否有效
7179

Diff for: get_email_code.py

+73-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import requests
66
import email
77
import imaplib
8+
import poplib
9+
from email.parser import Parser
810

911

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

1923
def get_verification_code(self, max_retries=5, retry_interval=60):
@@ -38,7 +42,10 @@ def get_verification_code(self, max_retries=5, retry_interval=60):
3842
self._cleanup_mail(first_id)
3943
return verify_code
4044
else:
41-
verify_code = self._get_mail_code_by_imap()
45+
if self.protocol.upper() == 'IMAP':
46+
verify_code = self._get_mail_code_by_imap()
47+
else:
48+
verify_code = self._get_mail_code_by_pop3()
4249
if verify_code is not None:
4350
return verify_code
4451

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

141+
# 使用 POP3 获取邮件
142+
def _get_mail_code_by_pop3(self, retry = 0):
143+
if retry > 0:
144+
time.sleep(3)
145+
if retry >= 20:
146+
raise Exception("获取验证码超时")
147+
148+
pop3 = None
149+
try:
150+
# 连接到服务器
151+
pop3 = poplib.POP3_SSL(self.imap['imap_server'], int(self.imap['imap_port']))
152+
pop3.user(self.imap['imap_user'])
153+
pop3.pass_(self.imap['imap_pass'])
154+
155+
# 获取最新的10封邮件
156+
num_messages = len(pop3.list()[1])
157+
for i in range(max(1, num_messages-9), num_messages+1):
158+
response, lines, octets = pop3.retr(i)
159+
msg_content = b'\r\n'.join(lines).decode('utf-8')
160+
msg = Parser().parsestr(msg_content)
161+
162+
# 检查发件人
163+
if 'no-reply@cursor.sh' in msg.get('From', ''):
164+
# 提取邮件正文
165+
body = self._extract_pop3_body(msg)
166+
if body:
167+
# 查找验证码
168+
code_match = re.search(r"\b\d{6}\b", body)
169+
if code_match:
170+
code = code_match.group()
171+
pop3.quit()
172+
return code
173+
174+
pop3.quit()
175+
return self._get_mail_code_by_pop3(retry=retry + 1)
176+
177+
except Exception as e:
178+
print(f"发生错误: {e}")
179+
if pop3:
180+
try:
181+
pop3.quit()
182+
except:
183+
pass
184+
return None
185+
186+
def _extract_pop3_body(self, email_message):
187+
# 提取邮件正文
188+
if email_message.is_multipart():
189+
for part in email_message.walk():
190+
content_type = part.get_content_type()
191+
content_disposition = str(part.get("Content-Disposition"))
192+
if content_type == "text/plain" and "attachment" not in content_disposition:
193+
try:
194+
body = part.get_payload(decode=True).decode('utf-8', errors='ignore')
195+
return body
196+
except Exception as e:
197+
logging.error(f"解码邮件正文失败: {e}")
198+
else:
199+
try:
200+
body = email_message.get_payload(decode=True).decode('utf-8', errors='ignore')
201+
return body
202+
except Exception as e:
203+
logging.error(f"解码邮件正文失败: {e}")
204+
return ""
205+
134206
# 手动输入验证码
135207
def _get_latest_mail_code(self):
136208
# 获取邮件列表

Diff for: requirements.txt

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
DrissionPage==4.1.0.9
22
colorama==0.4.6
3-
python-dotenv==1.0.0
4-
pyinstaller
3+
python-dotenv
4+
pyinstaller
5+
requests

Diff for: test_email.py

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import os
2+
from dotenv import load_dotenv
3+
from get_email_code import EmailVerificationHandler
4+
import logging
5+
6+
def test_temp_mail():
7+
"""测试临时邮箱方式"""
8+
handler = EmailVerificationHandler()
9+
print("\n=== 测试临时邮箱模式 ===")
10+
print(f"临时邮箱: {os.getenv('TEMP_MAIL')}@mailto.plus")
11+
code = handler.get_verification_code()
12+
if code:
13+
print(f"成功获取验证码: {code}")
14+
else:
15+
print("未能获取验证码")
16+
17+
def test_email_server():
18+
"""测试邮箱服务器方式(POP3/IMAP)"""
19+
handler = EmailVerificationHandler()
20+
protocol = os.getenv('IMAP_PROTOCOL', 'POP3')
21+
print(f"\n=== 测试 {protocol} 模式 ===")
22+
print(f"邮箱服务器: {os.getenv('IMAP_SERVER')}")
23+
print(f"邮箱账号: {os.getenv('IMAP_USER')}")
24+
code = handler.get_verification_code()
25+
if code:
26+
print(f"成功获取验证码: {code}")
27+
else:
28+
print("未能获取验证码")
29+
30+
def print_config():
31+
"""打印当前配置"""
32+
print("\n当前环境变量配置:")
33+
print(f"TEMP_MAIL: {os.getenv('TEMP_MAIL')}")
34+
if os.getenv('TEMP_MAIL') == 'null':
35+
print(f"IMAP_SERVER: {os.getenv('IMAP_SERVER')}")
36+
print(f"IMAP_PORT: {os.getenv('IMAP_PORT')}")
37+
print(f"IMAP_USER: {os.getenv('IMAP_USER')}")
38+
print(f"IMAP_PROTOCOL: {os.getenv('IMAP_PROTOCOL', 'POP3')}")
39+
print(f"DOMAIN: {os.getenv('DOMAIN')}")
40+
41+
def main():
42+
# 加载环境变量
43+
load_dotenv()
44+
45+
# 打印初始配置
46+
print_config()
47+
48+
try:
49+
# 根据配置决定测试哪种模式
50+
if os.getenv('TEMP_MAIL') != 'null':
51+
test_temp_mail()
52+
else:
53+
test_email_server()
54+
except Exception as e:
55+
print(f"测试过程中发生错误: {str(e)}")
56+
57+
if __name__ == "__main__":
58+
main()

0 commit comments

Comments
 (0)