tempmail_sdk 1.3.4 → 1.3.6

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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/tempmail_sdk/channels.rb +52 -27
  4. data/lib/tempmail_sdk/channels_data.rb +52 -27
  5. data/lib/tempmail_sdk/providers/clawdemail.rb +122 -0
  6. data/lib/tempmail_sdk/providers/crazymailing.rb +114 -0
  7. data/lib/tempmail_sdk/providers/duckmail.rb +9 -2
  8. data/lib/tempmail_sdk/providers/firetempmail.rb +86 -0
  9. data/lib/tempmail_sdk/providers/flybymail.rb +93 -0
  10. data/lib/tempmail_sdk/providers/generator_email.rb +146 -0
  11. data/lib/tempmail_sdk/providers/huskmail.rb +132 -0
  12. data/lib/tempmail_sdk/providers/internxt.rb +176 -0
  13. data/lib/tempmail_sdk/providers/linshi_xyz.rb +79 -0
  14. data/lib/tempmail_sdk/providers/mail_tm.rb +9 -2
  15. data/lib/tempmail_sdk/providers/mailmomy.rb +1 -1
  16. data/lib/tempmail_sdk/providers/mailticking.rb +139 -0
  17. data/lib/tempmail_sdk/providers/mtempmail.rb +140 -0
  18. data/lib/tempmail_sdk/providers/nowtempmail.rb +112 -0
  19. data/lib/tempmail_sdk/providers/noxen_de5_net.rb +392 -0
  20. data/lib/tempmail_sdk/providers/nukemail.rb +188 -0
  21. data/lib/tempmail_sdk/providers/nullmail.rb +95 -0
  22. data/lib/tempmail_sdk/providers/shadowmail.rb +174 -0
  23. data/lib/tempmail_sdk/providers/shitpost_email.rb +85 -0
  24. data/lib/tempmail_sdk/providers/smails.rb +128 -0
  25. data/lib/tempmail_sdk/providers/temp_mail_gg.rb +362 -0
  26. data/lib/tempmail_sdk/providers/tempmail100.rb +148 -0
  27. data/lib/tempmail_sdk/providers/tempmail_ee.rb +373 -0
  28. data/lib/tempmail_sdk/providers/tempmailportal.rb +131 -0
  29. data/lib/tempmail_sdk/providers/tempmails_io.rb +89 -0
  30. data/lib/tempmail_sdk/providers/tempmailto.rb +312 -0
  31. data/lib/tempmail_sdk/providers/temporarymail_com.rb +184 -0
  32. data/lib/tempmail_sdk/providers/tenmin_app.rb +100 -0
  33. data/lib/tempmail_sdk/providers/thirty_min_email.rb +90 -0
  34. data/lib/tempmail_sdk/providers/tmpkit.rb +129 -0
  35. data/lib/tempmail_sdk/providers/zerodrop.rb +90 -0
  36. data/lib/tempmail_sdk/registry.rb +223 -107
  37. data/lib/tempmail_sdk/types.rb +13 -0
  38. data/lib/tempmail_sdk/version.rb +1 -1
  39. data/lib/tempmail_sdk.rb +1 -1
  40. metadata +31 -7
  41. data/lib/tempmail_sdk/providers/gonebox_email.rb +0 -89
  42. data/lib/tempmail_sdk/providers/mohmal.rb +0 -208
  43. data/lib/tempmail_sdk/providers/temp_mail_now.rb +0 -103
  44. data/lib/tempmail_sdk/providers/webmailtemp.rb +0 -108
@@ -0,0 +1,129 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+
5
+ module TempmailSdk
6
+ module Providers
7
+ # Tmpkit 渠道实现(tmpkit.com,Next.js tRPC 前端 + Go-Guerrilla SMTP 后端)
8
+ #
9
+ # 流程:
10
+ # POST /api/rpc/tempmail/initSession(body 为 tRPC 包裹 {"json":{}})建箱,
11
+ # 响应 session.sessionId 与 session.email(sessionId 同值 Set-Cookie)
12
+ # POST /api/rpc/tempmail/getEmails({"json":{"offset":0,"limit":20}} +
13
+ # Cookie tempmail_session=<sessionId>)列信(列表键 mailId,无 id)
14
+ # POST /api/rpc/tempmail/getEmailDetail({"json":{"mailId":<数字>}})取正文
15
+ # 会话粘性:token 保存 sessionId(tempMailSession=<sid>),读信显式携带
16
+ # Cookie 请求头,防并行会话串箱。
17
+ module Tmpkit
18
+ CHANNEL = "tmpkit"
19
+ BASE_URL = "https://tmpkit.com"
20
+ RPC_PREFIX = "#{BASE_URL}/api/rpc/tempmail"
21
+
22
+ USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 " \
23
+ "(KHTML, like Gecko) Chrome/154.0.0.0 Safari/537.36"
24
+
25
+ module_function
26
+
27
+ # tRPC 调用请求头(Content-Type JSON、Accept 通配、同站 Origin/Referer)
28
+ # @param cookie [String] sessionId,非空时携带 tempmail_session Cookie
29
+ # @return [Hash]
30
+ def rpc_headers(cookie = "")
31
+ hdrs = {
32
+ "User-Agent" => USER_AGENT,
33
+ "Accept" => "*/*",
34
+ "Content-Type" => "application/json",
35
+ "Origin" => BASE_URL,
36
+ "Referer" => "#{BASE_URL}/en"
37
+ }
38
+ hdrs["Cookie"] = "tempmail_session=#{cookie}" unless cookie.empty?
39
+ hdrs
40
+ end
41
+
42
+ # 对 tmpkit 发起 rpc 调用(tRPC 包裹 {"json":<reqBody>})
43
+ # 响应外层 {"json":{...}} 解析为 Hash 返回。
44
+ # @param procedure [String] rpc 过程名
45
+ # @param req_body [Hash] 过程参数
46
+ # @param cookie [String] sessionId
47
+ # @return [Hash]
48
+ def rpc(procedure, req_body, cookie = "")
49
+ resp = Http.post("#{RPC_PREFIX}/#{procedure}",
50
+ headers: rpc_headers(cookie),
51
+ body: JSON.generate({ json: req_body }),
52
+ timeout: 15)
53
+ resp.raise_for_status
54
+ outer = resp.json
55
+ payload = outer.is_a?(Hash) ? outer["json"] : nil
56
+ raise "tmpkit: #{procedure} 响应缺 json 载荷" unless payload.is_a?(Hash)
57
+
58
+ payload
59
+ end
60
+
61
+ # 创建 tmpkit.com 临时邮箱
62
+ # 调 initSession(tRPC 包裹 {"json":{}}),sessionId 与邮箱地址同返。
63
+ # @return [EmailInfo]
64
+ def generate_email
65
+ data = rpc("initSession", {})
66
+ sess = data["session"]
67
+ raise "tmpkit: 创建会话响应缺 session 字段" unless sess.is_a?(Hash)
68
+
69
+ email = sess["email"].to_s.strip
70
+ session_id = sess["sessionId"].to_s.strip
71
+ raise "tmpkit: 创建会话响应缺少必要字段(email/sessionId)" if email.empty? || session_id.empty? || !email.include?("@")
72
+
73
+ EmailInfo.new(channel: CHANNEL, email: email,
74
+ token: "tempMailSession=#{session_id}")
75
+ end
76
+
77
+ # 获取 tmpkit.com 邮件列表
78
+ # getEmails(offset 0 / limit 20)取摘要,逐封 getEmailDetail 拉详情并
79
+ # 将详情键并入摘要;详情失败回退列表摘要。getEmails 返回的 session.email
80
+ # 与收信邮箱不符时报错,防止会话被覆盖。
81
+ # @param email [String] 邮箱地址
82
+ # @param token [String] 会话凭据串(tempMailSession=<sessionId>)
83
+ # @return [Array<Email>]
84
+ def get_emails(email, token)
85
+ raw = token.to_s.strip
86
+ mailbox = raw.start_with?("tempMailSession=") ? raw.delete_prefix("tempMailSession=") : raw
87
+ raise "tmpkit: 会话 token 为空" if mailbox.empty?
88
+
89
+ data = rpc("getEmails", { offset: 0, limit: 20 }, mailbox)
90
+
91
+ # 会话指向校验:getEmails 响应自带 session.email(无 Cookie 时
92
+ # session 为 null,同样视为会话失效)
93
+ sess = data["session"]
94
+ if sess.is_a?(Hash)
95
+ got = sess["email"].to_s.strip
96
+ raise "tmpkit: 会话邮箱不匹配(响应 #{got},请求 #{email})" if !got.empty? && got != email
97
+ else
98
+ raise "tmpkit: 会话已失效(getEmails 返回空会话)"
99
+ end
100
+
101
+ list = data["emails"]
102
+ raise "tmpkit: 邮件列表响应缺 emails 字段" unless list.is_a?(Array)
103
+
104
+ list.map do |item|
105
+ next unless item.is_a?(Hash)
106
+
107
+ m = item.dup
108
+ # mailId 为数字:合法时逐封拉详情(详情键并入摘要,跳过会话类键)
109
+ mail_id = m["mailId"]
110
+ if mail_id.is_a?(Numeric) && mail_id.positive?
111
+ begin
112
+ detail = rpc("getEmailDetail", { mailId: mail_id.to_i }, mailbox)
113
+ if detail.is_a?(Hash)
114
+ detail.each do |k, v|
115
+ next if %w[session emails total error].include?(k)
116
+
117
+ m[k] = v
118
+ end
119
+ end
120
+ rescue StandardError
121
+ # 详情失败回退列表摘要
122
+ end
123
+ end
124
+ Normalize.normalize_email(m, email)
125
+ end.compact
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "uri"
4
+
5
+ module TempmailSdk
6
+ module Providers
7
+ # Zerodrop 渠道实现(zerodrop.dev)
8
+ #
9
+ # 无认证 REST:建箱无需请求,本地生成 "sdk"+8 位随机名,地址为 <名>@zerodrop-sandbox.online;
10
+ # 读信 GET /api/inbox/{name}?source=sdk,响应形如 {"emails":[...],"count":N}。
11
+ # 平台邮件对象只有 id/from/to/subject/receivedAt/raw/otp/magicLink,正文仅存在于
12
+ # raw(完整 MIME 原文),需剥离头部提取纯文本 body。
13
+ module Zerodrop
14
+ CHANNEL = "zerodrop"
15
+ BASE_URL = "https://zerodrop.dev"
16
+ DOMAIN = "zerodrop-sandbox.online"
17
+
18
+ HEADERS = {
19
+ "Accept" => "application/json",
20
+ "User-Agent" => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " \
21
+ "(KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36 Edg/146.0.0.0"
22
+ }.freeze
23
+
24
+ module_function
25
+
26
+ # 生成 "sdk"+8 位 [a-z0-9] 随机本地名
27
+ CHARS = ("a".."z").to_a + ("0".."9").to_a
28
+ def random_name
29
+ "sdk" + Array.new(8) { CHARS.sample }.join
30
+ end
31
+
32
+ # 从 raw(完整 MIME 原文)提取纯文本正文:
33
+ # 定位首个空行(RFC 5322 头部/正文分隔,\r\n\r\n 或 \n\n),其后部分即 body
34
+ # @param raw [String] MIME 原文
35
+ # @return [String]
36
+ def raw_body(raw)
37
+ idx = raw.index("\r\n\r\n")
38
+ return raw[(idx + 4)..] if idx
39
+
40
+ idx = raw.index("\n\n")
41
+ return raw[(idx + 2)..] if idx
42
+
43
+ ""
44
+ end
45
+
46
+ # 创建临时邮箱
47
+ # 建箱无需请求,本地生成随机名,token 复用完整地址以便收件箱回查
48
+ # @return [EmailInfo]
49
+ def generate_email
50
+ email = "#{random_name}@#{DOMAIN}"
51
+ EmailInfo.new(channel: CHANNEL, email: email, token: email)
52
+ end
53
+
54
+ # 读取收件箱
55
+ # GET /api/inbox/{name}?source=sdk
56
+ # @param email [String] 邮箱地址
57
+ # @param _token [String] 令牌(本渠道忽略,以邮箱为准)
58
+ # @return [Array<Email>]
59
+ def get_emails(email, _token)
60
+ addr = email.to_s.strip
61
+ parts = addr.split("@", 2)
62
+ raise "zerodrop: 非 #{DOMAIN} 域邮箱地址" unless parts.size == 2 && parts[1] == DOMAIN
63
+
64
+ url = "#{BASE_URL}/api/inbox/#{URI.encode_www_form_component(parts[0])}?source=sdk"
65
+ resp = Http.get(url, headers: HEADERS, timeout: 15)
66
+ resp.raise_for_status
67
+ data = resp.json
68
+ emails = data.is_a?(Hash) ? data["emails"] : nil
69
+ return [] unless emails.is_a?(Array)
70
+
71
+ emails.filter_map do |m|
72
+ next unless m.is_a?(Hash)
73
+
74
+ row = {
75
+ "id" => m["id"],
76
+ "from" => m["from"],
77
+ "to" => addr,
78
+ "subject" => m["subject"],
79
+ "date" => m["receivedAt"] || m["date"]
80
+ }
81
+ # 正文仅存在于 raw(完整 MIME 原文):提取纯文本 body 作 text
82
+ raw = m["raw"].to_s
83
+ body = raw_body(raw)
84
+ row["text"] = body unless body.empty?
85
+ Normalize.normalize_email(row, addr)
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end