Module: TempmailSdk::Providers::Mailinator
- Defined in:
- lib/tempmail_sdk/providers/mailinator.rb
Overview
Mailinator 渠道实现 -- https://mailinator.com
匿名公共信箱:邮箱本地部分即为信箱名,收信统一走 mailinator.com 的 public 域名 REST API。众多姊妹域名(如 blackhole.djurby.se、sink.fblay.com 等)本质是同一公共信箱的别名, 仅生成邮箱时域名不同,取信逻辑完全一致。
Constant Summary collapse
- CHANNEL =
"mailinator"- BASE_URL =
"https://mailinator.com"- PUBLIC_DOMAIN =
收信统一使用的公共域名标识
"public"- DEFAULT_DOMAIN =
默认生成邮箱所用域名
"mailinator.com"- HEADERS =
{ "Accept" => "application/json", "Accept-Language" => "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6", "Cache-Control" => "no-cache", "Pragma" => "no-cache", "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 Edg/146.0.0.0" }.freeze
Class Method Summary collapse
-
.attachment_url(value) ⇒ Object
补全附件下载 URL(相对路径补上 BASE_URL).
-
.build_attachments(att_payload) ⇒ Object
展平附件列表.
-
.first_non_empty(*values) ⇒ Object
返回首个非空字符串.
-
.flatten_message(summary, recipient_email, text_payload, html_payload, att_payload) ⇒ Object
将邮件摘要与正文/附件展平为 normalize 可识别的字段.
-
.generate_email(domain = nil, channel = CHANNEL) ⇒ EmailInfo
生成临时邮箱.
-
.get_emails(token, email = "") ⇒ Array<Email>
拉取邮件列表并逐封获取正文/附件.
-
.message_path(message_id, suffix) ⇒ Object
拼接单封邮件某子资源的 URL.
-
.parse_messages(data) ⇒ Object
从响应中解析消息数组(兼容顶层数组或 msgs/data 字段).
-
.random_string(length) ⇒ Object
生成随机本地部分:length 位小写字母数字.
-
.request_json(url) ⇒ Object
发起 GET 并解析 JSON,失败返回 nil;非 Hash 结果包裹为 { "data" => ... }.
-
.text_from_payload(payload, key) ⇒ Object
从 payload 中取指定 content-type 的文本.
-
.to_iso_time(value) ⇒ Object
将时间值统一为 ISO 8601(毫秒/秒时间戳或字符串).
Class Method Details
.attachment_url(value) ⇒ Object
补全附件下载 URL(相对路径补上 BASE_URL)
113 114 115 116 117 118 |
# File 'lib/tempmail_sdk/providers/mailinator.rb', line 113 def (value) return "" unless value.is_a?(String) && !value.empty? return value if value.start_with?("http://", "https://") "#{BASE_URL}#{value}" end |
.build_attachments(att_payload) ⇒ Object
展平附件列表
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/tempmail_sdk/providers/mailinator.rb', line 153 def (att_payload) list = att_payload.is_a?(Hash) ? att_payload["attachments"] : nil return [] unless list.is_a?(Array) list.filter_map do |att| next unless att.is_a?(Hash) { "filename" => att["name"] || att["filename"] || "", "size" => att["size"] || att["filesize"], "contentType" => att["contentType"] || att["content_type"] || att["mimeType"] || att["mime_type"], "url" => (att["downloadUrl"] || att["url"]) } end end |
.first_non_empty(*values) ⇒ Object
返回首个非空字符串
171 172 173 174 175 176 177 178 179 |
# File 'lib/tempmail_sdk/providers/mailinator.rb', line 171 def first_non_empty(*values) values.each do |v| next if v.nil? t = v.to_s return t unless t.empty? end "" end |
.flatten_message(summary, recipient_email, text_payload, html_payload, att_payload) ⇒ Object
将邮件摘要与正文/附件展平为 normalize 可识别的字段
138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/tempmail_sdk/providers/mailinator.rb', line 138 def (summary, recipient_email, text_payload, html_payload, att_payload) { "id" => (summary["id"] || summary["messageId"] || "").to_s, "from" => first_non_empty(summary["from"], summary["origfrom"]), "to" => summary["to"] || recipient_email, "subject" => summary["subject"] || "", "text" => text_from_payload(text_payload, "text/plain"), "html" => text_from_payload(html_payload, "text/html"), "date" => to_iso_time(summary["time"] || summary["date"]), "seen" => false, "attachments" => (att_payload) } end |
.generate_email(domain = nil, channel = CHANNEL) ⇒ EmailInfo
生成临时邮箱
42 43 44 45 46 |
# File 'lib/tempmail_sdk/providers/mailinator.rb', line 42 def generate_email(domain = nil, channel = CHANNEL) dom = domain.to_s.strip dom = DEFAULT_DOMAIN if dom.empty? EmailInfo.new(channel: channel, email: "#{random_string(12)}@#{dom}") end |
.get_emails(token, email = "") ⇒ Array<Email>
拉取邮件列表并逐封获取正文/附件
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/tempmail_sdk/providers/mailinator.rb', line 52 def get_emails(token, email = "") _ = token inbox = email.to_s.strip inbox = inbox.split("@", 2).first.to_s if inbox.include?("@") return [] if inbox.empty? data = request_json("#{BASE_URL}/api/v2/domains/#{PUBLIC_DOMAIN}/inboxes/#{inbox}") = (data) return [] if .empty? .map do |msg| = (msg["id"] || msg["messageId"]).to_s.strip text_payload = .empty? ? nil : request_json((, "text")) html_payload = .empty? ? nil : request_json((, "texthtml")) att_payload = .empty? ? nil : request_json((, "attachments")) Normalize.normalize_email( (msg, email, text_payload, html_payload, att_payload), email ) end end |
.message_path(message_id, suffix) ⇒ Object
拼接单封邮件某子资源的 URL
74 75 76 |
# File 'lib/tempmail_sdk/providers/mailinator.rb', line 74 def (, suffix) "#{BASE_URL}/api/v2/domains/#{PUBLIC_DOMAIN}/messages/#{}/#{suffix}" end |
.parse_messages(data) ⇒ Object
从响应中解析消息数组(兼容顶层数组或 msgs/data 字段)
90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/tempmail_sdk/providers/mailinator.rb', line 90 def (data) return data.select { |item| item.is_a?(Hash) } if data.is_a?(Array) if data.is_a?(Hash) %w[msgs data].each do |key| value = data[key] return value.select { |item| item.is_a?(Hash) } if value.is_a?(Array) end end [] end |
.random_string(length) ⇒ Object
生成随机本地部分:length 位小写字母数字
33 34 35 36 |
# File 'lib/tempmail_sdk/providers/mailinator.rb', line 33 def random_string(length) chars = ("a".."z").to_a + ("0".."9").to_a Array.new(length) { chars.sample }.join end |
.request_json(url) ⇒ Object
发起 GET 并解析 JSON,失败返回 nil;非 Hash 结果包裹为 { "data" => ... }
79 80 81 82 83 84 85 86 87 |
# File 'lib/tempmail_sdk/providers/mailinator.rb', line 79 def request_json(url) resp = Http.get(url, headers: HEADERS, timeout: 15) return nil unless resp.ok? data = resp.json data.is_a?(Hash) ? data : { "data" => data } rescue StandardError nil end |
.text_from_payload(payload, key) ⇒ Object
从 payload 中取指定 content-type 的文本
103 104 105 106 107 108 109 110 |
# File 'lib/tempmail_sdk/providers/mailinator.rb', line 103 def text_from_payload(payload, key) return "" unless payload.is_a?(Hash) value = payload[key] return "" if value.nil? value.is_a?(String) ? value : value.to_s end |
.to_iso_time(value) ⇒ Object
将时间值统一为 ISO 8601(毫秒/秒时间戳或字符串)
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/tempmail_sdk/providers/mailinator.rb', line 121 def to_iso_time(value) return "" if value.nil? || value == "" if value.is_a?(Numeric) millis = value > 1e12 ? value : value * 1000 return Time.at(millis / 1000.0).utc.iso8601 end text = value.to_s begin Time.iso8601(text.sub(/Z\z/, "+00:00")).utc.iso8601 rescue ArgumentError text end end |