tempemail-sdk 1.2.0__tar.gz → 1.2.2.dev0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/PKG-INFO +15 -12
  2. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/README.md +14 -11
  3. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/pyproject.toml +1 -1
  4. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempemail_sdk.egg-info/PKG-INFO +15 -12
  5. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempemail_sdk.egg-info/SOURCES.txt +6 -0
  6. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/client.py +44 -4
  7. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/normalize.py +4 -2
  8. tempemail_sdk-1.2.2.dev0/tempmail_sdk/providers/moakt.py +225 -0
  9. tempemail_sdk-1.2.2.dev0/tempmail_sdk/providers/ta_easy.py +62 -0
  10. tempemail_sdk-1.2.2.dev0/tempmail_sdk/providers/tempmailg.py +197 -0
  11. tempemail_sdk-1.2.2.dev0/tempmail_sdk/providers/tenmail_wangtz.py +118 -0
  12. tempemail_sdk-1.2.2.dev0/tempmail_sdk/providers/tenminute_one.py +255 -0
  13. tempemail_sdk-1.2.2.dev0/tempmail_sdk/providers/tmpmails.py +158 -0
  14. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/types.py +6 -0
  15. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/setup.cfg +0 -0
  16. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempemail_sdk.egg-info/dependency_links.txt +0 -0
  17. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempemail_sdk.egg-info/requires.txt +0 -0
  18. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempemail_sdk.egg-info/top_level.txt +0 -0
  19. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/__init__.py +0 -0
  20. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/config.py +0 -0
  21. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/http.py +0 -0
  22. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/logger.py +0 -0
  23. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/providers/__init__.py +0 -0
  24. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/providers/anonbox.py +0 -0
  25. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/providers/awamail.py +0 -0
  26. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/providers/boomlify.py +0 -0
  27. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/providers/chatgpt_org_uk.py +0 -0
  28. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/providers/dropmail.py +0 -0
  29. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/providers/emailnator.py +0 -0
  30. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/providers/fake_legal.py +0 -0
  31. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/providers/guerrillamail.py +0 -0
  32. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/providers/linshi_email.py +0 -0
  33. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/providers/linshi_token.py +0 -0
  34. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/providers/linshiyou.py +0 -0
  35. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/providers/mail_cx.py +0 -0
  36. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/providers/mail_gw.py +0 -0
  37. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/providers/mail_tm.py +0 -0
  38. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/providers/maildrop.py +0 -0
  39. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/providers/mffac.py +0 -0
  40. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/providers/minmail.py +0 -0
  41. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/providers/smail_pw.py +0 -0
  42. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/providers/temp_mail_io.py +0 -0
  43. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/providers/tempmail.py +0 -0
  44. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/providers/tempmail_cn.py +0 -0
  45. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/providers/tempmail_lol.py +0 -0
  46. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/providers/temporary_email_org.py +0 -0
  47. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/providers/vip_215.py +0 -0
  48. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/retry.py +0 -0
  49. {tempemail_sdk-1.2.0 → tempemail_sdk-1.2.2.dev0}/tempmail_sdk/telemetry.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tempemail-sdk
3
- Version: 1.2.0
3
+ Version: 1.2.2.dev0
4
4
  Summary: 临时邮箱 SDK,所有渠道返回统一标准化格式
5
5
  License: GPL-3.0
6
6
  Requires-Python: >=3.10
@@ -15,7 +15,7 @@ Requires-Dist: pygments>=2.19.2; extra == "dev"
15
15
 
16
16
  [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
17
17
 
18
- 临时邮箱 SDK(Python),支持 **21** 个邮箱服务提供商,顺序与 `client.py` 中 `ALL_CHANNELS` 一致,返回格式与根目录 README 描述一致。
18
+ 临时邮箱 SDK(Python),支持 **27** 个邮箱服务提供商,顺序与 `client.py` 中 `ALL_CHANNELS` 一致,返回格式与根目录 README 描述一致,并与 Go / npm / Rust / C 对齐。
19
19
 
20
20
  ## 安装
21
21
 
@@ -33,6 +33,11 @@ pip install https://github.com/XxxXTeam/tempmail-sdk/releases/latest/download/te
33
33
  |------|--------|:----------:|------|
34
34
  | `tempmail` | tempmail.ing | - | 支持自定义有效期 |
35
35
  | `tempmail-cn` | tempmail.cn | - | Socket.IO:`request shortid` / `set shortid` / `mail`;`GenerateEmailOptions.domain` 可指定自定义接入域名 |
36
+ | `tmpmails` | tmpmails.com | ✅ | Next.js Server Action 收信;`domain` 可选语言路径 |
37
+ | `tempmailg` | tempmailg.com | ✅ | 独立 `requests.Session` 建邮;`GET /public/{locale}` + `POST /public/get_messages`;Token `tmg1:` + Base64(JSON);`domain` 可选语言路径 |
38
+ | `ta-easy` | ta-easy.com | ✅ | REST `api-endpoint.ta-easy.com` |
39
+ | `10mail-wangtz` | 10mail.wangtz.cn | - | REST `/api/tempMail`、`/api/emailList`;**默认跳过 TLS 证书校验** |
40
+ | `10minute-one` | 10minutemail.one | ✅ | SSR / JWT + Web API;`GenerateEmailOptions.domain` 可选 |
36
41
  | `linshi-email` | linshi-email.com | - | |
37
42
  | `linshiyou` | linshiyou.com | ✅ | `NEXUS_TOKEN` + Cookie;HTML 分段解析 |
38
43
  | `mffac` | mffac.com | ✅ | mailbox `id`;REST 24h |
@@ -52,24 +57,22 @@ pip install https://github.com/XxxXTeam/tempmail-sdk/releases/latest/download/te
52
57
  | `vip-215` | vip.215.im | ✅ | `POST` 建箱 + WebSocket;无正文时 synthetic 兜底 |
53
58
  | `anonbox` | anonbox.net | ✅ | `GET /en/` 解析 HTML + mbox 收信 |
54
59
  | `fake-legal` | fake.legal | - | `/api/domains` + `/api/inbox/new`;可选 `GenerateEmailOptions.domain` |
60
+ | `moakt` | moakt.com | ✅ | HTML 收件箱 + `tm_session`;`domain` 可选语言路径;独立 `requests` 请求避免污染全局 Session Cookie |
55
61
 
56
62
  ## 快速开始
57
63
 
58
64
  ```python
59
- from tempmail_sdk import generate_email, get_emails, GenerateEmailOptions, GetEmailsOptions
65
+ from tempmail_sdk import generate_email, get_emails, GenerateEmailOptions
60
66
 
61
67
  # 创建临时邮箱
62
68
  info = generate_email(GenerateEmailOptions(channel="guerrillamail"))
63
- print(f"邮箱: {info.email}")
69
+ if info:
70
+ print(f"邮箱: {info.email}")
64
71
 
65
- # 获取邮件
66
- result = get_emails(GetEmailsOptions(
67
- channel=info.channel,
68
- email=info.email,
69
- token=info.token,
70
- ))
71
- if result.success:
72
- print(f"收到 {len(result.emails)} 封邮件")
72
+ # 获取邮件(channel / email / token 由 SDK 从 EmailInfo 读取,无需手动传入)
73
+ result = get_emails(info)
74
+ if result.success:
75
+ print(f"收到 {len(result.emails)} 封邮件")
73
76
  ```
74
77
 
75
78
  ## 使用客户端类
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
4
4
 
5
- 临时邮箱 SDK(Python),支持 **21** 个邮箱服务提供商,顺序与 `client.py` 中 `ALL_CHANNELS` 一致,返回格式与根目录 README 描述一致。
5
+ 临时邮箱 SDK(Python),支持 **27** 个邮箱服务提供商,顺序与 `client.py` 中 `ALL_CHANNELS` 一致,返回格式与根目录 README 描述一致,并与 Go / npm / Rust / C 对齐。
6
6
 
7
7
  ## 安装
8
8
 
@@ -20,6 +20,11 @@ pip install https://github.com/XxxXTeam/tempmail-sdk/releases/latest/download/te
20
20
  |------|--------|:----------:|------|
21
21
  | `tempmail` | tempmail.ing | - | 支持自定义有效期 |
22
22
  | `tempmail-cn` | tempmail.cn | - | Socket.IO:`request shortid` / `set shortid` / `mail`;`GenerateEmailOptions.domain` 可指定自定义接入域名 |
23
+ | `tmpmails` | tmpmails.com | ✅ | Next.js Server Action 收信;`domain` 可选语言路径 |
24
+ | `tempmailg` | tempmailg.com | ✅ | 独立 `requests.Session` 建邮;`GET /public/{locale}` + `POST /public/get_messages`;Token `tmg1:` + Base64(JSON);`domain` 可选语言路径 |
25
+ | `ta-easy` | ta-easy.com | ✅ | REST `api-endpoint.ta-easy.com` |
26
+ | `10mail-wangtz` | 10mail.wangtz.cn | - | REST `/api/tempMail`、`/api/emailList`;**默认跳过 TLS 证书校验** |
27
+ | `10minute-one` | 10minutemail.one | ✅ | SSR / JWT + Web API;`GenerateEmailOptions.domain` 可选 |
23
28
  | `linshi-email` | linshi-email.com | - | |
24
29
  | `linshiyou` | linshiyou.com | ✅ | `NEXUS_TOKEN` + Cookie;HTML 分段解析 |
25
30
  | `mffac` | mffac.com | ✅ | mailbox `id`;REST 24h |
@@ -39,24 +44,22 @@ pip install https://github.com/XxxXTeam/tempmail-sdk/releases/latest/download/te
39
44
  | `vip-215` | vip.215.im | ✅ | `POST` 建箱 + WebSocket;无正文时 synthetic 兜底 |
40
45
  | `anonbox` | anonbox.net | ✅ | `GET /en/` 解析 HTML + mbox 收信 |
41
46
  | `fake-legal` | fake.legal | - | `/api/domains` + `/api/inbox/new`;可选 `GenerateEmailOptions.domain` |
47
+ | `moakt` | moakt.com | ✅ | HTML 收件箱 + `tm_session`;`domain` 可选语言路径;独立 `requests` 请求避免污染全局 Session Cookie |
42
48
 
43
49
  ## 快速开始
44
50
 
45
51
  ```python
46
- from tempmail_sdk import generate_email, get_emails, GenerateEmailOptions, GetEmailsOptions
52
+ from tempmail_sdk import generate_email, get_emails, GenerateEmailOptions
47
53
 
48
54
  # 创建临时邮箱
49
55
  info = generate_email(GenerateEmailOptions(channel="guerrillamail"))
50
- print(f"邮箱: {info.email}")
56
+ if info:
57
+ print(f"邮箱: {info.email}")
51
58
 
52
- # 获取邮件
53
- result = get_emails(GetEmailsOptions(
54
- channel=info.channel,
55
- email=info.email,
56
- token=info.token,
57
- ))
58
- if result.success:
59
- print(f"收到 {len(result.emails)} 封邮件")
59
+ # 获取邮件(channel / email / token 由 SDK 从 EmailInfo 读取,无需手动传入)
60
+ result = get_emails(info)
61
+ if result.success:
62
+ print(f"收到 {len(result.emails)} 封邮件")
60
63
  ```
61
64
 
62
65
  ## 使用客户端类
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "tempemail-sdk"
7
- version = "1.2.0"
7
+ version = "1.2.02-dev"
8
8
  description = "临时邮箱 SDK,所有渠道返回统一标准化格式"
9
9
  readme = "README.md"
10
10
  license = {text = "GPL-3.0"}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tempemail-sdk
3
- Version: 1.2.0
3
+ Version: 1.2.2.dev0
4
4
  Summary: 临时邮箱 SDK,所有渠道返回统一标准化格式
5
5
  License: GPL-3.0
6
6
  Requires-Python: >=3.10
@@ -15,7 +15,7 @@ Requires-Dist: pygments>=2.19.2; extra == "dev"
15
15
 
16
16
  [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
17
17
 
18
- 临时邮箱 SDK(Python),支持 **21** 个邮箱服务提供商,顺序与 `client.py` 中 `ALL_CHANNELS` 一致,返回格式与根目录 README 描述一致。
18
+ 临时邮箱 SDK(Python),支持 **27** 个邮箱服务提供商,顺序与 `client.py` 中 `ALL_CHANNELS` 一致,返回格式与根目录 README 描述一致,并与 Go / npm / Rust / C 对齐。
19
19
 
20
20
  ## 安装
21
21
 
@@ -33,6 +33,11 @@ pip install https://github.com/XxxXTeam/tempmail-sdk/releases/latest/download/te
33
33
  |------|--------|:----------:|------|
34
34
  | `tempmail` | tempmail.ing | - | 支持自定义有效期 |
35
35
  | `tempmail-cn` | tempmail.cn | - | Socket.IO:`request shortid` / `set shortid` / `mail`;`GenerateEmailOptions.domain` 可指定自定义接入域名 |
36
+ | `tmpmails` | tmpmails.com | ✅ | Next.js Server Action 收信;`domain` 可选语言路径 |
37
+ | `tempmailg` | tempmailg.com | ✅ | 独立 `requests.Session` 建邮;`GET /public/{locale}` + `POST /public/get_messages`;Token `tmg1:` + Base64(JSON);`domain` 可选语言路径 |
38
+ | `ta-easy` | ta-easy.com | ✅ | REST `api-endpoint.ta-easy.com` |
39
+ | `10mail-wangtz` | 10mail.wangtz.cn | - | REST `/api/tempMail`、`/api/emailList`;**默认跳过 TLS 证书校验** |
40
+ | `10minute-one` | 10minutemail.one | ✅ | SSR / JWT + Web API;`GenerateEmailOptions.domain` 可选 |
36
41
  | `linshi-email` | linshi-email.com | - | |
37
42
  | `linshiyou` | linshiyou.com | ✅ | `NEXUS_TOKEN` + Cookie;HTML 分段解析 |
38
43
  | `mffac` | mffac.com | ✅ | mailbox `id`;REST 24h |
@@ -52,24 +57,22 @@ pip install https://github.com/XxxXTeam/tempmail-sdk/releases/latest/download/te
52
57
  | `vip-215` | vip.215.im | ✅ | `POST` 建箱 + WebSocket;无正文时 synthetic 兜底 |
53
58
  | `anonbox` | anonbox.net | ✅ | `GET /en/` 解析 HTML + mbox 收信 |
54
59
  | `fake-legal` | fake.legal | - | `/api/domains` + `/api/inbox/new`;可选 `GenerateEmailOptions.domain` |
60
+ | `moakt` | moakt.com | ✅ | HTML 收件箱 + `tm_session`;`domain` 可选语言路径;独立 `requests` 请求避免污染全局 Session Cookie |
55
61
 
56
62
  ## 快速开始
57
63
 
58
64
  ```python
59
- from tempmail_sdk import generate_email, get_emails, GenerateEmailOptions, GetEmailsOptions
65
+ from tempmail_sdk import generate_email, get_emails, GenerateEmailOptions
60
66
 
61
67
  # 创建临时邮箱
62
68
  info = generate_email(GenerateEmailOptions(channel="guerrillamail"))
63
- print(f"邮箱: {info.email}")
69
+ if info:
70
+ print(f"邮箱: {info.email}")
64
71
 
65
- # 获取邮件
66
- result = get_emails(GetEmailsOptions(
67
- channel=info.channel,
68
- email=info.email,
69
- token=info.token,
70
- ))
71
- if result.success:
72
- print(f"收到 {len(result.emails)} 封邮件")
72
+ # 获取邮件(channel / email / token 由 SDK 从 EmailInfo 读取,无需手动传入)
73
+ result = get_emails(info)
74
+ if result.success:
75
+ print(f"收到 {len(result.emails)} 封邮件")
73
76
  ```
74
77
 
75
78
  ## 使用客户端类
@@ -32,10 +32,16 @@ tempmail_sdk/providers/mail_tm.py
32
32
  tempmail_sdk/providers/maildrop.py
33
33
  tempmail_sdk/providers/mffac.py
34
34
  tempmail_sdk/providers/minmail.py
35
+ tempmail_sdk/providers/moakt.py
35
36
  tempmail_sdk/providers/smail_pw.py
37
+ tempmail_sdk/providers/ta_easy.py
36
38
  tempmail_sdk/providers/temp_mail_io.py
37
39
  tempmail_sdk/providers/tempmail.py
38
40
  tempmail_sdk/providers/tempmail_cn.py
39
41
  tempmail_sdk/providers/tempmail_lol.py
42
+ tempmail_sdk/providers/tempmailg.py
40
43
  tempmail_sdk/providers/temporary_email_org.py
44
+ tempmail_sdk/providers/tenmail_wangtz.py
45
+ tempmail_sdk/providers/tenminute_one.py
46
+ tempmail_sdk/providers/tmpmails.py
41
47
  tempmail_sdk/providers/vip_215.py
@@ -14,24 +14,29 @@ from .retry import with_retry, with_retry_with_attempts
14
14
  from .telemetry import report_telemetry
15
15
  from .logger import get_logger
16
16
  from .providers import (
17
- tempmail, tempmail_cn, linshi_email, linshiyou, mffac, tempmail_lol, chatgpt_org_uk,
17
+ tempmail, tempmail_cn, tmpmails, tempmailg, ta_easy, tenmail_wangtz, linshi_email, linshiyou, mffac, tempmail_lol, chatgpt_org_uk,
18
18
  temp_mail_io, awamail, temporary_email_org, mail_tm, mail_cx,
19
19
  dropmail, guerrillamail, maildrop, smail_pw,
20
- boomlify, minmail, vip_215, anonbox, fake_legal,
20
+ boomlify, minmail, vip_215, anonbox, fake_legal, moakt, tenminute_one,
21
21
  )
22
22
 
23
23
  # 所有支持的渠道列表
24
24
  ALL_CHANNELS = [
25
- "tempmail", "tempmail-cn", "linshi-email", "linshiyou", "mffac", "tempmail-lol", "chatgpt-org-uk",
25
+ "tempmail", "tempmail-cn", "tmpmails", "tempmailg", "ta-easy", "10mail-wangtz", "10minute-one", "linshi-email", "linshiyou", "mffac", "tempmail-lol", "chatgpt-org-uk",
26
26
  "temp-mail-io", "awamail", "temporary-email-org", "mail-tm", "mail-cx",
27
27
  "dropmail", "guerrillamail", "maildrop", "smail-pw",
28
- "boomlify", "minmail", "vip-215", "anonbox", "fake-legal",
28
+ "boomlify", "minmail", "vip-215", "anonbox", "fake-legal", "moakt",
29
29
  ]
30
30
 
31
31
  # 渠道信息映射表
32
32
  CHANNEL_INFO_MAP = {
33
33
  "tempmail": ChannelInfo(channel="tempmail", name="TempMail", website="tempmail.ing"),
34
34
  "tempmail-cn": ChannelInfo(channel="tempmail-cn", name="TempMail CN", website="tempmail.cn"),
35
+ "tmpmails": ChannelInfo(channel="tmpmails", name="TmpMails", website="tmpmails.com"),
36
+ "tempmailg": ChannelInfo(channel="tempmailg", name="TempMailG", website="tempmailg.com"),
37
+ "ta-easy": ChannelInfo(channel="ta-easy", name="TA Easy", website="ta-easy.com"),
38
+ "10mail-wangtz": ChannelInfo(channel="10mail-wangtz", name="10mail Wangtz", website="10mail.wangtz.cn"),
39
+ "10minute-one": ChannelInfo(channel="10minute-one", name="10 Minute Email", website="10minutemail.one"),
35
40
  "linshi-email": ChannelInfo(channel="linshi-email", name="临时邮箱", website="linshi-email.com"),
36
41
  "linshiyou": ChannelInfo(channel="linshiyou", name="临时邮", website="linshiyou.com"),
37
42
  "mffac": ChannelInfo(channel="mffac", name="MFFAC", website="mffac.com"),
@@ -51,6 +56,7 @@ CHANNEL_INFO_MAP = {
51
56
  "vip-215": ChannelInfo(channel="vip-215", name="VIP 215", website="vip.215.im"),
52
57
  "anonbox": ChannelInfo(channel="anonbox", name="Anonbox", website="anonbox.net"),
53
58
  "fake-legal": ChannelInfo(channel="fake-legal", name="Fake Legal", website="fake.legal"),
59
+ "moakt": ChannelInfo(channel="moakt", name="Moakt", website="moakt.com"),
54
60
  }
55
61
 
56
62
 
@@ -130,6 +136,16 @@ def _generate_email_once(channel: str, options: GenerateEmailOptions) -> EmailIn
130
136
  return tempmail.generate_email(options.duration)
131
137
  elif channel == "tempmail-cn":
132
138
  return tempmail_cn.generate_email(options.domain)
139
+ elif channel == "tmpmails":
140
+ return tmpmails.generate_email(options.domain)
141
+ elif channel == "tempmailg":
142
+ return tempmailg.generate_email(options.domain)
143
+ elif channel == "ta-easy":
144
+ return ta_easy.generate_email()
145
+ elif channel == "10mail-wangtz":
146
+ return tenmail_wangtz.generate_email(options.domain)
147
+ elif channel == "10minute-one":
148
+ return tenminute_one.generate_email(options.domain)
133
149
  elif channel == "linshi-email":
134
150
  return linshi_email.generate_email()
135
151
  elif channel == "linshiyou":
@@ -168,6 +184,8 @@ def _generate_email_once(channel: str, options: GenerateEmailOptions) -> EmailIn
168
184
  return anonbox.generate_email()
169
185
  elif channel == "fake-legal":
170
186
  return fake_legal.generate_email(options.domain)
187
+ elif channel == "moakt":
188
+ return moakt.generate_email(options.domain)
171
189
  else:
172
190
  raise ValueError(f"Unknown channel: {channel}")
173
191
 
@@ -234,6 +252,20 @@ def _get_emails_once(channel: str, email: str, token: Optional[str]) -> List[Ema
234
252
  return tempmail.get_emails(email)
235
253
  elif channel == "tempmail-cn":
236
254
  return tempmail_cn.get_emails(email)
255
+ elif channel == "tmpmails":
256
+ if not token:
257
+ raise ValueError("token is required for tmpmails channel")
258
+ return tmpmails.get_emails(email, token)
259
+ elif channel == "tempmailg":
260
+ if not token:
261
+ raise ValueError("token is required for tempmailg channel")
262
+ return tempmailg.get_emails(email, token)
263
+ elif channel == "ta-easy":
264
+ if not token:
265
+ raise ValueError("token is required for ta-easy channel")
266
+ return ta_easy.get_emails(email, token)
267
+ elif channel == "10mail-wangtz":
268
+ return tenmail_wangtz.get_emails(email, token or "")
237
269
  elif channel == "linshi-email":
238
270
  if not token:
239
271
  raise ValueError("token is required for linshi-email channel")
@@ -302,6 +334,14 @@ def _get_emails_once(channel: str, email: str, token: Optional[str]) -> List[Ema
302
334
  return anonbox.get_emails(token, email)
303
335
  elif channel == "fake-legal":
304
336
  return fake_legal.get_emails(email)
337
+ elif channel == "moakt":
338
+ if not token:
339
+ raise ValueError("token is required for moakt channel")
340
+ return moakt.get_emails(email, token)
341
+ elif channel == "10minute-one":
342
+ if not token:
343
+ raise ValueError("token is required for 10minute-one channel")
344
+ return tenminute_one.get_emails(email, token)
305
345
  else:
306
346
  raise ValueError(f"Unknown channel: {channel}")
307
347
 
@@ -71,6 +71,7 @@ def _normalize_from(raw: Dict[str, Any]) -> str:
71
71
  "from_addr",
72
72
  "from_address",
73
73
  "fromAddress",
74
+ "mail_sender",
74
75
  "sender",
75
76
  "address_from",
76
77
  "from_email",
@@ -87,7 +88,7 @@ def _normalize_to(raw: Dict[str, Any], recipient_email: str) -> str:
87
88
 
88
89
  def _normalize_subject(raw: Dict[str, Any]) -> str:
89
90
  """提取邮件主题"""
90
- return _get_str(raw, "subject", "e_subject")
91
+ return _get_str(raw, "subject", "e_subject", "mail_title")
91
92
 
92
93
 
93
94
  def _normalize_text(raw: Dict[str, Any]) -> str:
@@ -97,6 +98,7 @@ def _normalize_text(raw: Dict[str, Any]) -> str:
97
98
  "text",
98
99
  "text_body",
99
100
  "preview_text",
101
+ "mail_body_text",
100
102
  "body",
101
103
  "content",
102
104
  "body_text",
@@ -107,7 +109,7 @@ def _normalize_text(raw: Dict[str, Any]) -> str:
107
109
 
108
110
  def _normalize_html(raw: Dict[str, Any]) -> str:
109
111
  """提取 HTML 内容"""
110
- return _get_str(raw, "html", "html_body", "html_content", "body_html")
112
+ return _get_str(raw, "html", "html_body", "html_content", "body_html", "mail_body_html")
111
113
 
112
114
 
113
115
  def _normalize_date(raw: Dict[str, Any]) -> str:
@@ -0,0 +1,225 @@
1
+ """
2
+ moakt.com:GET 语言首页与收件箱 HTML;凭证为 tm_session 等 Cookie(序列化在 token 内);
3
+ 列表解析 /{locale}/email/{uuid},正文 GET .../html 解析 .email-body。
4
+ """
5
+
6
+ import base64
7
+ import html
8
+ import json
9
+ import re
10
+ from typing import Dict, List, Optional, Tuple
11
+
12
+ import requests
13
+
14
+ from ..config import get_config
15
+ from ..normalize import normalize_email
16
+ from ..types import Email, EmailInfo
17
+
18
+ CHANNEL = "moakt"
19
+ ORIGIN = "https://www.moakt.com"
20
+ TOK_PREFIX = "mok1:"
21
+
22
+ _EMAIL_DIV_RE = re.compile(r'(?is)<div\s+id="email-address"\s*>([^<]+)</div>')
23
+ _HREF_EMAIL_RE = re.compile(
24
+ r'href="(/[^"]+/email/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})"'
25
+ )
26
+ _TITLE_RE = re.compile(r'(?is)<li\s+class="title"\s*>([^<]*)</li>')
27
+ _DATE_RE = re.compile(r'(?is)<li\s+class="date"[^>]*>[\s\S]*?<span[^>]*>([^<]+)</span>')
28
+ _SENDER_RE = re.compile(
29
+ r'(?is)<li\s+class="sender"[^>]*>[\s\S]*?<span[^>]*>([\s\S]*?)</span>\s*</li>'
30
+ )
31
+ _BODY_RE = re.compile(r'(?is)<div\s+class="email-body"\s*>([\s\S]*?)</div>')
32
+ _FROM_ADDR_RE = re.compile(
33
+ r"<([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})>"
34
+ )
35
+ _TAG_RE = re.compile(r"<[^>]+>")
36
+
37
+ _DEFAULT_HEADERS = {
38
+ "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
39
+ "Cache-Control": "no-cache",
40
+ "DNT": "1",
41
+ "Pragma": "no-cache",
42
+ "Upgrade-Insecure-Requests": "1",
43
+ }
44
+
45
+
46
+ def _locale(domain: Optional[str]) -> str:
47
+ s = (domain or "").strip()
48
+ if not s or any(c in s for c in "/?#\\"):
49
+ return "zh"
50
+ return s
51
+
52
+
53
+ def _bare_get(url: str, headers: dict) -> requests.Response:
54
+ c = get_config()
55
+ kw: dict = {"timeout": c.timeout, "headers": headers, "verify": not c.insecure}
56
+ if c.proxy:
57
+ kw["proxies"] = {"http": c.proxy, "https": c.proxy}
58
+ return requests.get(url, **kw)
59
+
60
+
61
+ def _parse_cookie_map(hdr: str) -> Dict[str, str]:
62
+ m: Dict[str, str] = {}
63
+ for part in hdr.split(";"):
64
+ part = part.strip()
65
+ if not part or "=" not in part:
66
+ continue
67
+ k, _, v = part.partition("=")
68
+ k, v = k.strip(), v.strip()
69
+ if k:
70
+ m[k] = v
71
+ return m
72
+
73
+
74
+ def _merge_cookie_hdr(prev: str, resp: requests.Response) -> str:
75
+ d = _parse_cookie_map(prev)
76
+ d.update(resp.cookies.get_dict())
77
+ return "; ".join(f"{k}={d[k]}" for k in sorted(d.keys()))
78
+
79
+
80
+ def _page_headers(referer: str, ua: str) -> dict:
81
+ return {
82
+ **_DEFAULT_HEADERS,
83
+ "User-Agent": ua,
84
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
85
+ "Referer": referer,
86
+ }
87
+
88
+
89
+ def _encode_sess(locale: str, cookie_hdr: str) -> str:
90
+ raw = json.dumps({"l": locale, "c": cookie_hdr}, separators=(",", ":")).encode("utf-8")
91
+ return TOK_PREFIX + base64.standard_b64encode(raw).decode("ascii")
92
+
93
+
94
+ def _decode_sess(tok: str) -> Tuple[str, str]:
95
+ if not tok.startswith(TOK_PREFIX):
96
+ raise ValueError("moakt: invalid session token")
97
+ try:
98
+ data = base64.standard_b64decode(tok[len(TOK_PREFIX) :].encode("ascii"))
99
+ o = json.loads(data.decode("utf-8"))
100
+ except (json.JSONDecodeError, ValueError) as e:
101
+ raise ValueError("moakt: invalid session token") from e
102
+ loc = (o.get("l") or "").strip()
103
+ c = (o.get("c") or "").strip()
104
+ if not loc or not c:
105
+ raise ValueError("moakt: invalid session token")
106
+ return loc, c
107
+
108
+
109
+ def _parse_inbox_email(html_s: str) -> str:
110
+ m = _EMAIL_DIV_RE.search(html_s)
111
+ if not m:
112
+ raise RuntimeError("moakt: email-address not found")
113
+ addr = html.unescape(m.group(1).strip())
114
+ if not addr:
115
+ raise RuntimeError("moakt: empty email-address")
116
+ return addr
117
+
118
+
119
+ def _strip_tags(s: str) -> str:
120
+ return _TAG_RE.sub(" ", s).strip()
121
+
122
+
123
+ def _list_mail_ids(html_s: str) -> List[str]:
124
+ seen = set()
125
+ out: List[str] = []
126
+ for m in _HREF_EMAIL_RE.finditer(html_s):
127
+ path = m.group(1)
128
+ if "/delete" in path:
129
+ continue
130
+ mid = path.rsplit("/", 1)[-1]
131
+ if len(mid) == 36 and mid not in seen:
132
+ seen.add(mid)
133
+ out.append(mid)
134
+ return out
135
+
136
+
137
+ def _parse_detail(page: str, mid: str, recipient: str) -> dict:
138
+ from_s = ""
139
+ sm = _SENDER_RE.search(page)
140
+ if sm:
141
+ inner = html.unescape(sm.group(1))
142
+ from_s = _strip_tags(inner)
143
+ em = _FROM_ADDR_RE.search(inner)
144
+ if em:
145
+ from_s = em.group(1).strip()
146
+ subj = ""
147
+ tm = _TITLE_RE.search(page)
148
+ if tm:
149
+ subj = html.unescape(tm.group(1).strip())
150
+ date_s = ""
151
+ dm = _DATE_RE.search(page)
152
+ if dm:
153
+ date_s = html.unescape(dm.group(1).strip())
154
+ body = ""
155
+ bm = _BODY_RE.search(page)
156
+ if bm:
157
+ body = bm.group(1).strip()
158
+ return {
159
+ "id": mid,
160
+ "to": recipient,
161
+ "from": from_s,
162
+ "subject": subj,
163
+ "date": date_s,
164
+ "html": body,
165
+ }
166
+
167
+
168
+ def generate_email(domain: Optional[str] = None, **kwargs) -> EmailInfo:
169
+ loc = _locale(domain)
170
+ base = f"{ORIGIN}/{loc}"
171
+ inbox = f"{base}/inbox"
172
+ c = get_config()
173
+ ua = (c.headers or {}).get("User-Agent") or (
174
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
175
+ "Chrome/146.0.0.0 Safari/537.36 Edg/146.0.0.0"
176
+ )
177
+
178
+ r1 = _bare_get(base, _page_headers(base, ua))
179
+ r1.raise_for_status()
180
+ cookie_hdr = _merge_cookie_hdr("", r1)
181
+
182
+ r2 = _bare_get(
183
+ inbox,
184
+ {**_page_headers(base, ua), "Cookie": cookie_hdr},
185
+ )
186
+ r2.raise_for_status()
187
+ cookie_hdr = _merge_cookie_hdr(cookie_hdr, r2)
188
+ html_s = r2.text
189
+
190
+ email = _parse_inbox_email(html_s)
191
+ if "tm_session" not in _parse_cookie_map(cookie_hdr):
192
+ raise RuntimeError("moakt: missing tm_session cookie")
193
+ tok = _encode_sess(loc, cookie_hdr)
194
+ return EmailInfo(channel=CHANNEL, email=email, _token=tok)
195
+
196
+
197
+ def get_emails(email: str, token: str, **kwargs) -> List[Email]:
198
+ loc, cookie_hdr = _decode_sess(token)
199
+ inbox = f"{ORIGIN}/{loc}/inbox"
200
+ c = get_config()
201
+ ua = (c.headers or {}).get("User-Agent") or (
202
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
203
+ "Chrome/146.0.0.0 Safari/537.36 Edg/146.0.0.0"
204
+ )
205
+ base_ref = f"{ORIGIN}/{loc}"
206
+
207
+ r = _bare_get(
208
+ inbox,
209
+ {**_page_headers(base_ref, ua), "Cookie": cookie_hdr},
210
+ )
211
+ r.raise_for_status()
212
+ ids = _list_mail_ids(r.text)
213
+ out: List[Email] = []
214
+ for mid in ids:
215
+ detail = f"{ORIGIN}/{loc}/email/{mid}/html"
216
+ refer = f"{ORIGIN}/{loc}/email/{mid}"
217
+ rd = _bare_get(
218
+ detail,
219
+ {**_page_headers(refer, ua), "Cookie": cookie_hdr},
220
+ )
221
+ if rd.status_code != 200:
222
+ continue
223
+ raw = _parse_detail(rd.text, mid, email)
224
+ out.append(normalize_email(raw, email))
225
+ return out
@@ -0,0 +1,62 @@
1
+ """
2
+ ta-easy.com 临时邮箱
3
+ API: https://api-endpoint.ta-easy.com/temp-email/
4
+ """
5
+
6
+ from .. import http as tm_http
7
+ from ..normalize import normalize_email
8
+ from ..types import EmailInfo
9
+
10
+ CHANNEL = "ta-easy"
11
+ API_BASE = "https://api-endpoint.ta-easy.com"
12
+ ORIGIN = "https://www.ta-easy.com"
13
+
14
+ _HEADERS = {
15
+ "Accept": "application/json",
16
+ "User-Agent": (
17
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
18
+ "Chrome/146.0.0.0 Safari/537.36 Edg/146.0.0.0"
19
+ ),
20
+ "origin": ORIGIN,
21
+ "referer": f"{ORIGIN}/",
22
+ }
23
+
24
+
25
+ def generate_email(**kwargs) -> EmailInfo:
26
+ """POST /temp-email/address/new(空 body)"""
27
+ resp = tm_http.post(
28
+ f"{API_BASE}/temp-email/address/new",
29
+ headers={**_HEADERS, "Content-Length": "0"},
30
+ data=b"",
31
+ )
32
+ resp.raise_for_status()
33
+ data = resp.json()
34
+ if data.get("status") != "success" or not data.get("address") or not data.get("token"):
35
+ msg = data.get("message") or "create failed"
36
+ raise RuntimeError(f"ta-easy: {msg}")
37
+ exp = data.get("expiresAt")
38
+ expires_at = int(exp) if isinstance(exp, (int, float)) else None
39
+ return EmailInfo(
40
+ channel=CHANNEL,
41
+ email=data["address"],
42
+ _token=data["token"],
43
+ expires_at=expires_at,
44
+ )
45
+
46
+
47
+ def get_emails(email: str, token: str, **kwargs) -> list:
48
+ """POST /temp-email/inbox/list"""
49
+ resp = tm_http.post(
50
+ f"{API_BASE}/temp-email/inbox/list",
51
+ headers={**_HEADERS, "Content-Type": "application/json"},
52
+ json={"token": token, "email": email},
53
+ )
54
+ resp.raise_for_status()
55
+ data = resp.json()
56
+ if data.get("status") != "success":
57
+ msg = data.get("message") or "inbox failed"
58
+ raise RuntimeError(f"ta-easy: {msg}")
59
+ raw_list = data.get("data")
60
+ if not isinstance(raw_list, list):
61
+ raw_list = []
62
+ return [normalize_email(raw, email) for raw in raw_list]