mailtea 0.3.0 → 0.4.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 98e959c77cb6dc2c7b99cff06807b2c18052d6147bd03ec4b8256f89c88859e9
4
- data.tar.gz: 814086291d3c3937eb1cadeae73500add856b67f4f28ea1105a3ddceb4fceb9b
3
+ metadata.gz: d690859b9a966c7c3446b88a8ad18eaa3c403af32137d7e15e8aab72294cd79e
4
+ data.tar.gz: 9227bf62c989dce0a000d90433eb769d2762ba515614bbe037bb1b2cfbc4d0df
5
5
  SHA512:
6
- metadata.gz: b0cc04ddef836710cfc8690c8c4fee4fc400e04603be449d491024eaeac2a5c3b4558d31fd32bd8e509d4ec7e5c07cc1f48160d75b995fb45fca7514c217e807
7
- data.tar.gz: 2fa9199a5dded8c0b80024fe49fe54d82c1bb037cf96fe15d02f4c4ff20ed6d7e2b1064a167c1eaf83c9d83fce065e1e0c047e7602977ec9eff15029df1dac83
6
+ metadata.gz: 407fd01f8e7850bb13e4042955f4bdde236190f61a431718d3a76276218e92564bb1ee882bbbaca096c0239b72f60e1b4eb986c7b18111827a2822e1a3b75e1e
7
+ data.tar.gz: 5fb8f59e24537373bb3756257954c859cef61043cc3dd54478fe15720a53d77002a01898ba8867891d28454c7f8fa01620cbbf415209c667f80ea7d9b1c9a92e
data/CHANGELOG.md CHANGED
@@ -2,6 +2,21 @@
2
2
 
3
3
  All notable changes to the `mailtea` Ruby gem are documented here.
4
4
 
5
+ ## 0.4.0 (2026-09-15)
6
+
7
+ - Added: test mode. `mailtea.api_keys.create(name: "CI", mode: "test")` mints a
8
+ test key (prefixed `mt_test_`) whose sends are validated, recorded and
9
+ webhook-emitting but never delivered, so CI can run against production Mailtea
10
+ with your real code and your real webhook handler. A test key is **not** a
11
+ data sandbox — it reads and writes your real contacts, templates, senders and
12
+ webhooks. Only delivery is simulated.
13
+ - Added: `mailtea.emails.list(mode: "test")` reads test-mode mail, and every
14
+ email carries `mode`. There is no mixed view: a test key reads only test
15
+ emails and a live key only live ones.
16
+ - Reserved recipients on `test.mailtea.email` force an outcome: `delivered@`,
17
+ `bounced@`, `complained@`, `delayed@`, `failed@`. The first `to` recipient
18
+ decides; anything else is delivered.
19
+
5
20
  ## 0.3.0 (2026-09-10)
6
21
 
7
22
  - Added: `mailtea.domains.update(id, tracking_subdomain: nil)` removes a
data/README.md CHANGED
@@ -118,7 +118,7 @@ mailtea = Mailtea::Client.new(ENV["MAILTEA_API_KEY"], transport: recorder)
118
118
  | `emails.send(params)` | Send a transactional email → `{ "id" => … }` |
119
119
  | `emails.batch(emails)` | Send up to 100 emails → `{ "data" => [{ "id" => … }] }` |
120
120
  | `emails.get(id)` | Retrieve an email and its delivery status |
121
- | `emails.list(params = nil)` | List emails → `{ "data", "total", "limit", "offset", "has_more" }` |
121
+ | `emails.list(params = nil)` | List emails → `{ "data", "total", "limit", "offset", "has_more" }`. Pass `mode: "test"` for test-mode mail |
122
122
  | `emails.update(id, params)` | Reschedule a scheduled email |
123
123
  | `emails.reschedule(id, scheduled_at)` | Convenience wrapper over `update` |
124
124
  | `emails.cancel(id)` | Cancel a scheduled email (`POST /v1/emails/:id/cancel`) |
@@ -147,7 +147,7 @@ mailtea = Mailtea::Client.new(ENV["MAILTEA_API_KEY"], transport: recorder)
147
147
  | `domains.tracking.create / list / verify / delete` | Manage CNAME tracking sub-domains under a domain |
148
148
  | `webhooks.create / list / get / update / delete` | Manage outbound event subscriptions |
149
149
  | `contact_properties.create / list / update / delete` | Manage custom contact fields (team-scoped) |
150
- | `api_keys.create / list / revoke` | Manage API keys (`settings:write`) |
150
+ | `api_keys.create / list / revoke` | Manage API keys (`settings:write`). `create(mode: "test")` mints a test key |
151
151
  | `automations.create / list / get / update / delete` | Manage automation graphs (`steps` + optional `connections`) |
152
152
  | `automations.validate(params)` | Dry-run a graph → `{ "valid", "issues" }` (no automation needed) |
153
153
  | `automations.activate / pause / archive` | Lifecycle (`cancel_runs` defaults **false** on pause, **true** on archive) |
@@ -167,6 +167,35 @@ take none.
167
167
  on their resource object, because the API's verb is "send". Ruby's `__send__`
168
168
  is untouched, so metaprogramming still works.
169
169
 
170
+ ## Test mode
171
+
172
+ A test key (`mt_test_…`) sends nothing. Every message it creates is validated,
173
+ recorded and emits webhooks, but is never handed to a provider — so CI can point
174
+ at production Mailtea with your real code and your real webhook handler.
175
+
176
+ ```ruby
177
+ key = mailtea.api_keys.create(name: "CI", mode: "test")
178
+ # key["token"] starts with mt_test_
179
+
180
+ test = Mailtea::Client.new(key["token"])
181
+ test.emails.send(
182
+ from: "you@yourdomain.com",
183
+ to: "bounced@test.mailtea.email",
184
+ subject: "Bounce handling",
185
+ html: "<p>Never delivered.</p>"
186
+ )
187
+
188
+ page = test.emails.list(mode: "test")
189
+ ```
190
+
191
+ Reserved recipients on `test.mailtea.email` force the outcome — `delivered@`,
192
+ `bounced@`, `complained@`, `delayed@`, `failed@` — and the first `to` recipient
193
+ decides. Every email carries `mode`. A test key reads only test mail and a live
194
+ key only live mail; there is no mixed view.
195
+
196
+ A test key is **not** a data sandbox. It reads and writes your real contacts,
197
+ templates, senders and webhooks. Only delivery is simulated.
198
+
170
199
  ## Webhooks
171
200
 
172
201
  Mailtea signs every outbound webhook with
@@ -11,7 +11,13 @@ module Mailtea
11
11
  # Create an API key. The +token+ is returned ONCE — store it securely.
12
12
  #
13
13
  # Takes +name+, optional +permission+ ("full_access" or "sending_access"),
14
- # and optional +domain_id+.
14
+ # optional +domain_id+, and optional +mode+.
15
+ #
16
+ # +mode+ is "live" (the default) or "test". A test key is prefixed
17
+ # <tt>mt_test_</tt>: its sends are validated, recorded and emit webhooks but
18
+ # are never delivered, and it reads only test mail. It is NOT a data sandbox
19
+ # — it reads and writes your real contacts, templates, senders and webhooks.
20
+ # Only delivery is simulated.
15
21
  def create(params = nil, **fields)
16
22
  request("POST", "/v1/api-keys", payload(params, fields))
17
23
  end
@@ -90,9 +90,15 @@ module Mailtea
90
90
  email
91
91
  end
92
92
 
93
- # List emails (most recent first). Optional filters: +status+, +tag_name+,
94
- # +tag_value+, +search+ (substring match on recipient/sender/subject),
95
- # +from_date+, +to_date+, +limit+, +offset+.
93
+ # List emails (most recent first). Optional filters: +status+, +mode+,
94
+ # +tag_name+, +tag_value+, +search+ (substring match on
95
+ # recipient/sender/subject), +from_date+, +to_date+, +limit+, +offset+.
96
+ #
97
+ # +mode+ is "live" or "test" — there is no mixed view. A test key reads only
98
+ # test mail and a live key only live mail, so this filter matters to a
99
+ # session-backed credential; asking for the mode your key is not in is an
100
+ # error rather than an empty list. Every returned email carries its own
101
+ # +mode+.
96
102
  #
97
103
  # +from_date+ is clamped to the plan's analytics retention window — 30 days
98
104
  # on most plans, 90 on Scale and Enterprise. A value reaching further back
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mailtea
4
- VERSION = "0.3.0"
4
+ VERSION = "0.4.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mailtea
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mailtea
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-09-10 00:00:00.000000000 Z
11
+ date: 2026-09-15 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: 'The official Ruby SDK for Mailtea: a thin, zero-dependency wrapper over
14
14
  the Mailtea REST API, built on net/http and json.'