mailtea 0.3.0 → 0.5.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 +4 -4
- data/CHANGELOG.md +92 -0
- data/README.md +32 -3
- data/lib/mailtea/api_keys.rb +7 -1
- data/lib/mailtea/automations.rb +8 -2
- data/lib/mailtea/emails.rb +9 -3
- data/lib/mailtea/posts.rb +13 -4
- data/lib/mailtea/templates.rb +34 -16
- data/lib/mailtea/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3539cea90528dd0db53f91ddaf0897c093ce83f6ec75ccac90666ba24fb6dcd9
|
|
4
|
+
data.tar.gz: e1f33edadd5e115d42f3d3294d589034d76bb29e870dbe5c952c06fc11fab42e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: abc137144ae2f95a8a881005409eeff50142404f8b9ba35043482f2780d80c4e2e887263c1953c16b79f39bbd3ec364c484e8cd95c0541978c1d3746a3878c56
|
|
7
|
+
data.tar.gz: 56f72ee40bb049f99e4d95fc58c78539fa6da22109b25d6bbf7c6af87a08fa9109e7cb33f3bd72a787e6559067f5db97f6382ab00372b9b42ae8866e1db16b14
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,98 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to the `mailtea` Ruby gem are documented here.
|
|
4
4
|
|
|
5
|
+
## 0.5.0 (2026-09-28)
|
|
6
|
+
|
|
7
|
+
- Breaking: `Posts#create` with `template_id` now HTML-escapes the `variables`
|
|
8
|
+
you pass, the same as every other send. HTML passed in a `{{key}}` value now
|
|
9
|
+
arrives as visible text, and a value you escaped yourself arrives
|
|
10
|
+
double-escaped. Put `{{{key}}}` in the template where a value is meant to be
|
|
11
|
+
raw HTML. Variables are now filled in both the `{{key}}` and Visual Email
|
|
12
|
+
Designer `{key}` forms. A declared variable you do not pass stays in the
|
|
13
|
+
post with its `fallback_value`, so the broadcast gives each recipient their
|
|
14
|
+
own value or that fallback, and undeclared tokens like
|
|
15
|
+
`{{contact.first_name}}` are left for the broadcast too. The post keeps the
|
|
16
|
+
template's published page style, is wrapped in that page, and has its
|
|
17
|
+
show-if blocks decided per recipient when it is sent. Before, only the
|
|
18
|
+
variables you passed were replaced, raw, and only in `{{key}}` form. It uses
|
|
19
|
+
the template's published version; Mailtea Studio's "Use template" starts
|
|
20
|
+
from the latest saved design instead.
|
|
21
|
+
- Changed: `Templates#update` and `Templates#restore_version` no longer move a
|
|
22
|
+
published template back to draft. The template keeps its published status,
|
|
23
|
+
and automations and the API keep sending its published version until
|
|
24
|
+
`Templates#publish` is called again. The template's `from` and `reply_to`
|
|
25
|
+
are part of the published version too, so a new sender or reply-to address
|
|
26
|
+
reaches sends only after the next publish. `Templates#unpublish` is now the
|
|
27
|
+
only way to stop a published template sending, short of deleting it, and it
|
|
28
|
+
drops the stored published version so the next publish starts from the
|
|
29
|
+
current content.
|
|
30
|
+
- Added: `has_unpublished_versions` on every returned template hash. True only
|
|
31
|
+
when the template is published and its saved content (From, Reply-To and the style profile
|
|
32
|
+
included) differs from the published version.
|
|
33
|
+
- Added: `is_published` on each template version entry: true for the one entry
|
|
34
|
+
automations and the API are sending now. `is_current` is now described as
|
|
35
|
+
what it is: the entry that matches the working copy (the saved design being
|
|
36
|
+
edited), not necessarily what is sending. `is_published` is false on every
|
|
37
|
+
entry of a draft, and on a template published before the field existed until
|
|
38
|
+
it is published again.
|
|
39
|
+
- Changed: the `unpublished` key on the update and restore replies is kept for
|
|
40
|
+
compatibility and is now always `false`. Check `has_unpublished_versions`
|
|
41
|
+
(or the reply's `message`) instead.
|
|
42
|
+
- Changed (API behavior): a template variable's `fallback_value` can no longer
|
|
43
|
+
contain `{` or `}`. Creating a template with one, or changing a fallback
|
|
44
|
+
to one on update, is a 400 ("Fallbacks can't contain { or }."). A value
|
|
45
|
+
the template already stores is accepted unchanged, so a template saved
|
|
46
|
+
before the rule keeps saving. Inline chip fallbacks such as
|
|
47
|
+
`{first_name|Mom & Pop}` now render as written instead of double-escaped.
|
|
48
|
+
- Changed (API behavior): saving an active automation is refused only when the
|
|
49
|
+
edit adds an error the live version does not already have. The 422
|
|
50
|
+
`active_graph_invalid` reply's `issues` lists just those new problems.
|
|
51
|
+
Before, any error refused the save, even one the live version already had.
|
|
52
|
+
Starting refuses every error as before, except an `unknown_step_ref` at a
|
|
53
|
+
`config.*` path or a trigger `missing_branch` that the version the
|
|
54
|
+
automation last ran on already had, so pausing and starting an unchanged
|
|
55
|
+
automation keeps working. Issues the last live version already had come back
|
|
56
|
+
with `pre_existing: true`.
|
|
57
|
+
- Added (API behavior): issue objects carry `field`, what a rule reads (the
|
|
58
|
+
rule's `field`, or the path in a `{"var": ...}` value, e.g.
|
|
59
|
+
`steps.welcome.opened`) when the issue is about one.
|
|
60
|
+
- Changed (API behavior): two issues are the same problem when their code and
|
|
61
|
+
step match, and their `field` or, when there is none, their `path`. Moving
|
|
62
|
+
a rule, by removing a rule beside it or putting it in a group, no longer
|
|
63
|
+
makes a problem the live version already had look new. An error is
|
|
64
|
+
`pre_existing` only if the live version had an error there, not a warning.
|
|
65
|
+
- Changed (API behavior): `validate_only` on an active automation answers the
|
|
66
|
+
way the save would. A trigger change is a 422 `trigger_locked_while_active`,
|
|
67
|
+
a change that adds a problem is a 422 `active_graph_invalid` listing only
|
|
68
|
+
the new problems, and otherwise issues come back with `pre_existing` marked
|
|
69
|
+
against the version live now. Before, it returned every issue unmarked.
|
|
70
|
+
- Changed (API behavior): changing the trigger (its type or key) of an active
|
|
71
|
+
automation is now refused with 422 `trigger_locked_while_active`. Pause it
|
|
72
|
+
first; draft and paused automations can still change their trigger. Before,
|
|
73
|
+
the change was accepted.
|
|
74
|
+
- Added (API behavior): new validation rules. A trigger with nothing after it
|
|
75
|
+
is a `missing_branch` error at `branches.next`. A rule or `{"var": ...}`
|
|
76
|
+
value that reads `steps.<key>.*` for a step that isn't in the automation is
|
|
77
|
+
an `unknown_step_ref` error at that `config.*` path, or a warning when the
|
|
78
|
+
`{"var": ...}` has a `default`. A rule or value that reads
|
|
79
|
+
`event.properties.*` when the automation does not start from an app event is
|
|
80
|
+
the new warning `event_field_without_event_trigger`.
|
|
81
|
+
|
|
82
|
+
## 0.4.0 (2026-09-15)
|
|
83
|
+
|
|
84
|
+
- Added: test mode. `mailtea.api_keys.create(name: "CI", mode: "test")` mints a
|
|
85
|
+
test key (prefixed `mt_test_`) whose sends are validated, recorded and
|
|
86
|
+
webhook-emitting but never delivered, so CI can run against production Mailtea
|
|
87
|
+
with your real code and your real webhook handler. A test key is **not** a
|
|
88
|
+
data sandbox — it reads and writes your real contacts, templates, senders and
|
|
89
|
+
webhooks. Only delivery is simulated.
|
|
90
|
+
- Added: `mailtea.emails.list(mode: "test")` reads test-mode mail, and every
|
|
91
|
+
email carries `mode`. There is no mixed view: a test key reads only test
|
|
92
|
+
emails and a live key only live ones.
|
|
93
|
+
- Reserved recipients on `test.mailtea.email` force an outcome: `delivered@`,
|
|
94
|
+
`bounced@`, `complained@`, `delayed@`, `failed@`. The first `to` recipient
|
|
95
|
+
decides; anything else is delivered.
|
|
96
|
+
|
|
5
97
|
## 0.3.0 (2026-09-10)
|
|
6
98
|
|
|
7
99
|
- 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`) |
|
|
@@ -139,7 +139,7 @@ mailtea = Mailtea::Client.new(ENV["MAILTEA_API_KEY"], transport: recorder)
|
|
|
139
139
|
| `templates.create / list / get / update / publish / unpublish / duplicate / delete` | Manage reusable email templates |
|
|
140
140
|
| `templates.render(params)` | Render a spec to HTML without saving → `{ "html", "text" }` |
|
|
141
141
|
| `templates.versions(id, params = nil)` | List a template's design history, newest first (metadata only) |
|
|
142
|
-
| `templates.restore_version(id, version, params = nil)` | Put an older design back
|
|
142
|
+
| `templates.restore_version(id, version, params = nil)` | Put an older design back as unpublished changes; a published template keeps sending its published version until you `publish` again |
|
|
143
143
|
| `assets.upload / list / delete` | The publication's image library (raw bytes are base64-encoded for you) |
|
|
144
144
|
| `suppressions.list / add / remove` | Manage the team-wide do-not-send list |
|
|
145
145
|
| `suppressions.export` | Export the whole suppression list as CSV (raw text) |
|
|
@@ -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
|
data/lib/mailtea/api_keys.rb
CHANGED
|
@@ -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 +
|
|
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
|
data/lib/mailtea/automations.rb
CHANGED
|
@@ -59,7 +59,11 @@ module Mailtea
|
|
|
59
59
|
#
|
|
60
60
|
# <tt>validate_only: true</tt> returns an +automation_validation+ and writes
|
|
61
61
|
# nothing. A graph change that carries errors saves anyway while the
|
|
62
|
-
# automation is draft/paused/archived
|
|
62
|
+
# automation is draft/paused/archived. On an +active+ one it is a 422
|
|
63
|
+
# +active_graph_invalid+ only when it adds an error the live version does
|
|
64
|
+
# not already have; +issues+ then lists just those new problems, and older
|
|
65
|
+
# ones come back with <tt>pre_existing: true</tt>. Changing an +active+
|
|
66
|
+
# automation's trigger is a 422 +trigger_locked_while_active+. Either way:
|
|
63
67
|
# pause, save, then start again.
|
|
64
68
|
def update(id, params = nil, **fields)
|
|
65
69
|
scope, body = Util.split_publication(payload(params, fields), keep_in_body: false)
|
|
@@ -75,7 +79,9 @@ module Mailtea
|
|
|
75
79
|
|
|
76
80
|
# Start the automation so new contacts enroll. Requires +publication_id+. A
|
|
77
81
|
# graph with errors is refused with 422 +automation_invalid+ and the
|
|
78
|
-
# blocking +issues
|
|
82
|
+
# blocking +issues+, except an +unknown_step_ref+ at a <tt>config.*</tt>
|
|
83
|
+
# path or a trigger +missing_branch+ that the version it last ran on
|
|
84
|
+
# already had (<tt>pre_existing: true</tt>).
|
|
79
85
|
def activate(id, params = nil, **filters)
|
|
80
86
|
request("POST", "/v1/automations/" + escape(id) + "/activate" + query(payload(params, filters)))
|
|
81
87
|
end
|
data/lib/mailtea/emails.rb
CHANGED
|
@@ -90,9 +90,15 @@ module Mailtea
|
|
|
90
90
|
email
|
|
91
91
|
end
|
|
92
92
|
|
|
93
|
-
# List emails (most recent first). Optional filters: +status+, +
|
|
94
|
-
# +tag_value+, +search+ (substring match on
|
|
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
|
data/lib/mailtea/posts.rb
CHANGED
|
@@ -7,10 +7,19 @@ module Mailtea
|
|
|
7
7
|
# <tt>mailtea.posts</tt>.
|
|
8
8
|
class Posts < Resource
|
|
9
9
|
# Create a newsletter post (a draft by default). Seed it from a published
|
|
10
|
-
# server template with +template_id+ + +variables+,
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
10
|
+
# server template with +template_id+ + +variables+, using the template's
|
|
11
|
+
# PUBLISHED version and not any unpublished edits saved since, or pass
|
|
12
|
+
# inline +html+. The +variables+ you pass are filled in, in both the
|
|
13
|
+
# <tt>{{key}}</tt> and Visual Email Designer <tt>{key}</tt> forms, and
|
|
14
|
+
# HTML-escaped (use <tt>{{{key}}}</tt> in the template for raw HTML).
|
|
15
|
+
# Everything else is left for the broadcast to fill per recipient: a
|
|
16
|
+
# declared variable you do not pass keeps its +fallback_value+ for
|
|
17
|
+
# recipients with no value, and undeclared tokens like
|
|
18
|
+
# <tt>{{contact.first_name}}</tt> stay as they are. The post keeps the
|
|
19
|
+
# template's published page style. +kind+ selects the post type
|
|
20
|
+
# ("newsletter" or "broadcast"). Set <tt>send: true</tt> to deliver right
|
|
21
|
+
# after creating (or with +scheduled_at+ to schedule); that requires the
|
|
22
|
+
# +issues:send+ scope.
|
|
14
23
|
#
|
|
15
24
|
# Returns <tt>{ "id" => ... }</tt>.
|
|
16
25
|
def create(params = nil, publication_id: UNSET, subject: UNSET, html: UNSET,
|
data/lib/mailtea/templates.rb
CHANGED
|
@@ -46,6 +46,13 @@ module Mailtea
|
|
|
46
46
|
# +global_css+, +category+, +preview_image_url+, +tags+, +text+, +subject+,
|
|
47
47
|
# +from+ and +reply_to+ accept +nil+ to clear them. +publication_id+ is
|
|
48
48
|
# required and goes in the query string.
|
|
49
|
+
#
|
|
50
|
+
# Editing a published template no longer unpublishes it: the change is
|
|
51
|
+
# saved as the working copy, the template keeps its published status, and
|
|
52
|
+
# the published version keeps sending until #publish is called again. The
|
|
53
|
+
# reply's +unpublished+ is kept for compatibility and is always +false+
|
|
54
|
+
# now; check +has_unpublished_versions+ on the reply instead (it also
|
|
55
|
+
# carries +message+ when that is +true+).
|
|
49
56
|
def update(id, params = nil, **fields)
|
|
50
57
|
scope, body = Util.split_publication(payload(params, fields))
|
|
51
58
|
request("PATCH", "/v1/templates/" + escape(id) + scope, body)
|
|
@@ -57,8 +64,11 @@ module Mailtea
|
|
|
57
64
|
end
|
|
58
65
|
|
|
59
66
|
# Return a published template to draft. +published_at+ is kept — it records
|
|
60
|
-
# that the template was published once, not that it still is.
|
|
61
|
-
#
|
|
67
|
+
# that the template was published once, not that it still is. This is now
|
|
68
|
+
# the only way to stop a published template sending, short of deleting it
|
|
69
|
+
# (editing or restoring it no longer does that on its own). It also drops
|
|
70
|
+
# the published version, so the next #publish starts from the current
|
|
71
|
+
# (working) content. Requires +publication_id+.
|
|
62
72
|
def unpublish(id, params = nil, **filters)
|
|
63
73
|
request("POST", "/v1/templates/" + escape(id) + "/unpublish" + query(payload(params, filters)))
|
|
64
74
|
end
|
|
@@ -66,13 +76,18 @@ module Mailtea
|
|
|
66
76
|
# List a template's design history, newest first. Requires +publication_id+;
|
|
67
77
|
# optional +limit+ (the server caps it at the retained maximum).
|
|
68
78
|
#
|
|
69
|
-
# Entries are metadata only
|
|
79
|
+
# Entries are metadata only: +version+, +origin+ ("edit", "publish" or
|
|
70
80
|
# "restore"), +restored_from_version+, +format+, +name+, +sealed+,
|
|
71
|
-
# +is_current+, +created_at+, +updated_at+ and +author+ (or
|
|
72
|
-
# design document,
|
|
73
|
-
# +is_current+ marks the
|
|
74
|
-
# not always the newest entry: a
|
|
75
|
-
# without recording a version.
|
|
81
|
+
# +is_current+, +is_published+, +created_at+, +updated_at+ and +author+ (or
|
|
82
|
+
# nil). The design document is never included, because one entry alone can
|
|
83
|
+
# carry half a megabyte of it. +is_current+ marks the entry that matches the working copy
|
|
84
|
+
# (the saved design being edited), which is not always the newest entry: a
|
|
85
|
+
# metadata-only update touches the template without recording a version.
|
|
86
|
+
# +is_published+ (a boolean) marks the entry automations and the API are
|
|
87
|
+
# sending now. They differ while a published template has unpublished
|
|
88
|
+
# changes. +is_published+ is +false+ on every entry of a draft, and on every
|
|
89
|
+
# entry of a template published before the field existed until it is
|
|
90
|
+
# published again.
|
|
76
91
|
#
|
|
77
92
|
# The reply also carries +retention+: only the newest +max_versions+ are
|
|
78
93
|
# kept, and consecutive edits by the same author within
|
|
@@ -84,10 +99,13 @@ module Mailtea
|
|
|
84
99
|
# Put an older design from #versions back onto the template. Requires
|
|
85
100
|
# +publication_id+.
|
|
86
101
|
#
|
|
87
|
-
# *Restoring
|
|
88
|
-
#
|
|
89
|
-
#
|
|
90
|
-
#
|
|
102
|
+
# *Restoring no longer unpublishes the template.* It is a content write,
|
|
103
|
+
# and lands in the working copy: a published template keeps its published
|
|
104
|
+
# status and keeps sending its published version until #publish makes the
|
|
105
|
+
# restored design live. The reply's +unpublished+ is kept for
|
|
106
|
+
# compatibility and is always +false+ now; check +has_unpublished_versions+
|
|
107
|
+
# on the returned +template+ (or the reply's +message+) to see whether the
|
|
108
|
+
# restored design is live yet.
|
|
91
109
|
#
|
|
92
110
|
# History is forward-only: the design being replaced is recorded as its own
|
|
93
111
|
# version first, then the restored design is appended as the new newest one.
|
|
@@ -96,10 +114,10 @@ module Mailtea
|
|
|
96
114
|
#
|
|
97
115
|
# Restoring the design that is already current writes nothing and returns
|
|
98
116
|
# <tt>restored: false</tt> with <tt>reason: "identical"</tt> and
|
|
99
|
-
# <tt>unpublished: false</tt
|
|
100
|
-
#
|
|
101
|
-
#
|
|
102
|
-
#
|
|
117
|
+
# <tt>unpublished: false</tt>. A version that has aged out of retention
|
|
118
|
+
# raises Mailtea::Error with +code+ "template_version_not_found". Returns
|
|
119
|
+
# +restored+, +restored_from_version+, +unpublished+, +message+ and the
|
|
120
|
+
# updated +template+.
|
|
103
121
|
def restore_version(id, version, params = nil, **filters)
|
|
104
122
|
request(
|
|
105
123
|
"POST",
|
data/lib/mailtea/version.rb
CHANGED
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.
|
|
4
|
+
version: 0.5.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-
|
|
11
|
+
date: 2026-09-28 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.'
|