broadcast-ruby 0.1.4 → 0.3.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 +113 -0
- data/Gemfile.lock +3 -2
- data/README.md +582 -17
- data/SDK-COVERAGE.md +422 -0
- data/lib/broadcast/client.rb +90 -119
- data/lib/broadcast/configuration.rb +56 -5
- data/lib/broadcast/connection.rb +278 -0
- data/lib/broadcast/debug_logger.rb +64 -0
- data/lib/broadcast/delivery_method.rb +5 -0
- data/lib/broadcast/errors.rb +29 -1
- data/lib/broadcast/resources/autopilots.rb +100 -0
- data/lib/broadcast/resources/discovery.rb +36 -0
- data/lib/broadcast/resources/email_servers.rb +88 -0
- data/lib/broadcast/resources/migration.rb +75 -0
- data/lib/broadcast/resources/opt_in_forms.rb +83 -0
- data/lib/broadcast/resources/subscribers.rb +43 -1
- data/lib/broadcast/resources/templates.rb +17 -0
- data/lib/broadcast/resources/transactionals.rb +86 -0
- data/lib/broadcast/response.rb +104 -0
- data/lib/broadcast/version.rb +1 -1
- data/lib/broadcast/webhook.rb +34 -0
- data/lib/broadcast.rb +9 -0
- metadata +12 -3
- data/.rubocop.yml +0 -48
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fec10ff364f7b63e728e1da143f2e0ff4445e2466f8a9e1a307370142d4c8666
|
|
4
|
+
data.tar.gz: efce695852b7774e6e40f1f91a93ee2487e8d635a579ab0fe20505a9fe4a9efe
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b72667f6f90ecb99ec60d0d9c905f529fbf0f78e30386e78ca93aeb1ac783e2a923750b76a41b73f2da771be67b3bfca012749066614a2ddb99c6cebb093924c
|
|
7
|
+
data.tar.gz: ff0b6ba2de7606b7dbc1fab2c552f6947158cd69ad28ae328d3b23f1d52b8878700802a08d108841e7453b5495398258c70e2e287bbc5ac76e1a908baedab1c1
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,119 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.3.0] - 2026-07-26
|
|
6
|
+
|
|
7
|
+
Catches the gem up to the Broadcast v2.19 API. The API gained a response-warnings
|
|
8
|
+
contract, idempotency keys, and several discovery endpoints since 0.2.0; none of
|
|
9
|
+
them were represented here.
|
|
10
|
+
|
|
11
|
+
### Breaking
|
|
12
|
+
- **`host` is now required.** It previously defaulted to `https://sendbroadcast.com`,
|
|
13
|
+
which 301-redirects to `sendbroadcast.net` — and since the client did not follow
|
|
14
|
+
redirects, the default failed every request with
|
|
15
|
+
`APIError: Unexpected response: 301`. Broadcast is self-hosted-first, so there is
|
|
16
|
+
no URL the gem can guess. Pass `host:` explicitly or set `BROADCAST_HOST`.
|
|
17
|
+
A host without a scheme is now rejected at construction rather than at request time.
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
- **`client.autopilots`** — the Autopilot API (AI-generated newsletters): CRUD,
|
|
21
|
+
activate / pause / deactivate, trigger_run, and runs. The `autopilot_read` /
|
|
22
|
+
`autopilot_write` token permissions existed since 2026-01-30 but had no
|
|
23
|
+
endpoints behind them until Broadcast v2.19.1. `update` strips a bullet-masked
|
|
24
|
+
`openrouter_api_key` so a fetch-modify-save cannot destroy the stored key.
|
|
25
|
+
- **API warnings.** Successful writes can carry a `warnings` array describing what
|
|
26
|
+
the server ignored (`unrecognized_parameter`, `parameter_ignored`,
|
|
27
|
+
`parameter_overridden`, `double_opt_in_skipped`). Exposed as `result.warnings`
|
|
28
|
+
and controlled by `warnings_mode:` — `:log` (default), `:raise`, or `:ignore`.
|
|
29
|
+
- **`Broadcast::Response`.** All JSON calls now return a Hash subclass carrying
|
|
30
|
+
`#warnings`, `#rate_limit`, `#status`, `#headers`, and `#idempotent_replay?`.
|
|
31
|
+
Existing Hash-based code is unaffected.
|
|
32
|
+
- **Idempotent transactional sends.** `transactionals.create(..., idempotency_key:)`
|
|
33
|
+
sends the `Idempotency-Key` header; `Broadcast::ConflictError` maps 409 (previously
|
|
34
|
+
a generic `APIError`).
|
|
35
|
+
- **Rate-limit awareness.** `result.rate_limit` exposes the `X-RateLimit-*` headers,
|
|
36
|
+
`RateLimitError#retry_after` exposes `Retry-After`, and 429s are now retried
|
|
37
|
+
honouring it, bounded by the new `max_retry_delay` setting (default 30s).
|
|
38
|
+
- **Discovery endpoints:** `client.whoami`, `client.status`, `client.prime`, and
|
|
39
|
+
`client.skill` (plain text).
|
|
40
|
+
- **Migration/export namespace:** `client.migration.*` covers all 19 read-only
|
|
41
|
+
endpoints under `/api/migration/v1`, plus `each_record` for automatic paging and
|
|
42
|
+
`download_file_asset` for binary assets. Requires an admin token.
|
|
43
|
+
- **`Broadcast::Webhook::EVENT_TYPES`** and per-category constants (`EMAIL_EVENTS`,
|
|
44
|
+
`SUBSCRIBER_EVENTS`, `BROADCAST_EVENTS`, `SEQUENCE_EVENTS`, `SYSTEM_EVENTS`).
|
|
45
|
+
- `BROADCAST_HOST` / `BROADCAST_API_TOKEN` environment fallbacks, matching the
|
|
46
|
+
Broadcast CLI's config keys.
|
|
47
|
+
- Redirect handling: same-host GETs follow up to 3 hops. Writes, and any redirect
|
|
48
|
+
that changes host, fail with an error naming the target — every request carries
|
|
49
|
+
the bearer token, so following a cross-host redirect would leak it.
|
|
50
|
+
- Documented attributes added to the API after 0.2.0 — template
|
|
51
|
+
`template_purpose` / `confirmation_text` / `default_confirmation` /
|
|
52
|
+
`confirmation_page_settings`; opt-in form `confirmation_email_template_id` /
|
|
53
|
+
`welcome_email_template_id` / `confirmation_redirect_url` /
|
|
54
|
+
`include_unsubscribe_link_in_confirmation`; admin-only `confirmed_at` on
|
|
55
|
+
subscriber create; and the full subscriber list filter set.
|
|
56
|
+
|
|
57
|
+
### Fixed
|
|
58
|
+
- Debug logging redacted: SMTP passwords and provider API keys are no longer written
|
|
59
|
+
to the log when `debug: true`.
|
|
60
|
+
- 2xx responses other than 200/201 (e.g. 204) no longer raise.
|
|
61
|
+
- A 2xx response with a non-JSON body no longer raises `JSON::ParserError`.
|
|
62
|
+
- Error messages now include ActiveModel-style `errors` hashes, not just `error` strings.
|
|
63
|
+
- Binary responses keep binary encoding instead of being tagged UTF-8.
|
|
64
|
+
- The ActionMailer delivery method no longer wraps `WarningError` in `DeliveryError` —
|
|
65
|
+
the email was sent, so reporting a delivery failure would be wrong.
|
|
66
|
+
- **Packaging:** the gemspec shipped this repo's internal planning documents
|
|
67
|
+
(`TODO.md`, `SDK-TODO.md`, `.api-coverage.yml`) and the committed `.gem`
|
|
68
|
+
artifacts at the repo root to every install. The file list now excludes them,
|
|
69
|
+
along with `.github/` and `pkg/`. `SDK-COVERAGE.md` is kept deliberately —
|
|
70
|
+
"what does this gem support" is a user's question.
|
|
71
|
+
|
|
72
|
+
### Internal
|
|
73
|
+
- HTTP transport extracted from `Client` into `Broadcast::Connection`, and debug
|
|
74
|
+
logging into `Broadcast::DebugLogger`.
|
|
75
|
+
- Test coverage for the gemspec's file list, since a wrong package fails
|
|
76
|
+
silently: nothing breaks, the download is just wrong.
|
|
77
|
+
|
|
78
|
+
### Verification
|
|
79
|
+
- 292 tests, rubocop clean.
|
|
80
|
+
- Coverage against the generated OpenAPI document: 104/104 operations
|
|
81
|
+
(`rake "openapi:coverage[../broadcast-ruby]"` in the `broadcast` repo).
|
|
82
|
+
- The built `.gem` was installed into an isolated `GEM_HOME` and exercised.
|
|
83
|
+
- `rake test_live` run against a real self-hosted instance: 14 tests, 52
|
|
84
|
+
assertions, 0 failures. Covers the discovery endpoints, the `X-RateLimit-*`
|
|
85
|
+
headers, and full create/read/update/delete round-trips for subscribers,
|
|
86
|
+
sequences, segments, templates, and webhook endpoints.
|
|
87
|
+
- Two gaps in that run, both deliberate: the transactional **send** test is
|
|
88
|
+
skipped unless `BROADCAST_TEST_EMAIL` is set, so no mail was delivered; and
|
|
89
|
+
the target was a local development instance over plain HTTP, so TLS and
|
|
90
|
+
real-world latency and rate limiting are still unexercised.
|
|
91
|
+
|
|
92
|
+
## [0.2.0] - 2026-04-28
|
|
93
|
+
|
|
94
|
+
### Added
|
|
95
|
+
- `client.opt_in_forms` resource: list, get, create, update, delete, analytics, create_variant, duplicate
|
|
96
|
+
- `client.email_servers` resource: list, get, create, update, delete, test_connection, copy_to_channel
|
|
97
|
+
- `client.transactionals` resource with full create surface (`template_id`, `preheader`, `include_unsubscribe_link`, `subscriber:` attrs); `client.send_email` and `client.get_email` are now thin shims that delegate
|
|
98
|
+
- Double opt-in support: pass `double_opt_in: true` (or a hash with `reply_to:` / `confirmation_template_id:` / `include_unsubscribe_link:`) to `transactionals.create` and `subscribers.create`. Optional top-level `confirmation_template_id:` is also accepted
|
|
99
|
+
- `Configuration#broadcast_channel_id` plus `client.with_channel(id) { ... }` block API for admin/system tokens — auto-includes the channel on every request inside the block (or globally when set on config), without overriding callers that pass it explicitly
|
|
100
|
+
- `Broadcast::AuthorizationError` for 403 responses (previously fell through to a generic `APIError`)
|
|
101
|
+
- Credential redaction scrubber on `email_servers.update`: values matching the API's bullet-redaction shape on known credential fields are stripped from the payload (with a logger warning) so callers can't accidentally round-trip a redacted response back into the model
|
|
102
|
+
|
|
103
|
+
### Notes
|
|
104
|
+
- `opt_in_forms.list` returns up to 250 results per page with `pagination` metadata; only main forms are returned (variants are excluded)
|
|
105
|
+
- `opt_in_forms` `index`/`show` JSON shape (rendered via JBuilder views) differs slightly from `create`/`update` (rendered via the controller's inline serializer)
|
|
106
|
+
- `email_servers.copy_to_channel` requires an admin token and is account-scoped in SaaS mode
|
|
107
|
+
|
|
108
|
+
## [0.1.4] - 2026-03-18
|
|
109
|
+
|
|
110
|
+
### Fixed
|
|
111
|
+
- Register delivery method at class load time instead of in an initializer. ActionMailer's railtie applies config settings (including `broadcast_settings`) inside `on_load(:action_mailer)`, which ran before our initializer-based registration. This caused `undefined method broadcast_settings=` on boot in Rails 8.1.
|
|
112
|
+
|
|
113
|
+
## [0.1.3] - 2026-03-18
|
|
114
|
+
|
|
115
|
+
### Fixed
|
|
116
|
+
- Attempted fix for Railtie timing: use `before: :load_config_initializers`. Did not fully resolve the issue — superseded by 0.1.4.
|
|
117
|
+
|
|
5
118
|
## [0.1.2] - 2026-03-18
|
|
6
119
|
|
|
7
120
|
### Added
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
broadcast-ruby (0.
|
|
4
|
+
broadcast-ruby (0.3.0)
|
|
5
5
|
base64
|
|
6
6
|
|
|
7
7
|
GEM
|
|
@@ -155,6 +155,7 @@ GEM
|
|
|
155
155
|
|
|
156
156
|
PLATFORMS
|
|
157
157
|
arm64-darwin-24
|
|
158
|
+
arm64-darwin-25
|
|
158
159
|
x86_64-linux
|
|
159
160
|
|
|
160
161
|
DEPENDENCIES
|
|
@@ -176,7 +177,7 @@ CHECKSUMS
|
|
|
176
177
|
ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383
|
|
177
178
|
base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b
|
|
178
179
|
bigdecimal (4.0.1) sha256=8b07d3d065a9f921c80ceaea7c9d4ae596697295b584c296fe599dd0ad01c4a7
|
|
179
|
-
broadcast-ruby (0.
|
|
180
|
+
broadcast-ruby (0.3.0)
|
|
180
181
|
builder (3.3.0) sha256=497918d2f9dca528fdca4b88d84e4ef4387256d984b8154e9d5d3fe5a9c8835f
|
|
181
182
|
concurrent-ruby (1.3.6) sha256=6b56837e1e7e5292f9864f34b69c5a2cbc75c0cf5338f1ce9903d10fa762d5ab
|
|
182
183
|
connection_pool (3.0.2) sha256=33fff5ba71a12d2aa26cb72b1db8bba2a1a01823559fb01d29eb74c286e62e0a
|