relaygrid 0.2.0 → 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 +35 -0
- data/QUICKSTART.md +29 -0
- data/README.md +51 -0
- data/lib/relaygrid/delivery.rb +15 -2
- data/lib/relaygrid/resources/messages.rb +12 -0
- data/lib/relaygrid/resources/notifications.rb +40 -2
- data/lib/relaygrid/send_result.rb +27 -2
- data/lib/relaygrid/version.rb +1 -1
- metadata +19 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b882a7bed3e374b22766cb62d2d79d29ce370ac1ac9eb62c3190c3ccf0239e16
|
|
4
|
+
data.tar.gz: 580b2d452d74e956bce502515ed67c0db9747fc38ab40c42c80081970341d345
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a271ee98e4bb2d8720c2e74bd75b57fcfb3eded0f7a3888bac266bba828048463fe47c6721d2aaae1f5b82a1a70a1eae2fa4d2616812f81510f04aa286232352
|
|
7
|
+
data.tar.gz: d7fc151625f6bfa0159839c8f6952c7d7265ab65fbf41445e863d662cd541571e815f9476c7712ccc763a3ff438be52002ca610981787f49050e08488b871488
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,41 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.3.0] - 2026-08-26
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Scheduled deliveries.** `notify` accepts `scheduled_at:` to deliver later
|
|
15
|
+
instead of immediately. A `Time`, `DateTime`, or `ActiveSupport::TimeWithZone`
|
|
16
|
+
is serialized with `.iso8601`, which always emits a UTC offset; a `String` is
|
|
17
|
+
passed through untouched for the server to validate. **The server requires an
|
|
18
|
+
explicit UTC offset and returns a 422 on a naive or malformed timestamp** —
|
|
19
|
+
it never assumes a timezone, so a client that serializes naively would
|
|
20
|
+
otherwise turn into a 422 the caller can't diagnose. A bare `Date` raises
|
|
21
|
+
`ArgumentError` locally, since a date has no instant.
|
|
22
|
+
- `messages.cancel_schedule(id)` withdraws a scheduled send before it
|
|
23
|
+
dispatches (`DELETE /api/v1/messages/:id/schedule`). Raises `ValidationError`
|
|
24
|
+
if the message has already dispatched or been canceled.
|
|
25
|
+
- `SendResult#scheduled?` and `#scheduled_at`, read off the created message.
|
|
26
|
+
- **`wait_for_deliveries` returns immediately for a scheduled send**, without
|
|
27
|
+
polling. A `scheduled` delivery is never terminal — nothing has been handed
|
|
28
|
+
to a provider yet — so without this a caller who scheduled and then waited
|
|
29
|
+
would block for the full `timeout`.
|
|
30
|
+
- Note for integrators: a `201` at schedule time is not a delivery guarantee.
|
|
31
|
+
A scheduled send can still end in `delivery.failed` if the account's
|
|
32
|
+
monthly quota is spent by dispatch time. `push?`/`push_token` are unaffected
|
|
33
|
+
by scheduling — the token is for the device to subscribe now, independent
|
|
34
|
+
of when the message dispatches, because the server reads the template's
|
|
35
|
+
live channels rather than the deliveries.
|
|
36
|
+
|
|
37
|
+
## [0.2.1] - 2026-08-21
|
|
38
|
+
|
|
39
|
+
### Fixed
|
|
40
|
+
|
|
41
|
+
- Gemspec metadata now points at the self-hosted GitLab repository
|
|
42
|
+
(`git.relaygrid.dev`): the homepage, source, and changelog URIs no longer
|
|
43
|
+
reference the old GitHub location. No code changes.
|
|
44
|
+
|
|
10
45
|
## [0.2.0] - 2026-08-06
|
|
11
46
|
|
|
12
47
|
### Added
|
data/QUICKSTART.md
CHANGED
|
@@ -74,6 +74,33 @@ them when you want status. Don't block a web request waiting — see
|
|
|
74
74
|
`wait_for_deliveries` in the README for when that helper is and isn't
|
|
75
75
|
appropriate.
|
|
76
76
|
|
|
77
|
+
## 6a. Schedule for later (optional)
|
|
78
|
+
|
|
79
|
+
Pass `scheduled_at` instead of sending immediately:
|
|
80
|
+
|
|
81
|
+
```ruby
|
|
82
|
+
RelayGrid.client.notify(
|
|
83
|
+
user: current_user.id, template: "order_shipped",
|
|
84
|
+
scheduled_at: Time.now + 1.day # or an ISO 8601 String like "2026-09-01T09:00:00-07:00"
|
|
85
|
+
)
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**The timestamp must carry an explicit UTC offset.** A `Time`/`DateTime`/
|
|
89
|
+
`ActiveSupport::TimeWithZone` is serialized with `.iso8601` for you, which
|
|
90
|
+
always includes one; a naive `String` (no offset) is rejected by the server
|
|
91
|
+
with a 422 rather than assumed to mean UTC. A bare `Date` raises
|
|
92
|
+
`ArgumentError` locally — it has no instant to schedule.
|
|
93
|
+
|
|
94
|
+
A `201` here means the schedule was accepted, not that the message will
|
|
95
|
+
successfully send: a scheduled delivery can still end in `delivery.failed`
|
|
96
|
+
if the account's quota is spent by dispatch time. Withdraw it beforehand with:
|
|
97
|
+
|
|
98
|
+
```ruby
|
|
99
|
+
RelayGrid.client.messages.cancel_schedule(result.message_id)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
See the [README](README.md#scheduling-a-send) for the full behavior.
|
|
103
|
+
|
|
77
104
|
## 7. Receive (optional)
|
|
78
105
|
|
|
79
106
|
If your template has a push channel, the send hands you a token for the
|
|
@@ -104,6 +131,8 @@ ws.connect
|
|
|
104
131
|
| `result.push_token` is `nil` | The template has no live push channel attached. |
|
|
105
132
|
| Delivery stuck at `queued` | The delivery job hasn't run yet; poll again shortly. |
|
|
106
133
|
| Delivery `failed` | Read `delivery.friendly_error_message` — usually channel credentials. |
|
|
134
|
+
| `scheduled_at` gets a 422 | The timestamp has no UTC offset, or isn't a real date/time. Use `Time`/`DateTime`/`ActiveSupport::TimeWithZone`, or an explicit-offset ISO 8601 string. |
|
|
135
|
+
| A scheduled send ends in `delivery.failed` | Quota was spent between scheduling and dispatch. The `201` at schedule time isn't a delivery guarantee. |
|
|
107
136
|
|
|
108
137
|
## Next steps
|
|
109
138
|
|
data/README.md
CHANGED
|
@@ -123,8 +123,53 @@ result.rendered_subject # => "Hi Ada"
|
|
|
123
123
|
result.push_token # => "eyJf..." or nil
|
|
124
124
|
result.push_token_expires_at # => 2026-07-28 11:00:00 +0000
|
|
125
125
|
result.push? # => true when a push channel was dispatched
|
|
126
|
+
result.scheduled? # => true when scheduled_at was set
|
|
127
|
+
result.scheduled_at # => 2026-09-01 16:00:00 +0000, or nil for an immediate send
|
|
126
128
|
```
|
|
127
129
|
|
|
130
|
+
### Scheduling a send
|
|
131
|
+
|
|
132
|
+
Pass `scheduled_at` to deliver later instead of immediately:
|
|
133
|
+
|
|
134
|
+
```ruby
|
|
135
|
+
RelayGrid.client.notify(
|
|
136
|
+
user: "user-123", template: "order_shipped",
|
|
137
|
+
scheduled_at: Time.now + 3600 # or a DateTime, an ActiveSupport::TimeWithZone, or an ISO 8601 String
|
|
138
|
+
)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
A `Time`, `DateTime`, or `ActiveSupport::TimeWithZone` is serialized with
|
|
142
|
+
`.iso8601`, which always emits a UTC offset. A `String` is passed through
|
|
143
|
+
untouched for the server to validate. **The server requires an explicit UTC
|
|
144
|
+
offset and returns a 422 (`RelayGrid::ValidationError`) on a naive or
|
|
145
|
+
malformed timestamp** — it never guesses what timezone you meant, so
|
|
146
|
+
`"2026-09-01T09:00:00"` (no offset) is rejected rather than silently treated
|
|
147
|
+
as UTC. A bare `Date` raises `ArgumentError` locally, before any request is
|
|
148
|
+
made — a date has no instant, so there's no correct offset to send.
|
|
149
|
+
|
|
150
|
+
The message is created immediately with status-`scheduled` deliveries, and
|
|
151
|
+
returns a `201` right away; nothing has reached a channel provider yet. A
|
|
152
|
+
scheduled send can still end in `delivery.failed` at dispatch time if the
|
|
153
|
+
account's monthly quota is spent by then — the `201` at schedule time is not
|
|
154
|
+
a guarantee of delivery, only that the schedule was accepted.
|
|
155
|
+
|
|
156
|
+
The push token, when present, is unaffected by scheduling: it authenticates
|
|
157
|
+
the recipient's device to subscribe *now*, independent of when the message
|
|
158
|
+
actually dispatches. `push?`/`push_token` work exactly as they do for an
|
|
159
|
+
immediate send, because the server reads the template's live channels, not
|
|
160
|
+
the deliveries.
|
|
161
|
+
|
|
162
|
+
Withdraw a scheduled send before it dispatches:
|
|
163
|
+
|
|
164
|
+
```ruby
|
|
165
|
+
RelayGrid.client.messages.cancel_schedule(message_id)
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Only pending messages can be withdrawn. Once dispatch has claimed the row,
|
|
169
|
+
sends may already be going out, and the call raises `ValidationError` (422) —
|
|
170
|
+
there is a small window where a well-timed cancel can lose the race to the
|
|
171
|
+
dispatch sweep.
|
|
172
|
+
|
|
128
173
|
### The push token
|
|
129
174
|
|
|
130
175
|
When the template has a live push channel, the send response carries a token
|
|
@@ -165,6 +210,12 @@ It returns once every delivery is **terminal** — successful or not — so chec
|
|
|
165
210
|
`success?` yourself rather than treating a return as a win. A delivery the server
|
|
166
211
|
is still retrying reads `retrying`, which is why `failed` means final.
|
|
167
212
|
|
|
213
|
+
For a scheduled send (`result.scheduled?`), this returns `deliveries`
|
|
214
|
+
immediately — still reading `status: "scheduled"` — instead of polling. A
|
|
215
|
+
`scheduled` delivery is never terminal, since nothing has been handed to a
|
|
216
|
+
provider yet, so polling it would otherwise just block for the full `timeout`
|
|
217
|
+
waiting on a state change that isn't coming until dispatch.
|
|
218
|
+
|
|
168
219
|
> **This blocks the calling thread.** Use it in a background job, a rake task, or
|
|
169
220
|
> a script — never inside a web request, where it would pin a request thread for
|
|
170
221
|
> up to `timeout` seconds. In a request, return `delivery_ids` and let the
|
data/lib/relaygrid/delivery.rb
CHANGED
|
@@ -15,11 +15,16 @@ module RelayGrid
|
|
|
15
15
|
FAILED = "failed"
|
|
16
16
|
BOUNCED = "bounced"
|
|
17
17
|
OPENED = "opened"
|
|
18
|
+
SCHEDULED = "scheduled"
|
|
19
|
+
CANCELED = "canceled"
|
|
18
20
|
|
|
19
21
|
SUCCESS_STATUSES = [DELIVERED, OPENED].freeze
|
|
20
22
|
|
|
21
|
-
# States the server will not move away from on its own.
|
|
22
|
-
|
|
23
|
+
# States the server will not move away from on its own. `scheduled` is
|
|
24
|
+
# deliberately absent -- only the sweep moves it, which can be well past
|
|
25
|
+
# any reasonable poll timeout. `canceled` is terminal; the server never
|
|
26
|
+
# revives a canceled delivery.
|
|
27
|
+
TERMINAL_STATUSES = (SUCCESS_STATUSES + [FAILED, BOUNCED, CANCELED]).freeze
|
|
23
28
|
|
|
24
29
|
attr_reader :id, :message_id, :status, :channel_id, :channel_name, :channel_type,
|
|
25
30
|
:error_message, :friendly_error_message,
|
|
@@ -79,6 +84,14 @@ module RelayGrid
|
|
|
79
84
|
status == OPENED
|
|
80
85
|
end
|
|
81
86
|
|
|
87
|
+
def scheduled?
|
|
88
|
+
status == SCHEDULED
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def canceled?
|
|
92
|
+
status == CANCELED
|
|
93
|
+
end
|
|
94
|
+
|
|
82
95
|
# Reached a state the server considers final and successful.
|
|
83
96
|
def success?
|
|
84
97
|
SUCCESS_STATUSES.include?(status)
|
|
@@ -58,6 +58,18 @@ module RelayGrid
|
|
|
58
58
|
def render(id)
|
|
59
59
|
@client.get("/api/v1/messages/#{id}/render_message")
|
|
60
60
|
end
|
|
61
|
+
|
|
62
|
+
# Withdraw a scheduled send before it dispatches. Only pending messages
|
|
63
|
+
# can be withdrawn -- once dispatch has claimed the row, channel sends
|
|
64
|
+
# may already be going out, and there's nothing left to cancel.
|
|
65
|
+
#
|
|
66
|
+
# @return [Hash] the message, with `schedule_canceled_reason: "requested"`
|
|
67
|
+
# @raise [RelayGrid::ValidationError] the message already dispatched or
|
|
68
|
+
# was already canceled (the sweep won the race)
|
|
69
|
+
# @raise [RelayGrid::NotFoundError] no such message
|
|
70
|
+
def cancel_schedule(id)
|
|
71
|
+
@client.delete("/api/v1/messages/#{id}/schedule")["message"]
|
|
72
|
+
end
|
|
61
73
|
end
|
|
62
74
|
end
|
|
63
75
|
end
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "date"
|
|
4
|
+
require "time"
|
|
5
|
+
|
|
3
6
|
module RelayGrid
|
|
4
7
|
module Resources
|
|
5
8
|
# Sending. The developer contract the gem exists for: a user, a template
|
|
@@ -28,11 +31,19 @@ module RelayGrid
|
|
|
28
31
|
# Passing an empty string removes the contact.
|
|
29
32
|
# @param template [String] the message template's name
|
|
30
33
|
# @param attributes [Hash] values for the template's `{{placeholders}}`
|
|
34
|
+
# @param scheduled_at [Time, DateTime, ActiveSupport::TimeWithZone, String, nil]
|
|
35
|
+
# when to deliver instead of immediately. A `Time`/`DateTime`/`TimeWithZone`
|
|
36
|
+
# is serialized with `.iso8601`, which always emits a UTC offset; a
|
|
37
|
+
# `String` is passed through untouched for the server to validate. The
|
|
38
|
+
# server rejects a naive or malformed timestamp with a 422 -- it never
|
|
39
|
+
# guesses a timezone. `nil` (the default) sends immediately.
|
|
31
40
|
# @return [RelayGrid::SendResult]
|
|
32
41
|
#
|
|
33
42
|
# @raise [RelayGrid::TemplateNotFoundError] no such template in the account
|
|
34
43
|
# @raise [RelayGrid::LimitExceededError] the monthly notification limit is spent
|
|
35
|
-
# @raise [RelayGrid::ValidationError] the payload was rejected
|
|
44
|
+
# @raise [RelayGrid::ValidationError] the payload was rejected, e.g. a
|
|
45
|
+
# `scheduled_at` with no UTC offset
|
|
46
|
+
# @raise [ArgumentError] `scheduled_at` is a bare `Date`, which has no instant
|
|
36
47
|
#
|
|
37
48
|
# @example
|
|
38
49
|
# result = RelayGrid.client.notify(
|
|
@@ -41,18 +52,45 @@ module RelayGrid
|
|
|
41
52
|
# attributes: { order_number: "1042", eta: "tomorrow" }
|
|
42
53
|
# )
|
|
43
54
|
# result.delivery_ids # => [201, 202]
|
|
44
|
-
|
|
55
|
+
#
|
|
56
|
+
# @example Scheduling a send
|
|
57
|
+
# RelayGrid.client.notify(
|
|
58
|
+
# user: "user-123", template: "order_shipped",
|
|
59
|
+
# scheduled_at: Time.now + 3600 # or "2026-09-01T09:00:00-07:00"
|
|
60
|
+
# )
|
|
61
|
+
def notify(user:, template:, attributes: {}, scheduled_at: nil)
|
|
45
62
|
message = {
|
|
46
63
|
message_template_name: template.to_s,
|
|
47
64
|
message_attributes_attributes: format_attributes(attributes),
|
|
48
65
|
}
|
|
49
66
|
message.merge!(recipient_params(user))
|
|
67
|
+
message[:scheduled_at] = serialize_scheduled_at(scheduled_at) unless scheduled_at.nil?
|
|
50
68
|
|
|
51
69
|
SendResult.new(@client.post("/api/v1/messages", body: { message: message }), client: @client)
|
|
52
70
|
end
|
|
53
71
|
|
|
54
72
|
private
|
|
55
73
|
|
|
74
|
+
# A `Date` has a day but no instant, so there's no correct offset to emit
|
|
75
|
+
# -- `DateTime` (which `Date` is a superclass of) is fine, only a bare
|
|
76
|
+
# `Date` is rejected. Everything else that responds to `iso8601` (`Time`,
|
|
77
|
+
# `DateTime`, `ActiveSupport::TimeWithZone`) is serialized with it; a
|
|
78
|
+
# `String` passes through for the server to validate.
|
|
79
|
+
def serialize_scheduled_at(value)
|
|
80
|
+
return value if value.is_a?(String)
|
|
81
|
+
|
|
82
|
+
if value.is_a?(Date) && !value.is_a?(DateTime)
|
|
83
|
+
raise ArgumentError, "scheduled_at must be a Time, DateTime, or TimeWithZone -- " \
|
|
84
|
+
"a Date has no instant, so there is no offset to serialize"
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
unless value.respond_to?(:iso8601)
|
|
88
|
+
raise ArgumentError, "scheduled_at must be a Time, DateTime, TimeWithZone, or ISO 8601 String"
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
value.iso8601
|
|
92
|
+
end
|
|
93
|
+
|
|
56
94
|
# A Hash upserts the recipient server-side (one round trip instead of
|
|
57
95
|
# registering the user first); a bare id is a strict lookup.
|
|
58
96
|
def recipient_params(user)
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "time"
|
|
4
|
+
|
|
3
5
|
module RelayGrid
|
|
4
6
|
# What `RelayGrid.client.notify` hands back: the message that was created, the
|
|
5
7
|
# deliveries queued for it, and -- when the template has a live push channel
|
|
@@ -7,7 +9,7 @@ module RelayGrid
|
|
|
7
9
|
# realtime channel.
|
|
8
10
|
class SendResult
|
|
9
11
|
attr_reader :message_id, :push_token, :push_token_expires_at, :deliveries,
|
|
10
|
-
:rendered_subject, :rendered_body, :raw
|
|
12
|
+
:rendered_subject, :rendered_body, :scheduled_at, :raw
|
|
11
13
|
|
|
12
14
|
def initialize(body, client:)
|
|
13
15
|
@raw = body
|
|
@@ -17,6 +19,7 @@ module RelayGrid
|
|
|
17
19
|
@message_id = message["id"]
|
|
18
20
|
@rendered_subject = message["rendered_subject"]
|
|
19
21
|
@rendered_body = message["rendered_body"]
|
|
22
|
+
@scheduled_at = parse_time(message["scheduled_at"])
|
|
20
23
|
|
|
21
24
|
@push_token = body["push_token"]
|
|
22
25
|
expires_in = body["push_token_expires_in"]
|
|
@@ -43,16 +46,28 @@ module RelayGrid
|
|
|
43
46
|
deliveries.find { |delivery| delivery.channel_type == channel_type.to_s }
|
|
44
47
|
end
|
|
45
48
|
|
|
49
|
+
# True when this send was scheduled for later rather than sent immediately.
|
|
50
|
+
def scheduled?
|
|
51
|
+
!scheduled_at.nil?
|
|
52
|
+
end
|
|
53
|
+
|
|
46
54
|
# Poll until every delivery reaches a terminal state, or `timeout` seconds
|
|
47
55
|
# elapse. A delivery the server is still retrying reads `retrying`.
|
|
48
56
|
#
|
|
57
|
+
# A `scheduled` delivery is never terminal -- nothing has been handed to a
|
|
58
|
+
# provider yet, so there is nothing to settle -- and polling it would just
|
|
59
|
+
# burn the full `timeout` waiting for a state change that isn't coming
|
|
60
|
+
# until dispatch. When `scheduled?` is true, this returns `deliveries`
|
|
61
|
+
# (each still reading `status: "scheduled"`) immediately without calling
|
|
62
|
+
# the API at all.
|
|
63
|
+
#
|
|
49
64
|
# @param timeout [Numeric] seconds to keep polling
|
|
50
65
|
# @param interval [Numeric] seconds between polls
|
|
51
66
|
# @param raise_on_timeout [Boolean] raise TimeoutWaitingForDeliveries
|
|
52
67
|
# instead of returning the last-seen deliveries
|
|
53
68
|
# @return [Array<RelayGrid::Delivery>] deliveries as last seen
|
|
54
69
|
def wait_for_deliveries(timeout: 30, interval: 2, raise_on_timeout: false)
|
|
55
|
-
return deliveries if deliveries.empty?
|
|
70
|
+
return deliveries if deliveries.empty? || scheduled?
|
|
56
71
|
|
|
57
72
|
@client.deliveries.wait_for(
|
|
58
73
|
delivery_ids,
|
|
@@ -70,5 +85,15 @@ module RelayGrid
|
|
|
70
85
|
"#<RelayGrid::SendResult message_id: #{message_id.inspect}, " \
|
|
71
86
|
"delivery_ids: #{delivery_ids.inspect}, push: #{push?}>"
|
|
72
87
|
end
|
|
88
|
+
|
|
89
|
+
private
|
|
90
|
+
|
|
91
|
+
def parse_time(value)
|
|
92
|
+
return nil if value.nil? || value.to_s.empty?
|
|
93
|
+
|
|
94
|
+
Time.parse(value.to_s)
|
|
95
|
+
rescue ArgumentError
|
|
96
|
+
nil
|
|
97
|
+
end
|
|
73
98
|
end
|
|
74
99
|
end
|
data/lib/relaygrid/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: relaygrid
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ali Zand
|
|
@@ -51,6 +51,20 @@ dependencies:
|
|
|
51
51
|
- - "~>"
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
53
|
version: '0.6'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: activesupport
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '7.1'
|
|
61
|
+
type: :development
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '7.1'
|
|
54
68
|
- !ruby/object:Gem::Dependency
|
|
55
69
|
name: rspec
|
|
56
70
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -153,13 +167,13 @@ files:
|
|
|
153
167
|
- lib/relaygrid/webhooks.rb
|
|
154
168
|
- lib/relaygrid/websocket_client.rb
|
|
155
169
|
- sig/relaygrid.rbs
|
|
156
|
-
homepage: https://
|
|
170
|
+
homepage: https://git.relaygrid.dev/relaygrid/relaygrid-gem
|
|
157
171
|
licenses:
|
|
158
172
|
- MIT
|
|
159
173
|
metadata:
|
|
160
|
-
homepage_uri: https://
|
|
161
|
-
source_code_uri: https://
|
|
162
|
-
changelog_uri: https://
|
|
174
|
+
homepage_uri: https://git.relaygrid.dev/relaygrid/relaygrid-gem
|
|
175
|
+
source_code_uri: https://git.relaygrid.dev/relaygrid/relaygrid-gem
|
|
176
|
+
changelog_uri: https://git.relaygrid.dev/relaygrid/relaygrid-gem/-/blob/master/CHANGELOG.md
|
|
163
177
|
rubygems_mfa_required: 'true'
|
|
164
178
|
rdoc_options: []
|
|
165
179
|
require_paths:
|