tempmail_sdk 1.3.3 → 1.3.5

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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/tempmail_sdk/channels.rb +29 -7
  4. data/lib/tempmail_sdk/channels_data.rb +29 -7
  5. data/lib/tempmail_sdk/providers/altmails.rb +99 -0
  6. data/lib/tempmail_sdk/providers/apihz.rb +138 -0
  7. data/lib/tempmail_sdk/providers/awamail.rb +95 -0
  8. data/lib/tempmail_sdk/providers/best_temp_mail.rb +77 -0
  9. data/lib/tempmail_sdk/providers/chatgpt_org_uk.rb +129 -0
  10. data/lib/tempmail_sdk/providers/clawdemail.rb +122 -0
  11. data/lib/tempmail_sdk/providers/crazymailing.rb +114 -0
  12. data/lib/tempmail_sdk/providers/disposablemail.rb +125 -0
  13. data/lib/tempmail_sdk/providers/disposablemail_app.rb +66 -0
  14. data/lib/tempmail_sdk/providers/email10min.rb +152 -0
  15. data/lib/tempmail_sdk/providers/emailnator.rb +132 -0
  16. data/lib/tempmail_sdk/providers/emailtemp_org.rb +131 -0
  17. data/lib/tempmail_sdk/providers/expressinboxhub.rb +118 -0
  18. data/lib/tempmail_sdk/providers/fakemail.rb +143 -0
  19. data/lib/tempmail_sdk/providers/firetempmail.rb +86 -0
  20. data/lib/tempmail_sdk/providers/flybymail.rb +93 -0
  21. data/lib/tempmail_sdk/providers/generator_email.rb +146 -0
  22. data/lib/tempmail_sdk/providers/haribu.rb +29 -3
  23. data/lib/tempmail_sdk/providers/huskmail.rb +132 -0
  24. data/lib/tempmail_sdk/providers/internxt.rb +176 -0
  25. data/lib/tempmail_sdk/providers/linshi_xyz.rb +79 -0
  26. data/lib/tempmail_sdk/providers/linshiyouxiang_net.rb +85 -0
  27. data/lib/tempmail_sdk/providers/mail_sunls.rb +42 -1
  28. data/lib/tempmail_sdk/providers/mail_td.rb +161 -0
  29. data/lib/tempmail_sdk/providers/mailcat_ai.rb +52 -0
  30. data/lib/tempmail_sdk/providers/maildrop.rb +79 -4
  31. data/lib/tempmail_sdk/providers/mailgolem.rb +96 -0
  32. data/lib/tempmail_sdk/providers/mailinator.rb +9 -2
  33. data/lib/tempmail_sdk/providers/mailmomy.rb +1 -1
  34. data/lib/tempmail_sdk/providers/mailtemp_cc.rb +91 -0
  35. data/lib/tempmail_sdk/providers/mailticking.rb +139 -0
  36. data/lib/tempmail_sdk/providers/minuteinbox.rb +174 -0
  37. data/lib/tempmail_sdk/providers/moakt.rb +29 -3
  38. data/lib/tempmail_sdk/providers/mtempmail.rb +140 -0
  39. data/lib/tempmail_sdk/providers/mytempmail_cc.rb +76 -0
  40. data/lib/tempmail_sdk/providers/nowtempmail.rb +112 -0
  41. data/lib/tempmail_sdk/providers/noxen_de5_net.rb +392 -0
  42. data/lib/tempmail_sdk/providers/nukemail.rb +188 -0
  43. data/lib/tempmail_sdk/providers/nullmail.rb +95 -0
  44. data/lib/tempmail_sdk/providers/openinbox.rb +102 -0
  45. data/lib/tempmail_sdk/providers/shadowmail.rb +174 -0
  46. data/lib/tempmail_sdk/providers/shitpost_email.rb +85 -0
  47. data/lib/tempmail_sdk/providers/smail_pw.rb +156 -0
  48. data/lib/tempmail_sdk/providers/smails.rb +128 -0
  49. data/lib/tempmail_sdk/providers/socketio_mail.rb +25 -0
  50. data/lib/tempmail_sdk/providers/temp_mail_gg.rb +362 -0
  51. data/lib/tempmail_sdk/providers/tempgbox.rb +118 -0
  52. data/lib/tempmail_sdk/providers/tempmail100.rb +148 -0
  53. data/lib/tempmail_sdk/providers/tempmail_cn.rb +111 -0
  54. data/lib/tempmail_sdk/providers/tempmail_ee.rb +373 -0
  55. data/lib/tempmail_sdk/providers/tempmailportal.rb +131 -0
  56. data/lib/tempmail_sdk/providers/tempmails_io.rb +89 -0
  57. data/lib/tempmail_sdk/providers/tempmailto.rb +312 -0
  58. data/lib/tempmail_sdk/providers/temporarymail_com.rb +184 -0
  59. data/lib/tempmail_sdk/providers/tenmin_app.rb +100 -0
  60. data/lib/tempmail_sdk/providers/tenminutemail_net.rb +183 -0
  61. data/lib/tempmail_sdk/providers/thirty_min_email.rb +90 -0
  62. data/lib/tempmail_sdk/providers/tmpkit.rb +129 -0
  63. data/lib/tempmail_sdk/providers/twentyfourmail_chacuo.rb +83 -0
  64. data/lib/tempmail_sdk/providers/vip_215.rb +171 -0
  65. data/lib/tempmail_sdk/providers/zerodrop.rb +90 -0
  66. data/lib/tempmail_sdk/registry.rb +285 -23
  67. data/lib/tempmail_sdk/types.rb +13 -0
  68. data/lib/tempmail_sdk/version.rb +1 -1
  69. data/lib/tempmail_sdk.rb +1 -1
  70. metadata +58 -6
  71. data/lib/tempmail_sdk/providers/gonebox_email.rb +0 -89
  72. data/lib/tempmail_sdk/providers/temp_mail_now.rb +0 -103
  73. data/lib/tempmail_sdk/providers/webmailtemp.rb +0 -108
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4c42b7ddf14c615d07554a2d6aa7efb1954cadad4ecef1f052bb6af5fb22f2a8
4
- data.tar.gz: 46ab91c0e8946782a83c60c020feeebf840e625be330839d62c69b1c8f1ab5bc
3
+ metadata.gz: 94b1283ca19ff9597330edb468dfa560e673fe8176921d74834e348ade013dc1
4
+ data.tar.gz: 1e9e82a350c0d42cba190079c117ed520ee4d48c2a28a0b2765e8746696856cd
5
5
  SHA512:
6
- metadata.gz: 175bf0d04d31f7db48739b559af1eba64bdc0c09b51bd18e90124fbf0f05727e4f2586157f714e6c76ee693d3b29725756c89f002fe9a484c4fc7bf969d26ba4
7
- data.tar.gz: 4052cdcfa7f88faf5eff0461a40e427eea368a86ca976fdd7dc25de4900d638f1479401ae98240936ffa489af05cd17446fcec7e4354c9b8debd896c79f2de1c
6
+ metadata.gz: 1b1d8285e29796a127ae34c83fd014df2fcf7a06efccc6739bac2a567cbf9eb9d15b87861ec488a61c432be578b5426643c6ded3ff6c2bfeccf2a9a7a7045709
7
+ data.tar.gz: d1c0b4969332cecc27ed714ebfa1adaef8715eb0c53fddc836c0b1c87a299b4f202081e180490500196f4f59ff165633ef46f09357d9f21d9fc12208e1c8417b
data/README.md CHANGED
@@ -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
- Ruby 语言临时邮箱 SDK,公开 **279** 个 `channel` 渠道标识,聚合 100+ 个第三方临时邮箱服务商,所有渠道返回**统一标准化格式**。渠道标识与顺序与 Go / npm / Rust / Python / C 等其余各端保持一致(十端同步);随机生成邮箱时在本端独立打乱尝试顺序。
5
+ Ruby 语言临时邮箱 SDK,公开 **296** 个 `channel` 渠道标识,聚合 100+ 个第三方临时邮箱服务商,所有渠道返回**统一标准化格式**。渠道标识与顺序与 Go / npm / Rust / Python / C 等其余各端保持一致(十端同步);随机生成邮箱时在本端独立打乱尝试顺序。
6
6
 
7
7
  ## 安装
8
8
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  #
3
- # 渠道标识常量模块(279 个),常量值即渠道 slug。
3
+ # 渠道标识常量模块(296 个),常量值即渠道 slug。
4
4
  # 由 .channel_meta.json 生成,供用户以常量方式引用渠道,避免手写字符串出错。
5
5
  #
6
6
  module TempmailSdk
@@ -31,6 +31,7 @@ module TempmailSdk
31
31
  MAILFORSPAM_DISPOSABLE = "mailforspam-disposable"
32
32
  TEMPMAILC = "tempmailc"
33
33
  MAILNESIA = "mailnesia"
34
+ MAILTICKING = "mailticking"
34
35
  THROWAWAYMAIL = "throwawaymail"
35
36
  TEMPMAIL_FISH = "tempmail-fish"
36
37
  NEIGHBOURS_SH = "neighbours-sh"
@@ -80,7 +81,6 @@ module TempmailSdk
80
81
  VILLATOGEL_COM = "villatogel-com"
81
82
  MAIL123 = "mail123"
82
83
  MAIL10S = "mail10s"
83
- WEBMAILTEMP = "webmailtemp"
84
84
  TEMPFASTMAIL = "tempfastmail"
85
85
  C_1SEC_MAIL = "1sec-mail"
86
86
  FAKEMAIL = "fakemail"
@@ -162,7 +162,6 @@ module TempmailSdk
162
162
  HARIBU = "haribu"
163
163
  ROOTSH = "rootsh"
164
164
  FAKE_EMAIL_SITE = "fake-email-site"
165
- MOHMAL = "mohmal"
166
165
  MAILGOLEM = "mailgolem"
167
166
  BEST_TEMP_MAIL = "best-temp-mail"
168
167
  DISPOSABLEMAIL_APP = "disposablemail-app"
@@ -183,14 +182,12 @@ module TempmailSdk
183
182
  TEMPP_MAILS = "tempp-mails"
184
183
  EMAILTEMP_ORG = "emailtemp-org"
185
184
  MYTEMPMAIL_CC = "mytempmail-cc"
186
- TEMP_MAIL_NOW = "temp-mail-now"
187
185
  MAIL_TD = "mail-td"
188
186
  MAILHOLE_DE = "mailhole-de"
189
187
  TMAIL_LINK = "tmail-link"
190
188
  C_24MAIL_CHACUO = "24mail-chacuo"
191
189
  NIMAIL = "nimail"
192
190
  FREECUSTOM = "freecustom"
193
- C_16888888_CYOU = "16888888-cyou"
194
191
  C_17666688_SHOP = "17666688-shop"
195
192
  C_282MAIL_COM = "282mail-com"
196
193
  BLACKHOLE_DJURBY_SE = "blackhole-djurby-se"
@@ -205,7 +202,6 @@ module TempmailSdk
205
202
  EASYME_PRO = "easyme-pro"
206
203
  EBS_COM_AR = "ebs-com-ar"
207
204
  ETGDEV_DE = "etgdev-de"
208
- EVERGREENCO_SHOP = "evergreenco-shop"
209
205
  FWD2M_ESZETT_ES = "fwd2m-eszett-es"
210
206
  JAMA_TRENET_EU = "jama-trenet-eu"
211
207
  J_FAIRUSE_ORG = "j-fairuse-org"
@@ -279,11 +275,37 @@ module TempmailSdk
279
275
  TEMPGMAILER = "tempgmailer"
280
276
  TEMP_MAIL_ORG = "temp-mail-org"
281
277
  XKX_ME = "xkx-me"
282
- GONEBOX_EMAIL = "gonebox-email"
283
278
  MAILCAT_AI = "mailcat-ai"
284
279
  TEMPGO_EMAIL = "tempgo-email"
285
280
  RESTMAIL_NET = "restmail-net"
286
281
  DROPMAIL_ME = "dropmail-me"
287
282
  TEN_MINUTE_MAIL_NET = "ten-minute-mail-net"
283
+ TEMPMAILS_IO = "tempmails-io"
284
+ SHITPOST_EMAIL = "shitpost-email"
285
+ SMAILS = "smails"
286
+ TEMPMAILPORTAL = "tempmailportal"
287
+ HUSKMAIL = "huskmail"
288
+ ZERODROP = "zerodrop"
289
+ FIRETEMPMAIL = "firetempmail"
290
+ NULLMAIL = "nullmail"
291
+ TENMIN_APP = "tenmin-app"
292
+ MTEMPMAIL = "mtempmail"
293
+ TEMPMAIL_EE = "tempmail-ee"
294
+ TEMPORARYMAIL_COM = "temporarymail-com"
295
+ C_30MINEMAIL = "30minemail"
296
+ LINSHI_XYZ = "linshi-xyz"
297
+ CRAZYMAILING = "crazymailing"
298
+ NOXEN_DE5_NET = "noxen-de5-net"
299
+ NUKEMAIL = "nukemail"
300
+ SHADOWMAIL = "shadowmail"
301
+ FLYBYMAIL = "flybymail"
302
+ NOWTEMPMAIL = "nowtempmail"
303
+ CLAWDEMAIL = "clawdemail"
304
+ TEMPMAIL100 = "tempmail100"
305
+ TEMPMAILTO = "tempmailto"
306
+ TEMP_MAIL_GG = "temp-mail-gg"
307
+ TMPKIT = "tmpkit"
308
+ INTERNXT = "internxt"
309
+ GENERATOR_EMAIL = "generator-email"
288
310
  end
289
311
  end
@@ -4,7 +4,7 @@
4
4
  # 每项为 [slug, name, website],注册表按此顺序枚举,顺序为硬约束。
5
5
  #
6
6
  module TempmailSdk
7
- # 279 个渠道的有序元数据
7
+ # 296 个渠道的有序元数据
8
8
  CHANNEL_DATA = [
9
9
  ["tempmail", "TempMail", "tempmail.ing"],
10
10
  ["tempmail-cn", "TempMail CN", "tempmail.cn"],
@@ -31,6 +31,7 @@ module TempmailSdk
31
31
  ["mailforspam-disposable", "MailForSpam Disposable", "disposable.email"],
32
32
  ["tempmailc", "TempMailC", "tempmailc.com"],
33
33
  ["mailnesia", "Mailnesia", "mailnesia.com"],
34
+ ["mailticking", "MailTicking", "mailticking.com"],
34
35
  ["throwawaymail", "ThrowawayMail", "throwawaymail.app"],
35
36
  ["tempmail-fish", "TempMail Fish", "tempmail.fish"],
36
37
  ["neighbours-sh", "Neighbours", "neighbours.sh"],
@@ -80,7 +81,6 @@ module TempmailSdk
80
81
  ["villatogel-com", "villatogel.com", "getnada.net"],
81
82
  ["mail123", "Mail123", "mail123.fr"],
82
83
  ["mail10s", "Mail10s", "mail10s.com"],
83
- ["webmailtemp", "WebMailTemp", "webmailtemp.com"],
84
84
  ["tempfastmail", "TempFastMail", "tempfastmail.com"],
85
85
  ["1sec-mail", "1SecMail", "1sec-mail.com"],
86
86
  ["fakemail", "FakeMail", "fakemail.net"],
@@ -162,7 +162,6 @@ module TempmailSdk
162
162
  ["haribu", "Haribu", "haribu.net"],
163
163
  ["rootsh", "Rootsh(BccTo)", "rootsh.com"],
164
164
  ["fake-email-site", "FakeEmailSite", "fake-email.site"],
165
- ["mohmal", "Mohmal", "mohmal.com"],
166
165
  ["mailgolem", "MailGolem", "mailgolem.com"],
167
166
  ["best-temp-mail", "BestTempMail", "best-temp-mail.com"],
168
167
  ["disposablemail-app", "DisposableMail", "disposablemail.app"],
@@ -183,14 +182,12 @@ module TempmailSdk
183
182
  ["tempp-mails", "TemppMails", "tempp-mails.com"],
184
183
  ["emailtemp-org", "EmailTemp", "emailtemp.org"],
185
184
  ["mytempmail-cc", "MyTempMail.cc", "mytempmail.cc"],
186
- ["temp-mail-now", "TempMailNow", "temp-mail.now"],
187
185
  ["mail-td", "Mail.td", "mail.td"],
188
186
  ["mailhole-de", "Mailhole.de", "mailhole.de"],
189
187
  ["tmail-link", "TMail.link", "tmail.link"],
190
188
  ["24mail-chacuo", "24Mail Chacuo", "24mail.chacuo.net"],
191
189
  ["nimail", "NiMail", "nimail.cn"],
192
190
  ["freecustom", "FreeCustom.Email", "freecustom.email"],
193
- ["16888888-cyou", "Mailmomy (16888888.cyou)", "mailmomy.com"],
194
191
  ["17666688-shop", "Mailmomy (17666688.shop)", "mailmomy.com"],
195
192
  ["282mail-com", "Mailmomy (282mail.com)", "mailmomy.com"],
196
193
  ["blackhole-djurby-se", "Mailinator (blackhole.djurby.se)", "mailinator.com"],
@@ -205,7 +202,6 @@ module TempmailSdk
205
202
  ["easyme-pro", "Mailmomy (easyme.pro)", "mailmomy.com"],
206
203
  ["ebs-com-ar", "Mailinator (ebs.com.ar)", "mailinator.com"],
207
204
  ["etgdev-de", "Mailinator (etgdev.de)", "mailinator.com"],
208
- ["evergreenco-shop", "Mailmomy (evergreenco.shop)", "mailmomy.com"],
209
205
  ["fwd2m-eszett-es", "Mailinator (fwd2m.eszett.es)", "mailinator.com"],
210
206
  ["jama-trenet-eu", "Mailinator (jama.trenet.eu)", "mailinator.com"],
211
207
  ["j-fairuse-org", "Mailinator (j.fairuse.org)", "mailinator.com"],
@@ -279,11 +275,37 @@ module TempmailSdk
279
275
  ["tempgmailer", "TempGmailer", "tempgmailer.com"],
280
276
  ["temp-mail-org", "Temp-Mail.org", "temp-mail.org"],
281
277
  ["xkx-me", "XKX.me", "xkx.me"],
282
- ["gonebox-email", "Gonebox Email", "gonebox.email"],
283
278
  ["mailcat-ai", "Mailcat AI", "mailcat.ai"],
284
279
  ["tempgo-email", "TempGo Email", "tempgo.email"],
285
280
  ["restmail-net", "Restmail.net", "restmail.net"],
286
281
  ["dropmail-me", "DropMail.me", "dropmail.me"],
287
282
  ["ten-minute-mail-net", "10MinuteMail.net", "10minutemail.net"],
283
+ ["tempmails-io", "TempMails.io", "tempmails.io"],
284
+ ["shitpost-email", "ShitPost.email", "shitpost.email"],
285
+ ["smails", "Smails.dev", "smails.dev"],
286
+ ["tempmailportal", "TempMail Portal", "tempmailportal.com"],
287
+ ["huskmail", "HuskMail", "huskmail.xyz"],
288
+ ["zerodrop", "Zerodrop", "zerodrop.dev"],
289
+ ["firetempmail", "FireTempMail", "firetempmail.com"],
290
+ ["nullmail", "NullMail", "nullmail.cc"],
291
+ ["tenmin-app", "Tenmin.app", "tenmin.app"],
292
+ ["mtempmail", "MTempMail", "mtempmail.com"],
293
+ ["tempmail-ee", "TempMail.ee", "tempmail.ee"],
294
+ ["temporarymail-com", "Temporarymail.com", "temporarymail.com"],
295
+ ["30minemail", "30minemail", "30minemail.com"],
296
+ ["linshi-xyz", "Linshi.xyz", "linshi.xyz"],
297
+ ["crazymailing", "CrazyMailing", "crazymailing.com"],
298
+ ["noxen-de5-net", "UniMail Bot", "tempmail.noxen.de5.net"],
299
+ ["nukemail", "NukeMail", "nukemail.app"],
300
+ ["shadowmail", "ShadowMail", "shadowmail.win"],
301
+ ["flybymail", "FlyByMail", "flybymail.com"],
302
+ ["nowtempmail", "NowTempMail", "nowtempmail.com"],
303
+ ["clawdemail", "ClawdEmail", "clawdemail.com"],
304
+ ["tempmail100", "TempMail100", "tempmail100.com"],
305
+ ["tempmailto", "Tempmailto", "tempmailto.com"],
306
+ ["temp-mail-gg", "TempMailGG", "temp-mail.gg"],
307
+ ["tmpkit", "Tmpkit", "tmpkit.com"],
308
+ ["internxt", "Internxt", "internxt.com"],
309
+ ["generator-email", "GeneratorEmail", "generator.email"],
288
310
  ].freeze
289
311
  end
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "uri"
4
+
5
+ module TempmailSdk
6
+ module Providers
7
+ # altmails.com 渠道实现
8
+ #
9
+ # 流程:
10
+ # 1. GET / 建立 session,从 HTML inline script 提取 CSRF token('_token': 'xxx')
11
+ # 2. GET /random-email-address 获取随机邮箱地址(纯文本响应)
12
+ # 3. 收信:重新建立 session 获取新 CSRF,POST /fetch-emails/{email} 获取邮件列表
13
+ # 4. GET /view/{id} 获取每封邮件正文 HTML
14
+ module Altmails
15
+ CHANNEL = "altmails"
16
+ BASE_URL = "https://tempmail.altmails.com"
17
+
18
+ BROWSER_HEADERS = {
19
+ "Accept" => "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
20
+ "Accept-Language" => "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
21
+ "User-Agent" => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36"
22
+ }.freeze
23
+
24
+ CSRF_RE = /'_token'\s*:\s*'([^']+)'/.freeze
25
+
26
+ module_function
27
+
28
+ # 访问首页提取 CSRF token
29
+ # @return [String]
30
+ def fetch_csrf
31
+ resp = Http.get("#{BASE_URL}/", headers: BROWSER_HEADERS)
32
+ resp.raise_for_status
33
+ m = resp.body.match(CSRF_RE)
34
+ raise "altmails: 未能从首页提取 CSRF token" unless m
35
+
36
+ m[1]
37
+ end
38
+
39
+ # 创建临时邮箱
40
+ # @return [EmailInfo]
41
+ def generate_email
42
+ csrf = fetch_csrf
43
+ resp = Http.get("#{BASE_URL}/random-email-address",
44
+ headers: BROWSER_HEADERS.merge("Referer" => "#{BASE_URL}/"))
45
+ resp.raise_for_status
46
+ email = resp.body.strip
47
+ raise "altmails: 邮箱地址无效: #{email.inspect}" if email.empty? || !email.include?("@")
48
+
49
+ EmailInfo.new(channel: CHANNEL, email: email, token: csrf)
50
+ end
51
+
52
+ # 获取邮件列表
53
+ # @param email [String]
54
+ # @param token [String] CSRF token(收信时重新获取新 session)
55
+ # @return [Array<Email>]
56
+ def get_emails(email, token)
57
+ _ = token
58
+ csrf = fetch_csrf
59
+ fetch_url = "#{BASE_URL}/fetch-emails/#{URI.encode_www_form_component(email)}"
60
+ form = "_token=#{URI.encode_www_form_component(csrf)}"
61
+ resp = Http.post(fetch_url,
62
+ headers: {
63
+ "Accept" => "application/json, text/plain, */*",
64
+ "Accept-Language" => "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
65
+ "Content-Type" => "application/x-www-form-urlencoded",
66
+ "Origin" => BASE_URL,
67
+ "Referer" => "#{BASE_URL}/",
68
+ "User-Agent" => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36",
69
+ "X-Requested-With" => "XMLHttpRequest"
70
+ },
71
+ body: form)
72
+ resp.raise_for_status
73
+ items = begin
74
+ resp.json
75
+ rescue StandardError
76
+ []
77
+ end
78
+ return [] unless items.is_a?(Array)
79
+
80
+ items.filter_map do |item|
81
+ next unless item.is_a?(Hash)
82
+
83
+ item["to"] = email
84
+ mail_id = item["id"].to_s
85
+ unless mail_id.empty?
86
+ begin
87
+ vr = Http.get("#{BASE_URL}/view/#{URI.encode_www_form_component(mail_id)}",
88
+ headers: BROWSER_HEADERS.merge("Referer" => "#{BASE_URL}/"))
89
+ item["html_body"] = vr.body if vr.ok?
90
+ rescue StandardError
91
+ # 忽略正文获取失败
92
+ end
93
+ end
94
+ Normalize.normalize_email(item, email)
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,138 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "base64"
4
+ require "json"
5
+ require "uri"
6
+
7
+ module TempmailSdk
8
+ module Providers
9
+ # apihz(接口盒子)渠道实现
10
+ #
11
+ # 需 id/key 凭据,邮箱有效期 10 分钟。读信须携带创建时的 pwd,
12
+ # 故 token 用 base64(JSON{mail,pwd}) 编码保存。
13
+ module Apihz
14
+ CHANNEL = "apihz"
15
+ BASE_URL = "https://cn.apihz.cn"
16
+ TOK_PREFIX = "apihz1:"
17
+ # 官方公共账号(共享频次),未配置自有 id/key 时使用
18
+ PUBLIC_ID = "88888888"
19
+ PUBLIC_KEY = "88888888"
20
+ DOMAINS = %w[apimail.email apimail.vip].freeze
21
+
22
+ HEADERS = {
23
+ "Accept" => "application/json",
24
+ "User-Agent" => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " \
25
+ "(KHTML, like Gecko) Chrome/149.0.0.0 Safari/537.36"
26
+ }.freeze
27
+
28
+ module_function
29
+
30
+ # 读取 id/key:优先环境变量 APIHZ_ID/APIHZ_KEY,回退官方公共账号
31
+ def credentials
32
+ id = ENV["APIHZ_ID"].to_s.strip
33
+ key = ENV["APIHZ_KEY"].to_s.strip
34
+ id = PUBLIC_ID if id.empty?
35
+ key = PUBLIC_KEY if key.empty?
36
+ [id, key]
37
+ end
38
+
39
+ # 生成随机本地部分
40
+ def random_local(length = 10)
41
+ chars = ("a".."z").to_a + ("0".."9").to_a
42
+ Array.new(length) { chars.sample }.join
43
+ end
44
+
45
+ # 生成 12 位随机密码
46
+ def random_password
47
+ chars = ("A".."Z").to_a + ("a".."z").to_a + ("0".."9").to_a
48
+ Array.new(12) { chars.sample }.join
49
+ end
50
+
51
+ # token 编码:前缀 + base64(JSON{mail,pwd})
52
+ def encode_token(mail, pwd)
53
+ raw = JSON.generate("mail" => mail, "pwd" => pwd)
54
+ TOK_PREFIX + Base64.strict_encode64(raw)
55
+ end
56
+
57
+ # token 解码
58
+ def decode_token(token)
59
+ raise "apihz: 无效 token" unless token.to_s.start_with?(TOK_PREFIX)
60
+
61
+ raw = Base64.strict_decode64(token[TOK_PREFIX.length..])
62
+ o = JSON.parse(raw)
63
+ mail = o["mail"].to_s.strip
64
+ pwd = o["pwd"].to_s.strip
65
+ raise "apihz: 无效 token" if mail.empty? || pwd.empty?
66
+
67
+ [mail, pwd]
68
+ rescue ArgumentError, JSON::ParserError
69
+ raise "apihz: 无效 token"
70
+ end
71
+
72
+ # 创建临时邮箱
73
+ # GET /api/mail/mailcache.php?id=&key=&domain=&name=&pwd=&buytype=0
74
+ # @return [EmailInfo]
75
+ def generate_email
76
+ id, key = credentials
77
+ domain = DOMAINS.sample
78
+ name = random_local
79
+ pwd = random_password
80
+
81
+ url = "#{BASE_URL}/api/mail/mailcache.php?" \
82
+ "id=#{URI.encode_www_form_component(id)}&key=#{URI.encode_www_form_component(key)}" \
83
+ "&domain=#{URI.encode_www_form_component(domain)}" \
84
+ "&name=#{URI.encode_www_form_component(name)}" \
85
+ "&pwd=#{URI.encode_www_form_component(pwd)}&buytype=0"
86
+
87
+ resp = Http.get(url, headers: HEADERS)
88
+ resp.raise_for_status
89
+ data = resp.json
90
+ raise "apihz: 创建邮箱失败 #{data['msg']}" if data["code"] != 200 || data["mail"].to_s.empty?
91
+
92
+ final_pwd = data["pwd"].to_s
93
+ final_pwd = pwd if final_pwd.empty?
94
+
95
+ EmailInfo.new(channel: CHANNEL, email: data["mail"], token: encode_token(data["mail"], final_pwd))
96
+ end
97
+
98
+ # 获取邮件列表
99
+ # GET /api/mail/mailgetlist.php?id=&key=&mail=&pwd=&page=1
100
+ # @param token [String]
101
+ # @return [Array<Email>]
102
+ def get_emails(token)
103
+ mail, pwd = decode_token(token)
104
+ id, key = credentials
105
+
106
+ url = "#{BASE_URL}/api/mail/mailgetlist.php?" \
107
+ "id=#{URI.encode_www_form_component(id)}&key=#{URI.encode_www_form_component(key)}" \
108
+ "&mail=#{URI.encode_www_form_component(mail)}" \
109
+ "&pwd=#{URI.encode_www_form_component(pwd)}&page=1"
110
+
111
+ resp = Http.get(url, headers: HEADERS)
112
+ resp.raise_for_status
113
+ data = resp.json
114
+ return [] if data["code"] != 200
115
+
116
+ list = data["data"]
117
+ return [] unless list.is_a?(Array) && !list.empty?
118
+
119
+ list.map do |msg|
120
+ from_addr = msg["frommail"].to_s
121
+ from_addr = msg["fromname"].to_s if from_addr.empty?
122
+ date_val = msg["time2"].to_s
123
+ date_val = msg["time1"].to_s if date_val.empty?
124
+ Normalize.normalize_email({
125
+ "id" => msg["time1"].to_s,
126
+ "from" => from_addr,
127
+ "to" => mail,
128
+ "subject" => msg["subject"].to_s,
129
+ "text" => msg["content"].to_s,
130
+ "html" => msg["content"].to_s,
131
+ "date" => date_val,
132
+ "isRead" => false
133
+ }, mail)
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+
5
+ module TempmailSdk
6
+ module Providers
7
+ # awamail.com 渠道实现
8
+ #
9
+ # 流程:
10
+ # 1. POST /welcome/change_mailbox(空 body)不跟随重定向,从 Set-Cookie 提取 awamail_session
11
+ # 2. GET /welcome/get_emails 携带 Cookie 获取邮件列表
12
+ module Awamail
13
+ CHANNEL = "awamail"
14
+ BASE_URL = "https://awamail.com/welcome"
15
+
16
+ HEADERS = {
17
+ "Accept" => "application/json, text/javascript, */*; q=0.01",
18
+ "Accept-Language" => "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
19
+ "Cache-Control" => "no-cache",
20
+ "DNT" => "1",
21
+ "Origin" => "https://awamail.com",
22
+ "Pragma" => "no-cache",
23
+ "Referer" => "https://awamail.com/?lang=zh",
24
+ "User-Agent" => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " \
25
+ "(KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36 Edg/144.0.0.0",
26
+ "X-Requested-With" => "XMLHttpRequest"
27
+ }.freeze
28
+
29
+ module_function
30
+
31
+ # 创建临时邮箱
32
+ # POST /welcome/change_mailbox,从 Set-Cookie 提取 awamail_session
33
+ # @return [EmailInfo]
34
+ def generate_email
35
+ resp = Http.post("#{BASE_URL}/change_mailbox",
36
+ headers: HEADERS.merge("Content-Length" => "0"))
37
+ # 不跟随重定向,直接从响应提取 cookie
38
+ session_cookie = resp.cookie_value("awamail_session")
39
+ raise "awamail: 未能提取 awamail_session cookie" if session_cookie.to_s.empty?
40
+
41
+ cookie_str = "awamail_session=#{session_cookie}"
42
+
43
+ data = begin
44
+ resp.json
45
+ rescue StandardError
46
+ {}
47
+ end
48
+
49
+ email_addr = data.is_a?(Hash) ? data.dig("data", "email_address").to_s : ""
50
+ if email_addr.empty?
51
+ # 若 POST 响应无邮箱,尝试 GET get_emails 获取
52
+ gr = Http.get("#{BASE_URL}/get_emails",
53
+ headers: HEADERS.merge("Cookie" => cookie_str))
54
+ gr.raise_for_status
55
+ gd = gr.json
56
+ email_addr = gd.is_a?(Hash) ? gd.dig("data", "email_address").to_s : ""
57
+ end
58
+
59
+ raise "awamail: 未能获取邮箱地址" if email_addr.empty?
60
+
61
+ info = EmailInfo.new(channel: CHANNEL, email: email_addr, token: cookie_str)
62
+ if data.is_a?(Hash)
63
+ info.expires_at = data.dig("data", "expired_at").to_s
64
+ info.created_at = data.dig("data", "created_at").to_s
65
+ end
66
+ info
67
+ end
68
+
69
+ # 获取邮件列表
70
+ # GET /welcome/get_emails,携带 Cookie
71
+ # @param token [String] awamail_session cookie 字符串
72
+ # @param email [String]
73
+ # @return [Array<Email>]
74
+ def get_emails(token, email)
75
+ resp = Http.get("#{BASE_URL}/get_emails",
76
+ headers: HEADERS.merge(
77
+ "Cookie" => token,
78
+ "X-Requested-With" => "XMLHttpRequest"
79
+ ))
80
+ resp.raise_for_status
81
+ data = resp.json
82
+ return [] unless data.is_a?(Hash) && data["success"]
83
+
84
+ emails_raw = data.dig("data", "emails")
85
+ return [] unless emails_raw.is_a?(Array)
86
+
87
+ emails_raw.filter_map do |raw|
88
+ next unless raw.is_a?(Hash)
89
+
90
+ Normalize.normalize_email(raw, email)
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "securerandom"
5
+
6
+ module TempmailSdk
7
+ module Providers
8
+ # best-temp-mail.com 渠道实现
9
+ #
10
+ # 纯 JSON REST API,无需认证,无需 Session。
11
+ # 创建邮箱: POST /api/v3/createEmail body: {"intToken":"<uuid>"}
12
+ # 获取邮件: POST /api/v3/getEmailList body: {"address":"...","id":"...","intToken":"...","update_tag":"..."}
13
+ module BestTempMail
14
+ CHANNEL = "best-temp-mail"
15
+ API_BASE = "https://best-temp-mail.com/api/v3"
16
+
17
+ HEADERS = {
18
+ "Accept" => "application/json, text/plain, */*",
19
+ "Accept-Language" => "zh-CN,zh;q=0.9,en;q=0.8",
20
+ "Content-Type" => "application/json",
21
+ "Origin" => "https://best-temp-mail.com",
22
+ "Referer" => "https://best-temp-mail.com/",
23
+ "User-Agent" => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " \
24
+ "(KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36"
25
+ }.freeze
26
+
27
+ module_function
28
+
29
+ # 创建临时邮箱
30
+ # @return [EmailInfo]
31
+ def generate_email
32
+ int_token = SecureRandom.uuid
33
+ resp = Http.post("#{API_BASE}/createEmail",
34
+ headers: HEADERS,
35
+ json: { "intToken" => int_token })
36
+ resp.raise_for_status
37
+ data = resp.json
38
+ raise "best-temp-mail: 创建邮箱失败 status=#{data['status']}" \
39
+ if data["status"] != "success" || data.dig("data", "address").to_s.empty?
40
+
41
+ d = data["data"]
42
+ token = JSON.generate("intToken" => int_token, "id" => d["id"].to_s, "update_tag" => d["update_tag"].to_s)
43
+ EmailInfo.new(channel: CHANNEL, email: d["address"], token: token)
44
+ end
45
+
46
+ # 获取邮件列表
47
+ # @param email [String]
48
+ # @param token [String] JSON 编码的 intToken/id/update_tag
49
+ # @return [Array<Email>]
50
+ def get_emails(email, token)
51
+ tkn = JSON.parse(token)
52
+ resp = Http.post("#{API_BASE}/getEmailList",
53
+ headers: HEADERS,
54
+ json: {
55
+ "address" => email,
56
+ "id" => tkn["id"].to_s,
57
+ "intToken" => tkn["intToken"].to_s,
58
+ "update_tag" => tkn["update_tag"].to_s
59
+ })
60
+ resp.raise_for_status
61
+ data = resp.json
62
+ return [] unless data.dig("data", "hasNewEmail")
63
+
64
+ emails_raw = data.dig("data", "emails")
65
+ return [] unless emails_raw.is_a?(Array)
66
+
67
+ emails_raw.filter_map do |raw|
68
+ next unless raw.is_a?(Hash)
69
+
70
+ Normalize.normalize_email(raw, email)
71
+ end
72
+ rescue JSON::ParserError
73
+ raise "best-temp-mail: 无效的 token 格式"
74
+ end
75
+ end
76
+ end
77
+ end