147 lines
4.2 KiB
Python
147 lines
4.2 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
"""
|
||
透過測試 IMAP 連線來推測 SMTP 設定
|
||
"""
|
||
|
||
import imaplib
|
||
import smtplib
|
||
import socket
|
||
import pytest
|
||
|
||
def _probe_imap_server(host, port=993):
|
||
"""測試 IMAP 伺服器連線"""
|
||
ok = True
|
||
try:
|
||
print(f"📥 測試 IMAP: {host}:{port}")
|
||
imap = imaplib.IMAP4_SSL(host, port, timeout=5)
|
||
print(f" ✅ IMAP 伺服器存在且可連接!")
|
||
imap.logout()
|
||
ok = True
|
||
except socket.gaierror:
|
||
print(f" ❌ DNS 解析失敗")
|
||
ok = False
|
||
except Exception as e:
|
||
print(f" ⚠️ {type(e).__name__}: {e}")
|
||
ok = False
|
||
|
||
return ok
|
||
|
||
|
||
def test_imap_server(host, port=993):
|
||
"""測試 IMAP 伺服器連線"""
|
||
if not _probe_imap_server(host, port):
|
||
pytest.skip(f"IMAP 無法連線:{host}:{port}")
|
||
|
||
def guess_smtp_from_imap(imap_host):
|
||
"""從 IMAP 主機推測 SMTP 主機"""
|
||
# 常見的對應關係
|
||
mappings = [
|
||
imap_host.replace('imap', 'smtp'),
|
||
imap_host.replace('mail', 'smtp'),
|
||
imap_host.replace('ms', 'smtp'),
|
||
imap_host, # 有些伺服器 IMAP 和 SMTP 用同一個
|
||
]
|
||
return list(set(mappings)) # 去重
|
||
|
||
def _probe_smtp_server(host, port):
|
||
"""測試 SMTP 伺服器"""
|
||
ok = True
|
||
try:
|
||
print(f" 測試 SMTP: {host}:{port} ... ", end='')
|
||
server = smtplib.SMTP(host, port, timeout=5)
|
||
server.ehlo()
|
||
if server.has_extn('STARTTLS'):
|
||
server.starttls()
|
||
print(f"✅ 成功(支援 STARTTLS)")
|
||
server.quit()
|
||
ok = True
|
||
else:
|
||
print(f"✅ 成功(不支援加密)")
|
||
server.quit()
|
||
ok = True
|
||
except Exception as e:
|
||
print(f"❌ {type(e).__name__}")
|
||
ok = False
|
||
|
||
return ok
|
||
|
||
|
||
def test_smtp_server(host, port):
|
||
"""測試 SMTP 伺服器"""
|
||
if not _probe_smtp_server(host, port):
|
||
pytest.skip(f"SMTP 無法連線:{host}:{port}")
|
||
|
||
def main():
|
||
print("=" * 80)
|
||
print("🔍 PChome 郵件伺服器探測")
|
||
print("=" * 80)
|
||
|
||
# 嘗試常見的 PChome IMAP 伺服器
|
||
imap_servers = [
|
||
'imap.pchome.tw',
|
||
'imap.pchome.com.tw',
|
||
'mail.pchome.tw',
|
||
'mail.pchome.com.tw',
|
||
'ms1.pchome.tw',
|
||
'ms1.pchome.com.tw',
|
||
]
|
||
|
||
print("\n1️⃣ 測試 IMAP 伺服器(接收郵件)")
|
||
print("-" * 80)
|
||
|
||
found_imap = None
|
||
for imap_host in imap_servers:
|
||
if _probe_imap_server(imap_host):
|
||
found_imap = imap_host
|
||
break
|
||
|
||
if not found_imap:
|
||
print("\n❌ 找不到可用的 IMAP 伺服器")
|
||
print("\n這可能表示:")
|
||
print(" 1. PChome 郵件伺服器只能在內部網路訪問")
|
||
print(" 2. 需要連接 VPN")
|
||
print(" 3. 伺服器名稱不是常見格式")
|
||
return
|
||
|
||
print(f"\n✅ 找到 IMAP 伺服器: {found_imap}")
|
||
|
||
# 根據 IMAP 推測 SMTP
|
||
print("\n2️⃣ 根據 IMAP 推測 SMTP 伺服器(發送郵件)")
|
||
print("-" * 80)
|
||
|
||
smtp_guesses = guess_smtp_from_imap(found_imap)
|
||
smtp_ports = [587, 25, 465]
|
||
|
||
found_smtp = None
|
||
for smtp_host in smtp_guesses:
|
||
print(f"\n嘗試: {smtp_host}")
|
||
for port in smtp_ports:
|
||
if _probe_smtp_server(smtp_host, port):
|
||
found_smtp = (smtp_host, port)
|
||
break
|
||
if found_smtp:
|
||
break
|
||
|
||
print("\n" + "=" * 80)
|
||
print("📊 測試結果")
|
||
print("=" * 80)
|
||
|
||
if found_smtp:
|
||
print(f"\n🎉 找到可用的 SMTP 設定!")
|
||
print(f"\n建議的 .env 設定:")
|
||
print(f" EMAIL_HOST={found_smtp[0]}")
|
||
print(f" EMAIL_PORT={found_smtp[1]}")
|
||
print(f" EMAIL_HOST_USER=yingpin_chen@pchome.tw")
|
||
print(f" EMAIL_HOST_PASSWORD=您的郵件密碼")
|
||
print(f" EMAIL_SENDER=yingpin_chen@pchome.tw")
|
||
else:
|
||
print(f"\n⚠️ 找到 IMAP 但找不到 SMTP")
|
||
print(f"\n建議:")
|
||
print(f" 1. 檢查 Outlook/郵件客戶端的「寄件伺服器」設定")
|
||
print(f" 2. 詢問 IT 部門 SMTP 伺服器地址")
|
||
print(f" 3. 或暫時使用 Gmail 進行測試")
|
||
|
||
if __name__ == '__main__':
|
||
main()
|